分类 编程及辅助 下的文章

CMake | CPack使用NSIS打包安装程序


描述

由于配置项比较多,所以单独起一篇文章来说打包的事情。所里的项目发布更新包都是手动压缩出来,其实是和不方便的。正常就应该是按照流水线形式处理,也方便以后在Jenkins等持续集成工具上打包封装。

示例代码

testLib.zip
Git 地址

实现代码

set(_install_path "bin")

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

install(
    FILES                                           # 复制文件
    $<TARGET_FILE:testLib>                          # testLib库静态文件
    DESTINATION ${_install_path}                    # 指定文件复制目录
)

install(
    DIRECTORY                                       # 复制目录
    ${testLib_DIR}/../static/                       # 执行所需文件(注意:带最后一个是复制此目录下的文件,不带/则是复制static这个目录到目标目录)
    DESTINATION ${_install_path}                    # 指定复制目录
)

############################## 打包(会用到install) ##############################
include (InstallRequiredSystemLibraries)
set(CPACK_GENERATOR "NSIS")                         # 指定NSIS打包成EXE(或者ZIP、TG等)
set(CPACK_SYSTEM_NAME "win64")                      # 系统名
set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME} "测试软件")   # 可执行文件的名称和快捷方式标签
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/static\\\\icon.ico")       # 安装包左上角图标(严格要求的bmp,后来处理了一下图片convert cion.bmp BMP3:cion2.bmp)
set(CPACK_PACKAGE_NAME "测试软件")                  # 设置安装包的包名,打好的包将会是<packagename>-<version>-<sys>.deb,如果不设置,默认是工程名
set(CPACK_PACKAGE_VERSION "1.0.0")                  # 设置版本号
SET(CPACK_PACKAGE_DESCRIPTION "这是一个测试软件 项目包")        # 设置description
SET(CPACK_PACKAGE_CONTACT "root@bug-maker.com")     # 设置联系方式
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")      # 设置架构
set(CPACK_DEBIAN_PACKAGE_NAME "测试软件")           # 设置程序名,就是程序安装后的名字
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "猪在天上飞")   # 设置维护人
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/static/License.txt")  # 设置安装界面的License

# set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\测试软件2.lnk' '$INSTDIR\\\\${_install_path}\\\\${PROJECT_NAME}.exe'")    # 在开始菜单中创建快捷链接
set(CPACK_NSIS_MENU_LINKS "${_install_path}\\\\${PROJECT_NAME}.exe" "测试软件2")    # 指定开始菜单中的快捷方式
set(CPACK_NSIS_CREATE_ICONS_EXTRA "CreateShortCut '$DESKTOP\\\\测试软件.lnk' '$INSTDIR\\\\${_install_path}\\\\${PROJECT_NAME}.exe'")    # 在桌面创建快捷链接
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/static\\\\install.ico")       # 指定NSIS安装程序的图标文件(格式要求ico)
set(CPACK_NSIS_UNINSTALL_NAME "Uninstall") # 卸载名称
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/static\\\\uninstall.ico")     # 指定NSIS卸载程序的图标文件(格式要求ico)
set(CPACK_NSIS_MUI_HEADERIMAGE "${CMAKE_CURRENT_SOURCE_DIR}/static\\\\icon2.bmp")   # 安装包左上角图标(严格要求的bmp,后来处理了一下图片convert cion.bmp BMP3:cion2.bmp)
set(CPACK_NSIS_PACKAGE_NAME "软件包名称")           # 指定生成的NSIS安装程序的名称。
set(CPACK_NSIS_PACKAGE_VERSION ${PROJECT_VERSION})  # 指定生成的NSIS安装程序的版本号。
set(CPACK_NSIS_PACKAGE_VENDOR "供应商名称")         # 指定生成的NSIS安装程序的供应商名称。
set(CPACK_NSIS_PACKAGE_DESCRIPTION "简单的描述")    # 指定生成的NSIS安装程序的描述。
set(CPACK_NSIS_BRANDING_TEXT "左下角描述")          # 左下角描述
set(CPACK_NSISDISPLAY_NAME "显示名称")              # 指定生成的NSIS安装程序的显示名称。
set(CPACK_NSIS_HELP_LINK "https://www.test.com/help") # 指定生成的NSIS安装程序的帮助链接。
set(CPACK_NSIS_PACKAGE_URL "https://www.test.com")  # 指定生成的NSIS安装程序的URL链接。

include(CPack)

说明

