1

我有一个在 Xcode 7.2 及更早版本上编译良好的项目,但在使用 Xcode 7.3 编译时出现链接器错误。我已经能够将其缩小到一个重复问题的简单示例项目。

基本的项目结构是这样的:

.
├── one
│   ├── lib
│   │   └── lib1.dylib
│   └── src
│       └── one.c
├── two
│   ├── lib
│   │   └── lib2.dylib
│   └── src
│       └── three.c
└── three
    ├── lib
    │   └── lib3.dylib
    └── src
        └── two.c

lib3与 的链接lib2,以及与lib2的链接lib1。编译库时,其输出位于../lib与其目录相关的src目录中。

当我尝试编译lib3时,它会出错file not found: ../lib/lib1.dylib,即使../../one/lib在库搜索路径中。

我可以使用什么奇怪而神秘的链接器标志来使搜索路径正常工作?或者这是 Xcode 的一个错误?

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C one/src
cc -I ../../include   -c -o one.o one.c
cc -dynamiclib -undefined dynamic_lookup -flat_namespace -o ../lib/lib1.dylib one.o
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C two/src
cc -I ../../include   -c -o two.o two.c
cc -dynamiclib -undefined dynamic_lookup -flat_namespace -L ../../one/lib -o ../lib/lib2.dylib two.o -l1
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C three/src
cc -I ../../include   -c -o three.o three.c
cc -dynamiclib -undefined dynamic_lookup -flat_namespace -L ../../two/lib -L ../../one/lib -o ../lib/lib3.dylib three.o -l2
ld: file not found: ../lib/lib1.dylib for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [../lib/lib3.dylib] Error 1
make: *** [all] Error 2
4

1 回答 1

1

好的,我花了一段时间来修复这个错误。我知道问题的一部分是设置库的运行路径安装名称,因此可以在链接期间和运行时找到它们,这将是您面临的下一个问题。

我决定将库构建到一个通用的顶级lib目录中,但是最终我很确定这实际上是没有必要的,但它确实减少了传递给链接器的命令行选项,这非常很麻烦,因为它需要完成-Wl,-linker-option并且-Wl,linker-option-argumentcc用于链接而不是ld直接链接。

我认为实际的答案是添加-l1到您的three/src/Makefile行中:

$(LD) -o $@ $< -l2 -l1

我不清楚为什么这是必要的,就好像lib3依赖于lib2那么不需要将lib2' 的依赖项添加到链接器行中。这可能与您对 的使用有关-undefined dynamic_lookup,因为我以前从未见过该选项。但是,我没有时间对此进行充分试验。

如果您对您的 s 版本进行此更改,您Makefile可能会遇到运行时问题,因为运行路径安装名称隐含在您传递给的任何内容中-L(过去是../../one/lib并且../../two/lib它们在运行时几乎肯定会出错)。因此,最好明确设置运行路径安装名称,并且每个库都将其运行路径设置为@loader_path/,并将其安装名称设置为@rpath/libX.dylib。使用这些库的可执行文件可能需要不同的运行路径才能找到这些库。

请参阅我的拉取请求以了解我所做的更改。

我想赞扬您如何通过托管在 github 上的可测试项目提出这个问题;否则,您将不太可能获得任何体面的反馈。

于 2016-04-09T10:23:54.657 回答