[CMake] cmake side effects: possible bug

William A. Hoffman billlist at nycap.rr.com
Sun Aug 27 16:30:43 EDT 2006


At 12:00 PM 8/27/2006, Steve Johns wrote:
>Michael Bell wrote:
>>>ADD_CUSTOM_TARGET(makeExecutable ALL)
>>>FOREACH(file ${SCRIPTS})
>>>   CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}
>>>       ${EXECUTABLE_OUTPUT_PATH}/../${file}
>>>       @ONLY)
>>>   ADD_CUSTOM_COMMAND(
>>>       TARGET makeExecutable
>>>       POST_BUILD
>>>       COMMAND chmod
>>>       ARGS +x ${EXECUTABLE_OUTPUT_PATH}/../${file}
>>>       )
>>>ENDFOREACH(file)
>
>Like MB, I would have assumed that the code above in CMakelists.txt in a subdir would operate on (only) that subdir when 'make' was invoked in that subdir.
>
>Brad King wrote in reply:
>>CMake now always runs globally, which makes most things MUCH easier to
>>implement.  There is no longer a "local generate" capability.
>>
>>You can use CONFIGURE_FILE and EXECUTE_PROCESS to do this all at CMake time.
>
>Would it be possible to elaborate on the CMake processing sequence so that the reason why the given code doesn't produce the assumed effect can be clear?
>
>IOW, I guess I'm not clear on what the summary statement "CMake now always runs globally" really means, and I'd like to replace my flawed assumptions with good facts!
>
>This is a point of understanding for me, not a current production issue, so if the explanation awaits a "calm moment"  (does such exist? :^), that's cool by me.  (It might even make a good addition to the online docs somewhere ...)

I will give it a try.   All CMake commands are run at CMake run time.  They are
used to generated makefiles, IDE files, and other files used at build time. 
CONFIGURE_FILE creates a file when CMake is run, not when the build system is run.
ADD_CUSTOM_COMMAND is used to create commands that are run a build time, by the
build system (makefile or IDE).   Under most cases cmake will not run during the build.
There are hooks put into the build system that check to see if a cmake input file
(input to configure command, or a cmakelist.txt file) has changed since the last run
of cmake, and this will re-run cmake.  

The global vs. local cmake goes back to the original makefile generator in cmake.
When cmake is run on a project now, it will read ALL cmakelist files for that project.
The original makefiles allowed for a local run of cmake that only read a sub-set of
cmakelist files in that were local to that directory.  This caused many problems,
variables set in other cmakefiles were not set, and it often produced unexpected results
because of this.   So, cmake is now always run on the whole project.

So, in the above example, the foreach and configure_file will run when cmake is
run on the project, and not when make is run.  The custom target will run when make
is run but not the foreach and configure_file.

-Bill



More information about the CMake mailing list