CPack NSIS Generator的配置描述

  1. CPACK_NSIS_INSTALL_ROOT
    指定用户默认安装路径
  2. CPACK_NSIS_MUI_ICON
    指定NSIS安装程序的图标文件(格式要求.ico)
  3. CPACK_NSIS_MUI_UNIICON
    指定NSIS卸载程序的图标文件(格式要求.ico)
  4. CPACK_NSIS_INSTALLER_MUI_ICON_CODE
    允许你指定一个NSIS脚本代码片段,用于设置安装程序的MUI图标,可以使用NSIS的内置函数和命令来设置图标。
  5. CPACK_NSIS_MUI_WELCOMEFINISHPAGE_BITMAP(CMake 3.5 添加)
    指定一个位图图像文件的路径,用于替换NSIS MUI插件默认的欢迎页和完成页的图像。
  6. CPACK_NSIS_MUI_UNWELCOMEFINISHPAGE_BITMAP(CMake 3.5 添加)
    指定一个位图图像文件的路径,用于替换NSIS MUI插件默认的取消欢迎页和完成页的图像。
  7. CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
    指定一个或多个自定义命令,这些命令将在NSIS安装程序执行预安装命令之前执行。
  8. CPACK_NSIS_EXTRA_INSTALL_COMMANDS
    指定一个或多个自定义命令,这些命令将在NSIS安装程序执行预安装命令之后执行。
  9. CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
    指定一个或多个自定义命令,这些命令将在NSIS安装程序执行卸载命令之后执行。
  10. CPACK_NSIS_COMPRESSOR
    指定NSIS安装程序生成时使用的压缩器。默认情况下,CPack使用NSIS的默认压缩器,即zlib压缩器。参数:zlib、lzma、bzip2
  11. CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL
    指定是否在安装之前先执行卸载操作(卸载自己)。默认为OFF,即不启用在安装之前先卸载的功能。
  12. CPACK_NSIS_MODIFY_PATH
    指定是否在安装过程中修改系统的PATH环境变量。默认为ON,即允许修改系统的PATH环境变量。
  13. CPACK_NSIS_DISPLAY_NAME
    指定生成的NSIS安装程序在Windows系统中显示的名称。默认该变量的值为项目的名称。
  14. CPACK_NSIS_PACKAGE_NAME
    指定生成的NSIS安装程序的名称。
  15. CPACK_NSIS_INSTALLED_ICON_NAME
    指定在Windows系统中安装完成后的快捷方式图标的名称。默认情况下,该变量的值为项目的图标文件名。
  16. CPACK_NSIS_HELP_LINK
    指定生成的NSIS安装程序的帮助链接。
  17. CPACK_NSIS_URL_INFO_ABOUT
    指定生成的NSIS安装程序的URL链接。
  18. CPACK_NSIS_CONTACT
    指定生成的NSIS安装程序中的联系信息。
  19. CPACK_NSIS_<compName>_INSTALL_DIRECTORY(CMake 3.7 添加)
    为特定的组件(compName)指定一个自定义的安装目录。默认情况下,该变量的值为空,即使用默认的安装目录。
  20. CPACK_NSIS_CREATE_ICONS_EXTRA
    命令形式创建开始菜单快捷方式
  21. CPACK_NSIS_DELETE_ICONS_EXTRA
    命令形式删除开始菜单快捷方式
  22. CPACK_NSIS_EXECUTABLES_DIRECTORY
    指定在NSIS安装程序中可执行文件的目录,默认为空,即使用默认的可执行文件目录。
  23. CPACK_NSIS_MUI_FINISHPAGE_RUN
    指定在NSIS安装程序的完成页面上显示的一个可执行文件的路径。默认为空,即不会在完成页面上显示任何可执行文件。
  24. CPACK_NSIS_MENU_LINKS
    指定开始菜单中的快捷方式。
  25. CPACK_NSIS_UNINSTALL_NAME(CMake 3.17 添加)
    指定卸载程序名称。 默认值为Uninstall。
  26. CPACK_NSIS_WELCOME_TITLE(CMake 3.17 添加)
    指定欢迎页面头部标题文字
  27. CPACK_NSIS_WELCOME_TITLE_3LINES(CMake 3.17 添加)
    指定NSIS安装程序的欢迎页面标题的三行文本。默认为空,即使用默认的欢迎页面标题。
  28. CPACK_NSIS_FINISH_TITLE(CMake 3.17 添加)
    指定NSIS安装程序的完成页面标题的三行文本
  29. CPACK_NSIS_FINISH_TITLE_3LINES(CMake 3.17 添加)
    指定NSIS安装程序的完成页面标题的三行文本。默认为空,即使用默认的完成页面标题。
  30. CPACK_NSIS_MUI_HEADERIMAGE(CMake 3.17 添加)
    指定NSIS安装程序的左上角图标(严格要求的bmp,后来处理了一下图片convert cion.bmp BMP3:cion2.bmp)
  31. CPACK_NSIS_MANIFEST_DPI_AWARE
    指定NSIS安装程序中应用程序的DPI感知属性。默认为空,即不设置DPI感知属性。参数:"default"、"true"、"false"
  32. CPACK_NSIS_BRANDING_TEXT(CMake 3.20 添加)
    指定NSIS安装程序中左下角标线描述。
  33. CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION(CMake 3.20 添加)
    指定NSIS安装程序中品牌文本的截断位置。默认为空,即不进行品牌文本的截断。参数:"left"、"right"
  34. CPACK_NSIS_EXECUTABLE(CMake 3.21 添加)
    指定NSIS安装程序的可执行文件。默认为空,即使用默认的可执行文件。
  35. CPACK_NSIS_IGNORE_LICENSE_PAGE(CMake 3.22 添加)
    指定NSIS安装程序是否忽略许可协议页面。默认为空,即不忽略许可协议页面。参数:"ON"、"OFF"
  36. CPACK_NSIS_EXECUTABLE_PRE_ARGUMENTS(CMake 3.25 添加)
    指定在NSIS安装程序运行可执行文件之前要添加的额外参数。
  37. CPACK_NSIS_EXECUTABLE_POST_ARGUMENTS
    指定在NSIS安装程序运行可执行文件之后要添加的额外参数。

