[CMake] Last minute build-date file.

Michael Hertling mhertling at online.de
Fri Oct 15 12:17:02 EDT 2010


On 10/15/2010 04:14 PM, william.crocker at analog.com wrote:
> Hello:
> 
> If my app requires relinking, then at link time
> I would like to capture the current date and time and place it
> in a last-minute source file which is linked with the application.
> Following is my attempt at this with CMake.
> 
> The problems I can see are:
> 1 - It is not portable as it uses the OS date command.
> 2 - It is not portable as it calls gcc directly.
> 3 - It will not work with Debug or Release builds unless
>      I set additional target LINK_FLAGS_<type> properties.
> 4 - I wish the creation of the link_date.cc file could be
>      done inline of the add_custom_command instead of requiring
>      a separate file. (I got into quoting hell.)
> 5 - Sneaking link_date.o onto the link line with the LINK_FLAGS
>      property is kind of a hack.
> 
> Suggestions please.
> 
> Thanks in advance.
> 
> Bill
> 
> -------------------- CMake code --------------
> 
> # Note that this is a simplified version of the real thing
> # and may contain syntax errors.
> 
> add_executable( myapp myapp.cc  )
> target_link_libraries( myapp lib1 lib2 )
> set_target_properties( myapp PROPERTIES LINK_FLAGS link_date.o )
> 
> add_custom_command(
>      TARGET myapp PRE_LINK
>      COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create_link_date
>      COMMAND gcc -m32 -c -I${UTILDIR} link_date.cc
>      COMMENT "Make the link_date file"
>      VERBATIM
> )
> 
> ------------- Contents of create_link_date ----------
> 
> #!/bin/csh
> 
> echo 'const char *link_date() { return("'`date`'"); }' > link_date.cc

You might use CMake's --build option when hooking into the linking stage:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(LINKDATE C)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "
#include <stdio.h>
int main(void)
{
    printf(\"%s\\n\",linkdate());
    return 0;
}")
FILE(WRITE ${CMAKE_BINARY_DIR}/linkdate.c.in "
const char *linkdate() { return(\"@LINKDATE@\"); }
")
FILE(WRITE ${CMAKE_BINARY_DIR}/linkdate.cmake "
EXECUTE_PROCESS(
    COMMAND date
    OUTPUT_VARIABLE LINKDATE
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
CONFIGURE_FILE(\${SRC} \${DST} @ONLY)
")
ADD_CUSTOM_COMMAND(
    OUTPUT ${CMAKE_BINARY_DIR}/linkdate.c
    COMMAND ${CMAKE_COMMAND} -DSRC=linkdate.c.in -DDST=linkdate.c
                             -P linkdate.cmake
    DEPENDS ${CMAKE_BINARY_DIR}/linkdate.c.in)
ADD_LIBRARY(linkdate STATIC EXCLUDE_FROM_ALL linkdate.c)
ADD_EXECUTABLE(main main.c)
TARGET_LINK_LIBRARIES(main linkdate)
ADD_CUSTOM_COMMAND(
    TARGET main
    PRE_LINK
    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/linkdate.c.in
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}
                             --target linkdate)

This rebuilds the target linkdate - a static library containing the
desired timestamp - just before the main target is linked against it.
Thus, the problems you mentioned should be solved except for #1 which
can not be done in a platform-independent manner at the moment, AFAIK.

Regards,

Michael


More information about the CMake mailing list