diff --git a/cmake/catkin_package.cmake b/cmake/catkin_package.cmake index fb6b01a17..a9b77b308 100644 --- a/cmake/catkin_package.cmake +++ b/cmake/catkin_package.cmake @@ -270,7 +270,8 @@ function(_catkin_package) catkin_filter_libraries_for_build_configuration(libraries ${PKG_CONFIG_LIBRARIES}) foreach(library ${libraries}) if(NOT IS_ABSOLUTE ${library}) - if(NOT ${library} MATCHES "^-l") + # Append -l to anything that's not a linker flag + if(NOT ${library} MATCHES "^-") set(library "-l${library}") endif() endif() diff --git a/cmake/templates/pkgConfig.cmake.in b/cmake/templates/pkgConfig.cmake.in index 9c0e46d4e..4e52046d8 100644 --- a/cmake/templates/pkgConfig.cmake.in +++ b/cmake/templates/pkgConfig.cmake.in @@ -123,6 +123,29 @@ foreach(library ${libraries}) list(APPEND @PROJECT_NAME@_LIBRARIES ${library}) elseif(${library} MATCHES "^-l") list(APPEND @PROJECT_NAME@_LIBRARIES ${library}) + elseif(${library} MATCHES "^-") + # This is a linker flag/option (like -pthread) + # There's no standard variable for these, so create an interface library to hold it + if(NOT @PROJECT_NAME@_NUM_DUMMY_TARGETS) + set(@PROJECT_NAME@_NUM_DUMMY_TARGETS 0) + endif() + # Make sure the target name is unique + set(interface_target_name "catkin::@PROJECT_NAME@::wrapped-linker-option${@PROJECT_NAME@_NUM_DUMMY_TARGETS}") + while(TARGET "${interface_target_name}") + math(EXPR @PROJECT_NAME@_NUM_DUMMY_TARGETS "${@PROJECT_NAME@_NUM_DUMMY_TARGETS}+1") + set(interface_target_name "catkin::@PROJECT_NAME@::wrapped-linker-option${@PROJECT_NAME@_NUM_DUMMY_TARGETS}") + endwhile() + add_library("${interface_target_name}" INTERFACE IMPORTED) + if("${CMAKE_VERSION}" VERSION_LESS "3.13.0") + set_property( + TARGET + "${interface_target_name}" + APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "${library}") + else() + target_link_options("${interface_target_name}" INTERFACE "${library}") + endif() + list(APPEND @PROJECT_NAME@_LIBRARIES "${interface_target_name}") elseif(TARGET ${library}) list(APPEND @PROJECT_NAME@_LIBRARIES ${library}) elseif(IS_ABSOLUTE ${library}) diff --git a/test/local_tests/test_with_mock_workspace.py b/test/local_tests/test_with_mock_workspace.py index 79f5e667e..4d3622ebe 100644 --- a/test/local_tests/test_with_mock_workspace.py +++ b/test/local_tests/test_with_mock_workspace.py @@ -39,6 +39,18 @@ def test_catkin_only(self): "setup.sh", "setup.zsh") + def test_linker_options_propagation(self): + dstdir = os.path.join(self.workspacedir, 'linker_options') + shutil.copytree(os.path.join(MOCK_DIR, 'src', 'linker_options'), dstdir) + out = self.cmake() + succeed(MAKE_CMD, cwd=self.builddir) + succeed(MAKE_CMD + ["install"], cwd=self.builddir) + + assert_exists(self.installdir, + "env.sh", + "setup.sh", + "setup.zsh") + def test_nolang(self): dstdir = os.path.join(self.workspacedir, 'nolangs') shutil.copytree(os.path.join(MOCK_DIR, 'src', 'nolangs'), dstdir) diff --git a/test/mock_resources/src/linker_options/src/leaf_pkg/CMakeLists.txt b/test/mock_resources/src/linker_options/src/leaf_pkg/CMakeLists.txt new file mode 100644 index 000000000..851aefc53 --- /dev/null +++ b/test/mock_resources/src/linker_options/src/leaf_pkg/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.0.2) +project(leaf_pkg) + +find_package(catkin REQUIRED COMPONENTS root_pkg) + +add_executable(leaf leaf.cpp) +target_link_libraries(leaf ${catkin_LIBRARIES}) +target_include_directories(leaf PUBLIC ${catkin_INCLUDE_DIRS}) + +catkin_package() + +list(LENGTH catkin_LIBRARIES size) +math(EXPR size_is_not_3 "${size} - 3") +if (size_is_not_3) + message(FATAL_ERROR "Wrong size for catkin_LIBRARIES: ${catkin_LIBRARIES} : ${size}") +else() + message(STATUS "All is OK: ${catkin_LIBRARIES}") +endif() diff --git a/test/mock_resources/src/linker_options/src/leaf_pkg/leaf.cpp b/test/mock_resources/src/linker_options/src/leaf_pkg/leaf.cpp new file mode 100644 index 000000000..b4fa14135 --- /dev/null +++ b/test/mock_resources/src/linker_options/src/leaf_pkg/leaf.cpp @@ -0,0 +1,9 @@ +#include +#include + +int main() +{ + std::cout << "leaf_pkg calling "; + root_pkg::func(); + return 0; +} diff --git a/test/mock_resources/src/linker_options/src/leaf_pkg/package.xml b/test/mock_resources/src/linker_options/src/leaf_pkg/package.xml new file mode 100644 index 000000000..74c9f8223 --- /dev/null +++ b/test/mock_resources/src/linker_options/src/leaf_pkg/package.xml @@ -0,0 +1,13 @@ + + leaf_pkg + 3.4.5 + Checks library and linker options + Somebody + Somebody + Unknown + + + catkin + + root_pkg + diff --git a/test/mock_resources/src/linker_options/src/root_pkg/CMakeLists.txt b/test/mock_resources/src/linker_options/src/root_pkg/CMakeLists.txt new file mode 100644 index 000000000..8687aed54 --- /dev/null +++ b/test/mock_resources/src/linker_options/src/root_pkg/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.0.2) +project(root_pkg) + +find_package(catkin REQUIRED) + +add_library(rootlib SHARED root.cpp) +target_include_directories(rootlib PUBLIC include) + +catkin_package( + INCLUDE_DIRS include + LIBRARIES -pthread -lpthread rootlib + ) + +install(TARGETS rootlib + ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} + RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}) + +install(DIRECTORY include/${PROJECT_NAME}/ + DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) diff --git a/test/mock_resources/src/linker_options/src/root_pkg/include/root_pkg/root.hpp b/test/mock_resources/src/linker_options/src/root_pkg/include/root_pkg/root.hpp new file mode 100644 index 000000000..514419534 --- /dev/null +++ b/test/mock_resources/src/linker_options/src/root_pkg/include/root_pkg/root.hpp @@ -0,0 +1,4 @@ +namespace root_pkg +{ +void func(); +} diff --git a/test/mock_resources/src/linker_options/src/root_pkg/package.xml b/test/mock_resources/src/linker_options/src/root_pkg/package.xml new file mode 100644 index 000000000..a83c7d30e --- /dev/null +++ b/test/mock_resources/src/linker_options/src/root_pkg/package.xml @@ -0,0 +1,11 @@ + + root_pkg + 3.4.5 + Exports library and linker options in ${root_pkg_LIBRARIES} + Somebody + Somebody + Unknown + + + catkin + diff --git a/test/mock_resources/src/linker_options/src/root_pkg/root.cpp b/test/mock_resources/src/linker_options/src/root_pkg/root.cpp new file mode 100644 index 000000000..f5ea0882d --- /dev/null +++ b/test/mock_resources/src/linker_options/src/root_pkg/root.cpp @@ -0,0 +1,11 @@ +#include + +#include "root_pkg/root.hpp" + +namespace root_pkg +{ +void func() +{ + std::cout << "root_pkg::func()\n"; +} +}