【问题标题】:How to compile boost unit test module with clang++?如何用 clang++ 编译 boost 单元测试模块?
【发布时间】:2015-09-08 08:55:23
【问题描述】:

我正在尝试使用 cmake 和 clang 编译一个 boost 单元测试模块,但遇到了链接器错误。我能够生成以下最小测试用例:

$ cat boost_test_test.cc
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE scanio
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(foo) { BOOST_CHECK(1); }

这与g++ 编译得很好:

$ g++ boost_test_test.cc -lboost_unit_test_framework
$ echo $?
0

但是clang++却没有:

$ /usr/bin/clang++-3.7 boost_test_test.cc -lboost_unit_test_framework
/tmp/boost_test_test-7e4892.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&, boost::unit_test::basic_cstring<char const>)':
boost_test_test.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x58): undefined reference to `boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring<char const>)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

所以在链接器阶段我收到了一个undefined reference 错误,无论clang++ 的参数顺序如何,这个问题都仍然存在。

既然它与g++ 配合得很好,我想这里有一些clang++ 特定的东西吗?

这是在 Debian Sid 上使用 g++ 5.2.1、clang++ 3.7 和 boost 1.58。

【问题讨论】:

  • 我无法在我的电脑上重现此内容,您使用的是哪个 boost 版本?
  • @m.s.谢谢,那就有希望了。我将这些版本添加到我最初的问题中。
  • 它在我的机器上也能很好地编译,虽然我无法访问你提到的两个编译器的版本。
  • 我也有同样的问题,gcc版本5.2.1 20150903(Debian 5.2.1-16); Debian clang 版本 3.5.2-1 (tags/RELEASE_352/final) (基于 LLVM 3.5.2); libboost-test1.58-dev 1.58.0+dfsg-3

标签: c++ unit-testing boost g++ clang++


【解决方案1】:

在 Ubuntu Willy 中,Boost 1.58 单元测试库是使用 GCC 5.0 编译的。库文件libboost_unit_test_framework.a 包含解析为boost::unit_test::ut_detail::normalize_test_case_name[abi:cxx11](boost::unit_test::basic_cstring&lt;char const&gt;) 的重整函数_ZN5boost9unit_test9ut_detail24normalize_test_case_nameB5cxx11ENS0_13basic_cstringIKcEE

但是,CLang 似乎没有使用新的 ABI,所以它搜索_ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE,即boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring&lt;char const&gt;)

为了克服这个问题,在测试文件中定义你自己的函数:

namespace boost { namespace unit_test { namespace ut_detail {
    std::string normalize_test_case_name(const_string name) {
        return ( name[0] == '&' ? std::string(name.begin()+1, name.size()-1) : std::string(name.begin(), name.size() ));
    }
}}}

这应该可以解决问题。如果使用与 Boost 相同版本的编译器进行编译,应该没问题,因为链接器会简单地忽略函数的库版本。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
相关资源
最近更新 更多