Estoy tratando de generar una biblioteca estática y vincularla con un binario de ejecución.
Esta es una función de biblioteca:
#include <stdio.h> int hello() { return 10; }
Con estos comandos, podría obtener una biblioteca estática.
gcc -c io.c ar -crv libio.a io.o
Con lip -info
, verifiqué que es arquitectura 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
Esta es la función principal que utiliza la biblioteca.
#include <stdio.h> extern int hello(); int main(int argc, char *argv[]) { printf("%d", hello()); }
Sin embargo, cuando vinculo el objeto con la biblioteca estática, tengo errores.
gcc main.c -lio -o main -L.
Los mensajes de error son:
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)
Uso el ar
como en /bin/ar
, y Mac OS X es 10.10.2 con 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
¿Qué podría estar mal?
La biblioteca debería haberse generado con libtool -static
.
gcc -c io.c libtool -static -o libio.a io.o gcc main.c -lio -o main -L. main
Devoluciones
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
Consejos de esta página .
Al piratear CMake generar el archivo make (CMakeFiles/test.dir/link.txt), el ar en /usr/local/ar
que se usa de forma predeterminada no parece funcionar correctamente.
Este es el contenido del link.txt
.
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar qc libtest.a CMakeFiles/test.dir/test.co /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib libtest.a
Del script, /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar
es el que tenía que usar.
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*
Del mismo modo, el ranlib que debe usarse es /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib
no el predeterminado.
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
Aparte de eso, se necesitaba usar la opción -qc
(del script generado por 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.
Estos son comandos para obtener el archivo de biblioteca correcto:
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
El uso es:
clang usehello.cpp -lhello -L.
nm y lipo muestran la información correcta del archivo de biblioteca:
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