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中均可正确找到头文件和库文件。