[CMake] Recompiles everything every time
Michael Hertling
mhertling at online.de
Thu Feb 10 19:30:31 EST 2011
On 02/10/2011 09:47 PM, Collier, Jack wrote:
> I have a large project that I recently converted from autotools to cmake. Everything works great save for the fact that everytime I make the project every single source file is recompiled. I think the reason is that my build relies on a number of custom targets this generate a bunch of header files that are used by almost all the other sources in the project. According to the documentation for add_custom_target the target is always considered out of date so it will recompile everytime. Is there anyway to get around this and only compile if something has changed? I have included one of the custom targets and the associated custom command below:
>
>
> #Add command to compile IDL files
> ADD_CUSTOM_TARGET(CompileIdl ALL)
> ADD_CUSTOM_COMMAND(
> DEPENDS ${TAO_IDL}
> COMMAND ${TAO_IDL} -in -hc C.h -cs C.cpp -ci C.i.h -hs S.h -hT S_T.h -ss S.cpp -sT S_T.cpp -si S.i.h ${IDL_INCLUDES} ${SRC_FINAL}
> TARGET CompileIdl
> OUTPUTS ${IDL_CLIENT_CPP} ${IDL_CLIENT_H} ${IDL_CLIENT_IH} ${IDL_SERVER_CPP} ${IDL_SERVER_H} ${IDL_SERVER_IH}
> )
>
> #Now compile the generated sources
> SET(BUILT_SOURCES ${IDL_CLIENT_CPP} ${IDL_CLIENT_H} ${IDL_CLIENT_IH} ${IDL_SERVER_CPP} ${IDL_SERVER_H} ${IDL_SERVER_IH} )
> SET_SOURCE_FILES_PROPERTIES(${BUILT_SOURCES} PROPERTIES GENERATED true)
Don't attach the custom command to the custom target, but make the
latter depend on the former, i.e. don't use the TARGET signature:
ADD_CUSTOM_COMMAND(
OUTPUT ${IDL_CLIENT_CPP} ${IDL_CLIENT_H} ${IDL_CLIENT_IH}
${IDL_SERVER_CPP} ${IDL_SERVER_H} ${IDL_SERVER_IH}
COMMAND <whatever-necessary-to-generate-the-output-files>
DEPENDS <all-prerequisites-of-the-output-files-to-generate>
)
ADD_CUSTOM_TARGET(CompileIdl ALL
DEPENDS ${IDL_CLIENT_CPP} ${IDL_CLIENT_H} ${IDL_CLIENT_IH}
${IDL_SERVER_CPP} ${IDL_SERVER_H} ${IDL_SERVER_IH}
)
Although the custom target is always out of date, the custom command
runs only if an OUTPUT file doesn't exist or a prerequisite after the
DEPENDS clause is newer. For this to work well, it is inevitable that:
1) The custom command carefully denotes all OUTPUT files - BTW, the
option is named OUTPUT, not OUTPUTS, and you don't need to set the
GENERATED property for these files explicitly.
2) The custom command carefully denotes all prerequisites of the OUTPUT
files after the DEPENDS clause, i.e. everything that should trigger
the OUTPUT files' regeneration when it's changed.
3) The custom target carefully denotes the custom command's OUTPUT
files as prerequisites after its DEPENDS clause.
If not all of the OUTPUT files depend on each prerequisite after the
DEPENDS clause, consider to use multiple custom commands in order to
reduce the dependency graph as far as possible, but no further. ;)
'hope that helps.
Regards,
Michael
More information about the CMake
mailing list