c++ - Cmake:在没有直接 target_link_libraries 的情况下使用来自另一个目标的函数

标签 c++ cmake

这是一个奇怪的问题。我有一个“渲染器前端”静态目标和几个“渲染器后端”静态目标。 “renderer frontend”包含后端需要实现的头文件,前端的代码会调用它们。后端通过调用底层相应的 API(例如 OpenGL 或 DirectX)来实现这些功能。

到目前为止,还不错。我可以在编译时选择一个后端并将其链接到前端。但是,我决定将单元测试添加到需要“虚拟后端”而不是为主程序配置的后端的前端。

所以不要这样做:

if(${RendererBackend} STREQUAL "OpenGL")
    target_link_libraries(Renderer RendererBackendGL)
elseif(...)
    ...
end
target_link_libraries(Application Renderer)

我想这样做:

target_link_libraries(Application Renderer)
target_link_libraries(RendererTest Renderer RendererBackendDummy)
if(${RendererBackend} STREQUAL "OPENGL")
    target_link_libraries(Application RendererBackendGL)
elseif(...)
    ...
end

但是,每当渲染器前端调用由后端在 GCC 下实现的函数时,我的程序就会出现“ undefined reference ”链接错误。尽管该程序在 MSVC 下运行良好。

编辑:

我查看了链接命令,是这样的:

/usr/bin/g++ CMakeFiles/Demo.dir/src/main.cpp.o  -o Demo -rdynamic -lm -ldl /usr/lib/x86_64-linux-gnu/libX11.so -lpthread ../Engine/OpenGL/libRendererBackendGL.a ../Engine/Graphics/libRenderer.a

问题是“RendererBackendGL”中定义的“Renderer”库调用函数。

最佳答案

您的依赖项建模不正确。

如果 RendererRendererBackendGL 调用函数,您需要在 CMake 中为该关系建模:

target_link_libraries(Renderer PUBLIC RendererBackendGL)
target_link_libraries(Application PRIVATE Renderer)

是的,这意味着每个链接到 Renderer 的人也需要链接到后端,包括测试。但这是您的软件架构的问题,即。在 Renderer 中调用后端函数,这不是 CMake 的问题。

这在 gcc 中中断的原因是在链接器命令行上指定输入库的顺序很重要。这对 MSVC 来说并非如此(只要 lib 存在,它就会起作用,无论它出现在最前面还是最后)。由于此类顺序依赖性是特定于工具链的,因此实现这种可移植性的唯一方法是在 CMake 中正确地明确建模所有目标间依赖性。

那么您现在可以做什么来解决这个问题呢?我想到的一些选项:

  • 翻转依赖项。让后端依赖于前端,并且应用程序仅链接到它想要使用的后端。
  • 转向插件概念。前端不是静态链接,而是在运行时从共享库动态加载它想要使用的后端。
  • 在编译时选择一个特定的后端。这意味着,如果您仍想在同一个构建步骤中构建具有 GL 后端的应用程序和具有虚拟后端的测试,您将需要构建前端两次。这可能是最接近您当前尝试执行的方法。您可以使用 object libraries以尽量减少前端的重新编译量,但您最终仍会得到多个前端库目标。

请注意,所有这些都需要对您的代码进行一定程度的架构更改。因此,请务必在开始重构之前考虑所有影响。

关于c++ - Cmake:在没有直接 target_link_libraries 的情况下使用来自另一个目标的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46046443/

相关文章:

c++ - 下面的 std::move 是多余的吗?

c++ - 检查字符串是否为 16 进制数

c - 使用列表作为 add_custom_command 的依赖项

CLion 说 'Process finished with exit code 127'

c++ - 如何在我的项目中从cmake中的同一个项目中获取多个库

cmake - premake4 外源构建

CMake VTK_DIR-NOTFOUND

c++ - 将矩阵加载到二维 vector C++

c++ - 复制或 constref 一个 shared_ptr?

C++ STL 广度优先搜索