c++ - 在 Windows 中链接第三方预编译动态库和静态库

标签 c++ cmake cmake-gui

最近,我一直在使用 cmake 作为我项目的生成器。我已经成功生成了许多 vtk 和其他应用程序项目。但是,我现在在尝试链接动态和静态预编译库时遇到问题。特别是,我获得了一些动态预编译的第三方 dll 以及它们各自的 .lib 文件。此外,我正在尝试将一些静态预编译库(仅 .lib 文件)链接到我的项目以检查软件许可证。

假设我的项目名为 test_example,我在 libs 目录中有一些预编译的动态库。我的项目目录结构是:

测试示例
-/包括
-/库
-/ build
-CMakeLists.txt

用于链接动态库的 CMakeLists.txt 包含以下内容:

cmake_minimum_required(VERSION 2.8.9)
project (test_example)
set(CMAKE_BUILD_TYPE Release)

#For the shared libraries:
set (PROJECT_LINK_LIBS dynamic_1.dll dynamic_2.dll )
set (PROJECT_LINK_DIR ${test_example_SOURCE_DIR}/libs/)
set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)

link_directories(${PROJECT_LINK_DIR})
include_directories(${PROJECT_INCLUDE_DIR})

add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${PROJECT_LINK_LIBS})  

当我用这个 cmake 列表生成项目时,我可以成功地使用预编译 dll 中的方法。但是,我也没有找到链接到我的静态库的方法。假设我有一个名为 test_licence.lib 的静态库。我是否也应该将它放在 libs 文件夹中,然后像处理动态一样简单地引用它?当我这样做并在 Visual Studio 中打开我的项目解决方案时,我可以看到动态库和静态库都已添加到 Linker-->Input-->Additional Dependencies。但是,当我尝试构建项目时,我有 Unresolved external 依赖项,这些外部依赖项是静态库中的方法。
你们中有人知道什么是最有效的方法吗?非常感谢!

最佳答案

这里有几个问题。

与您可能习惯的 VS 不同,CMake prefers absolute paths for linking ,而不是设置链接目录并给出相对路径。

此外,您不要链接到 .dll 文件。 Dll 在运行时加载,而不是在链接时加载。许多 dll 附带导入库(以 .lib 结尾),它们会自动为您处理运行时加载。 These are the ones you should link against .

也尽量不要在 CMake 代码中对库进行硬编码。这里的问题是,如果出现问题,您最终会遇到神秘的链接器错误。你应该使用 find_library相反,如果出现问题,这通常会让 CMake 提前提示。

您的 CMake 脚本的更简洁版本类似于

cmake_minimum_required(VERSION 2.8.9)
project (test_example)

# note setting the build type does nothing on a visual studio build
# and should probably be left to the user for other generators
set(CMAKE_BUILD_TYPE Release)

#For the shared libraries:
# this call will succeed if it finds a dynamic_1.lib file
find_library(DYNAMIC_LIB1 dynamic_1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB1)
    message(FATAL_ERROR "Library dynamic_1 was not found!")
endif()
find_library(DYNAMIC_LIB2 dynamic_2 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB2)
    message(FATAL_ERROR "Library dynamic_2 was not found!")
endif()

# for the static libraries:
# basically the same; again this looks for a static_1.lib file
find_library(STATIC_LIB1 static1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT STATIC_LIB1)
    message(FATAL_ERROR "Library static_1 was not found!")
endif()


set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)

include_directories(${PROJECT_INCLUDE_DIR})

add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${DYNAMIC_LIB1} ${DYNAMIC_LIB2} ${STATIC_LIB1})

在 Visual Studio 中仔细检查所有库是否按预期添加为链接器输入。如果您仍然收到链接器错误,则意味着您的第三方 .lib 文件有问题。使用您收到的确切链接器错误打开一个新问题。

关于c++ - 在 Windows 中链接第三方预编译动态库和静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38433515/

相关文章:

cmake - 使用 CMake 时忽略外部模块中的警告

opencv - 'cmake'将引发 “OpenCVGenSetupVars.cmake”错误(在配置OpenCV时)

cmake - 使用 CMake GUI 设置交叉编译器文件

c++ - `cout << x` 和 `cout.operator<<(x)` 和 `operator(std::cout, x)` 之间的区别?

c++ - 使用 HEX 定义使用 ESC 命令创建字符串

c++ - 返回对 C++ 中动态数组元素的引用?

python - OpenCV 2.0 与 MacPorts 的 SWIG Python 绑定(bind)

c++ - 卡在 _dl_sysinfo_int80 上的多线程应用程序

cmake - CTest 在子目录中添加测试

cmake - 如何使CMake将Visual Studio链接器的选项“生成调试信息”设置为"is"?