当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - How to get a header only library portably from version control using CMake?

问题描述:

For a typical C++ header only library located on, e.g., github, at: https://github.com/username/library_name,

has a directory structure with an include/library_name folder like:

  • include/library_name

containing all the library sources. This is typically installed by users to, e.g., under Linux: /usr/local/include/library_name.

I need a cmake script for using the library in external projects portably (across Linux, MacOs, BSD, Windows).

It should:

  • find if the library is installed, if the version is over a threshold, use the installed library

  • otherwise, get the library from github, configure it as an external project, and put it in the system include path so that it can be used by the project as if it were installed.

What is the correct way of achieving this with CMake?

网友答案:

I finally got it to work, this FindLibraryName.cmake tries to find the library and if it doesn't find it, gets it from github and sets it up as an external project:

# Find the Library_Name include directory
# The following variables are set if Library_Name is found.
#  Library_Name_FOUND        - True when the Library_Name include directory is found.
#  Library_Name_INCLUDE_DIRS - The path to where the poco include files are.
# If Library_Name is not found, Library_Name_FOUND is set to false.

find_package(PkgConfig)

# Allow the user can specify the include directory manually:
if(NOT EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
     find_path(LIBRARY_NAME_INCLUDE_DIR
         NAMES library_name/library_name.hpp 
         DOC "Library_Name library header files"
     )
endif()

if(EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
  include(FindPackageHandleStandardArgs)
  mark_as_advanced(LIBRARY_NAME_INCLUDE_DIR)
else()
  include(ExternalProject)
  ExternalProject_Add(library_name
    GIT_REPOSITORY https://github.com/username/library_name.git
    TIMEOUT 5
    CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
    PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
    INSTALL_COMMAND "" # Disable install step, is a header only lib!
    )

  # Specify include dir
  ExternalProject_Get_Property(library_name source_dir)
  set(LIBRARY_NAME_INCLUDE_DIRS ${source_dir}/include)
endif()

if(EXISTS "${LIBRARY_NAME_INCLUDE_DIR}")
  set(Library_Name_FOUND 1)
else()
  set(Library_Name_FOUND 0)
endif()

Then in the projects CMakeLists.txt, just add:

find_package(Library_Name)
include_directories(${LIBRARY_NAME_INCLUDE_DIRS})

You can replace GIT with SVN above and provide the URL of an svn repo and it will work as well. Other version control systems are also available.

分享给朋友:
您可能感兴趣的文章:
随机阅读: