diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccb281955..2856b91b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,6 +209,17 @@ add_library(osrm::customize ALIAS osrm_customize) add_library(osrm::update ALIAS osrm_update) add_library(osrm::store ALIAS osrm_store) +# Public include directories for downstream consumers of the exported osrm +# target. Public headers are installed under /include/osrm/... while +# some headers use non-prefixed paths like "engine/api/route_parameters.hpp" +# internally, so the consumer needs both /include and /include/osrm +# on the include path (mirroring the historical pkg-config behaviour). +target_include_directories(osrm INTERFACE + $ + $ + $ + $) + # Explicitly set the build type to Release if no other type is specified # on the command line. Without this, cmake defaults to an unoptimized, # non-debug build, which almost nobody wants. @@ -512,7 +523,9 @@ endif() # (e.g. nodejs) that expect the same zlib ABI. find_package(ZLIB REQUIRED) add_dependency_includes(${ZLIB_INCLUDE_DIRS}) -set(ZLIB_LIBRARY ${ZLIB_LIBRARIES}) +# Use the imported target (not the file-path variable) so it can serialize +# cleanly into the exported LibOSRMTargets.cmake for downstream consumers. +set(ZLIB_LIBRARY ZLIB::ZLIB) add_definitions(${OSRM_DEFINES}) include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS}) @@ -528,7 +541,7 @@ target_link_libraries(osrm-routed osrm ${Boost_PROGRAM_OPTIONS_LIBRARY} ${OPTION set(EXTRACTOR_LIBRARIES ${BZIP2_LIBRARIES} ${BOOST_BASE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${EXPAT_LIBRARIES} ${LUA_LIBRARIES} ${OSMIUM_LIBRARIES} @@ -537,47 +550,47 @@ set(EXTRACTOR_LIBRARIES ${MAYBE_COVERAGE_LIBRARIES}) set(PARTITIONER_LIBRARIES ${BOOST_ENGINE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES}) set(CUSTOMIZER_LIBRARIES ${BOOST_ENGINE_LIBRARIES} ${ZLIB_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES}) set(UPDATER_LIBRARIES ${BOOST_BASE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES} ${ZLIB_LIBRARY}) set(CONTRACTOR_LIBRARIES ${BOOST_BASE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${LUA_LIBRARIES} ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES}) set(ENGINE_LIBRARIES ${BOOST_ENGINE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES} ${ZLIB_LIBRARY}) set(STORAGE_LIBRARIES ${BOOST_BASE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_RT_LIBRARY} ${MAYBE_COVERAGE_LIBRARIES}) set(UTIL_LIBRARIES ${BOOST_BASE_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} + Threads::Threads ${TBB_LIBRARIES} ${MAYBE_COVERAGE_LIBRARIES} ${ZLIB_LIBRARY}) @@ -646,7 +659,16 @@ install(TARGETS osrm-contract DESTINATION bin) install(TARGETS osrm-datastore DESTINATION bin) install(TARGETS osrm-routed DESTINATION bin) -install(TARGETS osrm DESTINATION lib) +# Install osrm as part of an EXPORT set so consumers can find_package(LibOSRM) +# and link osrm::osrm with its usage requirements (include dirs + transitive +# deps) baked in. The other osrm_* libraries are build-internal support for +# the command-line tools; they are still installed for pkg-config / legacy +# consumers but are not part of the exported CMake package. +install(TARGETS osrm + EXPORT LibOSRMTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin) install(TARGETS osrm_extract DESTINATION lib) install(TARGETS osrm_partition DESTINATION lib) install(TARGETS osrm_customize DESTINATION lib) @@ -654,6 +676,11 @@ install(TARGETS osrm_update DESTINATION lib) install(TARGETS osrm_contract DESTINATION lib) install(TARGETS osrm_store DESTINATION lib) +install(EXPORT LibOSRMTargets + FILE LibOSRMTargets.cmake + NAMESPACE osrm:: + DESTINATION lib/cmake/LibOSRM) + # Install profiles and support library to /usr/local/share/osrm/profiles by default set(DefaultProfilesDir profiles) install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm) @@ -701,7 +728,15 @@ JOIN("-I${DEPENDENCIES_INCLUDE_DIRS}" " -I" PKGCONFIG_OSRM_INCLUDE_FLAGS) foreach(engine_lib ${ENGINE_LIBRARIES}) - if(TARGET ${engine_lib}) + # Translate well-known imported targets to portable pkg-config flags. + # Threads::Threads is INTERFACE-only and has no library name to derive a + # `-l` flag from; ZLIB::ZLIB would otherwise serialize as an absolute path + # via TARGET_LINKER_FILE, which is non-portable across install prefixes. + if(engine_lib STREQUAL "Threads::Threads") + list(APPEND PKGCONFIG_DEPENDENT_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}") + elseif(engine_lib STREQUAL "ZLIB::ZLIB") + list(APPEND PKGCONFIG_DEPENDENT_LIBRARIES "-lz") + elseif(TARGET ${engine_lib}) # Some imported targets (e.g. Boost::regex in modern Boost) are # INTERFACE-only and have no TARGET_LINKER_FILE. Only embed a linker # file for targets that actually produce one. @@ -734,6 +769,24 @@ if(NOT _is_multi_config) install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION ${PKGCONFIG_LIBRARY_DIR}/pkgconfig) endif() +# CMake package config: downstream users do +# find_package(LibOSRM REQUIRED) +# target_link_libraries(myapp PRIVATE osrm::osrm) +# LibOSRMTargets.cmake is written by install(EXPORT ...) above. +include(CMakePackageConfigHelpers) +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibOSRMConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/LibOSRMConfig.cmake + INSTALL_DESTINATION lib/cmake/LibOSRM) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/LibOSRMConfigVersion.cmake + VERSION ${OSRM_VERSION} + COMPATIBILITY SameMinorVersion) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/LibOSRMConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LibOSRMConfigVersion.cmake + DESTINATION lib/cmake/LibOSRM) + # uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" diff --git a/cmake/LibOSRMConfig.cmake.in b/cmake/LibOSRMConfig.cmake.in new file mode 100644 index 0000000000..cdd91241df --- /dev/null +++ b/cmake/LibOSRMConfig.cmake.in @@ -0,0 +1,15 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +# osrm is built as a static library and links against all of the +# below, so consumers need them re-resolved at link time. +find_dependency(Boost 1.83 CONFIG COMPONENTS date_time iostreams regex thread) +find_dependency(TBB CONFIG) +find_dependency(Threads) +find_dependency(ZLIB) +find_dependency(LibArchive) + +include("${CMAKE_CURRENT_LIST_DIR}/LibOSRMTargets.cmake") + +check_required_components(LibOSRM) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index c1a9e5667e..318175f63d 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -16,23 +16,11 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - message(STATUS "Building on a 64 bit system") -else() - message(STATUS "Building on a 32 bit system") -endif() - -find_package(Boost REQUIRED CONFIG COMPONENTS date_time iostreams thread) - -link_directories(${LibOSRM_LIBRARY_DIRS}) -add_executable(osrm-example example.cpp) - +# find_package(LibOSRM) resolves via the CMake Config package installed +# at /lib/cmake/LibOSRM/ (LibOSRMConfig.cmake). That package +# re-declares Boost / TBB / Threads / ZLIB as find_dependency() calls, +# so consumers do not have to call find_package() for them by hand. find_package(LibOSRM REQUIRED) -set(LibOSRM_LINKABLE_LIBRARIES ${LibOSRM_LIBRARIES} ${LibOSRM_DEPENDENT_LIBRARIES}) -list(REMOVE_DUPLICATES LibOSRM_LINKABLE_LIBRARIES) -target_link_libraries(osrm-example ${LibOSRM_LINKABLE_LIBRARIES}) -include_directories(SYSTEM ${LibOSRM_INCLUDE_DIRS}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LibOSRM_CXXFLAGS}") +add_executable(osrm-example example.cpp) +target_link_libraries(osrm-example PRIVATE osrm::osrm) diff --git a/example/cmake/FindLibOSRM.cmake b/example/cmake/FindLibOSRM.cmake deleted file mode 100644 index 622ac3ed25..0000000000 --- a/example/cmake/FindLibOSRM.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# - Try to find LibOSRM -# Once done this will define -# LibOSRM_FOUND - System has LibOSRM -# LibOSRM_LIBRARIES - The libraries and ldflags needed to use LibOSRM -# LibOSRM_DEPENDENT_LIBRARIES - The libraries and ldflags need to link LibOSRM dependencies -# LibOSRM_LIBRARY_DIRS - The libraries paths needed to find LibOSRM -# LibOSRM_CXXFLAGS - Compiler switches required for using LibOSRM - -find_package(PkgConfig) -pkg_search_module(PC_LibOSRM QUIET libosrm) - -function(JOIN VALUES GLUE OUTPUT) - string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}") - set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE) -endfunction() - -list(REMOVE_ITEM PC_LibOSRM_CFLAGS " ") -JOIN("${PC_LibOSRM_CFLAGS}" " " output) - -set(LibOSRM_CXXFLAGS ${output}) -set(LibOSRM_LIBRARY_DIRS ${PC_LibOSRM_LIBRARY_DIRS}) - -find_path(LibOSRM_INCLUDE_DIR osrm/osrm.hpp - PATH_SUFFIXES osrm include/osrm include - HINTS ${PC_LibOSRM_INCLUDEDIR} ${PC_LibOSRM_INCLUDE_DIRS} - ~/Library/Frameworks - /Library/Frameworks - /usr/local - /usr - /opt/local - /opt) - -set(LibOSRM_DEPENDENT_LIBRARIES ${PC_LibOSRM_STATIC_LDFLAGS}) -set(LibOSRM_LIBRARIES ${PC_LibOSRM_LDFLAGS}) - -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set LIBOSRM_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(LibOSRM DEFAULT_MSG - LibOSRM_LIBRARY_DIRS - LibOSRM_CXXFLAGS - LibOSRM_LIBRARIES - LibOSRM_DEPENDENT_LIBRARIES - LibOSRM_INCLUDE_DIR) \ No newline at end of file