【问题标题】:'file too short' error on g++ when compiling .o file编译.o文件时g ++上的“文件太短”错误
【发布时间】:2020-11-17 22:48:35
【问题描述】:

这是错误:

g++  -lpthread -pthread -std=c++11 -g -D_GNU_SOURCE  src/QuoridorMain.o src/Tree.o src/utility.o src/Game.o src/storage.o -o qbot
/usr/bin/ld: error: src/QuoridorMain.o: file too short
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: qbot] Error 1

这是我正在使用的 Makefile。

# Makefile for qbot

# Compiler options
CXX = g++ # use g++ compiler
CXXFLAGS = -lpthread -pthread -std=c++11 -g -D_GNU_SOURCE -no-pie# openmp and pthread, g for debugging


.SUFFIXES: .o .cpp
OFILES = src/QuoridorMain.o src/Tree.o src/utility.o src/Game.o src/storage.o

qbot: $(OFILES)
    $(CXX) $(CXXFLAGS) $(OFILES) -o qbot
    @echo Produced qbot executable 

clean: 
    $(RM) *.o *~


# Dependency rules for *.o files
src/Tree.o: src/Tree.cpp src/Tree.h src/utility.cpp src/Global.h
src/QuoridorMain.o: src/QuoridorMain.cpp src/Tree.cpp src/Game.cpp src/Global.h
src/utility.o: src/utility.h src/utility.cpp src/Global.h 
src/Game.o: src/Game.cpp src/Game.h src/Global.h
src/storage.o: src/storage.cpp src/storage.h

我不是很擅长确定 makefile 中什么是必要的,什么是杂乱无章的,而链接器错误通常是我的失败。话虽这么说,这之前编译得很好,我认为在完美编译和这个错误之间唯一改变的是添加了一些 std::cout 语句。所以我很不知道发生了什么。

也许相关的东西:与我开发大部分代码的计算机相比,我正在一台新计算机上进行编译,并且之前遇到了 ld 相关错误,我通过添加 -no-pie 标志修复了该错误。但是,这对我来说是有意义的,即使删除 -no-pie 标志现在也会得到相同的编译错误。另外:我的代码运行时可能存在重大错误。早些时候,根据某些std::cout 语句是否被注释掉,我在运行期间得到段错误或非段错误。有人告诉我这是其他地方出现重大问题的迹象,但如果您能具体说明这些问题通常是什么,以及它们现在将如何影响编译而不仅仅是运行时,我将非常感激。谢谢!

编辑:根据评论者的建议,我已从 .o 依赖规则中取出所有 .cpp 文件。在make clean 之后,我仍然收到同样的错误。我怀疑我需要做更多的事情才能让它真正工作,而不是仅仅删除 .cpp 文件,但这似乎不是直接的问题。

【问题讨论】:

  • 您的 cpp 文件不应依赖于其他 cpp 文件。除此之外,如果你make clean,问题会消失吗?
  • 您永远不会将 C++ 文件编译为目标文件。
  • 不,make clean 没有帮助。是否有特定的最佳实践可以帮助强制执行无 cpp 依赖项?我不久前就这样做了,不记得确切的原因,但当时它确实奏效了。
  • 哦,呵呵。您的make clean 不会删除src 中的文件。您可能应该将该配方更改为rm -f $(OFILES)make -B src/QuoridorMain.o 产生什么?那应该无条件地重新制作该文件。
  • @Botje 这很尴尬。这似乎是问题所在。我仍然不确定问题出在哪里,或者为什么它之前工作,但似乎自项目开始以来我还没有做过真正的make clean。有没有办法将评论标记为正确?谢谢!

标签: c++ makefile linker g++ ld


【解决方案1】:

核心问题是您的 .o 文件在过去的某个时间被损坏了。

第二个问题是您的 clean 目标实际上并没有清理 OFILES,因为它只删除了 *.o,而不是 src/*.o

## EDIT: removed -lpthread
CXXFLAGS = -pthread -std=c++11 -g -D_GNU_SOURCE -no-pie # openmp and pthread, g for debugging

OFILES = src/QuoridorMain.o src/Tree.o src/utility.o src/Game.o src/storage.o

## EDIT: Used $@ and $^ instead
qbot: $(OFILES)
    $(CXX) $(CXXFLAGS) $@ -o $^
    @echo Produced qbot executable 

## EDIT: fixed clean target and designated it as .PHONY, which stops Make from looking
## EDIT: for a file named "clean"
.PHONY: clean
clean: 
    $(RM) -f qbot $(OFILES) *~

## EDIT: Removed .cpp files from dependency list.
## EDIT: Keeping the similarly-named cpp files, even though they are redundant.
# Dependency rules for *.o files
src/Tree.o: src/Tree.cpp src/Tree.h src/Global.h
src/QuoridorMain.o: src/QuoridorMain.cpp src/Global.h
src/utility.o: src/utility.cpp src/utility.h src/Global.h 
src/Game.o: src/Game.cpp src/Game.h src/Global.h
src/storage.o: src/storage.cpp src/storage.h

【讨论】:

    【解决方案2】:

    您写道目标文件依赖于您的 C++ 文件,但您没有包含从 C++ 文件生成目标文件的规则。您可以看到您从未使用.cpp 文件参数调用g++。我认为正在发生的是make,没有看到规则,只是创建了空的目标文件。

    【讨论】:

    • ... 除了make 具有将cpp 文件编译成目标文件的内置规则。
    • @Botje 啊。好吧,我一般不使用这些。可能是由于那里的 .h 文件。可能正在阻止生成隐式规则。
    • 我添加了一个编辑以添加我已从 .o 依赖规则中删除所有 .cpp 文件。此外,昨天使用您在帖子中看到的确切(屠宰)依赖规则编译得很好。我知道这不是最佳做法,但至少看起来确实达到了我的预期。
    • @EamonCollins 您不应该将*.h 文件提供给编译器。这些只是被包括在内,而不是被制作成目标文件。检查一下可能吗?也不要从 *.o 文件的依赖项列表中删除 *.cpp 文件。评论者@Botje 说没有*.cpp 文件取决于*.cpp 文件,而您似乎没有。只需自己添加一条规则即可创建目标文件。
    • @Anonymous1847 不,隐式规则的格式为“%.o: %.cpp”。 OP 所做的只是添加额外的 dependencies,而不是额外的 inputs
    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2011-07-29
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    相关资源
    最近更新 更多