[CMake] BUILD_COMMAND having a hard time getting usable command lines

Michael Hertling mhertling at online.de
Mon Nov 28 20:53:50 EST 2011


On 11/28/2011 08:43 PM, J Decker wrote:
> So the idea was, to make the build process a single click (or couple)
> or at least a single application to build.  Since CMake knows how to
> build a project, it became easier to maintain a cmakelists.txt which
> does the build than a batch file...
> 
> So my top most level project now is a series of targets which do a
> build and an install and possibly additional commands between each
> target.  (Some project have deploy commands that build other scripts
> that get used later in the build).
> 
> By adding some options to do the build command at the end of the
> script (especially if those options default as off) I figured I could
> trigger a build.
> 
> Yes; If I do 'cmake -G 'SomeGenerator' -DGENERATOR_BUILD_ALL_NOW=1'
> then in a clean directory, this fails to actually to the build,
> repeating this command allows the project build to commence.
> 
> If I don't use the command line with the custom knowledge that things
> exist in a cmakelists; and I use 'cmake-gui' then point it at the
> sources, click 'configure' and the options are read, and hmm I guess I
> could still just configure and not generate and set the build now
> option; then the build can happen automatically from just knowing
> cmake, not the environment specific mingw32-make.exe or wmake or
> devenv or whatever

(1) Build the following project from the VS command prompt:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(BUILD C)
ADD_EXECUTABLE(main main.c)
SET_TARGET_PROPERTIES(main PROPERTIES
    COMPILE_DEFINITIONS NUMBER=1)

/* main.c: */
#include <stdio.h>
int main(void)
{
    printf("%d\n",NUMBER); return 0;
}

Now, set NUMBER to 2 in the CMakeLists.txt file and rebuild with
"cmake --build", so in the end, you do the same as the command line
returned by BUILD_COMMAND() would do. You'll see that the project is
reconfigured but not rebuilt although the modified COMPILE_DEFINITIONS
effect the executable. That's because a touched .vcproj file obviously
doesn't have VC rebuild the associated targets. Of course, this isn't
caused by your building-while-configuring approach, but the latter
makes it harder to account for inconveniences of that kind.

(2) Configure the following project from the CMake GUI:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(THREETIMES C)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c)
OPTION(OPTION_X "Option X" OFF)
IF(OPTION_X)
    OPTION(OPTION_Y "Option Y" OFF)
ENDIF()
IF(OPTION_Y)
    OPTION(OPTION_Z "Option Z" OFF)
ENDIF()

After the second run, when there are no more red entries in the cache
window, check the OPTION_X box, reconfigure and the OPTION_Y box will
appear. Check it and reconfigure to see the OPTION_Z box. In order to
enable OPTION_{X,Y,Z}, you have to reconfigure three times, see [1,2]
for more information. In general, you must be prepared to reconfigure
an arbitrary number of times till you reach the desired configuration.
You would definitely not want to rebuild the project each time.

(3) It's even possible to cause a, say, configuration loop:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LOOP C)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c)
OPTION(LOOP "Option LOOP" OFF)
IF(LOOP)
    UNSET(LOOP CACHE)
ELSE()
    SET(LOOP ON CACHE BOOL "Option LOOP" FORCE)
ENDIF()

Configure the project multiple times from the CMake GUI and you will
see that the cache doesn't stabilize; instead, it oscillates between
two states. Of course, this example is pathological but proves that
the cache might generally traverse a cycle of states - one step per
reconfiguration - and only the user can know which state is the
desired one. You would definitely not want... see above.

The essence is: Even if your approach worked from within the CMake GUI,
it might have serious conceptional drawbacks, depending on the project,
so you should heed David's counsel and simply not pursue it, IMO.

Regards,

Michael

[1] http://www.cmake.org/cmake/help/runningcmake.html
[2] http://www.mail-archive.com/cmake@cmake.org/msg31287.html


More information about the CMake mailing list