我试图使用cmake和clang编译一个boost单元测试模块,但遇到链接器错误。我能够生成以下最小测试用例:
<li>
<input type="checkbox" id="foo">
<label for="foo">Content of the element to be positioned at the center of it</label>
</li>
这与$ 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++
具体的内容吗?
这是关于Debian Sid的g ++ 5.2.1,clang ++ 3.7和boost 1.58。
答案 0 :(得分:2)
在Ubuntu Willy中,使用GCC 5.0编译Boost 1.58单元测试库。库文件libboost_unit_test_framework.a
包含已解析为_ZN5boost9unit_test9ut_detail24normalize_test_case_nameB5cxx11ENS0_13basic_cstringIKcEE
的错位函数boost::unit_test::ut_detail::normalize_test_case_name[abi:cxx11](boost::unit_test::basic_cstring<char const>)
但是,CLang似乎没有使用新的ABI,因此会搜索_ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE
,boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring<char const>)
。
为了克服这个问题,请在测试文件中定义自己的函数:
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相同的编译器版本进行编译,则应该没有问题,因为链接器将忽略函数的库版本。