Mac OS X 的静态库链接问题:找不到架构 x86_64 的符号

问题描述 投票:0回答:3

我正在尝试生成一个静态库并将其与执行二进制文件链接。

这是一个库函数:

#include <stdio.h>

int hello() {
    return 10;
}

通过这些命令,我可以获得一个静态库。

gcc -c io.c 
ar -crv libio.a io.o

通过

lip -info
,我检查了它是
x86_64
架构。

ar> lipo -info libio.a 
input file libio.a is not a fat file
Non-fat file: libio.a is architecture: x86_64

这是使用该库的主要函数。

#include <stdio.h>
extern int hello();

int main(int argc, char *argv[]) {
    printf("%d", hello());
}

但是,当我将对象与静态库链接时,出现错误。

gcc main.c -lio -o main -L.

错误消息是:

ld: warning: ignoring file ./libio.a, file was built for archive which is not the architecture being linked (x86_64): ./libio.a
Undefined symbols for architecture x86_64:
  "_hello", referenced from:
      _main in main-2c41a0.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我使用

ar
,如
/bin/ar
,Mac OS X 是 10.10.2,带有 clang-602.0.53。

ar> clang -v
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

可能出了什么问题?

c macos clang static-libraries unix-ar
3个回答
11
投票

该库应该已通过

libtool -static
生成。

gcc -c io.c 
libtool -static -o libio.a io.o
gcc main.c -lio -o main -L.
main

退货

10

ar> lipo -info libio.a 
input file libio.a is not a fat file
Non-fat file: libio.a is architecture: x86_64

ar> file libio.a 
libio.a: current ar archive

ar> nm libio.a 

io.o:
0000000000000000 T _hello

来自此页面的提示。


3
投票

从黑客 CMake 生成 make 文件(CMakeFiles/test.dir/link.txt)中,默认使用的

/usr/local/ar
中的 ar 似乎无法正常工作。

这就是

link.txt
的内容。

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar qc libtest.a  CMakeFiles/test.dir/test.c.o   
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib libtest.a

从脚本来看,

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar
是我必须使用的。

smcho@macho ar> ls -alF /usr/bin/ar
-rwxr-xr-x  1 root  wheel  18160 Oct 17 18:49 /usr/bin/ar*
smcho@macho ar> ls -alF /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar 
-rwxr-xr-x  1 root  wheel  33472 Oct 29 16:36 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar*

同样,应该使用的 ranlib 是

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib
而不是默认的。

smcho@macho ar> ls -alF `which ar`
-rwxr-xr-x  1 root  wheel  18160 Oct 17 18:49 /usr/bin/ar*
smcho@macho ar> ls -alF /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib
lrwxr-xr-x  1 root  wheel  7 Nov 10 21:10 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib@ -> libtool

除此之外,还需要使用

-qc
选项(来自cmake生成的脚本)

 -c      Whenever an archive is created, an informational message to that
         effect is written to standard error.  If the -c option is speci-
         fied, ar creates the archive silently. 
 -q      (Quickly) append the specified files to the archive.  If the ar-
         chive does not exist a new archive file is created.  Much faster
         than the -r option, when creating a large archive piece-by-piece,
         as no checking is done to see if the files already exist in the
         archive.

这些是获取正确库文件的命令:

clang -c hellolib.cpp -o hellolib.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar -qc libhello.a hellolib.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib libhello.a

用法是:

clang usehello.cpp -lhello -L.

nm和lipo显示正确的库文件信息:

smcho@macho ar> nm libhello.a 
libhello.a(hellolib.o):
0000000000000000 T __Z3addii
smcho@macho ar> lipo -info libhello.a 
input file libhello.a is not a fat file
Non-fat file: libhello.a is architecture: x86_64

0
投票

在将 macOS 系统升级到 Catalina 后(这也升级了 Xcode 和 Apple Clang 的版本),由于未正确构建静态

symbol(s) not found for architecture x86_64
文件,我开始收到链接器错误
.lib
。这些失败只会在尝试链接到一个特定的静态库时发生(我的应用程序构建并链接到几十个 C++ 静态库 - 所有这些都具有几乎相同的 CMake 设置)。

每次构建后,我可以通过运行

ar -t /path/to/mystatic.lib
来验证静态库是否正确构建。我要么得到存档中的函数列表,要么得到错误。有趣的是,有时库构建得很好,有时却被破坏了——使用相同的构建配置。当我的 macOS 系统运行 Mojave 时,这个库总是构建得很好。但我并不打算降级。

CMakeLists.txt
文件添加以下内容解决了该问题:

if(APPLE)
    set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r -LS <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()

-r -LS
参数运行
ar
而不创建归档符号表。运行
ar
后,CMake 会以创建符号表的方式自动运行
ranlib
(实际上是 macOS 上的
libtool
)。不知何故,这确保了静态库始终可靠地构建。

我的其他静态库不需要上述 CMake 设置。我不知道为什么只有一个图书馆受到影响。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.