2014-09-18 5 views
6

Sto sviluppando plugin e strumenti usando le disposizioni di clang per farlo tramite plugin e clTooling di LibTooling. Sono in grado di fare le seguenti cose:Quando si esegue clang compilato da source, come specificare la posizione di libC++, oppure qualcuno mi spiega cosa -stdlib = libC++ fa

  • compilazione LLVM con clangore all'interno, da svn (Linux e OSX), seguendo la pagina di ottenere iniziato eseguendo lo script di configurazione (senza l'utilizzo di cmake)
  • Compile libcxx/libC++ su Linux (anche da svn), e non ho motivo di aspettarsi alcun problema con questo su OSX. Il fatto è che esistono già libc intestazioni ++, sul mio sistema OSX a

    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/ 
    

    e la libC++ dylib vive in/usr/lib /.

    Modifica 4: Sono riuscito a compilare libcxx bene su OS X seguendo le istruzioni. Ho una nuova libC++ 1.0.dylib seduta qui ora.

  • su OSX, utilizzare la versione + asserisce (e Debug + Asserisce) build di clang++ per compilare il codice sorgente C++ aggiungendo

    -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/ 
    

    e senza usare -stdlib=libc++. L'utilizzo di questo flag per specificare esplicitamente libC++ come una directory include consente il clang che ho creato per "vedere" le intestazioni standard di C++. Sorprendentemente, sembra essere felice con lui durante la compilazione di un file sorgente moderatamente di base (che esercita ancora una buona quantità di C++ 11 follia in essa)

Sulla base di questo, si può vedere che sto hacking il mio nuovo clang version 3.6.0 (trunk 217905) per cercare la libC++ imballata da Xcode di Apple. Questo funziona apparentemente per ora perché la libC++ di Apple fornita con Xcode rimane ABI-compatibile con il compilatore che ho appena creato dal sorgente. Ciò che è ancora molto curioso per me è come il mio clang appena compilato sia in grado di capire dove trovare il corrispondente libC++ dylib! Ciò solleva la questione più avanti quando effettivamente ottengo la compilazione di libC++, come dovrei dire al mio nuovo clang svn-compilato di cercare e usare il nuovo dylib libC++ svn-compilato ??

Quindi, fondamentalmente, sono ancora completamente confuso su quello che sono davvero supposto fare per impostare correttamente libC++. Cosa, in particolare, fa clang fare effettivamente quando lo dici -stdlib=libc++?

È un percorso di inclusione hardcoded? Probabilmente voglio creare libC++ abi e libC++ da svn per usarlo insieme al clang che è stato creato da svn. Questo ha più senso ... Allora come dovrei fare per installarlo? Dover mettere -I~/libcxx/include/c++/v1/ (o qualunque cosa sarebbe) in una configurazione di build è inelegante.

Presumibilmente posso solo impostare il mio compilazione LLVM per costruire clang insieme a libC++ ABI e libC++ da anche check-out libcxxabi e libcxx da svn, e la mia aspettativa è che l'installazione dovrebbe rendere -stdlib=libc++ magicamente lavoro. Nota anche che il clang che Apple ti offre con Xcode non richiede realmente l'uso di -stdlib=libc++. Magicamente sa dove afferrare i file della libreria.

Tuttavia!L'unico neo, almeno l'unico finora che so cercare: la mia macchina ha già un /usr/bin/clang++:

$ ls -la $(which clang++) 
-rwxr-xr-x 1 root wheel 14240 Mar 17 2014 /usr/bin/clang++ 

Questo non è un link simbolico a dentro Xcode.app come mi aspettavo! Ora ho una vera preoccupazione per l'esecuzione di make install dalla mia directory di costruzione llvm! Probabilmente potrebbe rovinare il mio ambiente Xcode o impedire al mio Mac di avviarsi (come afferma chiaramente il libC++ llvm doc se succede qualcosa di brutto a /usr/lib/libc++.1.dylib)!

Speriamo che non ci sia già una documentazione che mi sia sfuggita e che risponda a queste domande, perché avrei dovuto trovarlo ora.

Edit: vedo nelle istruzioni sparse trovate su http://libcxx.llvm.org che

potrebbe in realtà essere il "modo giusto" in questo momento. Ma ciò che fallisce è spiegare cosa -stdlib=libc++fa clang a fare, o cosa -nostdinc++causa clang fare.

