Ошибка сборки QtCreator
это мой .pro файл:
QT += core gui widgets
TARGET = link_mult_def
TEMPLATE = app
SOURCES += main.cpp \
path2/file.cpp \
path1/file.cpp
HEADERS +=
По какой-то причине QtCreator не уважает структуру исходной папки при создании файлов .o из файлов .cpp. Оба файла будут скомпилированы в "shadow_build_directory/file.o". Я бы ожидал, что процесс сборки создаст директории path1 и path2 в каталоге создания теней и скомпилирует "path1/file.cpp" в "shadow_build_directory/path1/file.o" и "path2/file.cpp" в "shadow_build_directory/path2/file.o".
Так как скомпилированные символы из обоих источников складываются в файл. Это еще не проблема. Это становится большой проблемой, когда QtCreator пытается связать:
g++ -Wl,-O1 -o link_mult_def main.o file.o file.o -L/usr/lib/x86_64-linux-gnu -lQtCore -lpthread
QtCreator связывает файл .o два раза, что заставляет компоновщик сбой с ошибкой определения.
Как я могу убедиться, что QtCreator компилирует объектные файлы, которые отражают структуру исходного каталога?
Спасибо
EDIT:
path1/file.cpp
#include <iostream>
void function1()
{
std::cout << "function1" << std::endl;
}
path2/file.cpp
#include <iostream>
void function2()
{
std::cout << "function2" << std::endl;
}
Процесс сборки с помощью 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
Если вам удобно располагать ваши объектные файлы вместе с вашими исходными файлами, вы можете использовать
CONFIG += object_parallel_to_source
или
CONFIG += object_with_source
в зависимости от того, какую версию QMake вы используете.
Откликнуться из SO ответ здесь.
Ответ 2
У меня была такая же проблема с Visual Studio в прошлом. Что он делает, так это компиляция и размещение всех объектных файлов в одном каталоге, как и в вашем случае. Мы работали над этим, не имея дубликатов имен файлов в проекте.
Если вы говорите правду, что QtCreator помещает все объектные файлы в один каталог, то все, что вы можете сделать, это назвать ваши файлы уникальными именами для каждого проекта.
Ответ 3
Возможно, вы могли бы разделить весь проект на два (не касаясь существующей конфигурации исходных файлов, просто управляя файлами .pro) и настраивать зависимости между ними. Затем для каждого проекта вы можете установить собственный каталог файлов выходных файлов (см., Например, здесь).
Ответ 4
Решение состоит в том, чтобы просто переименовать ваши файлы. Каталоги и структура вашего проекта не имеют ничего общего с компилятором. Компилятор даже не заботится о том, где находятся файлы, ему просто нужно получить файлы, независимо от того, находятся ли файлы в папке /src
или на Луне.
Теперь очевидно, что после создания файлов .o
вы получите ошибку, просто потому, что у вас есть два файла с тем же именем.
Даже если у вас не было этой проблемы, умножение файлов с тем же именем плохо, особенно если имена бессмысленны, как file.cpp
.