[CMake] compiling single source with different flags
Michael Wild
themiwi at gmail.com
Wed Dec 30 03:49:19 EST 2009
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