put*_*mpp 5 c++ ubuntu singleton dynamic-linking boost-unit-test-framework
我正在尝试使用Boost的单元测试框架构建单元测试.我想动态地将测试套件库与Boost提供的自动生成的测试模块链接起来.这是我一直在使用的基本结构:
test_main.cpp:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
Run Code Online (Sandbox Code Playgroud)
lib_case.cpp:
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE( test_lib )
BOOST_AUTO_TEST_CASE( test_lib_case ) {
BOOST_ASSERT(true);
}
BOOST_AUTO_TEST_SUITE_END()
Run Code Online (Sandbox Code Playgroud)
Makefile文件:
all: unittest unittest2 unittest3
lib_case.o: lib_case.cpp
g++ -g -c -Wall -fPIC lib_case.cpp -o lib_case.o
libcase.so: lib_case.o
g++ -shared -Wl,-soname,libcase.so -o libcase.so lib_case.o
unittest: libcase.so
g++ -o unittest test_main.cpp -L. -lcase -lboost_unit_test_framework
unittest2: test_main.cpp lib_case.cpp
g++ -o unittest2 test_main.cpp lib_case.cpp -lboost_unit_test_framework
unittest3: lib_case.o
g++ -o unittest3 test_main.cpp lib_case.o -lboost_unit_test_framework
Run Code Online (Sandbox Code Playgroud)
在Ubuntu 14.04上进行测试,所有可执行文件都可以编译和链接而不会出错.
'unittest'无法执行'test_lib'套件声称安装失败,但'unittest2'和'unittest3'成功:
$./unittest
Test setup error: test tree is empty
$./unittest2
Running 1 test case...
*** No errors detected
$./unittest3
Running 1 test case...
*** No errors detected
Run Code Online (Sandbox Code Playgroud)
现在头疼:所有unittest*在Fedora 20上运行测试套件.
在查看'unittest'的依赖列表时,我确实看到'libcase.so'没有在Ubuntu版本中列出,但是在Fedora 20版本中.我已经玩过重新排序依赖项,使用SO的绝对路径,以及更改Boost版本(1.54和1.55).没有任何效果.
关于什么可能阻止'libcase.so'的任何想法在Ubuntu 14.04上被链接而在Fedora 20上没有?我错过了一些神奇的编译器/链接器标志吗?
更新:
Sehe的评论和回答有助于缩小问题范围.如果我正确理解Boost的动态链接UTF实现(至少从1.54/55开始),那么框架提供了一个测试用例管理器单例.每个测试用例都会在构建时自动向经理注册.
我认为问题是,无论出于何种原因,在Ubuntu上链接'优化'在将库链接到二进制文件期间用于管理器的单例实例的静态全局变量.实际上,尽管共享相同的全局静态变量,但它并不链接两个单例实例.它将它们视为两个独立的实例.
我按照Linux上共享库的多个单例实例中描述的步骤来检查库和二进制文件.与他们的情况不同,-rdynamic选项不能解决我的问题.
我做了一些测试,发现这很有趣.如果你预加载libcase.so对象,unittest适用于Ubuntu.即使libcase.so没有出现在其ldd列表中.我觉得这是预期的,因为当单元测试运行时,管理器的单例被"预加载"它将链接到它.
$ LD_PRELOAD=/absolute/path/to/libcase.so ./unittest
Running 1 test case ...
Run Code Online (Sandbox Code Playgroud)
仍然不知道为什么Ubuntu不想像Fedora那样预期/预期链接.阅读本教程(特别是'与Microsoft DLL的比较'部分)让我觉得Ubuntu遵循Windows链接模式.
得到它了!
Ubuntu似乎--as-needed默认使用链接器选项,而Fedora可能不会.关闭它会将libcase.so库添加到unittest所需的列表中.部署库(或使用LD_LIBRARY_PATH)后,unittest现在可以正常工作.
unittest: libcase.so
g++ -o unittest test_main.cpp -Wl,--no-as-needed -L. -lcase -lboost_unit_test_framework
Run Code Online (Sandbox Code Playgroud)
数字很简单......
| 归档时间: |
|
| 查看次数: |
1825 次 |
| 最近记录: |