为没有CMake配置的第三方库添加CMake配置

1 编写CMakeLists.txt

cmake_minimum_required(VERSION 3.15)  
  
#如果你第三方库和自己的库没有xxxConfig.cmake  
#请修改项目名称和命名空间(一般不需要)  
project("pthreads" LANGUAGES C CXX)  
set(KC_NAMESPACE "")  
#set(KC_NAMESPACE "Threads::")  
set(KC_NAMESPACE_EMPTY "")  
  
# TODO:设置编译器标准  
set(CMAKE_C_STANDARD 99)  
set(CMAKE_C_STANDARD_REQUIRED ON)  
set(CMAKE_CXX_STANDARD 17)  
set(CMAKE_CXX_STANDARD_REQUIRED ON)  
  
# 包含GNUInstallDirs模块是为了通过使目录可用作缓存变量来为项目提供安装到不同平台布局的灵活性。  
include(GNUInstallDirs)  
  
  
# TODO:添加所有头文件  
set(KC_HEADERS  
        empty.h  
)  
  
# TODO:添加所有源文件  
set(KC_SOURCE_SRC  
        empty.c  
)  
  
# TODO: 生成动态链接库。  
add_library(${PROJECT_NAME} SHARED  
        ${KC_SOURCE_SRC}  
)  
  
# TODO: 目标指定包含目录  
# 我们需要告诉 CMake 我们想要使用不同的包含目录,具体取决于我们是在构建库还是从已安装的位置使用它。  
# 如果我们不这样做,当 CMake 创建导出信息时,它将导出一个特定于当前构建目录的路径,并且对其他项目无效。  
# 我们可以使用 generator expressions 来指定如果我们正在构建库包括当前源目录。  
# 否则,在安装时,包含 include 目录。有关更多详细信息,请参阅“创建可重定位包”部分。  
target_include_directories(${PROJECT_NAME} PUBLIC  
        "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"  
        "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"  
)  
  
# TODO: 指定库所依赖的库。(可选)如果指定为PUBLIC,则依赖库将被导出。  
target_link_libraries(${PROJECT_NAME} PUBLIC  
)  
  
# TODO: 在 install(TARGETS) 命令中,将指定目标、EXPORT 名称和告诉 CMake 在何处安装目标的目的地。  
install(TARGETS ${PROJECT_NAME}  
        EXPORT ${PROJECT_NAME}Config # 5.a 使用“导出”选项指定导出名称。  
        # RUNTIME DESTINATION bin  
        LIBRARY DESTINATION lib # 5.b 安装库  
        # ARCHIVE DESTINATION lib  
        INCLUDES DESTINATION include # 5.c 安装一个头文件,指定导出时包含路径中要包含的路径。  
)  
  
#使用install(FILES)命令安装头文件  
install(FILES ${KC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})  
  
# TODO: 安装 ${PROJECT_NAME}Config导出细节  
if ("${KC_NAMESPACE}" STREQUAL "${KC_NAMESPACE_EMPTY}")  
    install(EXPORT ${PROJECT_NAME}Config   # 6.a 在 5.a中指定的名称  
            FILE ${PROJECT_NAME}Config.cmake   # 6.b 指定文件名  
            DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake  #cmake安装目录 ${CMAKE_INSTALL_LIBDIR}表示cmake目录位于lib\cmake中  
    )  
else ()  
    install(EXPORT ${PROJECT_NAME}Config   # 6.a 在 5.a中指定的名称  
            FILE ${PROJECT_NAME}Config.cmake   # 6.b 指定文件名  
            NAMESPACE Threads::            # 6.c 命名空间  
            DESTINATION ${CMAKE_INSTALL_PREFIX}/cmake   #cmake安装目录 ${CMAKE_INSTALL_LIBDIR}表示cmake目录位于lib\cmake中  
    )  
endif ()

2 添加一个.h和.c文件

empty.h和empty.c是防止第一节的"CMakeLists.txt"编译错误,实际不需要 。

empty.h

#include <stdio.h>  
#include <stdlib.h>  
  
#ifndef KC_690052D6_304C_3640_9218_2B58EF66E677  
#define KC_690052D6_304C_3640_9218_2B58EF66E677  
  
  
#ifdef __cplusplus  
extern "C" {  
#endif  /*__cplusplus 1*/  
  
    extern __declspec(dllexport) int __stdcall kcTest();  
#ifdef __cplusplus  
};  
#endif  /*__cplusplus 2*/  
  
