Domanda

Qualcuno può spiegare come lavori di compilazione?

Io non riesco a capire come lavori di compilazione..

Per essere più precisi, ecco un esempio..Sto cercando di scrivere del codice in MSVC++ 6 per caricare un Lua stato..

L'ho già:

  • impostare la directory aggiuntive per la biblioteca e i file da includere per il diritto directory
  • utilizzato extern "C" (perché Lua è solo C o così ho sentito)
  • includere avevo il diritto file di intestazione

Ma sto ancora ricevendo alcuni errori in MSVC++6 a proposito di simboli esterni non risolti (per le funzioni Lua che ho usato).

Quanto mi piacerebbe sapere come risolvere questo problema e andare avanti, penso che sarebbe molto meglio per me, se sono arrivato a comprendere i processi sottostanti coinvolti, in modo che chiunque potrebbe forse scrivere una bella spiegazione per questo?Ciò che mi interessa sapere è il processo..Potrebbe apparire come questo:

Passaggio 1:

  • Ingresso:Codice sorgente(s)
  • Processo:L'analisi (forse aggiungere ulteriori dettagli qui)
  • Output:tutto ciò che è uscita qui..

Passaggio 2:

  • Ingresso:Tutto ciò che era uscita dalla fase 1, più, forse, tutto ciò che è necessario (librerie?Dll?.così?.lib?)
  • Processo:tutto ciò che viene fatto con l'input
  • Output:tutto ciò che è uscita

e così via..

Grazie..

Forse questo spiega quali simboli sono, che cosa è esattamente il "collegamento" è, per quanto "oggetto" codice o quant'altro..

Grazie..Mi dispiace di essere un noob..

P. S.Questo non deve essere il linguaggio specifico..Ma sentitevi liberi di esprimere nella lingua che si sta più comodi..:)

MODIFICA:Quindi, comunque, sono stato in grado di ottenere gli errori risolti, si scopre che devo aggiungere manualmente .lib file al progetto;semplicemente specificare la directory di libreria (dove l' .lib risiede nell'IDE impostazioni o le impostazioni di progetto non funziona..

Tuttavia, le risposte di seguito hanno un po ' mi ha aiutato a capire il processo di meglio.Molte grazie!..Se qualcuno ha ancora voglia di scrivere una guida approfondita, si prega di fare..:)

MODIFICA:Solo per ulteriore riferimento, ho trovato due articoli di un autore (Mike Diehl) per spiegare abbastanza bene..:) Esaminando il Processo di Compilazione:Parte 1 Esaminando il Processo di Compilazione:Parte 2

È stato utile?

Soluzione

Dal sorgente all'eseguibile è generalmente un processo in due fasi per C e associati lingue, anche se l'IDE probabilmente presenta come un singolo processo.

1/ codice di origine e correre attraverso il compilatore.Il compilatore in questa fase ha bisogno del tuo sorgente e i file di intestazione delle altre cose che si sta andando al link (vedi sotto).

La compilazione consiste di trasformare il vostro file di origine in file oggetto.Oggetto file hanno il codice compilato e informazioni sufficienti per sapere che cosa altre cose di cui hanno bisogno, ma non dove trovare che altre cose (ad esempio, LUA, biblioteche).

2/ di Collegamento, la fase successiva, è la combinazione di tutti i tuoi file oggetto con le librerie per creare un file eseguibile.Non coprire il collegamento dinamico qui, visto che complicherà la spiegazione con scarso beneficio.

Non solo è necessario per specificare la directory in cui il linker può trovare il codice, è necessario specificare il libreria che contiene il codice.Il fatto che stai ricevendo esterni non risolti indica che non è stato fatto questo.

Come esempio, si consideri il seguente semplificato il codice C (xx.c) e il comando.

#include <bob.h>
int x = bob_fn(7);

cc -c -o xx.obj xx.c

