2012-09-11 18 views
11

questo è il mio file .pro:QtCreator multipla definizione di compilazione bug

QT  += core gui widgets 

TARGET = link_mult_def 

TEMPLATE = app 

SOURCES += main.cpp \ 
      path2/file.cpp \ 
      path1/file.cpp 

HEADERS += 

Per qualche ragione, QtCreator non rispetta la struttura della cartella principale quando si costruisce i file .o dai file cpp. Entrambi i file saranno compilati in "shadow_build_directory/file.o". Mi aspetto che il processo di generazione crei le directory path1 e path2 nella directory di creazione shadow e compili "path1/file.cpp" in "shadow_build_directory/path1/file.o" e "path2/file.cpp" in "shadow_build_directory/path2/file.o".

Poiché i simboli compilati da entrambe le fonti si sommano nel file.o non è ancora un grosso problema. Essa diventa un grosso problema quando QtCreator cerca di link:

g++ -Wl,-O1 -o link_mult_def main.o file.o file.o -L/usr/lib/x86_64-linux-gnu -lQtCore -lpthread 

link QtCreator file.o due volte che rende il linker esito negativo con mutiple Errore di definizione.

Come posso assicurarmi che QtCreator compili per i file oggetto che riflettono la struttura della directory di origine?

Grazie

EDIT:

percorso1/file.cpp

#include <iostream> 
void function1() 
{ 
    std::cout << "function1" << std::endl; 
} 

percorso2/file.cpp

#include <iostream> 
void function2() 
{ 
    std::cout << "function2" << std::endl; 
} 

processo di compilazione da QtCreator:

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I../link_mult_def -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I../link_mult_def -I. -o main.o ../link_mult_def/main.cpp 

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I../link_mult_def -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I../link_mult_def -I. -o file.o ../link_mult_def/path1/file.cpp 

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_WEBKIT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I../link_mult_def -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I../link_mult_def -I. -o file.o ../link_mult_def/path2/file.cpp 

g++ -Wl,-O1 -o link_mult_def main.o file.o file.o -L/usr/lib/x86_64-linux-gnu -lQtGui -lQtCore -lpthread 

file.o: In function `function2()': 
file.cpp:(.text+0x0): multiple definition of `function2()' 
make: Leaving directory `/home/schmid/code/misc/trash/link_mult_def-build-desktop-Qt_4_8_1_in_PATH__System__Release' 
file.o:file.cpp:(.text+0x0): first defined here 
collect2: error: ld returned 1 exit status 
make: *** [link_mult_def] Error 1 
+1

In realtà è il modo in cui QtCreator utilizza qmake. Non dico nulla a qmake. Ho appena aggiunto i file sorgenti al mio progetto. Ho bisogno di tutti i file per creare il mio eseguibile. Ma quando costruisco il progetto fallisce. – HenrySpencer

+0

Sono abbastanza sicuro che il codice sorgente sia a posto. È un problema con QtCreator. Come puoi vedere entrambi i file sorgente sono compilati nello stesso file oggetto che appare due volte nella chiamata del linker. Che porta a un errore di definizione più semplice. Non so come dire a QtCreator di compilare file di oggetti separati. – HenrySpencer

+0

Mi dispiace, non avevo visto che hai usato lo stesso nome di file nelle sottodirectory ... scusa per il rumore. – Mat

risposta

0

Ho avuto lo stesso identico problema con Visual Studio in passato. Quello che fa è che compila e posiziona tutti i file oggetto in una directory, proprio come nel tuo caso. Ci siamo preoccupati di non avere nomi di file duplicati in un progetto.

Se quello che dici è vero - che il QtCreator colloca tutti i file oggetto in una directory, allora tutto quello che puoi fare è assegnare un nome al file con nomi unici al progetto.

+0

Ho aggiunto i passaggi di costruzione da QtCreator. Puoi vedere che si compila sullo stesso file oggetto. Purtroppo non ho il permesso di cambiare la struttura sorgente perché non è il mio codice ... – HenrySpencer

-1

La soluzione sarebbe semplicemente rinominare i file. Le directory e la struttura dir del tuo progetto hanno niente da fare con il compilatore. Il compilatore non si cura nemmeno di dove sono i file, ha solo bisogno di ottenere i file, non importa se i file sono nella cartella /src o sulla Luna.

Ora, ovviamente, dopo che i file sono resi .o si ottiene l'errore, semplicemente perché si dispone di due file con lo stesso nome.

Anche se non si è verificato questo problema, la creazione di file multipli con lo stesso nome non è buona, soprattutto se i nomi non hanno significato, come file.cpp.

+0

Non devo rinominare i file perché non è il mio codice e non devo cambiare la struttura del codice. Le persone mi uccideranno se inizio a rinominare i file. Penso che il problema sia che abbiamo i file sorgente separati nelle directory, ma il processo di compilazione non separa i file oggetto nello stesso modo. – HenrySpencer

+4

"Anche se non si è verificato questo problema, creare file multipli con lo stesso nome è sbagliato, specialmente se i nomi non hanno significato, come file.cpp." Ho creato un esempio minimale, ecco perché i file sono denominati "file.cpp". Non penso che sia brutto avere file con lo stesso nome. Questo è il motivo per cui abbiamo directory nei file system. Immagina un enorme progetto con codice sorgente distribuito su centinaia di sottodirectory. Hai diversi team che lavorano su diverse sottodirectory e non puoi dire loro di non usare gli stessi nomi di file come in altre sottodirectory ... – HenrySpencer

0

Forse si potrebbe dividere l'intero progetto in due più (senza toccare la configurazione file di origine esistente, solo la gestione dei file .pro) e impostare le dipendenze tra loro. Quindi per ogni progetto è possibile impostare la propria directory dei file di generazione di output (vedere, ad esempio, here).

1

Se sei a tuo agio con i tuoi file oggetto a fianco i file sorgente, quindi è possibile utilizzare

CONFIG += object_parallel_to_source 

o

CONFIG += object_with_source 

a seconda di quale versione di QMake si sta utilizzando.

Risposta cribbed from SO answer here.

Problemi correlati