注意事项

生成

E:\test\testMain\build>cpack.exe CPackConfig.cmake
CPack: Create package using NSIS
CPack: Install projects
CPack: - Install project: testMain []
CPack: Create package
CPack: - package: E:/test/testMain/build/测试软件-1.0.0-win64.exe generated.

最后效果

屏幕截图 2023-06-30 112619.jpg
屏幕截图 2023-06-30 112638.jpg


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)

结果


MSVC中的_BitScanForward和GCC中的__builtin_ctzl


问题

索博尔算法中用到了_BitScanForward这个函数,在做统信UOS适配的时候发现这个函数是MSVC专有的,百度了一下linux下对应的有__builtin_ctz相关的系列函数

头文件引用

*winlinux
头文件intrin.hx86intrin.h
函数_BitScanForward__builtin_ctzl

代码对比

win

#include <iostream>
#include <intrin.h>
using namespace std;

#pragma intrinsic(_BitScanForward)

static const unsigned QRNG_NDMS = 32;
    struct
    {
        unsigned __int64 uValue;
        unsigned uPrevSeed;
    } m_prev[QRNG_NDMS];

unsigned __int64 cjn[QRNG_NDMS][63] = { 0 };

int main()
{
    unsigned long mask = 0;
    unsigned long index;
    unsigned char isNonzero;

    unsigned m_uCurSeed = 2048,m_uCurDim;
    m_uCurDim = 0;
    unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed;
    unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode;
    unsigned long uBit;
    
    while (_BitScanForward(&uBit, changedBits))
    {
        cout << uBit << endl << changedBits <<endl;
        m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit];
        changedBits &= ~(1 << uBit);
    }
    
    cout << uBit << endl << changedBits <<endl;

    return 0;
}

Linux

#include <iostream>
#include <x86intrin.h>

using namespace std;

static const unsigned QRNG_NDMS = 32;
    struct
    {
        unsigned long long uValue;
        unsigned uPrevSeed;
    } m_prev[QRNG_NDMS];

unsigned long long cjn[QRNG_NDMS][63] = { 0 };

int main(int, char**) {
    unsigned long mask = 0;
    unsigned long index = 0;
    unsigned char isNonzero;

    unsigned m_uCurSeed = 2048,m_uCurDim;
    m_uCurDim = 0;
    unsigned grayCode = (m_uCurSeed >> 1) ^ m_uCurSeed;
    unsigned changedBits = m_prev[m_uCurDim].uPrevSeed ^ grayCode;
    unsigned long uBit;
    cout << __builtin_ctzl(10) << endl;
    while (true)
    {
        uBit = __builtin_ctzl(changedBits);
        if(uBit >= 64){
            break;
        }
        cout << uBit << endl << changedBits <<endl;
        m_prev[m_uCurDim].uValue ^= cjn[m_uCurDim][uBit];
        changedBits &= ~(1 << uBit);
    }
    
    cout << uBit << endl << changedBits <<endl;
}

C/C++ Linux创建文件夹


描述

系统做linux适配的时候发现不能追迹,最后检查发现不能在对应目录创建相关文件夹导致的。

包含头文件

#include <sys/stat.h>  
#include <sys/types.h>

函数

函数原型:   int mkdir(const char *pathname, mode_t mode);   
函数说明:   mkdir()函数以mode方式创建一个以参数pathname命名的目录,mode定义新创建目录的权限。   
返回值:   若目录创建成功,则返回0;否则返回-1,并将错误记录到全局变量errno中。

mode模式类型:

S_IRWXU 00700权限,代表该文件所有者拥有读,写和执行操作的权限
S_IRUSR(S_IREAD) 00400权限,代表该文件所有者拥有可读的权限
S_IWUSR(S_IWRITE) 00200权限,代表该文件所有者拥有可写的权限
S_IXUSR(S_IEXEC) 00100权限,代表该文件所有者拥有执行的权限
S_IRWXG 00070权限,代表该文件用户组拥有读,写和执行操作的权限
S_IRGRP 00040权限,代表该文件用户组拥有可读的权限
S_IWGRP 00020权限,代表该文件用户组拥有可写的权限
S_IXGRP 00010权限,代表该文件用户组拥有执行的权限
S_IRWXO 00007权限,代表其他用户拥有读,写和执行操作的权限
S_IROTH 00004权限,代表其他用户拥有可读的权限
S_IWOTH 00002权限,代表其他用户拥有可写的权限
S_IXOTH 00001权限,代表其他用户拥有执行的权限

示例结果

屏幕截图 2023-03-29 071402.png


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