Hello! I'm converting a legacy C code base with a slightly unusual problem, but one that I've seen elsewhere occasionally. Basically, the libraries were not written with any concept of namespace cleanliness, and when they are linked together there are many symbol conflicts. Worse, there are symbol conflicts in object files with the same name, which apparently silently link successfully without warning!
The legacy build system used some scripting to process all libraries and object files through objcopy, and I'm attempting to do something similar in cmake. I'd appreciate any critique and improvements for this code. Particularly, I'm not sure why using "${TARGET_PROPERTY:${target},INTERFACE_LINK_LIBRARIES>" doesn't work. I'd also love help simplifying the two custom commands. The approach I'm taking is to define a new target: ${target}-doexport which renames all symbols in the library except for the exported ones. I then create an INTERFACE library named ${target}-export which copies the INTERFACE properties from the orginal target and uses output that has been properly prefixed. FInally, I create an alias target to the new library, which is what is actually used in the rest of the codebase to link against. It's expect to be used like so: add_library(foo bar.c) target_link_libraries(foo PUBLIC Threads::Threads) target_include_directories(foo PUBLIC inc) target_export_symbols(foo project::foo symbol1 another_symbol ) #or refer to symbols in another file target_export_symbols(foo project::foo INTERFACE foo_exports ) function(target_export_symbols target export_target) set(options) set(oneValueArgs INTERFACE) set(multiValueArgs) cmake_parse_arguments(PARSE_ARGV 2 export "${options}" "${oneValueArgs}" "${multiValueArgs}") set(name "${CMAKE_CURRENT_BINARY_DIR}/lib${target}.a") set(export_name "${CMAKE_CURRENT_BINARY_DIR}/lib${target}-export.a") set(stamp ${CMAKE_CURRENT_BINARY_DIR}/${target}-export.stamp) set(prefix ${target}_) set(exports ${CMAKE_CURRENT_BINARY_DIR}/${target}-exported_symbols) set(renames ${CMAKE_CURRENT_BINARY_DIR}/${target}-renamed_symbols) if(export_INTERFACE AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${export_INTERFACE}) set(interface ${CMAKE_CURRENT_SOURCE_DIR}/${export_INTERFACE}) set(interface_cmd "`cat ${interface}`") else() set(interface) set(interface_cmd) endif() add_custom_command(OUTPUT ${exports} DEPENDS "${interface}" ${CMAKE_CURRENT_LIST_FILE} COMMAND echo ${interface_cmd} ${export_UNPARSED_ARGUMENTS} | perl -lane \'print \"\$$_\\$$\" for @F\' > ${exports} ) add_custom_command(OUTPUT ${stamp} ${export_name} COMMENT "Unexporting symbols from ${target}" DEPENDS ${exports} ${target} COMMAND nm --defined-only -g ${name} | grep -v -e\'^ W\' -e\'^ V\' -f ${exports} | awk \'NF>2 { print \$$3 \" ${prefix}\" \$$3 }\' | sort -u > ${renames} COMMAND objcopy --redefine-syms=${renames} ${name} ${export_name} COMMAND cmake -E touch ${stamp} ) add_library(${target}-export INTERFACE) add_custom_target(${target}-doexport DEPENDS ${stamp}) add_dependencies(${target}-export ${target} ${target}-doexport) foreach(prop INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_LINK_LIBRARIES INTERFACE_INCLUDE_DIRECTORIES) set(val "$<TARGET_PROPERTY:${target},${prop}>") # INTERFACE_LINK_LIBRARIES causes linker failures when used with above generator expression... if (${prop} MATCHES INTERFACE_LINK_LIBRARIES) get_target_property(val ${target} ${prop}) if (NOT val) set(val "") endif() list(APPEND val ${export_name}) endif() if(val) set_target_properties(${target}-export PROPERTIES "${prop}" "${val}") endif() endforeach() add_library(${export_target} ALIAS ${target}-export) endfunction() -- Sent from: http://cmake.3232098.n2.nabble.com/ -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake