【问题标题】:Why do I have to double run make to fully compile my program? GNU c++为什么我必须两次运行 make 才能完全编译我的程序? GNU C++
【发布时间】:2013-04-29 05:56:27
【问题描述】:

我很难理解运行程序时幕后发生的事情。

在我的学校服务器上,每次我需要制作 makefile 时,我只使用 gcc 和几乎相同的代码。哈哈。

我下载了我的程序以在 NetBeans 中对其进行调试,并在数小时/数天后.. 我终于几乎一切正常。

在查看了这里和其他网站上的一些帖子后,我发现由于某种原因我需要使用 g++ 而不是 gcc 来编译,因为我使用的是 MacBook。我不太明白.. 但是如果我将 gcc 更改为 g++ 并在我的 makefile 中运行这一行:

编辑:

 g++ -c $< -o $@ -std=c++0x -lstdc++

我得到一个错误。但是如果我删除“-std=c++0x”并再次运行 make.. 一切都很好。

但是如果我运行我的“make clean”,我必须重新做一遍..

当我将程序放回我的学校服务器时,这会搞砸一切吗?或者只要我在服务器上有一个与我的 MacBook 上的 makefile 不同的 makefile 就可以了吗?

有人能帮我解释一下为什么会发生这种情况以及我该如何解决它吗?

这是我第一次运行 make 时的 makefile:

OBJECTS = Ammunition.o Armor.o Consumable.o 
HEADERS = Ammunition.h Armor.h Consumable.h 

all: Jhack

%.o: %.cpp $(HEADERS)
    g++ -c $< -o $@ -std=c++0x

Jhack: $(OBJECTS) main.o
    g++ -o Jhack $^

clean:
    rm -f *.o Jhack

run: Jhack
    ./Jhack

谢谢。

【问题讨论】:

  • 那么,你得到了什么错误,你使用的是什么编译器? -std=c++0x-lstdc++ 不可互换。
  • 你的makefile叫什么名字?
  • @juanchopanza GNU/g++
  • @Justin 好的,只是检查一下你没有叫它 Jhack 什么的,人们对各种奇怪的事情做了。所以你是说当你运行make clean时,你的makefile被删除了?还是我完全误读了这个问题?
  • @john 完全可以理解。当我运行干净时,makefile 很好。但是我使用标题行运行它:“g++ -c $

标签: c++ compilation linker makefile gnu


【解决方案1】:

首先,对于 Linux GNU C 编译器,gcc 是 C 编译器,而 g++ 是 C++ 编译器。这意味着当你用 gcc 编译时,你所有的错误信息基本上都是在说,“我不知道这些奇怪的语法是什么。”

您的学校没有使用 Linux 服务器,或者“gcc”可能有指向 c++ 编译器的链接。或者核心 make 规则正在用 g++ 替换您的编译器选择。

我认为在这方面您无需担心太多。只要记住区别,并可能在您的 makefile 中用宏替换 gcc 和 g++。

至于 -std 选项,这是选择您要编译的 C++ 标准的版本。由于您的某些代码需要 2011 C++ 标准,因此您需要使用 -std 选项指定它。如果您查看您的 g++ 手册页,它应该会告诉您支持哪些选项。

你可以试试-std=c++0x-std=c++11-std=gnu++11

其中任何一个都应该为您提供所需的功能。根据我搜索的内容,您不需要指定 -std=stdc++,因为 我认为默认情况下 g++ 包含它。

【讨论】:

  • GCC 很早以前就变成了“Gnu Compiler collection。它知道.cpp 是一个C++ 文件,并且是这样编译的。同样,.c 是一个 C 文件并按此编译。-x &lt;language&gt; 覆盖它,但默认为 -x none,自动选择。
  • @serge 好的,这更有意义。但是,我尝试了所有这 3 个,但我仍然遇到错误。编程的挫败感。
  • @MSalters 我也是这么想的,只是我永远无法使用gcc 成功构建cpp 代码,而g++ 可以工作。我刚刚意识到 gcc 不包含 stdc++ 库,因此它没有将正确的库要求传递给链接器。我需要将-lstdc++ 添加到 gcc 行。
【解决方案2】:

您可能正在使用旧的实验版本的 GCC。 cmets 中的“ConceptGCC”和-std=c++0x 标志告诉我。现代 GCC 变体将使用 -std=c++11

你永远需要使用 g++ 代替 gcc。这只是一种方便,因此您不需要传递编译 C++ 所需的所有 gcc 选项。特别是,-lstdc++ 被 g++ 隐含。

由于您使用的是相当不寻常的“ConceptGCC”包,我建议您将其替换为普通的 GCC 版本 4.8.0。

要调试 make 正在尝试执行的操作,请运行 make -n。然后,您可以手动运行这些命令以准确查看发生了什么。

【讨论】:

  • “现代”,如 GCC 4.7.1 之后的版本。 -std=c++11 很久以前没有添加。
  • 嗯。我有 4.7.1。我尝试将其改回 gcc 而不是 g++ 并显示更多错误?
  • @justin:然后问一个新问题。请包括实际的命令行和产生的错误文本。
  • @Justin:运用常识,大多数错误可能是相似的。您评论中的错误(此文件需要 ISO C++ 2011 标准的编译器和库支持...必须使用 -std=c++11 启用...)是应该出现的错误的一个很好的例子原来的问题。 std::mt19937 确实是 ISO C++11 标准中的新内容,这就是您需要 -std=c++11 的原因。
  • @MSalters 是的,这是有道理的。但是我尝试将其添加到我的 makfile 的每一种方式,都会出现更多错误。我无法正确使用语法。那好吧。我放弃。我在这上面浪费了太多时间,只是为了调试我的代码。只是在浪费大家的时间。感谢您尝试帮助我。
【解决方案3】:

贾斯汀,我不知道 std=c++0x 做了什么(我查了一下,但我不知道哪些“实验性功能”可能会受到影响...),但如果删除它有帮助,那就删除它.

在我看来,您所描述的内容就像某些对象需要 std=c++0x 标志,而有些则不会使用它构建。你会尝试只删除标志,清理然后重建吗?

最坏的情况 - 删除变量规则并为每个目标文件编写三个不同的规则。

【讨论】:

  • 我认为是让我在指向一个对象时做“this->”。我想我已经尝试过了,但我会很快再做一次。好吧,我实际上有 18 个目标文件,但为了简单起见,我把它们中的大部分都去掉了。
  • 以下是错误:/opt/local/include/gcc47/c++/bits/c++0x_warning.h:32:2: error: #error 此文件需要 ISO 的编译器和库支持C++ 2011 标准。此支持目前是实验性的,必须使用 -std=c++11 或 -std=gnu++11 编译器选项启用。在 Creature.h:5:0 包含的文件中,来自 Creature.cpp:1: DungeonLevel.h:12:45: error: 'std::mt19937' has not been declared DungeonLevel.h:28:30: error: ' >>' 应该是嵌套模板参数列表中的 '> >' ......还有几行
  • 好的,所以至少 Creature.o 肯定需要它。包含标志时会出现什么错误?希望它会影响不同对象的构建。
  • 大量警告。还有一些在建筑中找不到的东西。然后是:“物品的类型信息”,引用自:弹药中的弹药类型信息.o 盔甲中的盔甲类型信息。 ItemFactory.o 中的 ItemFactory() ItemFactory::ItemFactory() 在 ItemFactory.o ... ld:未找到架构 x86_64 collect2 的符号:错误:ld 返回 1 个退出状态
  • 我下载了 ConceptGCC 包。你知道我需要把它放在哪里才能让它工作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多