[CMake] set_target_properties not setting COMPILE_DEFINITIONS?

Michael Hertling mhertling at online.de
Tue Mar 29 01:58:13 EDT 2011


On 03/29/2011 07:47 AM, Michael Hertling wrote:
> On 03/28/2011 08:23 PM, David Doria wrote:
>> I have setup a list of definitions:
>>
>> SET(MAIN_BUILD_DEFINITIONS "${MAIN_BUILD_DEFINITIONS} UNIX;")
>> SET(MAIN_BUILD_DEFINITIONS "${MAIN_BUILD_DEFINITIONS} PIXEL_DIMENSION=3;")
>>
>> I display them and apply them to my executable as follows:
>>
>> add_executable(ImageCompleter ${MainSources})
>> message("Main build definitions: " ${MAIN_BUILD_DEFINITIONS})
>> set_target_properties(ImageCompleter PROPERTIES COMPILE_DEFINITIONS
>> "${MAIN_BUILD_DEFINITIONS}")
>>
>> The output is:
>> Main build definitions:  UNIX PIXEL_DIMENSION=3
>>
>> which looks correct (i.e. UNIX was defined)
>>
>> However, in my code there is:
>>
>> #if defined(UNIX)
>> 	... some code...
>> #else
>> #error "Not implemented for this platform!"
>> #endif
>>
>> When I build, the error is produced, indicating that UNIX was not defined.
>>
>> I created a small standalone example and it worked as expected... any
>> suggestions of what else to check?
>>
>> Thanks,
>>
>> David
> 
> AFAICS, you mess up the value of the MAIN_BUILD_DEFINITIONS
> list variable. Look at the following CMakeLists.txt file:
> 
> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
> PROJECT(COMPDEFS C)
> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
> ADD_EXECUTABLE(main main.c)
> SET(MAIN_BUILD_DEFINITIONS
>     "${MAIN_BUILD_DEFINITIONS} UNIX;")
> LIST(LENGTH MAIN_BUILD_DEFINITIONS n)
> MESSAGE("MAIN_BUILD_DEFINITIONS: ${MAIN_BUILD_DEFINITIONS} -- n=${n}")
> SET(MAIN_BUILD_DEFINITIONS
>     "${MAIN_BUILD_DEFINITIONS} PIXEL_DIMENSION=3;")
> LIST(LENGTH MAIN_BUILD_DEFINITIONS n)
> MESSAGE("MAIN_BUILD_DEFINITIONS: ${MAIN_BUILD_DEFINITIONS} -- n=${n}")
> SET_TARGET_PROPERTIES(main PROPERTIES
>     COMPILE_DEFINITIONS "${MAIN_BUILD_DEFINITIONS}")
> 
> CMake's output contains:
> 
> MAIN_BUILD_DEFINITIONS:  UNIX; -- n=2
> MAIN_BUILD_DEFINITIONS:  UNIX; PIXEL_DIMENSION=3; -- n=3
> 
> Provided that MAIN_BUILD_DEFINITIONS is initially empty, the command
> SET(MAIN_BUILD_DEFINITIONS "${MAIN_BUILD_DEFINITIONS} UNIX;") makes
> MAIN_BUILD_DEFINITIONS a list of *two* elements: " UNIX" - note the
> leading blank - and the empty string "", and the second SET() adds
> "PIXEL_DIMENSION=3". Probably, this is not what you intended. ;)
> 
> Instead, try
> 
> LIST(APPEND MAIN_BUILD_DEFINITIONS "UNIX")
> LIST(APPEND MAIN_BUILD_DEFINITIONS "PIXEL_DIMENSION=3")
> 
> and CMake's output changes to
> 
> MAIN_BUILD_DEFINITIONS: UNIX -- n=1
> MAIN_BUILD_DEFINITIONS: UNIX;PIXEL_DIMENSION=3 -- n=2
> 
> which should work when used as COMPILE_DEFINITIONS property.
> 
> IMO, the rule of thumb is: Don't use semicolons explicitly in SET()
> commands to assign list variables, but let CMake do this by itself.
> Moreover, be particularly careful when SETting list values, e.g.
> 
> SET(A1 "a")
> SET(AB1 "${A1} b")
> LIST(LENGTH AB1 n)
> MESSAGE("AB1: ${AB1} -- n=${n}")
> SET(A2 "a" "a")
> SET(AB2 "${A2} b")
> LIST(LENGTH AB2 n)
> MESSAGE("AB2: ${AB2} -- n=${n}")
> 
> results in
> 
> AB1: a b -- n=1
> AB2: a;a b -- n=2
> 
> i.e. AB1 is a non-list value which might by unexpected, and AB2 remains
> a list with just two elements which might be unexpected, too. Here, the
> correct coding is SET(AB1 "${A1}" "b") and SET(AB2 "${A2}" "b") which
> could nevertheless lead to AB{1,2} being lists of length two with an
> empty first element if AB{1,2} have been empty before. When adding

Oops: "... if A{1,2} have been empty before.", to be exact. 8-0

> elements to lists it's best to use the LIST(APPEND ...) command.
> 
> BTW, I can see the abovementioned CMakeLists.txt work correctly with
> CMake 2.8.4, so what version of CMake do you use for your project?
> 
> Regards,
> 
> Michael


More information about the CMake mailing list