【问题标题】:Strange CMake shared lib linking issue on LinuxLinux上奇怪的CMake共享库链接问题
【发布时间】:2023-03-10 00:36:01
【问题描述】:

我在 Linux 上看到一个奇怪的链接问题,它使用 CMake 从同一源代码树创建 OS X 框架和 Linux 共享库的跨平台库项目。该项目的跨平台方面在过去(大约两年前)运行良好,但从那时起,我们只在 OS X 上进行开发工作。暂时放弃 Linux 的原因是开发人员短缺:所有那些仍然使用 OS X 的人 - 几年来没有在 Linux 上构建源代码没有技术原因。

除了一个可能相关的例外(稍后会详细介绍),与此同时,我们的来源没有发生根本性的变化。但是当然 Linux 已经进步了:所以当我们回到那里时,当然有一些小的障碍。诸如新版本的编译器抱怨他们过去没有抱怨过的事情(有问题的强制转换、无效指针巫毒等)。这些问题很快就解决了。

整个源代码树现在在 Mint 17.1 上再次编译,并带有一些绝对无害的剩余警告。但是链接失败并显示一条相当奇怪的消息:

Linking CXX shared library lib<ourLibName>.so
CMakeFiles/<file1>.c.o:1:1: error: stray '\177' in program
CMakeFiles/<file1>.c.o:1:1: error: stray '\2' in program
CMakeFiles/<file2>.c.o:1:1: error: stray '\213' in program
(and so on, thousands of times, with seemingly random values in the quotes
for all the object files in the library)

对我来说,这看起来像是链接器不小心尝试再次编译目标文件,而不是链接它们。在 gcc 和 clang 之间切换没有任何区别。

正如我已经说过的,自上次在 L​​inux 下编译以来,该项目有一个潜在的相关结构变化:它曾经是仅 C 和 Objective-C 源代码的组合。它现在包含 C、Objective-C 以及 Objective-C++ 源代码。在 OS X 上,此更改没有引起任何问题,我很难想象添加一些 .mm 文件会导致我们在这里看到的情况。但仍然 - 更奇怪的事情发生了。

此外,关于在 C/C++ 程序中错误地包含 unicode 字符的几篇关于 stackoverflow 的文章存在一个流行的问题。这不是这里的问题 - 在实际编译期间不会出现此类消息。马戏团只有在发生链接时才开始。

源代码树太大而无法发布,而且 CMake 文件也相当复杂、嵌套且很大(即不可能包含在此处)。雪上加霜的是,他们过去在 Ubuntu 10.10 上运行良好。我不再拥有它,以测试当前树是否仍然在那里工作(我想这太容易了)。 Linux下生成库的CMakeList中的相关命令为

set_target_properties(
    <ourLibName> 
    PROPERTIES
        VERSION    2.0
        SOVERSION  2
    )

target_link_libraries(
    <ourLibName>
    ${our_other_link_libraries}
    )

install (
    TARGETS
        <ourLibName>
    DESTINATION
        lib
    )

看起来还不错。乍一看我。我如何在这里进行?我不知道下一步该尝试什么。

附:涉及的软件版本:Cmake 2.8.11、gcc 4.8.2、clang 3.4-1ubuntu3。

【问题讨论】:

    标签: objective-c linux linker cmake objective-c++


    【解决方案1】:

    事实证明问题的根源很简单:一两年前,一个不再与我们在一起的项目开发人员显然曾尝试在 Linux 上构建 Objective-C++ 版本的源代码。从他失败的尝试中,CMake 编译器标志的仅 Linux 部分有一个看起来很合理的剩余部分:

    else ( APPLE )
        set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -x objective-c++" )
    endif ( APPLE )
    

    最重要的当然是-x objective-c++ 标志。这不会在编译过程中造成任何伤害,除了您会收到大量不必要的警告。但由于这些标志也传递给链接器,它迫使可怜的东西将所有目标文件视为 ObjC++ 输入。该标志不应该存在:CMake 足够聪明,可以立即处理 C、ObjC 和 ObjC++ 的混合。删除标志后,一切都会按预期进行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-08
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多