标签 install 下的文章

CMake: 引入三方库及打包当前项目


前述

这里整一个cmake引入三方库及导出安装包的示例代码。
引入三方库用的是

set(*_DIR "**")
find_package(*)
target_link_libraries(${PROJECT_NAME} PRIVATE *)

导出安装报用到的是

install(TARGETS ${PROJECT_NAME} 
    RUNTIME 
    DESTINATION bin
)

install(
    FILES
    $<TARGET_FILE:*>
    DESTINATION bin
)
include (InstallRequiredSystemLibraries)\
...此处为CPack配置...
include(CPack)

示例

test.zip
Git testMain
Git testLib

CPack文档地址

https://cmake.org/cmake/help/latest/manual/cpack-generators.7.html

代码

部分代码已注释,具体详解也写道对应的注释里了。

cmake_minimum_required(VERSION 3.5.0)
project(testMain VERSION 0.1.1 LANGUAGES C CXX)

# set(testLib_DIR "Y:\\thirdparty\\testLib\\cmake")   # 如果不是安装形式的第三方库需要设置对应目录
find_package(testLib REQUIRED)                      # 查找已安装的三方库

include_directories(include)                        # 添加头文件路径
file(GLOB FILES_SRC "src/*.cpp")                    # 添加当前目录下的源文件至FILES_SRC

add_executable(${PROJECT_NAME} "main.cpp" ${FILES_SRC})

target_link_libraries(${PROJECT_NAME} PRIVATE testLib)

add_custom_command(                                 # 将自定义构建规则添加到生成的构建系统
    TARGET ${PROJECT_NAME}  POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:testLib> $<TARGET_FILE_DIR:${PROJECT_NAME}>         # 复制testLib.dll文件到目标目录
    # COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/bin/                              # 创建bin目录存放三方dll
    # COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:testLib> $<TARGET_FILE_DIR:${PROJECT_NAME}>/bin/    # 复制dll库到bin目录
)

# add_custom_target(                                  # 增加一个没有输出的目标(总会被构建)
#     CopyFile
#     VERBATIM
#     COMMAND_EXPAND_LISTS
#     COMMAND ${CMAKE_COMMAND} -E copy_if_different
#     $<TARGET_FILE:testLib> $<TARGET_FILE_DIR:${PROJECT_NAME}>
# )

install(TARGETS ${PROJECT_NAME} 
    RUNTIME 
    DESTINATION bin                                 # 指定安装目录
)

install(
    FILES
    $<TARGET_FILE:testLib>
    DESTINATION bin                                 # 指定文件复制目录
)

############################## 打包 ##############################
include (InstallRequiredSystemLibraries)
# set(CPACK_GENERATOR ZIP)                            # 指定打包成ZIP
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")  #设置安装界面的License
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")      #设置架构
set(CPACK_DEBIAN_PACKAGE_NAME "测试软件")           #设置程序名,就是程序安装后的名字
set(CPACK_PACKAGE_NAME "测试软件")                  #设置安装包的包名,打好的包将会是<packagename>-<version>-<sys>.deb,如果不设置,默认是工程名
set(CPACK_PACKAGE_VERSION "1.0.0")                  #设置版本号
set(CPACK_SYSTEM_NAME "win64")                      #系统名
SET(CPACK_PACKAGE_DESCRIPTION "这是一个测试软件 项目包")        #设置description
SET(CPACK_PACKAGE_CONTACT "root@bug-maker.com")     #设置联系方式
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "猪在天上飞")   #设置维护人
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/DEBIAN/postinst;${CMAKE_SOURCE_DIR}/DEBIAN/postrm;")  #设置包的安装脚本
include(CPack)

结果


CMake: 使用install-export和find_package查找并链接到库


摘要

一个库生成后然后find_package来引用。下边的示例代码涉及到

dome代码下载

testLib.zip
GIT项目地址

库导出cmake说明

cmake_minimum_required(VERSION 3.5)
project(testLib VERSION 0.1.1 LANGUAGES C CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/../install)    # 指定安装目录

