How to create a shared library with cmake?

前端 未结 4 940
死守一世寂寞
死守一世寂寞 2020-11-28 17:10

I have written a library that I used to compile using a self-written Makefile, but now I want to switch to cmake. The tree looks like this (I removed all the irrelevant file

4条回答
  •  -上瘾入骨i
    2020-11-28 17:52

    First, this is the directory layout that I am using:

    .
    ├── include
    │   ├── class1.hpp
    │   ├── ...
    │   └── class2.hpp
    └── src
        ├── class1.cpp
        ├── ...
        └── class2.cpp
    

    After a couple of days taking a look into this, this is my favourite way of doing this thanks to modern CMake:

    cmake_minimum_required(VERSION 3.5)
    project(mylib VERSION 1.0.0 LANGUAGES CXX)
    
    set(DEFAULT_BUILD_TYPE "Release")
    
    if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
      message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
      set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE)
      # Set the possible values of build type for cmake-gui
      set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
    endif()
    
    include(GNUInstallDirs)
    
    set(SOURCE_FILES src/class1.cpp src/class2.cpp)
    
    add_library(${PROJECT_NAME} ...)
    
    target_include_directories(${PROJECT_NAME} PUBLIC
        $
        $
        PRIVATE src)
    
    set_target_properties(${PROJECT_NAME} PROPERTIES
        VERSION ${PROJECT_VERSION}
        SOVERSION 1)
    
    install(TARGETS ${PROJECT_NAME} EXPORT MyLibConfig
        ARCHIVE  DESTINATION ${CMAKE_INSTALL_LIBDIR}
        LIBRARY  DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME  DESTINATION ${CMAKE_INSTALL_BINDIR})
    install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
    
    install(EXPORT MyLibConfig DESTINATION share/MyLib/cmake)
    
    export(TARGETS ${PROJECT_NAME} FILE MyLibConfig.cmake)
    

    After running CMake and installing the library, there is no need to use Find***.cmake files, it can be used like this:

    find_package(MyLib REQUIRED)
    
    #No need to perform include_directories(...)
    target_link_libraries(${TARGET} mylib)
    

    That's it, if it has been installed in a standard directory it will be found and there is no need to do anything else. If it has been installed in a non-standard path, it is also easy, just tell CMake where to find MyLibConfig.cmake using:

    cmake -DMyLib_DIR=/non/standard/install/path ..
    

    I hope this helps everybody as much as it has helped me. Old ways of doing this were quite cumbersome.

提交回复
热议问题