在Windows中链接第三方预编译的动态和静态库
Linking both third party precompiled dynamic and static libaries in Windows
最近,我一直在使用cmake作为我的项目的生成器。我已经成功地生成了许多vtk和其他应用程序项目。然而,我现在在尝试链接动态和静态预编译库时遇到了一个问题。特别是,我得到了一些动态预编译的第三方dll以及它们各自的.lib文件。此外,我正在尝试将一些静态预编译库(只有.lib文件)链接到我的项目,以便检查软件许可证。
假设我的项目名为test_example,并且在libs目录中有一些预编译的动态库。我的项目目录结构是:
测试示例
-/包括
-/libs
-/生成
-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 DEpendences中。然而,当我试图构建项目时,我有未解析的外部依赖项,这些依赖项是静态库中的方法
你们中有人知道什么是实现这一目标的最有效方法吗?非常感谢!
这里有几个问题。
与你可能习惯的VS不同,CMake更喜欢绝对路径进行链接,而不是设置链接目录并给出相对路径。
此外,您不会针对.dll
文件进行链接。DLL是在运行时加载的,而不是在链接时加载的。许多dll都附带了导入库(以.lib结尾),这些库可以自动处理运行时加载。这些是你应该联系起来反对的。
也尽量不要在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
文件有问题。打开一个新问题,使用您得到的确切链接器错误。
以下是我们的做法:
首先,使用带有最终参数STATIC IMPORTED
的add_library
。然后使用set_property
设置IMPORTED_LOCATION
属性,该属性是指向已构建库的路径。例如,我们这样拉gtest:
add_library(gtest UNKNOWN IMPORTED)
set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a)
然后,gtest
是您构建系统中的一个已知库,您可以稍后通过执行来正常链接它
target_link_libraries(target-name gtest)
另请参阅:Cmake导入库文档
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 视觉studo 2019中的漫画和静态/动态绑定
- 静态数组的自由动态数组
- 动态初始化 C 与 C++ 中的静态值
- 以下代码执行哪种内存分配(动态或静态)?
- 将静态内存更改为动态C++
- 如何静态识别动态堆分配?
- 如果包含映射的静态库与可执行文件和动态库链接,静态映射(变量)是否会被多次释放?
- 非类类型表达式的静态类型与动态类型之间的差异
- 如何使用类型级函数动态创建静态类型?
- 静态和动态模板初始化可以交错吗?
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- 虚拟成员函数的定义是否强制在同一转换单元中动态初始化静态数据成员?
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 动态分配的数组和静态数组之间的区别
- 动态分配对象中的字段-动态分配更好还是静态分配更好?C++
- 如何对以下程序使用静态或动态转换
- 如何使用cmake设置OpenCV以启用动态和静态构建
- 静态分配和动态分配返回不同的答案
- 我应该在这个程序中使用静态内存分配还是动态内存分配