我在Linux上发现了一个奇怪的链接问题,这个问题是使用CMake从同一源代码树创建OS X Framework和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之间切换没有任何区别。
正如我已经说过的,自上次在Linux下编译以来,项目有一个可能相关的结构变化:它曾经只是C和Objective-C源的组合。它现在包含C,Objective-C 以及Objective-C ++ 源。在OS X上,这种变化并没有引起任何问题,而且我很难想象这些.mm文件的添加会导致我们在这里看到的内容。但仍然 - 发生了奇怪的事情。
此外,关于stackoverflow的一些文章有一个流行的问题,即错误地在C / C ++程序中包含unicode字符。这不是问题 - 在实际编译期间不会出现此类消息。马戏团只有在连接发生后才会开始。
源树太大而不能发布,并且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
)
仍然看起来像o.k.对我来说乍一看。我该怎么办?我对下一步该尝试的想法不以为然。
P.S。涉及的软件版本:Cmake 2.8.11,gcc 4.8.2,clang 3.4-1ubuntu3。
答案 0 :(得分: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 ++的混合物。删除标志后,一切都按预期工作。