【问题标题】:QtCreator multiple definition build bugQtCreator 多定义构建错误
【发布时间】:2012-09-04 04:05:33
【问题描述】:

这是我的 .pro 文件:

QT       += core gui widgets

TARGET = link_mult_def

TEMPLATE = app

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

HEADERS +=

由于某种原因,QtCreator 在从 .cpp 文件构建 .o 文件时不尊重源文件夹结构。这两个文件都将编译为“shadow_build_directory/file.o”。我希望构建过程在影子构建目录中创建 path1 和 path2 目录并将“path1/file.cpp”编译为“shadow_build_directory/path1/file.o”和“path2/file.cpp”编译为“shadow_build_directory/path2/文件.o”。

由于来自两个来源的编译符号在 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 链接 file.o 两次,导致链接器失败并出现多重定义错误。

如何确保 QtCreator 编译为反映源目录结构的目标文件?

谢谢

编辑:

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

【问题讨论】:

  • 其实就是QtCreator使用qmake的方式。我什么都不告诉qmake。我只是将源文件添加到我的项目中。我需要所有文件来构建我的可执行文件。但是当我构建项目时它失败了。
  • 我很确定源代码没问题。这是 QtCreator 的问题。如您所见,两个源文件都编译为同一个目标文件,该目标文件在链接器调用中出现两次。这会导致多重定义错误。我不知道如何告诉 QtCreator 编译为单独的目标文件。
  • 抱歉,我没有看到您在子目录中使用相同的文件名...抱歉打扰了。

标签: c++ linker qt-creator multiple-definition-error


【解决方案1】:

如果您愿意将目标文件与源文件放在一起,那么您可以使用任一

CONFIG += object_parallel_to_source

CONFIG += object_with_source

取决于您使用的 QMake 版本。

答案抄自SO answer here

【讨论】:

    【解决方案2】:

    过去我在使用 Visual Studio 时遇到过完全相同的问题。它的作用是将所有目标文件编译并放置在一个目录中,就像您的情况一样。我们通过在项目中没有重复的文件名来解决这个问题。

    如果您说的是真的 - QtCreator 将所有对象文件放在一个目录中,那么您所能做的就是为每个项目使用唯一名称来命名您的文件。

    【讨论】:

    • 我从 QtCreator 添加了构建步骤。您可以看到它编译为相同的目标文件。不幸的是,我不允许更改源结构,因为它不是我的代码...
    【解决方案3】:

    也许您可以将整个项目分成两个(无需触及现有的源文件配置,只需管理 .pro 文件)并设置它们之间的依赖关系。然后,您可以为每个项目设置自己的输出构建文件目录(例如,参见here)。

    【讨论】:

      【解决方案4】:

      解决方案是重命名您的文件。项目的目录和 dir 结构与编译器无关。编译器甚至不关心文件在哪里,它只需要get 文件,无论文件是在/src 文件夹中,还是在月球上。

      现在很明显,在创建.o 文件后,您会收到错误消息,这仅仅是因为您有两个同名文件。

      即使你没有这个问题,用相同的名字制作多个文件也是不好的,特别是如果名字没有意义,如file.cpp

      【讨论】:

      • 我不能重命名文件,因为它不是我的代码,我不能更改代码结构。如果我开始重命名文件,人们会杀了我。我认为问题在于,我们将源文件分隔在目录中,但构建过程并没有以相同的方式分隔目标文件。
      • "即使你没有遇到这个问题,使用相同名称制作多个文件也是不好的,尤其是在名称无意义的情况下,例如 file.cpp。"我创建了一个最小的例子,这就是文件被命名为“file.cpp”的原因。我认为拥有相同名称的文件并不坏。这就是我们在文件系统中有目录的原因。想象一个庞大的项目,其源代码分布在数百个子目录中。您有不同的团队在处理不同的子目录,您不能告诉他们不要使用与其他子目录相同的文件名...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 2016-10-11
      • 2016-05-02
      • 1970-01-01
      相关资源
      最近更新 更多