On 11/26/2010 05:00 PM, Sebastian Schaetz wrote: > Hi, > > I have a somewhat weird setup to build binaries for the Cell processor: > > |-- CMakeLists.txt > |-- kernels > | |-- CMakeLists.txt > | `-- kernel.cpp > `-- main.cpp > > From the main.cpp in the root directory the executable is built. > > In the kernels folder strange things (have to) happen: first the kernel.cpp is > compiled with a custom compiler (I use a combination of SET, CMAKE_C_COMPILER > and ADD_EXECUTABLE), then this binary is converted into a library using a > custom > POST_BUILD command that calls a special tool to do just that. If the binary is > called kernel_executable_bin, the custom command generates a file > libkernel_executable.a > > Now I have to link this library to my main executable (built from main.cpp). > What I did so far is to put in the kernels/CMakeLists.txt file: > > add_dependencies(main_target kernel_executable_bin) > > and in the /CMakeLists.txt file: > > link_directories("${CMAKE_CURRENT_BINARY_DIR}/kernels/") > target_link_libraries(main_target kernel_executable) > > This works as expected for one ugly flaw: if I only change kernels/kernel.cpp > it > won't relink the main_target. I have thus far been unsuccessful in getting > this > to work. I've tried various combinations of add_library(STATIC IMPORTED) and > add_custom_target(DEPENDS) but it won't work. > > Any ideas would be greatly appreciated.
Despite TARGET_LINK_LIBRARIES(), there's no dependency of main_target on libkernel_executable.a, so main_target isn't relinked if the kernel stuff is rebuilt. Nevertheless, there're some approaches I could offer: 1) In the top-level CMakeLists.txt, you might say SET_SOURCE_FILES_PROPERTIES( main.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/kernels/libkernel_executable.a ) When libkernel_executable.a has changed, this results in recompiling main.cpp - a penalty - and the desired relinking of main_target. If main.cpp's recompilation is expensive you may possibly add an empty cpp file to main_target's sources and impose the property on that. 2) In kernels/CMakeLists.txt, add the following lines FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/empty.c) ADD_LIBRARY(empty STATIC empty.c) ADD_CUSTOM_COMMAND(TARGET kernel_executable_bin POST_BUILD COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/empty.c ) or enhance the custom command which creates libkernel_executable.a from kernel_executable_bin by the "cmake -E touch" shown above. Finally, in the top-level CMakeLists.txt, say: TARGET_LINK_LIBRARIES(main_target kernel_executable empty) When kernels/kernel.cpp has changed the kernel_executable_bin and libkernel_executable.a are rebuilt as usual, but kernels/empty.c is touched by the way. This results in rebuilding libempty.a which in turn makes main_target be relinked since it depends on the empty library. If there's trouble with an empty static library just write some dummy code in kernels/empty.c that you don't refer to from anywhere in the project. 3) If you get along with Makefiles you may possibly use a script in junction with the RULE_LAUNCH_LINK target property to generate the libkernel_executable.a from kernel_executable_bin as an actual target like ADD_LIBRARY(kernel_executable STATIC "") ADD_DEPENDENCIES(kernel_executable kernel_executable_bin) so the TARGET_LINK_LIBRARIES(main_target kernel_executable) in the top-level CMakeLists.txt should be sufficient to trigger the linker. 'hope that helps. Regards, 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