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))