Modifica 2: Grazie a @ n.m. ora sappiamo che -nostdinc++ significa che nessun percorso di ricerca C++ standard è stato cercato. Ciò significa che lo standard include path è una cosa. Questo percorso è hardcoded quando viene creato clang? Ho cercato su Google e ho trovato qualcosa che fa riferimento a una variabile CLANG_INCLUDEPATH, questo sembra possibilmente una variabile makefile. Sfortunatamente sto eseguendo una ricerca completa del file system sulla mia directory di llvm source e non trovo corrispondenze con una tale stringa (quindi non può essere una configurazione usata da clang o durante il processo di costruzione clang).

Edit 3: Con l'aiuto di --verbose, ora posso vedere qualche uscita utile:

clang di Xcode:

clang -cc1 version 5.1 based upon LLVM 3.4svn default target x86_64-apple-darwin13.4.0 
ignoring nonexistent directory "/usr/include/c++/v1" 
#include "..." search starts here: 
#include <...> search starts here: 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1 
/usr/local/include 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include 
/usr/include 
/System/Library/Frameworks (framework directory) 
/Library/Frameworks (framework directory) 
End of search list. 

svn clang fresco:

clang -cc1 version 3.6.0 based upon LLVM 3.6.0svn default target x86_64-apple-darwin13.4.0 
ignoring nonexistent directory "/Users/username/Documents/llvmbuild/Release+Asserts/bin/../include/c++/v1" 
ignoring nonexistent directory "/usr/include/c++/v1" 
#include "..." search starts here: 
#include <...> search starts here: 
/usr/local/include 
/Users/username/Documents/llvmbuild/Release+Asserts/bin/../lib/clang/3.6.0/include 
/usr/include 
/System/Library/Frameworks (framework directory) 
/Library/Frameworks (framework directory) 
End of search list. 

Va bene, quindi questo è dipingere una foto di alcuni posti per depositare alcuni file libC++.

