Windows环境下CMake动态链接库编译时无法找到lib文件的问题求助
Windows环境下CMake动态链接库编译时无法找到lib文件的问题求助
嘿,我来帮你搞定这个Windows下动态库编译的问题!先理清楚你的项目情况和错误根源,再一步步调整:
你的项目文件内容
先把你提供的项目文件整理出来,方便对照修改:
根目录CMakeLists.txt
cmake_minimum_required(VERSION 3.27) # 确定 CMake 最低版本要求 project(CppThreadPool VERSION 0.1.0 DESCRIPTION "A simple thread pool for C++" LANGUAGES C CXX) # 项目名称及使用的编程语言 set(CMAKE_CXX_STANDARD 20) # 设置 C++ 标准 # 编译选项 option(BUILD_POOL_TEST "Build pool test" ON) option(BUILD_POOL_EXAMPLES "Build pool examples" ON) # 添加子目录 add_subdirectory(src) if (BUILD_POOL_EXAMPLES) add_subdirectory(examples) endif () if (BUILD_POOL_TEST) enable_testing() find_package(GTest CONFIG REQUIRED) add_subdirectory(tests) endif ()
src/CMakeLists.txt
set(MODULE_NAME "thread_pool") set(THREADPOOL_SRC thread_pool.cpp ) add_library(${MODULE_NAME} SHARED ${THREADPOOL_SRC}) #add_library(${MODULE_NAME} STATIC ${THREADPOOL_SRC}) target_link_libraries(${MODULE_NAME}) target_include_directories(${MODULE_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
src/thread_pool.cpp
#include <iostream> #include "../include/thread_pool.h" namespace fx { int PoolTest() { std::cout << "PoolTest" << std::endl; return 1; } }
include/thread_pool.h
#pragma once namespace fx { int PoolTest(); }
examples/CMakeLists.txt
add_executable(pool_example pool_example.cpp) target_link_libraries(pool_example PRIVATE thread_pool)
examples/pool_example.cpp
#include "../include/thread_pool.h" int main() { fx::PoolTest(); return 0; }
tests/CMakeLists.txt
set(TEST_SRC test.cpp) add_executable(pool_test ${TEST_SRC}) target_link_libraries(pool_test PUBLIC GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main thread_pool) add_test(NAME PoolTests COMMAND pool_test)
tests/test.cpp
#include "gtest/gtest.h" #include "../include/thread_pool.h" TEST(BasicPoolTest, Test1) { EXPECT_EQ(fx::PoolTest(), 1); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
编译错误信息
你遇到的核心错误是:
FAILED: examples/pool_example.exe ... LINK : fatal error LNK1104: 无法打开文件“src\thread_pool.lib”
问题原因&解决步骤
这个问题是Windows平台MSVC编译器的特性导致的:当编译动态链接库(SHARED)时,如果没有显式导出符号,编译器只会生成.dll文件,不会生成用于链接的导入库.lib,所以你的示例程序链接时找不到这个lib文件。另外还有几个CMake配置的小问题需要调整,具体改法如下:
1. 修改src/CMakeLists.txt,添加导出宏和修正include目录
把src下的CMakeLists.txt改成这样:
set(MODULE_NAME "thread_pool") set(THREADPOOL_SRC thread_pool.cpp ) add_library(${MODULE_NAME} SHARED ${THREADPOOL_SRC}) # 关键:添加编译宏,用于Windows下的符号导出/导入 target_compile_definitions(${MODULE_NAME} PRIVATE THREAD_POOL_EXPORTS) # 把include目录设为PUBLIC,这样依赖这个库的目标(examples/tests)能自动找到头文件 target_include_directories(${MODULE_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) target_link_libraries(${MODULE_NAME})
2. 修改include/thread_pool.h,添加符号导出宏
Windows下动态库需要明确告诉编译器哪些函数是要导出的,所以头文件要加导出宏:
#pragma once // Windows平台的动态库符号导出/导入宏定义 #ifdef _WIN32 #ifdef THREAD_POOL_EXPORTS #define THREAD_POOL_API __declspec(dllexport) #else #define THREAD_POOL_API __declspec(dllimport) #endif #else // 非Windows平台不需要这个宏 #define THREAD_POOL_API #endif namespace fx { // 用宏标记要导出的函数 THREAD_POOL_API int PoolTest(); }
3. 简化examples和tests里的头文件引用(可选,但更规范)
因为我们已经把include目录设为PUBLIC,所以examples/pool_example.cpp和tests/test.cpp里的头文件可以改成:
#include "thread_pool.h"
不用再写相对路径了,CMake会自动帮你找到头文件。
4. 重新构建项目
先删除你的cmake-build-debug目录,然后重新运行CMake配置,再编译。这时候应该会在src目录下生成thread_pool.dll和thread_pool.lib两个文件,示例程序也能正常链接了。
备注:内容来源于stack exchange,提问作者fanxing
相关产品推荐
相关产品推荐

