【问题标题】:CMake unit testing - Unresolved external symbolCMake单元测试 - 未解析的外部符号
【发布时间】:2020-10-31 07:21:00
【问题描述】:

我对 C++ 和 CMake 比较陌生。我正在尝试创建一个库,当我尝试运行单元测试时出现错误。根据我的研究,我已经收集了“未解析的外部符号”错误的含义,但我无法弄清楚如何修复它。

这是我的项目结构:

lib
  glfw - GLFW source folder
src
  ogl-renderer.cpp
  ogl-renderer.h
  CMakeLists.txt
  ...additional source files
test
  ogl-test.cpp
  ogl-test.h
  CMakeLists.txt
CMakeLists.txt

CMakeLists.txt:

cmake_minimum_required (VERSION 3.8)

project("ogl-renderer")

set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

add_subdirectory ("lib/glfw-3.3.2")

add_subdirectory ("src")
add_subdirectory ("test")

enable_testing()

add_test (ogl-renderer olg-test)

src/CMakeLists.txt:

cmake_minimum_required (VERSION 3.8)

add_library (ogl-renderer "engine/renderer.cpp" "engine/renderer.h" "engine/renderer.cpp" "engine/renderer.h" "engine/Window.cpp" "engine/Window.h" "engine/Shape.cpp" "engine/Shape.h" "engine/message-queue.cpp" "engine/message-queue.h" "engine/messages/window-mgmt.h" "engine/messages/window-mgmt.cpp")

target_link_libraries(ogl-renderer glfw)

测试/CMakeLists.txt:

add_executable (ogl-test "ogl-test.cpp" "ogl-test.h")

target_link_libraries(ogl-test ogl-renderer)

测试/ogl-test.cpp:

#include "../src/ogl-renderer.h"

void testWindow() {
    NglRenderer::startRenderer();

    int windowId = NglRenderer::createWindow("Test", 640, 480);
}

int main() {
    testWindow();
}

错误:

Error   LNK2019 unresolved external symbol "void __cdecl NglRenderer::startRenderer(void)" (?startRenderer@NglRenderer@@YAXXZ) referenced in function "void __cdecl testWindow(void)" (?testWindow@@YAXXZ)  C:\Users\chansen\source\repos\ogl-renderer\out\build\x64-Debug\ogl-renderer C:\Users\chansen\source\repos\ogl-renderer\out\build\x64-Debug\ogl-test.cpp.obj 1

Error   LNK2019 unresolved external symbol "int __cdecl NglRenderer::createWindow(char *,int,int)" (?createWindow@NglRenderer@@YAHPEADHH@Z) referenced in function "void __cdecl testWindow(void)" (?testWindow@@YAXXZ) C:\Users\chansen\source\repos\ogl-renderer\out\build\x64-Debug\ogl-renderer C:\Users\chansen\source\repos\ogl-renderer\out\build\x64-Debug\ogl-test.cpp.obj 1

我可以通过在每个位置始终包含 .h 和 .cpp 文件来修复它,但我想以正确的方式解决这个问题。我知道我需要将源项目编译成一个库,然后将它链接到测试可执行文件,但我不知道如何正确地做到这一点。我什至不完全确定我的 CMakeList.txt 文件有多正确。所有这些配置都是我猜测或复制的。

【问题讨论】:

  • NglRenderer::startRendererNglRenderer::createWindow 在什么库中?
  • @StephenNewell NglRenderer 是我的库的命名空间,在 src/ogl-renderer 中定义
  • 我的意思是实际的库。您将两个链接到您的测试中:glfwogl-renderer
  • @StephenNewell 对,GLFW 是 OpenGL。它在src 文件夹中使用。现在想起来可能不需要在测试中链接它。
  • add_library (ogl-renderer " 没有必要在一长行中这样做,您可以在源文件之间添加换行符。 #include "../src/ogl-renderer.h" 只是 target_include_directories(... ${CMAKE_CURRENT_SOURCE_DIR})#include <ogl-renderer.h>NglRenderer is the namespace for my library, defined in the src/ogl-renderer 所以ogl-renderer.cppadd_library 中丢失了,所以....符号丢失了。为什么它不见了?为什么不加呢? add_test (ogl-renderer olg-test) 看起来很奇怪,你想运行ogl-renderer exe 吗?猜你想要add_test(NAME ogl-test COMMAND ogl-test)

标签: c++ cmake


【解决方案1】:

每个 CMakeLists.txt 文件都定义了一个要编译的项目。每个项目都必须包含它的所有文件、依赖项和构建选项。

所以"test/CMakeLists.txt" 必须包含所有相关的test 源文件。并且"src/CMakeLists.txt" 必须包含所有相关的src 源文件。这就是添加 .h 和 .cpp 文件修复错误的原因。

每个项目配置完成后,链接库定义为target_link_libraries()

例如在src 中,target_link_libraries(ogl-renderer glfw) 行将链接到glfw。在test 中,target_link_libraries(ogl-test ogl-renderer) 行将链接到您的src 可执行文件。

只要target_link_libraries() 命令有意义,链接就会自动进行。

一些提供更多信息的线程:

【讨论】:

  • 所以从你所说的来看,我的看起来像是遵循了所有这些。带有测试的典型项目配置实际上是什么样的?
  • @chrispytoes,是的,应该没问题。 enable_testing() 是标准方式,添加了一些包含更多信息的链接。
猜你喜欢
  • 2018-05-10
  • 2022-01-06
  • 1970-01-01
  • 2021-08-02
  • 2011-02-09
  • 1970-01-01
相关资源
最近更新 更多