La presenza di due "ignorando directory inesistente" voci indica a me che clang di Xcode è in grado di trovare una libC++ al suo hardcoded /Apps/Xcode.app/.../c++/v1/ mentre il mio svn clang non è trovare uno al posto che vuole guardare (all'interno del Release+Asserts accumulo dir, che sembra sciocco ma potrebbe essere in realtà in cui libcxx copia le intestazioni nel sistema di costruzione di llvm).

Nessun accenno a dove preleva i dylibs di libC++. Nemmeno guardando attraverso le stringhe che sono negli eseguibili clang, usando string (che comunque era un colpo lungo).

Non è esattamente chiaro cosa esattamente fare, ma sembra che ora abbia gli strumenti per iniziare il mio progetto. Il problema principale ora è che cosa sta succedendo con lo libc++.dylib. Non riesco a capire se il clang appena costruito sia hardcoded per trovarlo a /usr/lib/libc++.1.dylib o cosa.Ho bisogno di fare questo:

  1. non toccare /usr/lib/libc++.1.dylib in modo da non rompere il mio intero sistema operativo
  2. Point appena compilato clang++ di utilizzare la libc++.1.dylib che è ora è stato costruito, ed è seduto in una posizione diversa rispetto/usr/lib/libc++.1.dylib. Non mi interessa dove va a questo punto, ma NON sto per eseguire make install che probabilmente sovrascriverà /usr/lib/libc++.1.dylib.

Non è chiaro cosa abbia senso fare. Specificare -stdlib=libc++ causa clang++ per collegare il /usr/lib/libc++.1.dylib con codice hard? In tal caso, posso semplicemente rilasciarlo e -l<compiled libc++.dylib> esplicitamente? Altrimenti, come faccio a compilare clang in un modo per modificare questo percorso per farlo usare quello giusto?

Per il momento userò -stdlib=libc++ -nostdinc++ (vedi prima modifica) e prego che in realtà significhi per clang ascoltare il -I<new libc++ header path> -L<new libc++ dylib path>. Suppongo che se ancora non funziona e che i file di sistema vengano usati comunque nonostante questi sforzi, sarò comunque felice finché i miei programmi continueranno a compilare ...

+0

-nostdinC++ = nessuno standard C++ include il percorso di ricerca. –

+0

Grazie, domanda aggiornata con questa conoscenza aggiuntiva. –

+0

"Questo percorso è hardcoded quando viene creato clang?" sì. prova 'clang ++ -stdlib = libC++ --verbose somefile.cpp' per vederlo, quindi esegui' strings' su clang ++ eseguibile per vedere quelle directory. –

risposta

2

Sono arrivato abbastanza lontano per rispondere in modo soddisfacente al mio proprie domande, quindi riassumerò le mie conclusioni qui.

Questo potrebbe non essere l'intero quadro, ma è sufficiente per ottenere le informazioni che stavo riscontrando.

Intorno alla riga 606 di tools/clang/lib/Driver/ToolChains.cpp è il codice che semplicemente spinge -lc++ agli argomenti del comando. Questo è nell'implementazione di clang della toolchain (che è più o meno parte dei componenti che permettono a clang di emulare il comportamento della riga di comando di gcc, in modo che sia compatibile per scopi di costruzione).

Ciò significa che libC++. Dylib/so viene caricato utilizzando lo stesso meccanismo di tutte le altre librerie. Non esiste un trattamento speciale per la libreria standard C++. Ciò significa anche che viene fatto in modo semi-hardcoded. Forse questo non è abbastanza preciso, perché mi aspetto che le specifiche esplicite del percorso della libreria (-L) possano avere la precedenza sui percorsi root predefiniti.

In ogni caso, piuttosto che provare a armeggiare con -L, c'è un martello più grande che può essere utilizzato, --sysroot. Installando libC++ in una posizione separata dal sistema /usr/lib, posso usare --sysroot con invocazioni di clang per forzare clang a non pensare nemmeno a cercare in /usr/lib per libC++, o qualsiasi altra cosa, per quella questione. Questo è qualcosa di utile per es. lavori di compilazione incrociata.

Ok, questi sono alcuni modi per manipolare il clang per fare le nostre offerte. Sicuramente sono sufficientemente potenti. Ora dovevo essere assolutamente sicuro che la libC++ che pensavo fosse inclusa e collegata fosse effettivamente inclusa e collegata.

Sono andato per qualcosa infallibile piuttosto che qualcosa di semplice e intelligente. Ho apportato alcune modifiche strategiche a libC++ stesso, e poi l'ho installato in una directory alternativa (non /usr/lib - vedi la mia domanda per perché non voglio scherzare con il mio sistema libC++): questo può essere piuttosto arbitrario, ho aggiunto

std::libcxx_custom_version_type::libcxx_custom_version_type() { 
    libcxx_custom_version = "slu_libc++_svn_218071"; 
} 

in src/typeinfo.cpp (in libC++) e corrispondentemente

struct libcxx_custom_version_type { 
    char* libcxx_custom_version; 
    libcxx_custom_version_type(); 
}; 

da includere/tipoinfo. Lo scopo che serve (sì, è terribile, vabbè) è di rendere inequivocabilmente facile verificare che la libC++ con cui sto collegando sia effettivamente quella che ho compilato dal sorgente. Infatti posso trovare la stringa slu_libc++_svn_218071 usando strings su libC++. Dylib. Una piccola quantità di codice di test in un file C++ di test può ora mostrare facilmente se la libC++ collegata è quella che ho appena compilato.

Fare la stessa verifica per le intestazioni libC++ reali è molto più banale, abbiamo solo bisogno di definire una nuova macro e controllarla durante una compilazione.

Ora ho tutti gli strumenti per rispondere alle mie domande.

Bene, in realtà, in questo momento sto ricevendo questo errore, quindi non riesco ancora a creare qualcosa.

Undefined symbols for architecture x86_64: 
    "std::terminate()", referenced from: 
     ___clang_call_terminate in reflect-16fcd7.o 
ld: symbol(s) not found for architecture x86_64 

Un passo alla volta, immagino ...

+0

Sì, costruisco Clang dai sorgenti per assicurarmi di avere gli ultimi disinfettanti. È sempre una gioia avere qualcosa da compilare, specialmente se si usa '-std = C++ 11' perché le intestazioni non sono in-path neanche. – jww

+0

Non riesco a trovare una soluzione per l'errore linker 'terminate()'. Mi sto temporaneamente arrendendo e usando la libreria fornita da Apple libC++ con il mio clang appena compilato. Questo per fortuna produce un eseguibile funzionante durante la compilazione del mio codice di test. Forse lo svn libcxx è appena rotto? Immagino che con il mio sistema libC++, mi permetta ancora di fare confusione con i plugin e lo sviluppo degli strumenti. –

Problemi correlati