[CMake] compiling single source with different flags

Michael Wild themiwi at gmail.com
Wed Dec 30 15:59:21 EST 2009


Hi

found the problem... Too much quoting, I'm sorry for that.

See below

Michael

On 30. Dec, 2009, at 21:41 , Bart wrote:

> Hi Michael,
> 
> I'm not quite sure if I'm getting the list building right, since if I add an extra source
> file to the project, it generates the int and long files, but then can not find (see below)
> The files are there, and it does find src1, but src2 is not observed. Is this possibly because
> of bad usage of the foreach?
> 
> Sorry to bother you, but this is a mystery to me.
> 
> Thanks,
> 
> Bart
> 
> -- Configuring done
> CMake Error in CMakeLists.txt:
>  Cannot find source file "foo_src2_int.c".  Tried extensions .c .C .c++ .cc
>  .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx
> 
> 
> 
> PROJECT(foo)
> cmake_minimum_required(VERSION 2.6)
> 
> # There will be more than one source file..
> SET(LIBSOURCES foo_src1 foo_src2)
> 
> foreach(libsrc ${LIBSOURCES})
> 
> set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/${libsrc}.c")
> 
> set(DST_I "${CMAKE_CURRENT_BINARY_DIR}/${libsrc}_int.c")
> set(DST_L "${CMAKE_CURRENT_BINARY_DIR}/${libsrc}_long.c")
> 
> 
> CONFIGURE_FILE("${SRC}" "${DST_I}" COPYONLY)
> CONFIGURE_FILE("${SRC}" "${DST_L}" COPYONLY)
> 
> LIST(APPEND LIBSOURCES_I "${DST_I}")
> LIST(APPEND LIBSOURCES_L "${DST_L}")
> 
> endforeach(libsrc)
> 
> SET_SOURCE_FILES_PROPERTIES("${LIBSOURCES_I}" PROPERTIES COMPILE_FLAGS -DDINT)
> SET_SOURCE_FILES_PROPERTIES("${LIBSOURCES_L}" PROPERTIES COMPILE_FLAGS -DDLONG)
> 
> ADD_LIBRARY( foo "${LIBSOURCES_I}" "${LIBSOURCES_L}")
> 

SET_SOURCE_FILES_PROPERTIES(${LIBSOURCES_I} PROPERTIES COMPILE_FLAGS -DDINT)
SET_SOURCE_FILES_PROPERTIES(${LIBSOURCES_L} PROPERTIES COMPILE_FLAGS -DDLONG)

ADD_LIBRARY( foo ${LIBSOURCES_I} ${LIBSOURCES_L})

Without the quoting it works for me. However, I'm not sure what happens if the paths contain spaces...

Michael

