Skip to content

Split off Dependency Management from Build System #3381

Open
@daniel-j-h

Description

@daniel-j-h

We now provide two ways to resolve dependencies: 1/ having them already installed locally through a package manager or from source and 2/ using mason to download dependencies. Our CMake build system then picks up include paths and library dirs bailing out if dependencies do not match.

The Mason integration is intertwined into out CMake build system mixing those two concepts:

  • if(ENABLE_MASON)
    # versions in use
    set(MASON_CLANG_VERSION "3.8.1")
    set(MASON_BOOST_VERSION "1.61.0")
    set(MASON_STXXL_VERSION "1.4.1")
    set(MASON_EXPAT_VERSION "2.2.0")
    set(MASON_LUA_VERSION "5.2.4")
    set(MASON_LUABIND_VERSION "e414c57bcb687bb3091b7c55bbff6947f052e46b")
    set(MASON_BZIP2_VERSION "1.0.6")
    set(MASON_TBB_VERSION "43_20150316")
    set(MASON_CCACHE_VERSION "3.3.1")
    message(STATUS "Enabling mason")
    find_program(CURL_FOUND curl)
    if(NOT CURL_FOUND)
    message(FATAL_ERROR "curl command required with -DENABLE_MASON")
    endif()
    set(MASON_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mason/mason)
    include(${CMAKE_CURRENT_SOURCE_DIR}/third_party/mason/mason.cmake)
    endif()
  • osrm-backend/CMakeLists.txt

    Lines 233 to 236 in ef087f9

    if (ENABLE_MASON AND (LTO_WORKS OR ENABLE_GOLD_LINKER))
    message(WARNING "ENABLE_MASON and ENABLE_LTO/ENABLE_GOLD_LINKER may not work on all linux systems currently")
    message(WARNING "For more details see: https://github.com/Project-OSRM/osrm-backend/issues/3202")
    endif()
  • osrm-backend/CMakeLists.txt

    Lines 335 to 424 in ef087f9

    # if mason is enabled no find_package calls are made
    # to ensure that we are only compiling and linking against
    # fully portable mason packages
    if(ENABLE_MASON)
    message(STATUS "Installing dependencies via mason")
    set(Boost_USE_STATIC_LIBS ON)
    mason_use(boost VERSION ${MASON_BOOST_VERSION} HEADER_ONLY)
    add_dependency_includes(${MASON_PACKAGE_boost_INCLUDE_DIRS})
    mason_use(boost_libfilesystem VERSION ${MASON_BOOST_VERSION})
    set(Boost_FILESYSTEM_LIBRARY ${MASON_PACKAGE_boost_libfilesystem_STATIC_LIBS})
    mason_use(boost_libiostreams VERSION ${MASON_BOOST_VERSION})
    set(Boost_IOSTREAMS_LIBRARY ${MASON_PACKAGE_boost_libiostreams_STATIC_LIBS})
    mason_use(boost_libprogram_options VERSION ${MASON_BOOST_VERSION})
    set(Boost_PROGRAM_OPTIONS_LIBRARY ${MASON_PACKAGE_boost_libprogram_options_STATIC_LIBS})
    mason_use(boost_libregex VERSION ${MASON_BOOST_VERSION})
    set(Boost_REGEX_LIBRARY ${MASON_PACKAGE_boost_libregex_STATIC_LIBS})
    mason_use(boost_libtest VERSION ${MASON_BOOST_VERSION})
    set(Boost_UNIT_TEST_FRAMEWORK_LIBRARY ${MASON_PACKAGE_boost_libtest_STATIC_LIBS})
    mason_use(boost_libdate_time VERSION ${MASON_BOOST_VERSION})
    set(Boost_DATE_TIME_LIBRARY ${MASON_PACKAGE_boost_libdate_time_STATIC_LIBS})
    mason_use(boost_libthread VERSION ${MASON_BOOST_VERSION})
    set(Boost_THREAD_LIBRARY ${MASON_PACKAGE_boost_libthread_STATIC_LIBS})
    mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION})
    set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS})
    mason_use(stxxl VERSION ${MASON_STXXL_VERSION})
    add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS})
    set(STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS})
    mason_use(expat VERSION ${MASON_EXPAT_VERSION})
    add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS})
    set(EXPAT_LIBRARIES ${MASON_PACKAGE_expat_STATIC_LIBS})
    mason_use(lua VERSION ${MASON_LUA_VERSION})
    add_dependency_includes(${MASON_PACKAGE_lua_INCLUDE_DIRS})
    set(USED_LUA_LIBRARIES ${MASON_PACKAGE_lua_STATIC_LIBS})
    mason_use(luabind_lua524 VERSION ${MASON_LUABIND_VERSION})
    add_dependency_includes(${MASON_PACKAGE_luabind_lua524_INCLUDE_DIRS})
    set(LUABIND_LIBRARY ${MASON_PACKAGE_luabind_lua524_STATIC_LIBS})
    mason_use(bzip2 VERSION ${MASON_BZIP2_VERSION})
    add_dependency_includes(${MASON_PACKAGE_bzip2_INCLUDE_DIRS})
    set(BZIP2_LIBRARIES ${MASON_PACKAGE_bzip2_STATIC_LIBS})
    mason_use(tbb VERSION ${MASON_TBB_VERSION})
    add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS})
    set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS})
    if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS)
    message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work")
    endif()
    set(TBB_LINKER_RPATHS "")
    foreach(libpath ${MASON_PACKAGE_tbb_LIBRARY_DIRS})
    set(TBB_LINKER_RPATHS "${TBB_LINKER_RPATHS} -Wl,-rpath -Wl,${libpath}")
    file(GLOB TBBGlob ${libpath}/*.*)
    install(FILES ${TBBGlob} DESTINATION lib)
    endforeach()
    if(APPLE)
    set(LINKER_FLAGS "${TBB_LINKER_RPATHS} -Wl,-rpath -Wl,@executable_path")
    elseif(UNIX)
    set(LINKER_FLAGS "${TBB_LINKER_RPATHS} '-Wl,-rpath,$ORIGIN' -Wl,-z,origin")
    endif()
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
    if(BUILD_COMPONENTS)
    message(FATAL_ERROR "BUILD_COMPONENTS is not supported with ENABLE_MASON")
    endif()
    # current mason packages target -D_GLIBCXX_USE_CXX11_ABI=0
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
    if(ENABLE_CCACHE)
    mason_use(ccache VERSION ${MASON_CCACHE_VERSION})
    message(STATUS "Setting ccache to ccache ${MASON_CCACHE_VERSION} (via mason) ${MASON_PACKAGE_ccache_PREFIX}/bin/ccache")
    message(STATUS "Using ccache to speed up incremental builds")
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${MASON_PACKAGE_ccache_PREFIX}/bin/ccache)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${MASON_PACKAGE_ccache_PREFIX}/bin/ccache)
    set(ENV{CCACHE_CPP2} "true")
    endif()
    # note: we avoid calling find_package(Osmium ...) here to ensure that the
    # expat and bzip2 are used from mason rather than the system
    include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include)
    else()

and adding some hundred lines of code to the CMakeLists.

Instead I would love to separate these two aspects:

CMake should not have to worry about dependency management.
It's a build system and not a tool for dependency resolution.

Here's what a solution similar to Python's virtualenv or Nix's nix-shell could look like:

mason-env .mason
. .mason/activate.sh  # (prepends env var paths)
mason install libtbb  # (or install -r requirements.txt)

mkdir build
cd build
cmake ..

A design like this would allow us to properly split off dependency management from the build system: CMake then finds packages transparently by searching in .mason since we setup env vars appropriately)

I talked to @kkaefer over lunch about this and it sounded like we could pull this off via mason's install / link commands and some glue code as usual.

cc @springmeyer @TheMarex

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions