用错误的标志顺序编译后删除* .cpp文件?

时间:2017-01-25 14:46:55

标签: c++ makefile

我真的需要你的帮助! 我的makefile有问题。错误很常见:

makefile:11: recipe for target 'exec' failed

我的makefile如下所示:

CC = g++
PY = python
FLAGS = -std=c++11 -O3

all: main exec data

main: main.cpp
    $(CC) $(FLAGS) -o $@ $<

exec: main
    time ./$<

data: plot.py main
    $(PY) $< 

就我而言,没有错,但我仍然得到错误,也许main.cpp没有编译? 无论如何,我然后尝试(出于好奇):

g++ -std=c++11 -O3 -o main.cpp main

然后我收到了这个错误:

main: In function `_start':
(.text+0x1360): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.text+0x0): first defined here
main: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.fini+0x0): first defined here
main:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.rodata.cst4+0x0): first defined here
main: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.data+0x0): first defined here
main:(.rodata+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtbegin.o:(.rodata+0x0): first defined here
main: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.init+0x0): first defined here
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtend.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
main:(.data+0x8): first defined here
/usr/bin/ld: error in main(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status

现在我的main.cpp已经不见了。实际是什么..我怎样才能恢复它?我有一个旧版本,因为我使用git,但它还没有完成,我真的需要这个版本。

3 个答案:

答案 0 :(得分:3)

  

错误很常见

这是制造错误。之前它显示了什么?它完全运行编译器了吗?有编译错误吗?它是什么?

我在下面解决了您的近似问题,但原始问题是编译错误。您正在关注构建目标失败的事实,而不是理解为什么失败。

构建总是失败:非常普遍,因为代码中存在错误,并且很少因为先前工作的makefile中的错误。因此,在开始更改makefile或手动运行编译器之前,通常需要担心理解和修复编译器错误。

  

现在我的main.cpp已经不见了。实际是什么..

好吧,在

g++ -std=c++11 -O3 -o main.cpp main

选项-o filename告诉g ++将 filename 用于输出。因此,它为输出打开main.cpp并破坏了内容。

你的意思是

g++ -std=c++11 -O3 -o main main.cpp

这是一个容易犯的错误,这就是我们为我们构建系统来完成这些工作的原因。和备份。和版本控制。

将来,您只需键入make main即可选择单个目标,并让 告诉您它正在做什么。

  

我该如何恢复?

从编辑器,版本控制,备份或文件系统级别的快照,如果你有一个奇特的SAN,或者在极端情况下,从内存中。

没有什么能教会良好的源代码控制和备份习惯,比如必须从头开始重写。

  

不再有main.cpp文件了。究竟是为什么?

构建失败时,删除了不完整的输出文件。

考虑一下如何使作为参考。您有一个名为main的目标,因此它会检查名为main的文件是否存在。

  • 如果存在main,它会查看依赖项,并查看这些文件是否比main更新
  • 更新
  • 如果认为main应该(重新)生成(它不存在或者比依赖项更旧),它会运行你给它的规则

现在,如果g ++在编译失败后留下了main的空(或不完整)版本,那么下次构建时如何知道重新生成它?

编译失败时删除输出文件至关重要,否则make将无法正常工作。您还有一个目录,其中包含空的或损坏的部分编译的可执行文件和目标文件,这听起来不是一个好主意。

在其他新闻中,您的exec目标不会创建名为exec的文件。这应该是.PHONY规则。所以,可能应该data

答案 1 :(得分:2)

问题是:

insert

指定输出应放在g++ -std=c++11 -O3 -o main.cpp main 中的位置。您尝试编译main.cpp并将结果存储在main中。由于编译失败,编译停止后将删除输出文件。所以没有main.cpp

答案 2 :(得分:1)

这很简单:只需在编辑器中再次保存文件即可。

要执行此操作,请按C-x C-w并再次键入文件名。