强制库与 Qt 和 google test 链接

发布于 2024-08-12 12:01:30 字数 1236 浏览 4 评论 0原文

我正在尝试使用 google test 为我的 Qt(c++) 应用程序编写一套测试套件,主要问题是我的应用程序由一个主程序和各种共享库组成。一切都工作得很好,直到我尝试使用 gcov/lcov (它不在动态库上运行)进行一些代码覆盖,所以我修改了所有 .pro 文件以使用以下命令进行静态库编译:


CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a

问题是 google测试测试应用程序是这样的:



int main(int argc, char **argv) {

  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

所以它在运行时检测链接,这意味着当我在这里编译测试应用程序时没有警告或任何指示问题的内容,并且在运行测试应用程序时它执行 0 test 因为它不'没有找到任何。

我的解决方案(放弃烦人的解决方案)是在每个类中定义,该类将用于测试虚假的公共静态成员,并对其主测试应用程序执行操作:


class SETTINGS_TESTS_SHARED_EXPORT SettingsTests: public testing::Test {

public:
 SettingsTests();
 virtual ~SettingsTests();

 static bool dummy;
protected:
 virtual void SetUp();
 virtual void TearDown();

private:
 Settings* _setting0;
 Settings* _setting1;
 Settings* _setting2;
};



using namespace MBI::SETTINGS;
using namespace MBI::TESTS;

int main(int argc, char **argv) {

  SettingsTests::dummy = true;
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

这样我就可以在我的应用程序上强制该库的链接。

我还发现选项 -u 可以在 gcc 中执行类似的操作,但似乎不起作用。如果在编译时无法检测到符号,有人有办法强制静态库链接吗?

I'm trying to write a test suit for my Qt(c++) application using google test, the main problem is that my application consists of one main program and various shared libs. Everything was working just fine, until I tried to do some code coverage using gcov/lcov (which don't operate on dynamic libs), so I modified all my .pro file to have a static lib compilation using :


CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a

The problem is that google test test application is something like this:



int main(int argc, char **argv) {

  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

so it detects the linkage at runtime, which means that when I compile the test application here is no warning or whatever that indicate a problem, and when running the test application it execute 0 test because it doesn't found any.

my solution (quit annoying one) is to define in each class which will be used for test a phony public static member and do an operation for the main test application on it:


class SETTINGS_TESTS_SHARED_EXPORT SettingsTests: public testing::Test {

public:
 SettingsTests();
 virtual ~SettingsTests();

 static bool dummy;
protected:
 virtual void SetUp();
 virtual void TearDown();

private:
 Settings* _setting0;
 Settings* _setting1;
 Settings* _setting2;
};



using namespace MBI::SETTINGS;
using namespace MBI::TESTS;

int main(int argc, char **argv) {

  SettingsTests::dummy = true;
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

so I can force the linkage of that lib on my application.

I have also found the option -u to do something like that in gcc but doesn't seem to work. have anyone have a way to force static library linking if no symbol can be detected in compile time ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

窝囊感情。 2024-08-19 12:01:30

我不完全理解这个问题,它没有解释 ::testing::InitGoogleTestRUN_ALL_TESTS 实际上做了什么,以及它们与动态链接的关系。

但是:您可以使用选项 --unresolved-symbols=ignore-all 使 GNU 链接器在链接时忽略未解析的符号,或者如果您需要将该选项传递给 gcc,- Wl,--unresolved-symbols=ignore-all

I don't completely understand the question, it's not explained what ::testing::InitGoogleTest and RUN_ALL_TESTS actually do, and how they're related to dynamic linking.

But: you can make the GNU linker ignore unresolved symbols at link time by using the option --unresolved-symbols=ignore-all , or if you need to pass the option to gcc, -Wl,--unresolved-symbols=ignore-all.

ら栖息 2024-08-19 12:01:30

在谷歌测试文档中提到了与 Visual C++ DLL 的链接问题:

Important note for Visual C++ users

If you put your tests into a library and your main() function is in a different library or in your .exe file, those tests will not run. The reason is a bug in Visual C++. When you define your tests, Google Test creates certain static objects to register them. These objects are not referenced from elsewhere but their constructors are still supposed to run. When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out. You have to reference your library with tests from your main program to keep the linker from discarding it. Here is how to do it. Somewhere in your library code declare a function:

__declspec(dllimport) int PullInMyLibrary() { return 0; }
If you put your tests in a static library (not DLL) then __declspec(dllexport) is not required. Now, in your main program, write a code that invokes that function:

int PullInMyLibrary();
static int dummy = PullInMyLibrary();
This will keep your tests referenced and will make them register themselves at startup.

In addition, if you define your tests in a static library, add /OPT:NOREF to your main program linker options. If you use MSVC++ IDE, go to your .exe project properties/Configuration Properties/Linker/Optimization and set References setting to Keep Unreferenced Data (/OPT:NOREF). This will keep Visual C++ linker from discarding individual symbols generated by your tests from the final executable.

There is one more pitfall, though. If you use Google Test as a static library (that's how it is defined in gtest.vcproj) your tests must also reside in a static library. If you have to have them in a DLL, you must change Google Test to build into a DLL as well. Otherwise your tests will not run correctly or will not run at all. The general conclusion here is: make your life easier - do not write your tests in libraries!

并且采用的解决方案几乎就是我对 G++ 所做的。我怀疑 qmake 生成中间文件 moc_* 并且我的代码与之链接。

In the google test doc there is a mention of linkage problem with visual c++ dll:

Important note for Visual C++ users

If you put your tests into a library and your main() function is in a different library or in your .exe file, those tests will not run. The reason is a bug in Visual C++. When you define your tests, Google Test creates certain static objects to register them. These objects are not referenced from elsewhere but their constructors are still supposed to run. When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out. You have to reference your library with tests from your main program to keep the linker from discarding it. Here is how to do it. Somewhere in your library code declare a function:

__declspec(dllimport) int PullInMyLibrary() { return 0; }
If you put your tests in a static library (not DLL) then __declspec(dllexport) is not required. Now, in your main program, write a code that invokes that function:

int PullInMyLibrary();
static int dummy = PullInMyLibrary();
This will keep your tests referenced and will make them register themselves at startup.

In addition, if you define your tests in a static library, add /OPT:NOREF to your main program linker options. If you use MSVC++ IDE, go to your .exe project properties/Configuration Properties/Linker/Optimization and set References setting to Keep Unreferenced Data (/OPT:NOREF). This will keep Visual C++ linker from discarding individual symbols generated by your tests from the final executable.

There is one more pitfall, though. If you use Google Test as a static library (that's how it is defined in gtest.vcproj) your tests must also reside in a static library. If you have to have them in a DLL, you must change Google Test to build into a DLL as well. Otherwise your tests will not run correctly or will not run at all. The general conclusion here is: make your life easier - do not write your tests in libraries!

And the solution adopted is pretty much what I did with g++. I'm suspecting the fact that qmake produce intermediary file moc_* and that my code in linked against that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文