У меня есть простой тестовый файл, TestMe.cpp:
#include <gtest/gtest.h>
TEST(MyTest, SomeTest) {
EXPECT_EQ(1, 1);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Мне создали Google Test как статической библиотеке. (Я могу обеспечить make-файл, если это релевантно.)
Я могу скомпилировать TestMe.cpp от командной строки без проблемы:
g++ TestMe.cpp -IC:\gtest-1.5.0\gtest-1.5.0\include -L../gtest/staticlib -lgtest -o TestMe.exe
Это работает как ожидалось.
Однако я не могу заставить это компилировать в QT Мой спокойный файл проекта в том же каталоге:
SOURCES += TestMe.cpp
INCLUDEPATH += C:\gtest-1.5.0\gtest-1.5.0\include
LIBS += -L../gtest/staticlib -lgtest
Это приводит к 17 ошибкам "неразрешенной внешней ссылки", связанным с функциями gtest.
Я вытягиваю волосы здесь, поскольку я уверен, что это - что-то простое. Какие-либо идеи?
Вот некоторые внешние символы, которые не определены:
TestMe.obj:-1: error: unresolved external symbol "public: int __thiscall testing::UnitTest::Run(void)" (?Run@UnitTest@testing@@QAEHXZ) referenced in function _main
TestMe.obj:-1: error: unresolved external symbol "public: static class testing::UnitTest * __cdecl testing::UnitTest::GetInstance(void)" (?GetInstance@UnitTest@testing@@SAPAV12@XZ) referenced in function _main
TestMe.obj:-1: error: unresolved external symbol "void __cdecl testing::InitGoogleTest(int *,char * *)" (?InitGoogleTest@testing@@YAXPAHPAPAD@Z) referenced in function _main
TestMe.obj:-1: error: unresolved external symbol "public: __thiscall testing::internal::AssertHelper::~AssertHelper(void)" (??1AssertHelper@internal@testing@@QAE@XZ) referenced in function "private: virtual void __thiscall MyTest_SomeTest_Test::TestBody(void)" (?TestBody@MyTest_SomeTest_Test@@EAEXXZ)
Я так и не смог заставить его работать как статическую библиотеку, но он работает как DLL.
Сначала мне нужно было создать Google Test как DLL. У меня не получилось заставить это работать в Visual Studio, поэтому я просто использовал mingw32-make. Вы можете использовать Makefile, предоставленный в исходниках, внеся следующие изменения:
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -DGTEST_CREATE_SHARED_LIBRARY=1 -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -DGTEST_CREATE_SHARED_LIBRARY=1 -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
gtest.dll : gtest-all.o
$(CXX) -shared -o $@ $^ -Wl,--out-implib,gtest_dll.lib
gtest_main.dll : gtest-all.o gtest_main.o
$(CXX) -shared -o $@ $^ -Wl,--out-implib,gtest_main_dll.lib
Затем, при компиляции вашего тестового проекта, вы должны:
(Насколько я понимаю, вы используете gtest_main только если вы НЕ предоставляете свою собственную функцию main())
Вот пример файла Qt pro, основанный на том, который у меня (наконец-то!) работает:
DEFINES += GTEST_LINKED_AS_SHARED_LIBRARY=1
SOURCES += main.cpp MyClassTests.cpp
INCLUDEPATH += ../path/to/gtest/includes
LIBS += -L../path/to/gtest/libraries -lgtest_dll \
-L../ClassLibrary/bin -lMyClass
CONFIG += console
Я думаю, что с вашим файлом qmake все в порядке. Но почему INCLUDEPATH абсолютный, а LIBS относительный. Я бы попробовал также установить LIBS абсолютным.
Отсюда http://doc.trolltech.com/4.6/qmake-variable-reference.html#includepath
Но главная проблема (я думаю) в том, что вам нужно поставить прямые слеши в INCLUDEPATH. В документации это выглядит следующим образом.
INCLUDEPATH += C:/gtest-1.5.0/gtest-1.5.0/include
Я без проблем использую Qt + gtest / gmock. Я только что протестировал все возможные комбинации абсолютных / относительных путей с разными косыми чертами, но не смог воспроизвести вашу проблему. Проверяли ли вы содержимое переменной «LIBS» из Makefile.Debug, созданной qmake?
Вот общий совет: не используйте абсолютные пути, потому что ваш код не будет компилироваться на других машинах, кроме вашей, если вы не загрузите его точно в то же место (что может быть невозможно из-за другой настройки Qt и т. д.). Вместо этого используйте относительные пути, также для сторонних библиотек.
Я сохраняю сторонние библиотеки в системе контроля версий (вы ведь пользуетесь одной из них?). У меня есть «сторонний» каталог, и для каждого проекта, который использует эти библиотеки, я добавляю свойство svn: external, указывающее на явно указанную версию сторонней библиотеки. Последняя часть важна, потому что она гарантирует, что вы сможете собрать каждую версию своего проекта, даже если вы обновляете стороннюю библиотеку.