cmake 链接错误

2023-11-29

我试图理解为什么在编译使用 CMake 生成的项目时出现链接错误。

CMakeFiles.txt 为项目的每个文件夹构建一个静态库,然后通过以下方式将所有它们链接在一起:

# root CMakeLists.txt

add_subdirectory(subfolder1)
add_subdirectory(subfolder2)
add_subdirectory(...)

add_executable(target ${SOURCES})

set(LIBRARIES
  LIB_FOO
  LIB_BAR
  ...
)

target_link_libraries(target
  ${LIBRARIES}
)

然后在每个子文件夹中我都有一个简单的 CMakeLists.txt ,例如

file(GLOB FOO_SOURCE *.cpp)
add_library(LIB_FOO ${FOO_SOURCE})

现在,这可以正常工作并编译所有内容,但在链接时我得到了未定义的引用,因此我尝试调查最后所有内容是否可用,看起来像这样。实际错误如下:

libLIB_WORLD.a(World.cpp.o): In function `World::generate(WorldGenOptions)':
World.cpp:(.text+0x803): undefined reference to `MapGenerator::MapGenerator(BlockMap*)'
World.cpp:(.text+0x837): undefined reference to `MapGenerator::generate(bool, WorldGenOptions)'

现在,MapGenerator.cpp 是LIB_MAP,所以我检查文件是否存在并包含符号:

:~$ nm libLIB_MAP.a | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions

:~$ nm CMakeFiles/LIB_MAP.dir/MapGenerator.cpp.o | grep generate
....
00000000000044dc T _ZN12MapGenerator8generateEb15WorldGenOptions

所以这个符号是存在的,此时我检查了它是否被 ld 正确链接:

:~$ make VERBOSE=1
/usr/bin/g++  ... libLIB_MAP.a libLIB_WORLD.a ...

因此,它实际上与其他无法找到该符号的库一起存在于链接阶段。

我缺少什么微不足道的东西吗?我对 CMake 很陌生,所以我没有想法。


这是 CMake 中未正确建模的库依赖关系问题。

Your LIB_WORLD参考方法来自LIB_MAP。此依赖项未在您的 CMake 脚本中建模。由于这两个都是静态库,因此它们仍然可以自行构建良好。 (请记住,静态库本质上是一堆打包在一起的目标文件,但它们从不通过链接器。)

但是,一旦将它们链接到可执行文件或共享库,您就会遇到问题。即使您的可执行文件链接到两者LIB_WORLD and LIB_MAP,它这样做以错误的顺序。因此,当链接器尝试解决缺少的符号时LIB_WORLD,它还不知道导出的符号LIB_MAP,因此您遇到了错误消息。

正确的解决方法是引入对LIB_WORLD:

add_library(LIB_WORLD [...])
target_link_libraries(LIB_WORLD LIB_MAP)

现在,每当您链接某些内容时LIB_WORLD你也总是会链接到LIB_MAP and CMake 会注意顺序是否正确。 (特别是,如果您的可执行文件不直接使用来自LIB_MAP您可能想将其从其中删除target_link_libraries共。)

作为一个额外的好处,它现在允许您构建LIB_WORLD作为共享库,以前会因链接器错误而失败。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake 链接错误 的相关文章

随机推荐

  • PouchDB + 冲突解决

    我有一个关于难题的非常简单的问题 PouchDB 中的冲突解决如何工作 我查看了文档 并快速谷歌搜索 但没有帮助 那么 如何在使用 PouchDB 的应用程序中处理冲突管理 以下是在 CouchDB 中的操作方法 您可以直接将其转换为 Po
  • Spring Boot - 从属性文件注入映射[重复]

    这个问题在这里已经有答案了 属性文件如下所示 url1 path to binary1 url2 path to binary2 根据this我尝试了以下方法 Component EnableConfigurationProperties
  • 如何更改 WooCommerce 缩略图裁剪位置?

    我正在尝试更改 WooCommerce 缩略图裁剪位置 我发现这段代码可以帮助更改大小 add action init yourtheme woocommerce image dimensions 1 Define image sizes
  • 在 iFrame 中应用 CSS

    我正在尝试将广告图像的宽度从像素更改为百分比 我正在使用 Google DoubleClick 或 DFP 它会自动将您的广告图像放入 iframe 中 从而很难更改图像的实际尺寸 因此 我将图像宽度从像素更改为百分比的方法是 我在图像广告
  • 在 vhdl 中计算(并验证)以太网 FCS (crc32)

    我正在使用Spartan 3E 入门套件我正在尝试通过 100MBit 链路接收以太网帧 对于那些不知道的人 该板具有 PHY 芯片 暴露了 25MHz 的接收时钟 我 几乎 已经通过缓冲接收到的帧并通过串行链路重新发送它们来验证接收工作正
  • 如何从master上找到jenkins节点的ip地址

    从主节点脚本控制台或从系统 groovy 脚本 也在主节点上运行 运行 如何获取从节点的 IP 地址 我希望这个简单的脚本就足够了 import java net for slave in Jenkins instance slaves h
  • 列表追加正在覆盖我以前的值[重复]

    这个问题在这里已经有答案了 我正在尝试动态构建 ElasticSearch 的查询 这是我的代码 import json query string person human query query query query query boo
  • 如何允许用户在 ChicagoBoss 中下载文件

    我生成一个 xml 并将其存储到某个位置 比如myproject media doc xml因为我是 erlang 的新手开发人员 我所知道的是我必须设置请求标头 例如 Content Disposition attachment file
  • 如何从 Postman/WebSocket King 调用 SignalR Core hub 方法

    我有一个 SignalR Core 集线器 我可以使用 Postman 或 WebSocket King 等客户端连接到同一个集线器 但是 我无法调用需要参数的集线器方法 可以从 SignalR JS 客户端轻松调用相同的方法 我检查了浏览
  • Maven 类路径顺序问题

    有谁知道在 Maven2 中设置特定类路径顺序的方法 而不是我目前遇到的随机顺序 想要这样做有很多合理的理由 供应商提供了一个补丁 jar 其中包含先前发布的 jar 的重写类 因此该补丁 jar 必须出现在类路径排序中的第一个位置 通过遍
  • 如何将 PDF 文件中的特定 RGB 颜色更改为特定 CMYK 颜色?

    如果我有一个 PDF 文件 其中包含特定 RGB 颜色的对象 文本 艺术线条 并且我想将这些对象转换为具有特定的 CMYK 颜色 有哪些可用的库可以让我做到这一点 请注意 我不需要从任意 RGB 值 映射 到 合适的 CMYK 值的能力 这
  • Scanf_s 警告?跳过用户输入(主题:Runge-Kutta、流行病模拟)

    这是我的第一篇文章 我不得不承认 我在编程方面很糟糕 我是班上那个拼命工作的人 但似乎永远无法像我的其他同学那样掌握编程 所以请保持友善 我将在下面尝试解释我的问题 我有以下代码 已删除注释 但是当我运行它时 我收到类似于下面列出的警告 另
  • 61 秒不活动后,Indy 错误 10038“非套接字上的套接字操作”

    我想从 FTP 服务器下载一些大文件 GB 第一个文件的下载始终有效 然后 当尝试获取第二个文件时 我得到 套接字错误 10038 非套接字上的套接字操作 错误出现在 获取 上 在 获取 之后 我看到这些消息 通过 FTP 状态事件 Sta
  • 是否有一个内置函数可以打印对象的所有当前属性和值?

    所以我在这里寻找的是类似 PHP 的东西print r功能 这样我就可以通过查看相关对象的状态来调试我的脚本 你要vars 夹杂pprint from pprint import pprint pprint vars your object
  • WiX可配置目录的含义是什么?

    我有一个测试安装程序 有 2 个功能 A 和 B A 有 2 个文件 a1 和 a2 B 还有 2 个文件 b1 和 b2 每个文件属于单个组件 Feature A a1 a2 Feature B b1 b2 每个文件的安装位置如下 有些混
  • 从 SqlDataReader 转换为 JSON

    public string toJSON SqlDataReader o StringBuilder s new StringBuilder s Append if o HasRows while o Read s Append Id o
  • PHP CURL 和 SSL 证书(或证书链)

    再会 我有 REST API 可以通过 SSL https 访问 我想将正确的证书 或证书链 与我编写的 PHP 和 CURL 脚本一起发出请求 以下是我的目标的证书方式 http api vkontakte ru 在 Firefox 中看
  • [Shiny]:在另一个tabPanel中添加到另一个tabPanel的链接

    我试图在我的 主页 选项卡面板上放置一个链接到我的应用程序的所有其他选项卡面板 想法如下 ui navbarPage tabPanel home fluidPage fluidRow box this 1st box should lead
  • 将 Oracle SQL Select 转换为 PostgreSQL select

    我有这样的SQL语句 SELECT ABX ABX APO NUMBER COUNT A1 PROCESS MODE AS NUM PLANNING COUNT A2 PROCESS MODE AS NUM SETUP COUNT A3 P
  • cmake 链接错误

    我试图理解为什么在编译使用 CMake 生成的项目时出现链接错误 CMakeFiles txt 为项目的每个文件夹构建一个静态库 然后通过以下方式将所有它们链接在一起 root CMakeLists txt add subdirectory