2013-11-20 13 views
8

Mi piacerebbe compilare boost per Mac OS X 10.9, con stdlibC++. Eseguo il seguente comando:Come faccio a compilare boost per piattaforme OS X 64b con stdlibC++?

./b2 threading=multi link=static runtime-link=static cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++" 

La compilazione viene completata correttamente; tuttavia, la build dell'applicazione fallisce al momento del collegamento, quando non riesce a trovare i simboli succhia come std :: __ 1 :: locale :: use_facet, std :: __ 1 :: basic_string ecc. Il dettaglio pertinente è il __1, credo.

La mia domanda è, come faccio a compilare boost per piattaforme OSX 64b con stdlibC++?

Maggiori informazioni:

ho notato i seguenti registri durante la compilazione:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: bin.v2/libs/filesystem/build/clang-darwin-4.2.1/release/link-static/runtime-link-static/threading-multi/libboost_filesystem.a(windows_file_codecvt.o) has no symbols

+1

Si sta compilando la tua applicazione con '-stdlib = libstdC++'? perché sarà necessario anche – Petesh

+0

@Petesh si sto compilando l'app con libstdC++ –

+1

Scegli una libreria boost che hai costruito che * sicuramente * si affida a qualcosa in STL, esegui un nm su di esso, esegui il pipe attraverso 'C++ filt 'e controlla che stia menzionando' std :: __ 1 :: '. Se lo menziona, boost ** è ** stato costruito con 'libstdC++' e in questo caso non stai compilando/collegando correttamente la tua applicazione. – Petesh

risposta

21

Boost scaricati 1.55, bootstrap usando:

./bootstrap.sh --prefix=/usr/local/boost155 cxxflags="-arch i386 -arch x86_64" \ 
    address-model=32_64 threading=multi macos-version=10.8 stage 

Costruito utilizzando:

./b2 threading=multi link=static runtime-link=static \ 
    cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++" 

rese in libboost_chrono.a:

 U std::string::_Rep::_M_destroy(std::allocator<char> const&) 
    U std::string::_Rep::_S_empty_rep_storage 
    U std::string::append(char const*, unsigned long) 
    U std::string::append(std::string const&) 
    U std::string::assign(char const*, unsigned long) 
    U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) 
    U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) 

che implica che la biblioteca è stata costruita con l'opzione -stdlib=libstdc++ - vale a dire che è collegata con la versione GNU del runtime C++.

Abbiamo purgare la costruzione utilizzando:

find . -name \*.o -print0 | xargs -0 rm 
find . -name \*.a -print0 | xargs -0 rm 

Se non lo facciamo, allora non è così ricostruire, e si finisce con lo stesso codice di prima. Successivo costruiamo utilizzando:

./b2 threading=multi link=static runtime-link=static \ 
    cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" 

rendimenti in libboost_chrono.a:

 U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*) 
    U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long) 
    U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*) 
    U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) 
    U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string() 

che implica che è costruito contro libc++.

Ciò può essere verificato utilizzando un semplice programma di test C++ (per indicare il collegamento):

#include <string> 

int 
main(int argc, char **argv) 
{ 
    std::string s("Hello World"); 
    return 0; 
} 

$ make test 
c++  test.cpp -o test 
$ nm ./test | c++filt 
       U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long) 
       U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string() 

$ rm test 
$ make test CXXFLAGS=-stdlib=libstdc++ 
c++ -stdlib=libstdc++ test.cpp -o test 
$ nm ./test | c++filt 
       U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) 
       U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() 

quindi sì, è la compilazione con la bandiera in questione. Quello che indica che devi passare il -stdlib=libstdc++ a a tutto il che stai compilando se stai usando XCode 5 dato che ora usa per default -stdlib=libc++. Ciò significa che qualsiasi libreria basata su C++ che dipende dallo stdlib c++ da cui si dipende deve anche essere compilato con lo stesso flag.

Fate attenzione con un incrementale build di spinta - se non eliminare i file .o e .a, non ottengono ricompilato in base alle mutate bandiere, che mantiene i file come compilato, quindi se fossero mal interpretato quindi si verifica il problema.

+0

Hai idee su come può essere compilato con FreeBSD? Quando ho provato a compilare boost con FreeBSD con questo comando 'sudo ./b2 -j 4 threading = multi link = toolet statico = clang cxxflags =" - stdlib = libstdC++ "linkflags =" - stdlib = libstdC++ ', I avere il seguente errore 'libs/atomic/src/lockpool.cpp: 15: 10: errore fatale: file 'cstddef' non trovato #include ' – Irina

+0

Stai compilando una nuova versione di FreeBSD (11.0?) che non ha una copia di 'gcc' o' libstdC++ 'installata.Prima che sarà necessario assicurarsi che siano stati installati sul sistema, quindi * potrebbe * essere in grado di costruirlo.il progetto FreeBSD è stato spostato da' gcc' a 'clang', quindi a lungo termine, è molto meglio costruire tutto con clang, piuttosto che cercare di farlo funzionare .. – Petesh

+0

Petesh, grazie per una rapida risposta! Sì, ho FreeBDS 11.0 e in realtà ho 'gcc' installato ed ecco l'output' locate': '/usr/local/lib/gcc48/{libstdc++.a, libstdC++. So, libstdC++. So.6, libstdC++. So.6.0.19 , libstdC++. so.6.0.19-gdb.py, libstdC++. a, libstdC++. so, libstdC++. so.6, libstdC++. so.6.0.20, libstdC++. so.6.0.20-gdb.py} /usr /local/lib/gcc5/{libstdc++.a, libstdC++. so, libstdC++. so.6, libstdC++. so.6.0.21, libstdC++. so.6.0.21-gdb.py, libstdC++ fs.a} /usr/ports/lang/libstdc++_stldoc_4.2.2/{Makefile, distinfo, pkg-descr} ' Quale potrebbe essere un problema in questo caso? – Irina

0

Io uso una riga di comando semplice per fare il trucco trovato su impulso mailing list: http://lists.boost.org/boost-users/2014/02/81274.php

questo è il frammento di nel caso in cui il link non funziona più:

$ cd tools/build/v2/ 
$ ./bootstrap.sh 
$ cd ~/boost-stdc++-install/boost_1_54_0 
$ cd ~/boost-stdc++-install/boost_1_54_0 
$ tools/build/v2/b2 \ 
    --build-dir=`pwd`/tmp/build/ \ 
    --stagedir=`pwd`/tmp/stage/ \ 
    --buildid=libstdc++ \ 
    --layout=tagged -j24 \ 
    toolset=clang \ 
    cxxflags="-ftemplate-depth=999 -stdlib=libstdc++" \ 
    linkflags="-stdlib=libstdc++" \ 
    define=BOOST_SYSTEM_NO_DEPRECATED stage 
Problemi correlati