Проблема со статической ссылкой на библиотеку в Mac OS X: не найден(ы) символ(ы) для архитектуры x86_64

Я пытаюсь создать статическую библиотеку и связать ее с исполняемым двоичным файлом.

Это библиотечная функция:

#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

Что может быть не так?


person prosseek    schedule 19.06.2015    source источник
comment
Что действительно неправильно, так это то, что Apple неэтично обернула clang/llvm и назвала его gcc, тогда как в большинстве систем gcc относится к gnu gcc, а не к clang/llvm Apple. поскольку liblto_plugin.so является расширением gnu, компилятор Apple понятия не имеет, где его найти, поскольку он не находится в системном пути или фреймворке. Я использовал ar rcs lib*.a *.o, и вам вообще не нужно использовать libtool, просто дайте ссылку на gnu gcc, установите с помощью macports или brew.   -  person μολὼν.λαβέ    schedule 16.02.2016
comment
Эти два вопроса не являются точными копиями, но очень похожи: Файлы объектов неправильно добавлены в архив на Mac и Символ не найден при статической компоновке в MacOSX.   -  person Stanislav Pankevich    schedule 04.06.2017


Ответы (2)


Библиотека должна была сгенерироваться с 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

Советы от эта страница.

person prosseek    schedule 20.06.2015

Из-за взлома CMake сгенерируйте файл make (CMakeFiles/test.dir/link.txt), ar в /usr/local/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*

Точно так же следует использовать ранлиб /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
person prosseek    schedule 30.11.2015
comment
вы, сэр, мой герой! Пути xcode.app исправили проблему! - person nterry; 09.05.2018
comment
Выглядит довольно убедительно для меня, но это не сработало в моем случае. В любом случае, он убрал предыдущий ответ, который сработал. - person Nikage; 02.11.2020