【问题标题】:CMake project cannot link with Boost.Test statically or dynamicallyCMake 项目无法与 Boost.Test 静态或动态链接
【发布时间】:2020-08-23 10:39:14
【问题描述】:

我正在尝试使用 CMake 和 Boost 库(在本例中为 Boost.Test)设置一个简单的 C++ 项目。除了尝试静态链接之外,我正在遵循本指南:https://www.jetbrains.com/help/clion/boost-test-support.html。我已经使用本指南安装了 Boost:https://www.boost.org/doc/libs/1_73_0/more/getting_started/windows.html,并成功按照步骤 5 生成了库二进制文件。

使用以下 CMake 配置,我在尝试使用 cmake --build . 构建时收到此错误:

test1.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start@unit_test_log_t@unit_test@boost@@UEAAXK@Z)
tests2.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl boost::unit_test::unit_test_log_t::test_start(unsigned long)" (?test_start@unit_test_log_t@unit_test@boost@@UEAAXK@Z)
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(cmake_boost_test)

set(CMAKE_CXX_STANDARD 14)

add_executable(cmake_boost_test main.cpp)

add_subdirectory(Boost_tests)

Boost_tests/CMakeLists.txt

set(Boost_DEBUG ON)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
include_directories(${Boost_INCLUDE_DIRS})

add_executable(Boost_Tests_run test1.cpp tests2.cpp)
target_link_libraries(Boost_Tests_run ${Boost_LIBRARIES})

Boost_tests/test1.cpp

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

Boost_tests/tests2.cpp

#include <boost/test/unit_test.hpp>

【问题讨论】:

  • 根据 Boost Library naming 方案,libboost&lt;...&gt;.lib 之类的文件表示 static 库,boost&lt;...&gt;.lib 之类的文件表示 import动态的 (如果被命名为boost&lt;...&gt;.dll)。看来您只安装了静态 Boost 库。对于调试“Could NOT find Boost ...”问题,将 -DBoost_DEBUG=ON 选项传递给 cmake 并检查搜索的确切文件名。
  • 我有完全相同的问题,哪个根是宏分辨率。链接器报告,它找不到int main() {} 函数。它应该由 Boost.test 定义,但它没有:( 如果你找到了解决方案,那将非常有用
  • @BorikBobrujskov 抱歉,我不知道我是如何解决这个问题的。我相信这与我对下面答案的评论中提到的 Boost_USE_STATIC_LIBS 标志有关。但这是这个问题的工作项目(修复在这里的某个地方):github.com/JSchneidler/cmake_boost_template

标签: c++ visual-c++ boost cmake boost-test


【解决方案1】:

基本上有3个步骤:

  1. 构建 boost 和相关库及其变体(参见 here 了解 Boost.Test)
  2. 使用 CMake 配置项目(示例 here
  3. 构建项目

看起来你已经掌握了所有步骤,但让事情变得困难的是这 3 个步骤是相关的,应该以连贯的方式完成:

  1. 步骤 1+2:如果您在步骤 1 中构建 Boost(或 Boost.Test)的特定变体,则必须使用该变体指示 CMake
  2. 第 3 步:在构建项目时,您的代码程序在某些情况下应该使用定义来构建,该定义指示正在构建的变体是什么。例如,如果您想与 Boost.Test 的共享库版本链接,您必须定义 BOOST_TEST_DYN_LINK(在任何包含 Boost.Test 之前的代码中或使用 target_compile_definitions(test_executable PRIVATE "BOOST_TEST_DYN_LINK=1")

对于 Boost.Test,还有另一个问题:在 Windows 上,自动链接功能将指示链接器自动链接到 .lib 的一个版本:这是我通常通过传递定义来禁用的BOOST_ALL_NO_LIB.

如果您能够让 CMake 检测 Boost.Test,我不会一开始就为所有这些链接问题而烦恼,并使用不涉及链接问题的 header variant

回到你目前的状态:

  • 错误Could NOT find Boost (missing: unit_test_framework) (found version 1.60.0") 与步骤1+2 相关:CMake 无法找到具有您所指示的配置的库。有时您需要为 CMake 提供更多变量,以便它找到正确的库,但我猜您只是没有构建共享变体(请参阅here)。例如,我有时使用Boost_COMPILERBoost_ARCHITECTURE
  • Boost_USE_STATIC_LIBS 仅适用于 CMake:它不会强制您使用正确的定义进行编译。

如果您通过传递 -DBoost_DEBUG=ON 来发布您在 CMake 中遇到的错误,我们将能够更准确地为您提供支持。

【讨论】:

  • 谢谢!我绝对误会了Boost_USE_STATIC_LIBSBoost_DEBUG 已开启,我将用完整的错误更新问题(它很大)。我最终将切换到仅标题,因为它对我的小项目更有意义,尽管我想了解如何实际链接库(我对 Boost.Filesystem 有同样的问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 2020-04-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2015-02-09
  • 1970-01-01
相关资源
最近更新 更多