Compila i xx.c file xx.obj.Il bob.h contiene il prototipo per bob_fn() in modo che la compilazione avrà successo.Il -c indica al compilatore di generare un file oggetto piuttosto che un file eseguibile e il -o xx.obj imposta il nome del file di output.

Ma il vero codice per bob_fn() non è nell'intestazione del file, ma in /bob/libs/libbob.so, così link, avete bisogno di qualcosa come:

cc -o xx.exe xx.obj -L/bob/libs;/usr/lib -lbob

Questo crea xx.exe da xx.obj, utilizzando le librerie (cercato in data percorsi) del modulo libbob.so (lib e .così sono aggiunti dal linker di solito).In questo esempio, -L imposta il percorso di ricerca per le biblioteche.Il -l specifica un catalogo per trovare l'inclusione nell'eseguibile, se necessario.Il linker di solito prende il "bob" e trova la prima rilevante file di libreria nella ricerca percorso specificato -L.

Un file di libreria è una raccolta di file oggetto (un po ' come un file zip contiene più di altri file, ma non necessariamente compresso) - quando il primo rilevante il verificarsi di un indefinito esterno è trovato, il file oggetto viene copiato dalla libreria e aggiunto il file eseguibile, proprio come la vostra xx.obj file.Generalmente questo continua fino a quando non ci sono più esterni non risolti.Il 'rilevanti' biblioteca è una modifica del "bob" il testo, potrebbe cercare libbob.a, libbob.dll, libbob.so, bob.a, bob.dll, bob.so e così via.La rilevanza è deciso dal linker stesso e deve essere documentata.

Come funziona dipende dal linker, ma questo è fondamentalmente.

1/ Tutti i file oggetto contiene un elenco di esterni non risolti che hanno bisogno di avere risolto.Il linker mette insieme tutti questi oggetti e consente di correggere i collegamenti tra di loro (si risolve come molti esterni per quanto possibile).

2/ Quindi, per ogni esterne ancora irrisolta, il linker pettini i file di libreria alla ricerca di un file oggetto che può soddisfare il link.Se si trova, si tira in - questo potrebbe causare ulteriori esterni non risolti come l'oggetto tirato può avere la sua propria lista di esterni che devono essere soddisfatte.

3 Ripetere il passaggio 2 fino a quando non ci sono più esterni non risolti o non c'è possibilità di risolvere la lista della libreria (questo è dove il vostro sviluppo era, dal momento che non erano incluse LUA file di libreria).

La complicazione che ho citato prima è il linking dinamico.Questo è dove si collega con uno stub di una routine (una sorta di marcatore) piuttosto che l'effettivo di routine, che è poi risolto a tempo di caricamento (quando si esegue il file eseguibile).Cose come i controlli comuni di Windows sono in queste Dll in modo che si può cambiare senza dover ricollegare gli oggetti in un nuovo file eseguibile.

Altri suggerimenti

Passo 1 - Compilatore:

  • Ingresso:File di codice sorgente[s]
  • Processo:L'analisi del codice sorgente e traduzione in codice macchina
  • Output:Oggetto file[s], che consistono[s] di:
    • I nomi dei simboli che sono definiti in questo oggetto, e che questo oggetto file di "esportazioni"
    • Il codice macchina associate a ciascun simbolo definito in questo file oggetto
    • I nomi dei simboli che non sono definite in questo file oggetto, ma sul quale il software in questo file oggetto dipende e a cui si deve successivamente essere collegati, cioèi nomi di questo oggetto file di "importazioni"

Fase 2 - Collegamento:

  • Ingresso:
    • Oggetto file[s] dal passaggio 1
    • Biblioteche di altri oggetti (ad es.da O/S e altri software)
  • Processo:
    • Per ogni oggetto che si desidera collegare
    • Ottenere l'elenco dei simboli che questo oggetto importazioni
    • Trovare questi simboli in altre biblioteche
    • Link corrispondente librerie per il tuo file oggetto
  • Output:un unico file eseguibile, che include il codice di macchina da tutti i tuoi oggetti, più oggetti da librerie, che sono stati importati (collegati) per i vostri oggetti.

Le due fasi principali sono di compilazione e linking.

Compilazione richiede compilazione singola unità (quelli sono semplicemente i file di origine, con tutte le intestazioni comprendono), e creare file oggetto.Ora, in quei file oggetto, ci sono un sacco di funzioni (e altre cose, come i dati statici), definiti in specifiche posizioni (indirizzi).Nel passaggio successivo, collegamento, un po ' di informazioni in più su queste funzioni, è anche necessario:i loro nomi.Quindi queste sono memorizzate.Un singolo file oggetto può fare riferimento a funzioni (perché lo si vuole chiamare quando il codice viene eseguito) che sono in realtà in altri file oggetto, ma dal momento che abbiamo a che fare con un singolo file oggetto qui, solo riferimenti simbolici (i loro nomi) a quelli di altre funzioni vengono memorizzate nel file oggetto.

Viene poi il collegamento (cerchiamo di limitare se stessi per il collegamento statico qui).Il collegamento è dove l'oggetto file che sono stati creati nella prima fase (direttamente, o dopo che sono stati gettati insieme in una .lib file) vengono prese insieme e un file eseguibile viene creato.Nel collegamento di passaggio, tutti quei riferimenti simbolici da un oggetto file o lib per un altro sono risolti (se si può), per la ricerca di nomi in oggetto corretto, trovare l'indirizzo della funzione, e mettendo gli indirizzi nel posto giusto.

Ora, per spiegare qualcosa sulla "extern " C"' cosa avete bisogno:

C non hanno la funzione di sovraccarico.Una funzione è sempre riconoscibile per il suo nome.Pertanto, quando si compila il codice come codice C, solo il vero nome della funzione è memorizzato nel file oggetto.

C++, tuttavia, ha qualcosa chiamato 'funzione / metodo di overload'.Questo significa che il nome di una funzione non è più sufficiente per identificarlo.Compilatori C++, pertanto, creare nomi per le funzioni che includono i prototipi di funzione (dato che il nome e il prototipo di identificare in modo univoco una funzione).Questo è noto come "name mangling'.

Il "extern " C"' specifica è necessaria quando si desidera utilizzare una libreria che è stato compilato come 'C' di codice (per esempio, il pre-compilato Lua binari) da un progetto C++.

Per il tuo problema:se ancora non funziona, questi suggerimenti potrebbero essere d'aiuto:* hanno il Lua binari stato redatto con la stessa versione di VC++?* si può semplicemente compilare Lua se stessi, sia all'interno di VC soluzione, o come un progetto separato come codice C++?* sei sicuro di avere tutti i "extern " C"' le cose in modo corretto?

Devi andare in impostazioni di progetto e aggiungere una directory in cui si dispone che il LUA libreria *.lib file da qualche parte sul "linker" tab.Impostazione denominata "biblioteche" o qualcosa del genere, mi dispiace non posso guardare in su.

La ragione si ottiene esterni non risolti "simboli" è perché la compilazione in C++ funziona in due fasi.Innanzitutto, il codice viene compilato, ogni .cpp file in essa la propria .file obj, quindi "linker" inizia e unire tutti che .obj file .exe file..lib file è solo un mucchio di .i file obj unite insieme per rendere la distribuzione delle librerie solo un po ' più semplice.Con l'aggiunta di tutti i "#include" e dichiarazione extern hai detto che il compilatore che da qualche parte è possibile trovare il codice con le firme ma il linker non trova il codice perché non sa dove quelli .lib file con l'attuale codice viene inserito.

Assicurarsi di aver letto REDME della biblioteca, di solito sono piuttosto spiegazione dettagliata di ciò che si doveva fare per includere nel codice.

Si potrebbe anche voler controllare questo fuori: COMPILATORE, ASSEMBLATORE, LINKER E LOADER:UNA BREVE STORIA.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top