2012-09-11 10 views
11

este es mi archivo .pro:QtCreator definición múltiple acumulación de errores

QT  += core gui widgets 

TARGET = link_mult_def 

TEMPLATE = app 

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

HEADERS += 

Por alguna razón, QtCreator no respeta la estructura de carpeta de origen en la construcción de los archivos .o de los archivos .cpp. Ambos archivos se compilarán en "shadow_build_directory/file.o". Esperaría que el proceso de compilación creara directorios path1 y path2 en el directorio shadow build y compilara "path1/file.cpp" a "shadow_build_directory/path1/file.o" y "path2/file.cpp" a "shadow_build_directory/path2/file.o ".

Dado que los símbolos compilados de ambas fuentes se suman en el archivo.o, todavía no es un gran problema. Se convierte en un gran problema cuando se trata de QtCreator enlace:

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

enlaces QtCreator file.o dos veces, lo cual hace que el enlazador fallar con mutiple error de definición.

¿Cómo puedo asegurarme de que QtCreator compila a los archivos de objetos que reflejan la estructura del directorio de origen?

Gracias

EDIT:

rutaDeAcceso1/file.cpp

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

via2/file.cpp

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

proceso de construcción por 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

En realidad, es la forma en que QtCreator usa qmake. No le digo nada a qmake. Solo agrego archivos fuente a mi proyecto. Necesito todos los archivos para construir mi ejecutable. Pero cuando construyo el proyecto falla. – HenrySpencer

+0

estoy bastante seguro de que el código fuente está bien. Es un problema con QtCreator. Como puede ver, ambos archivos fuente se compilan en el mismo archivo objeto que aparece dos veces en la llamada del enlazador. Lo que lleva a un error de definición mutliple. No sé cómo decirle a QtCreator que compile para separar archivos de objetos. – HenrySpencer

+0

Disculpa por eso, no te había visto usar el mismo nombre de archivo en los subdirectorios ... lo siento por el ruido. – Mat

Respuesta

0

Tuve exactamente el mismo problema con Visual Studio en el pasado. Lo que hace es compilar y coloca todos los archivos de objeto en un directorio, como en su caso. Hemos solucionado eso al no tener nombres de archivo duplicados en un proyecto.

Si lo que dices es cierto, que el QtCreator coloca todos los archivos de objeto en un directorio, entonces todo lo que puedes hacer es nombrar tus archivos con nombres únicos por proyecto.

+0

Agregué los pasos de compilación de QtCreator. Puede ver que se compila en el mismo archivo de objeto. Lamentablemente, no puedo cambiar la estructura de origen porque no es mi código ... – HenrySpencer

-1

La solución sería simplemente cambiar el nombre de sus archivos. Los directorios y la estructura de directorios de su proyecto tienen nada que ver con el compilador. Al compilador ni siquiera le importa dónde están los archivos, solo necesita obtener los archivos, sin importar si los archivos están en la carpeta /src, o en la Luna.

Ahora, obviamente, después de que se hacen los archivos .o se obtiene el error, simplemente porque tiene dos archivos del mismo nombre.

Incluso si no tuvo este problema, hacer multiplicar archivos con el mismo nombre es malo, especialmente si los nombres no tienen sentido, como file.cpp.

+0

No debo cambiar el nombre de los archivos porque no es mi código y no debo cambiar la estructura del código. La gente me matará si comienzo a cambiar el nombre de los archivos. Creo que el problema es que tenemos archivos fuente separados en directorios, pero el proceso de compilación no separa los archivos objeto de la misma manera. – HenrySpencer

+4

"Incluso si no tuvo este problema, hacer multiplicar archivos con el mismo nombre es malo, especialmente si los nombres no tienen sentido, como file.cpp". Creé un ejemplo mínimo, por eso los archivos se llaman "file.cpp". No creo que sea malo tener archivos con el mismo nombre. Es por eso que tenemos directorios en sistemas de archivos. Imagine un gran proyecto con código fuente distribuido en cientos de subdirectorios. Tienes diferentes equipos trabajando en diferentes subdirectorios y no puedes decirles que no usen los mismos nombres de archivo que en otros subdirectorios ... – HenrySpencer

0

Quizás podría dividir todo el proyecto en dos unidades (sin tocar la configuración de los archivos de origen existentes, simplemente administrando los archivos .pro) y configurar las dependencias entre ellos. Luego, para cada proyecto, puede establecer el propio directorio de archivos de compilación de salida (consulte, por ejemplo, here).

1

Si se siente cómodo con sus archivos de objetos junto con los archivos de origen, a continuación, puede utilizar cualquiera

CONFIG += object_parallel_to_source 

o

CONFIG += object_with_source 

dependiendo de la versión de QMake que está utilizando.

Respuesta cribbed from SO answer here.

Cuestiones relacionadas