OPTION(BUILD_MODULE_test "test" OFF)                # 设置编译子模块
if (NOT BUILD_LIBRARY_TYPE)                         # 判定是否配置生成类型下拉项
    set (BUILD_LIBRARY_TYPE "Static" CACHE STRING "${BUILD_LIBRARY_TYPE_DESCR}" FORCE)  # 设置默认类型为静态库
    SET_PROPERTY(CACHE                              # 配置下拉选项
        BUILD_LIBRARY_TYPE PROPERTY STRINGS Shared Static   # 配置生成选择类型下拉项
    )
endif()

if ("${BUILD_LIBRARY_TYPE}" STREQUAL "Shared")
    set (BUILD_SHARED_LIBS ON)                      # 配置生成动态库(OFF/默认为静态库)
endif()

include_directories(include)                        # 添加头文件路径
file(GLOB FILES_SRC "src/*.cpp")                    # 添加当前目录下的源文件至FILES_SRC

add_library(${PROJECT_NAME} ${FILES_SRC})

ADD_CUSTOM_COMMAND(                                 # 用于将自定义构建规则添加到生成的构建系统
    TARGET ${PROJECT_NAME} POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/config $<TARGET_FILE_DIR:${PROJECT_NAME}>/config   # 复制配置目录到可执行目录下
)

############################## 安装部分 ##############################

TARGET_INCLUDE_DIRECTORIES(                         # 目标头文件搜索路径
    ${PROJECT_NAME} PUBLIC                          
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>  # 指定构建接口头文件路径, 可以add_subdirectory后直接头文件
    $<INSTALL_INTERFACE:include>                    # install会自动引用include头文件
)

SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES    # 设置目标的属性
    # DEBUG_POSTFIX d                                 # debug声称是添加d后缀
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}    # 二进制执行文件目录
    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}    # 静态库目录
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}    # 动态库目录
)

INSTALL(
    TARGETS ${PROJECT_NAME}                         # 安装目标名称
    EXPORT ${PROJECT_NAME}Targets                   # 导出项目名
    PUBLIC_HEADER DESTINATION include               # 指定头文件目录
    RUNTIME DESTINATION "bin/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>"  # 二进制执行文件目录
    ARCHIVE DESTINATION "lib/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>"  # 静态库目录
    LIBRARY DESTINATION "lib/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>"  # 动态库目录
)

INSTALL(
    DIRECTORY                                       # 安装目录
    include DESTINATION ${CMAKE_INSTALL_PREFIX}     # 指定头文件安装目录
)

INSTALL(
    EXPORT ${PROJECT_NAME}Targets                   # 导出项目名
    FILE ${PROJECT_NAME}Targets.cmake               # 生成xxxTargets.cmake文件
    # NAMESPACE Ftest::                               # 添加命名空间
    DESTINATION cmake                               # 指定相对路径cmake目录
)


include (CMakePackageConfigHelpers)
configure_package_config_file (                     # 生成 xxxConfig.cmake文件
    cmake/Config.cmake.in ${PROJECT_NAME}Config.cmake   # 根据.make.in 生成对应Config.cmake文件
    INSTALL_DESTINATION cmake                       # 安装目录
    # PATH_VARS INCLUDE_DIRS LIB_DIR
    # INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
)

write_basic_package_version_file(                   # 生成 xxxConfigVersion.cmake文件
    ${PROJECT_NAME}ConfigVersion.cmake              # 指定文件名
    VERSION ${PACKAGE_VERSION}                      # 指定版本号
    COMPATIBILITY SameMajorVersion                  # 指定兼容性
)

INSTALL(
    FILES
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake         # 复制xxxConfig.cmake文件到安装目录的cmake
    ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake  # 复制xxxConfigVersion.cmake文件到安装目录的cmake
    DESTINATION cmake                               # 指定相对路径
)

INSTALL(
    DIRECTORY
    config/                                         # 复制配置文件夹
    DESTINATION static                              # 指定目录
)

引入

直接find_package就可以直接将lib和头文件引入。

find_package(testLib REQUIRED)
target_link_libraries(${PROJECT_NAME} testLib::testLib)

使用

#include <iostream>
#include "testLib.h"

using namespace std;

int main(int, char**){
    std::cout << "Hello, from testMain!\n";
    auto pTestLib = make_shared<testLib>();
    pTestLib->say();
}

最终调用成功!
屏幕截图 2023-06-17 090831.jpg