[CMake] always rebuild executable

Michael Hertling mhertling at online.de
Wed Oct 19 10:26:59 EDT 2011


On 10/18/2011 02:21 PM, Anton Sibilev wrote:
> Hi! Looking for some help..
> I use add_executable(exename) + target_link_libraries (exename
> staticlibname), linux OS. If 'staticlibname' is not under CMake and chagnes
> somehow, CMake will not rebuild executable.
> And so I have a problem, that I have few updates of 'staticlibname' lib, but
> very old executable. Can I force to rebuild executable every build?

What do you mean with "rebuild"? If you just want to *relink* the final
binary - which is sufficient to incorporate a changed static library -
use a full path to the latter as recommended in the meantime. If you
actually want to *recompile* the final binary's object files, you
might do the following:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(REBUILD C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
EXECUTE_PROCESS(COMMAND gcc -c f.c)
EXECUTE_PROCESS(COMMAND ar cr libf.a f.o)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/m1.c "void m1(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/m2.c "void m2(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/m3.c "void m3(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/g.c "void g(void){}\n")
ADD_EXECUTABLE(main main.c m1.c m2.c m3.c)
TARGET_LINK_LIBRARIES(main -L. f)
ADD_CUSTOM_COMMAND(TARGET main POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/main.stamp)
GET_TARGET_PROPERTY(SOURCES main SOURCES)
STRING(REPLACE ";" ":" SOURCES "${SOURCES}")
ADD_CUSTOM_TARGET(invalidate ${CMAKE_COMMAND}
    -DSOURCES=${SOURCES}
    -DPREREQ=${CMAKE_BINARY_DIR}/libf.a
    -DSTAMP=${CMAKE_BINARY_DIR}/main.stamp
    -P ${CMAKE_SOURCE_DIR}/invalidate.cmake)
ADD_DEPENDENCIES(main invalidate)

# invalidate.cmake:
IF("${PREREQ}" IS_NEWER_THAN "${STAMP}")
    STRING(REPLACE ":" ";" SOURCES "${SOURCES}")
    FOREACH(i IN LISTS SOURCES)
        EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E touch ${i})
    ENDFOREACH()
ENDIF()

The invalidate.cmake script - triggered by a custom target - touches
a bunch of source files if a prerequisite is newer than a stamp file.
The latter is generated along with the main executable, and the pre-
requisite is the external static library. Note that one cannot use
-DSTAMP=$<TARGET_FILE:main> as this would introduce a circular
dependency among the targets.

Regards,

Michael


More information about the CMake mailing list