On 06/02/2010 04:23 PM, Doug Reiland wrote: > I am porting a library over to cmake. > This library is built both shared and static AND has several composite > objects that get linked in. > > For example, > > subdir-a had makefile that compiled and linked a1.c a2.c into ../a.o > > top directory linked in a.o into it's libs (shared and static)
Usually, source files are supposed to be compiled with different flags targeting a shared or a static library; thus, linking the same object file into both types of the library is a rather bad approach, IMO. > I have converted most of this over to cmake by: > > subdir-a's CMakeList.txt > - make a shared lib and top directory shared lib link in via > target_link_libraries So, you have an additional shared library to deal with; to me, this seems to be an avoidable complication of things. > - add it's list of source files to a global property. top > directory CMakeList.txt looks for that property and adds those files > to its list for it's static library Add subdir-a/a{1,2}.c to a list that contains all source files your library is made from and build the shared and static variants with: ADD_LIBRARY(mylib-shared SHARED ${SOURCES}) ADD_LIBRARY(mylib-static STATIC ${SOURCES}) Finally, use the target property OUTPUT_NAME for proper naming. > This is cumbersome, but it is working ok. > However, I am now running to other stuff the subdirs are doing, like > custom compile flags and dependencies. > > Question 1) Is the best method to handle these to get add more unique > (by source file name) properties in the global scope and have top > level CMakeList.txt look for them? No, I wouldn't say so. Use source file properties to impose compile flags where necessary and ADD_CUSTOM_COMMAND(OUTPUT ...) to define dependencies on generated files. > Question 2) How to handle custom targets at the subdir-level for the > static library? For example, I have: > a1.c which includes aa.c and ab.c > aa.c and ab.c are generated by a perl script Don't name them aa.c and ab.c but, say, aa.gen and ab.gen and modify a1.c accordingly, i.e. #include "aa.gen" and #include "ab.gen". In the parent directory's CMakeLists.txt, ADD_CUSTOM_COMMAND(OUTPUT aa.gen ...) ADD_CUSTOM_COMMAND(OUTPUT ab.gen ...) and add a{a,b}.gen to the source file list mentioned above. Note that such ADD_CUSTOM_COMMAND()s must reside in the same CMakeLists.txt as the ADD_LIBRARY() et al. processing the output files; otherwise, they will not be triggered when the library is rebuilt, i.e., you can't have the ADD_CUSTOM_COMMAND()s in subdir-a/CMakeLists.txt while their OUTPUT is mentioned in ADD_LIBRARY() in the parent directory's CMakeLists.txt. The renaming of a{a,b}.c to a{a,b}.gen is necessary to prevent CMake from compiling them twice, one time as direct prerequisites of the library and another time when compiling a1.c as included files. So, they're just an anchor for CMake's dependency tracking to trigger ADD_CUSTOM_COMMAND(). > In subdir's CMakeList.txt I have, note add_sources, and > add_file_dependencies are not included here, but add the absolute > filenames to the global property for top-level library and > add_file_source_properties(). I have already managed to extended > add_file_dependencies() to add per-file global property where > top-level Makefile to look to see if it needs to set > source_file_properties, but I have no idea how to handle this > custom_command. The shared library build works fine. > > set(name my-subdir-lib) > set(build-dir ${CMAKE_CURRENT_BINARY_DIR}) > set(source-dir ${CMAKE_CURRENT_SOURCE_DIR}) > set(generated-files aa.c ab.c) > > foreach (g ${generated-files}) > add_custom_command( > OUTPUT ${build-dir}/${g} > DEPENDS ${source-dir}/my_perl_script.pl > ${source-dir}/some_header_file.h > COMMAND ${source-dir}/my_perl_script.pl > ARGS -i ${source-dir}/some_header_file.h -o > ${build-dir}/${g} > ) > set(generated-results ${generated-results} ${build-dir}/${g}) > endforeach() > > > set(sources > a1.c a2.c > a3.c > ) > > add_file_dependencies(a3.c ${generated-results}) > add_sources(super ${sources}) > > include_directories( > ${source-dir} > ${build-dir} > ) > > add_library(${name} SHARED ${sources}) My advice would be - in the parent directory's CMakeLists.txt: set(name my-lib) set(build-dir ${CMAKE_CURRENT_BINARY_DIR}) set(source-dir ${CMAKE_CURRENT_SOURCE_DIR}) set(generated-files aa.gen ab.gen) foreach (g ${generated-files}) add_custom_command( OUTPUT ${build-dir}/${g} DEPENDS ${source-dir}/subdir-a/my_perl_script.pl ${source-dir}/subdir-a/some_header_file.h COMMAND ${source-dir}/subdir-a/my_perl_script.pl ARGS -i ${source-dir}/subdir-a/some_header_file.h -o ${build-dir}/${g} ) list(APPEND generated-results ${build-dir}/${g}) endforeach() set(sources subdir-a/a1.c subdir-a/a2.c subdir-a/a3.c ${generated-results} ) # add_file_dependencies(a3.c ${generated-results}) # add_sources(super ${sources}) set_source_files_properties(...) include_directories( ${source-dir}/subdir-a ${build-dir} ) add_library(${name}-shared SHARED ${sources}) add_library(${name}-static STATIC ${sources}) set_target_properties(${name}-shared PROPERTIES OUTPUT_NAME ${name}) set_target_properties(${name}-static PROPERTIES OUTPUT_NAME ${name}) Btw, if you absolutely want to use properties in the manner you've presented here consider to create custom target and source file properties instead global ones since they obviously relate to targets and source files and are not of global concern. 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