> 
> 
> On Dec 30, 2009, at 0:49, Michael Wild wrote:
> 
>> Hi
>> 
>> On 30. Dec, 2009, at 1:48 , Bart wrote:
>> 
>>> Thanks for those suggestions, I was on that path, but I can not get it to work properly:
>>> 
>>> foo$ cmake .
>>> -- Configuring done
>>> -- Generating done
>>> -- Build files have been written to: /home/bart/foo
>>> foo$ make
>>> Scanning dependencies of target foo
>>> make[2]: *** No rule to make target ` /home/bart/foo/foo_int.c', needed by `CMakeFiles/foo.dir/_/home/bart/foo/foo_int.c.o'.  Stop.
>>> make[1]: *** [CMakeFiles/foo.dir/all] Error 2
>>> make: *** [all] Error 2
>>> foo$ ls foo_int.c 
>>> foo_int.c
>>> foo$ 
>>> 
>> 
>> First of all, NEVER do in-source builds. They pollute your source tree and make it impossible to have multiple build configuration simultaneously. Refer to http://www.cmake.org/Wiki/CMake_FAQ#Out-of-source_build_trees for an overview.
>> 
>>> 
>>> ---------------------------
>>> File: CMakeLists.txt
>>> ---------------------------
>>> PROJECT(foo)
>>> 
>>> # There will be more than one source file..
>>> SET(LIBSOURCES foo)
>>> 
>>> foreach(libsrc ${LIBSOURCES})
>>> 
>>> set(DST_I "${CMAKE_CURRENT_SOURCE_DIR}/${libsrc}_int.c")
>>> set(DST_L "${CMAKE_CURRENT_SOURCE_DIR}/${libsrc}_long.c")
>> 
>> change CMAKE_CURRENT_SOURCE_DIR to CMAKE_CURRENT_BINARY_DIR. You don't want to pollute your source tree with generated files.
>> 
>>> 
>>> set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/${libsrc}.c")
>>> 
>>> CONFIGURE_FILE(${SRC} ${DST_I} COPYONLY)
>>> CONFIGURE_FILE(${SRC} ${DST_L} COPYONLY)
>>> 
>> 
>> Also, add quoting here (the paths might contain spaces, you never know):
>> 
>> CONFIGURE_FILE("${SRC}" "${DST_I}" COPYONLY)
>> CONFIGURE_FILE("${SRC}" "${DST_L}" COPYONLY)
>> 
>>> SET(LIBSOURCES_I "${LIBSOURCES_I} ${DST_I}")
>>> SET(LIBSOURCES_L "${LIBSOURCES_L} ${DST_L}")
>> 
>> Use
>> 
>> LIST(APPEND LIBSOURCES_I "${DST_I}")
>> LIST(APPEND LIBSOURCES_L "${DST_L}")
>> 
>> This is faster and much easier to understand. Besides, in your code the quoting is wrong. You'd need to either replace the space by a ; or use quoting like this (lists in CMake are string where the list-elements are separated by a ; character, not space):
>> 
>> SET(LIBSOURCES_I "${LIBSOURCES_I}" "${DST_I}")
>> SET(LIBSOURCES_L "${LIBSOURCES_L}" "${DST_L}")
>> 
>> 
>>> 
>>> endforeach(libsrc)
>>> 
>>> SET_SOURCE_FILES_PROPERTIES({LIBSOURCES_I} PROPERTIES COMPILE_FLAGS "-DDINT")
>>> SET_SOURCE_FILES_PROPERTIES({LIBSOURCES_L} PROPERTIES COMPILE_FLAGS "-DDLONG")
>> 
>> You forgot the $ and probably should add quoting:
>> 
>> SET_SOURCE_FILES_PROPERTIES("${LIBSOURCES_I}" PROPERTIES COMPILE_FLAGS -DDINT)
>> SET_SOURCE_FILES_PROPERTIES("${LIBSOURCES_L}" PROPERTIES COMPILE_FLAGS -DDLONG)
>> 
>>> SET_SOURCE_FILES_PROPERTIES(${LIBSOURCES_I} PROPERTIES GENERATED true)
>>> SET_SOURCE_FILES_PROPERTIES(${LIBSOURCES_L} PROPERTIES GENERATED true)
>> 
>> Above two lines are not required, since the sources are generated at CMake-time and not at build-time. They might even be harmful...
>> 
>>> 
>>> ADD_LIBRARY( foo ${LIBSOURCES_I} ${LIBSOURCES_L})
>> 
>> Again, quoting should be added for safety:
>> 
>> ADD_LIBRARY( foo "${LIBSOURCES_I}" "${LIBSOURCES_L}")
>> 
>> 
>> I hope this helps and things work as expected...
>> 
>> Michael
>> 
>>> 
>>> If I remove the generated property lines, cmake can not find the generated source files, either way there is 
>>> a problem with the dependencies as generated from my CMakeList.
>>> 
>>> Thanks for the help.
>>> 
>>> 
>>> 
>>> On Dec 29, 2009, at 12:52, Michael Wild wrote:
>>> 
>>>> 
>>>> On 29. Dec, 2009, at 21:44 , Eric Noulard wrote:
>>>> 
>>>>> 2009/12/29 Richard Wackerbarth <richard at nfsnet.org>:
>>>>>> Not as a "real" solution, but more as a "workaround", you could create a "derived source file" which is just a copy of the source file and then you would have two separate files to be compiled with the appropriate flags.
>>>>> 
>>>>> That's one solution, see below for more information.
>>>>> 
>>>>>> On Dec 29, 2009, at 2:22 PM, Bart wrote:
>>>>>> 
>>>>>>> Hi,
>>>>>>> 
>>>>>>> I'm trying to find a way to build a library with two different instances of the same source file.
>>>>>>> for example I would like to compile foo.c with -DDINT into foo_int.o and with -DDLONG into foo_long.o
>>>>>>> and have both objects added to the same library libfoo.a
>>>>>>> 
>>>>>>> I have experimented with custom command to generate the source files (which did not work), and would have still
>>>>>>> left me with how to compile them with different -D flags.
>>>>> 
>>>>> Same kind of question has been asked on the ML recently,
>>>>> may be you can re-read the thread
>>>>> http://www.cmake.org/pipermail/cmake/2009-December/033813.html
>>>>> 
>>>> 
>>>> Or you can use CONFIGURE_FILE to create "wrappers" which #include the actual source file. If it's always the same flags, you can do it statically, using something like this:
>>>> 
>>>> wrap_foo.c:
>>>> /* -------------------------- */
>>>> /* clean up */
>>>> #ifdef DINT
>>>> #undef DINT
>>>> #endif
>>>> #ifdef DLONG
>>>> #undef DLONG
>>>> #endif
>>>> 
>>>> /* compile for int */
>>>> #define DINT
>>>> #include "foo.c"
>>>> #undef DINT
>>>> 
>>>> /* compile for long */
>>>> #define DLONG
>>>> #include "foo.c"
>>>> #endif 
>>>> /* -------------------------- */
>>>> 
>>>> Michael
>>>> 
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>> 
>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>> 
>>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>>> 
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.cmake.org/mailman/listinfo/cmake
>>>> 
>>> 
>> 
>> 
> 



More information about the CMake mailing list