开发者

Force library linking with Qt and google test

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 sha开发者_运维技巧red 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 ?


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