#endif  /*KC_690052D6_304C_3640_9218_2B58EF66E677*/  

empty.c

int kcTest(){  
  return 0;
}  

3 开始编译

编译脚本如下

chcp 65001  
set KC_PROJECT_PATH=D:\MyWork\2025\cmake_config  
cd %KC_PROJECT_PATH%  
D:  
  
rd /S /Q build  
rd /S /Q dest  
cmake -G "NMake Makefiles" -Wno-dev -D CMAKE_BUILD_TYPE=Release -B build -S . ^  
-DCMAKE_INSTALL_PREFIX=dest  
  
cmake --build build --config Release  
  
cmake --install build --config Release  

编译完成后将"dest\cmake"目录复制到所在的库目录.

例如自行编译的pthreads4w库,实际的安装位置"D:/library/vs/pthreads",将"dest\cmake"拷贝至此目录。

4 修改xxxConfig.cmake

打开xxxConfig.cmake和xxxConfig-release.cmake

例如自行编译的pthreads4w库,实际的安装位置"D:/library/vs/pthreads",库名称为pthreads,没有命名空间

打开"D:/library/vs/pthreads/cmake/pthreadsConfig.cmake"

#找到  
set(_IMPORT_PREFIX "D:/MyWork/2025/cmake_config/dest")  
#修改为库实际所在的目录  
set(_IMPORT_PREFIX "D:/library/vs/pthreads")  

打开"D:/library/vs/pthreads/cmake/pthreadsConfig-release.cmake"

set_target_properties(pthreads PROPERTIES  
	IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/pthreads.lib"
	IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/pthreads.dll"
)  
  
list(APPEND _cmake_import_check_files_for_pthreads "${_IMPORT_PREFIX}/lib/pthreads.lib" "${_IMPORT_PREFIX}/bin/pthreads.dll" )  
#修改为库实际的名称  
set_target_properties(pthreads PROPERTIES
	IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/libpthreadVC3.lib"
	IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/pthreadVC3.dll"
)
list(APPEND _cmake_import_check_files_for_pthreads "${_IMPORT_PREFIX}/lib/libpthreadVC3.lib" "${_IMPORT_PREFIX}/bin/pthreadVC3.dll" )

至此我们为pthreads4w库配置了CMake find_package查找时所需要的配置文件

5 使用

新建一个项目,此项目需要使用到pthreads.

5.1 编写CMakeLists.txt

cmake_minimum_required(VERSION 3.15)  
  
project(chapter01 VERSION 1.0.0 LANGUAGES C)  
  
# TODO:查找软件包。此处就会使用到我们之前用到的配置,它会查找pthreadsConfig.cmake  
find_package(pthreads REQUIRED)  
  
# TODO:添加所有源文件  
set(KC_SOURCE_SRC  
        main.c)  
  
# TODO:生成可执行文件。  
add_executable(${PROJECT_NAME}  
        ${KC_SOURCE_SRC})  
  
# TODO:导入包含目录。因为pthreadsConfig.cmake已经设置了pthreads的头文件路径,这里不需要再配置了  
target_include_directories(${PROJECT_NAME} PRIVATE  
        ${CMAKE_CURRENT_SOURCE_DIR})  
  
# TODO:直接使用第一节中配置的项目名称即可链接库。注意如果有命名空间需要加上命名空间  
target_link_libraries(${PROJECT_NAME} PRIVATE  
        pthreads        #Threads::pthreads #如设置了命名空间名称为Threads,链接时要加上  
)  

5.2 添加编译参数使CMakeLists.txt能够正确的找到pthreads

pthreads_DIR的含义:pthreads为第一节中配置的项目名称,"_DIR"为固定值.

pthreads_DIR需要指向到xxxConfig.cmake所在的目录,而不是库安装目录 .

添加"pthreads_DIR:PATH=D:/library/vs/pthreads/cmake"至Vs Code、CLion、Visual Studio等开发工具即可使用。

如果使用命令行用以下方式添加

cmake -G "NMake Makefiles" -Wno-dev -D CMAKE_BUILD_TYPE=Debug -B build -S . ^  
-Dpthreads_DIR:PATH=D:/library/vs/pthreads/cmake  
  
cmake --build build --config Debug  
  
cmake --install build --config Debug  

上述操作完成后在Vs Code、CLion、Visual Studio中均可正确找到头文件和库文件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kmblack1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值