#c #visual-studio-code #cmake #googletest
#c #visual-studio-code #cmake #googletest
Вопрос:
Я не очень опытный программист и, когда я пишу код на своем компьютере, я использую Visual Studio. За несколько недель до этого я узнал о Visual Studio Code, и я был очень взволнован, и мне это очень понравилось. Однако, когда дело доходит до тестирования кода, у меня начинает болеть голова.
В Visual Studio я тестировал свой код с помощью Google Test, но я вижу, что в VSCode это намного сложнее, и я перепробовал все, каждый учебник, который я видел, чтобы использовать его. Не повезло, и каждый раз это происходит более или менее одинаково.
Например, допустим, я выполняю настройку в соответствии с руководством по googletest /README.md. Я создал решение с именем example, содержащее example.cpp , example.h и test.cpp , где мы находим модульные тесты.
example.h:
#pragma once
int Add(int a, int b);
example.cpp:
#include "example.h"
int Add(int a, int b) {
return a b;
}
test.cpp
#include <gtest/gtest.h>
#include "example.h"
TEST(ExampleTest, AddTest)
{
EXPECT_EQ(Add(2, 2), 4);
}
Затем я клонировал googletest, например, создал и открыл вставку с именем build и использовал $ cmake ../googletest
в терминале. На данный момент пример выглядит так:
example/
--build/
--googletest/
--example.cpp
--example.h
--test.cpp
Когда я пытаюсь запустить или отладить проект, терминал заканчивается кодом 1 и показывает ошибку fatal error C1083: Cannot open include file: 'gtest/gtest.h': No such file or directory
, что странно, поскольку даже IntelliSense может обнаружить gtest.
Затем я попытался выполнить сборку с помощью CMake и создал CMakeLists.txt в примере и настроил его для запуска как исполняемый файл.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.0)
project(example VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(example test.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Но затем CMake жалуется, говоря CMake Error: The source "C:/[...]/Projects/example/CMakeLists.txt" does not match the source "C:/[...]/Projects/example/googletest/CMakeLists.txt" used to generate cache. Re-run cmake with a different source directory.
Я прочитал почти все здесь, на Stack Overflow и на других сайтах, и ничего не помогло. Что я делаю не так?
Редактировать
Кроме того, вот tasks.json:
{
"tasks": [
{
"type": "shell",
"label": "C/C : cl.exe build active file",
"command": "cl.exe",
"args": [
"/Zi",
"/EHsc",
"/Fe:",
"${fileDirname}\${fileBasenameNoExtension}.exe",
"${file}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
}
}
],
"version": "2.0.0"
}
Редактировать
—
Когда я использую /IC:/[...]/Projects/example/googletest/googletest/include
и /link C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj
(я переместил example.cpp и example.h в файл с именем example, и я создал библиотеку через CMake), теперь я получаю это:
/debug
/out:c:[...]Projectsexample/test.exe
C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj
test.obj
test.obj : warning LNK4042: object specified more than once; extras ignored
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
test.obj : error LNK2019: unresolved external symbol "bool __cdecl testing::internal::IsTrue(bool)" (?IsTrue@internal@testing@@YA_N_N@Z) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::GTestLog::GTestLog(enum testing::internal::GTestLogSeverity,char const *,int)" (??0GTestLog@internal@testing@@QEAA@W4GTestLogSeverity@12@PEBDH@Z) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::GTestLog::~GTestLog(void)" (??1GTestLog@internal@testing@@QEAA@XZ) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::Message::Message(void)" (??0Message@testing@@QEAA@XZ) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::AssertionResult __cdecl testing::internal::EqFailure(char const *,char const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const amp;,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const amp;,bool)" (?EqFailure@internal@testing@@YA?AVAssertionResult@2@PEBD0AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@1_N@Z) referenced in function "class testing::AssertionResult __cdecl testing::internal::CmpHelperEQFailure<int,int>(char const *,char const *,int const amp;,int const amp;)" (??$CmpHelperEQFailure@HH@internal@testing@@YA?AVAssertionResult@1@PEBD0AEBH1@Z)
test.obj : error LNK2019: unresolved external symbol "void const * __cdecl testing::internal::GetTestTypeId(void)" (?GetTestTypeId@internal@testing@@YAPEBXXZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class testing::TestInfo * ExampleTest_AddTest_Test::test_info_''(void)" (??__E?test_info_@ExampleTest_AddTest_Test@@0QEAVTestInfo@testing@@EA@@YAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::TestInfo * __cdecl testing::internal::MakeAndRegisterTestInfo(char const
*,char const *,char const *,char const *,struct testing::internal::CodeLocation,void const *,void (__cdecl*)(void),void (__cdecl*)(void),class testing::internal::TestFactoryBase *)" (?MakeAndRegisterTestInfo@internal@testing@@YAPEAVTestInfo@2@PEBD000UCodeLocation@12@PEBXP6AXXZ3PEAVTestFactoryBase@12@@Z) referenced in function "void __cdecl `dynamic initializer for 'private: static class testing::TestInfo * ExampleTest_AddTest_Test::test_info_''(void)" (??__E?test_info_@ExampleTest_AddTest_Test@@0QEAVTestInfo@testing@@EA@@YAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::AssertionResult __cdecl testing::AssertionSuccess(void)" (?AssertionSuccess@testing@@YA?AVAssertionResult@1@XZ) referenced in function "class testing::AssertionResult __cdecl testing::internal::CmpHelperEQ<int,int>(char const *,char const *,int const amp;,int const amp;)" (??$CmpHelperEQ@HH@internal@testing@@YA?AVAssertionResult@1@PEBD0AEBH1@Z)
test.obj : error LNK2019: unresolved external symbol "public: virtual __cdecl testing::Test::~Test(void)" (??1Test@testing@@UEAA@XZ) referenced in function "public: virtual __cdecl ExampleTest_AddTest_Test::~ExampleTest_AddTest_Test(void)" (??1ExampleTest_AddTest_Test@@UEAA@XZ)
test.obj : error LNK2019: unresolved external symbol "protected: __cdecl testing::Test::Test(void)" (??0Test@testing@@IEAA@XZ) referenced in function "public: __cdecl ExampleTest_AddTest_Test::ExampleTest_AddTest_Test(void)" (??0ExampleTest_AddTest_Test@@QEAA@XZ)
test.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl testing::Test::SetUp(void)" (?SetUp@Test@testing@@MEAAXXZ)
test.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl testing::Test::TearDown(void)" (?TearDown@Test@testing@@MEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::AssertHelper::AssertHelper(enum testing::TestPartResult::Type,char const *,int,char const *)" (??0AssertHelper@internal@testing@@QEAA@W4Type@TestPartResult@2@PEBDH1@Z) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::AssertHelper::~AssertHelper(void)" (??1AssertHelper@internal@testing@@QEAA@XZ) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: void __cdecl testing::internal::AssertHelper::operator=(class testing::Message const amp;)const " (??4AssertHelper@internal@testing@@QEBAXAEBVMessage@2@@Z) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
c:[...]Projectsexampletest.exe : fatal error LNK1120: 15 unresolved externals
The terminal process "C:windowsSystem32WindowsPowerShellv1.0powershell.exe -Command cl.exe /Zi /EHsc /Fe: c:[...]Projectsexample/test.exe c:[...]Projectsexampletest.cpp /IC:/[...]/Projects/example/googletest/googletest/include '/link C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj'" terminated with exit code: 1.
Комментарии:
1. Насколько хорошо вы разбираетесь в CMake?
2. Можете ли вы также опубликовать задачи. json, который был сгенерирован из VS Code?
3. Я не очень хорошо знаю CMake, но я знаю пару вещей.
4. Вам нужен /I<путь к gtest-include> в аргументах.
5. В Visual Studio свойства показывают вывод командной строки. Вы можете просмотреть это и проверить, что нужно добавить в задачи. json -> атрибут args
Ответ №1:
Я понял, как решить проблему. Короче говоря, я использовал CMake для включения Google Test в проект.
Во-первых, я переместил example.cpp и example.h в новую папку с именем example и создал CMakeLists.txt для компиляции в виде библиотеки.
example/CMakeLists.txt:
add_library(example_lib example.cpp example.h)
Затем я изменил CMakeLists.txt в корне этого:
cmake_minimum_required(VERSION 3.18.2) # Set your version.
# If you don't, wou'll get a LNK1169 error and many others (don't know why)
project(example)
include(CTest)
enable_testing()
add_executable(example test.cpp)
add_subdirectory(googletest)
add_subdirectory(example)
target_link_libraries(example PUBLIC example_lib gtest gtest_main gmock gmock_main)
include(GoogleTest) # To use gtest_discover_tests
gtest_discover_tests(example) # Runs GTest with CTest
И теперь вы настраиваете, собираете и запускаете! 🙂
Комментарии:
1. Я также хочу поблагодарить @user3389943. Он / Она мне очень помог, и без него / нее я бы уже сдался.