x64 v7a que i686 arquitectura armeabi c++ macos linker static-libraries 32bit-64bit

c++ - v7a - arquitectura i686



Símbolos indefinidos para la arquitectura x86_64-Mavericks(Yosemite, El Capitán...) (2)

EDITAR:

Si caes en esta publicación, es posible que desees saltar directamente a la respuesta.

Envié un post sobre mi confusión esta mañana.

tipo de máquina (C ++ librairies): i386 vs x86_64

Pero supongo que cometí un error al no ser preciso. Así que decidí dar un ejemplo de las situaciones que enfrento y que no puedo entender.

PASO 1

Construyo una biblioteca en la máquina A, un mac de 2 años con OS x 10.7.5 (que supongo que es de 64 bits; mi suposición se basa en los comandos que verás a continuación en Información adicional) utilizando los siguientes archivos.

Un encabezado SimpleClass.hpp:

#ifndef SIMPLECLASS_HPP #define SIMPLECLASS_HPP class SimpleClass { public: SimpleClass(); SimpleClass(const SimpleClass& orig); virtual ~SimpleClass(); private: } ; #endif /* SIMPLECLASS_HPP */

Un archivo fuente SimpleClass.cpp:

#include "SimpleClass.h" #include <iostream> SimpleClass::SimpleClass() { std::cout << "A new instance of Simple Class was created" << std::endl; } SimpleClass::SimpleClass(const SimpleClass& orig) { } SimpleClass::~SimpleClass() { }

Creo la biblioteca usando

~/cpp_test$ clang++ -c -o SC.o -I SimpleClass.hpp SimpleClass.cpp ~/cpp_test$ ar rcs libtest_sc.a SC.o

Información adicional en la máquina A:

~/cpp_test$ clang++ --version Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) Target: x86_64-apple-darwin11.4.2 ~/cpp_test$ uname -m x86_64 ~/cpp_test$ uname -p i386 ~/cpp_test$ lipo -info libtest_sc.a input file libtest_sc.a is not a fat file Non-fat file: libtest_sc.a is architecture: x86_64

PASO 2

Copio SimpleClass.hpp así como la biblioteca a otra máquina B que es una mac de 5 años con osx 10.6.7 que creo que es de 32 bits. Y escribo el siguiente archivo de saludo para probar la biblioteca.

#include <iostream> #include "SimpleClass.hpp" int main() { std::cout << "Hello World!" << std::endl; SimpleClass testObj; return 0; }

Sorprendentemente, no hay problemas para vincular con la biblioteca y me da.

[~/Downloads/Gmail-9]$ g++ -o hello -L. -ltest_sc hello.cpp [~/Downloads/Gmail-9]$ ./hello Hello World! A new instance of Simple Class was created

Información adicional sobre la Máquina B:

[~/Downloads/Gmail-9]$ uname -m i386 [~/Downloads/Gmail-9]$ uname -p i386 [~/Downloads/Gmail-9]$ g++ --version i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3) Copyright (C) 2007 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

PASO 3

Copio la misma biblioteca de nuevo con el mismo encabezado y el mismo archivo de saludo en la Máquina C que es un nuevo mac con 10.9.2 que creo que es de 64 bits.

Sorprendentemente tengo problemas de vinculación.

MacBook-Pro:testcpp$ g++ -o hello -L. -ltest_sc hello.cpp Undefined symbols for architecture x86_64: "std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from: SimpleClass::SimpleClass() in libtest_sc.a(SC.o) "std::ios_base::Init::Init()", referenced from: ___cxx_global_var_init in libtest_sc.a(SC.o) "std::ios_base::Init::~Init()", referenced from: ___cxx_global_var_init in libtest_sc.a(SC.o) "std::cout", referenced from: SimpleClass::SimpleClass() in libtest_sc.a(SC.o) "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from: SimpleClass::SimpleClass() in libtest_sc.a(SC.o) "std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from: SimpleClass::SimpleClass() in libtest_sc.a(SC.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Información adicional sobre la máquina C

g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.1.0 Thread model: posix MacBook-Pro:testcpp$ uname -m x86_64 MacBook-Pro:testcpp$ uname -p i386

Hubiera esperado el problema de vinculación con la máquina B que es de 32 bits y no con la máquina C que es de 64 bits, pero obtuve lo contrario. ¿Alguien puede explicar lo que me estoy perdiendo aquí?

EDITAR (PASO 4)

En la máquina C, cuando agrego al comando g++ la opción -stdlib=libstdc++ , el error de "símbolos indefinidos" desaparece y el ejecutable se ejecuta correctamente. La ejecución de g ++ con la opción -v me permitió observar que el stdlib predeterminado era libc++ y no libstdc++ . Por lo tanto, parece que aunque la máquina A y la máquina C tienen ambos 64 bits, no usan la misma stdlib estándar por defecto, lo que causó el error de Undefined symbols for architecture x86_64 no stdlib Undefined symbols for architecture x86_64 .


Soy un poco perezoso y no voy a leer esto, así que siéntete libre de votar ...

Creo que estás intentando construir una biblioteca grande de 32/64 bits ...

tiene un par de maneras de hacerlo, una para construir explícitamente con 32 bits y explícitamente con 64 bits ... luego use lipo para combinarlos.

considerar que el código C ++ nominal está almacenado en main.cpp

entonces:

grady$ clang++ main.cpp -m64 -o64.out grady$ file 64.out 64.out: Mach-O 64-bit executable x86_64 grady$ clang++ main.cpp -m32 -o32.out grady$ file 32.out 32.out: Mach-O executable i386 grady$ lipo -arch i386 32.out -arch x86_64 64.out -create -output fat.out grady$ file fat.out fat.out: Mach-O universal binary with 2 architectures fat.out (for architecture i386): Mach-O executable i386 fat.out (for architecture x86_64): Mach-O 64-bit executable x86_64

o generalmente puedes usar algunos atajos con herramientas de Apple:

grady$ clang++ main.cpp -arch i386 -arch x86_64 -ofat2.out grady$ file fat2.out fat2.out: Mach-O universal binary with 2 architectures fat2.out (for architecture i386): Mach-O executable i386 fat2.out (for architecture x86_64): Mach-O 64-bit executable x86_64


Todos los problemas que tuve, que estaban dando

Undefined symbols for architecture x86_64

se debieron al hecho de que algunas bibliotecas se compilaron con libstdc ++ y no se pudieron usar para el código que se compila / vincula con libc ++

libc ++ es de hecho la nueva biblioteca predeterminada utilizada por clang desde Mavericks , sin embargo, es posible compilar con el mismo clang (no es necesario instalar un gcc antiguo) con el clásico libstdc ++ usando la opción

-stdlib=libstdc++

Para aquellos que usan Boost, también es posible tener bibliotecas de boost en los compiladores que se compilan / vinculan con libstdc ++ descargando la fuente y utilizando (al compilarla) en lugar de la versión clásica.

./b2

el seguimiento

./b2 cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"

Para aquellos que usan Cmake, es posible que desee agregar en el archivo cmake adecuado algo similar a:

find_library (LIBSTDCXX NAMES stdc++)

y

add_compile_options(-stdlib=libstdc++)

y

target_link_libraries(${PROJECT_NAME} ${LIBSTDCXX} ${YOUR_OTHER_LIBRARIES))