[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