我只是在学习GNU make,但是在使用.d(依赖)文件时,我在链接时遇到了麻烦。有人可以通过错误指向我正确的方向:...../part1.o: file not recognized: File truncatedrecipe for target 'bin/target/prog' failed
这是一个简单的程序,包含:main.cpp,part1.cpp,part1.h,part2.cpp,part2.h
其中part1和part2具有打印内容的方法。
这是在运行make时从终端发出的:
我不明白为什么我会因一次使用#pragma而收到警告?
stud@GoldenImageASE:~/Desktop/ISU/L1/2$ make ARCH=target -f Makefile.th
Compiling...part2.cpp
arm-devkit-g++ -MTbuild/target/part2.o -MM -I. part2.cpp > build/target/part2.d
Compiling...part1.cpp
arm-devkit-g++ -MTbuild/target/part1.o -MM -I. part1.cpp > build/target/part1.d
Compiling...main.cpp
arm-devkit-g++ -MTbuild/target/main.o -MM -I. main.cpp > build/target/main.d
object file....main.o
arm-devkit-g++ -I. -c main.cpp part1.h part2.h > build/target/main.o
part1.h:1:9: warning: #pragma once in main file
#pragma once
^
part2.h:1:9: warning: #pragma once in main file
#pragma once
^
object file....part1.o
arm-devkit-g++ -I. -c part1.cpp > build/target/part1.o
object file....part2.o
arm-devkit-g++ -I. -c part2.cpp > build/target/part2.o
arm-devkit-g++ -I. -o build/target/main.o build/target/part1.o build/target/part2.o -o prog
build/target/part1.o: file not recognized: File truncated
collect2: error: ld returned 1 exit status
Makefile.th:27: recipe for target 'bin/target/prog' failed
make: *** [bin/target/prog] Error 1
我的Makefile位于以下位置:
# Variables
SOURCES=main.cpp part1.cpp part2.cpp
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)
EXE=prog
CXXFLAGS =-I.
# Making for host
# > make ARCH=host
ifeq (${ARCH},host)
CXX=g++
BUILD_DIR=build/host
EXE_DIR=bin/host
endif
# Making for target
# > make ARCH= target
ifeq (${ARCH},target)
CXX=arm-devkit-g++
BUILD_DIR=build/target
EXE_DIR=bin/target
endif
$(addprefix ${EXE_DIR}/,$(EXE)): $(addprefix ${BUILD_DIR}/,$(DEPS)) $(addprefix ${BUILD_DIR}/,$(OBJECTS))
# << Check the $(DEPS) new dependency
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -o $(addprefix ${BUILD_DIR}/,$(OBJECTS))
$(addprefix $(BUILD_DIR)/, %.o): %.cpp
@echo "object file...."$*.o
$(CXX) $(CXXFLAGS) -c $^ > $@
# Rule that describes how a .d ( dependency ) file is created from a .cpp
# Similar to the assigment %. cpp -> %.o
${BUILD_DIR}/%.d: %.cpp
@mkdir -p $(dir $@)
@echo "Compiling..."$<
$(CXX) -MT$(@:.d=.o) -MM $(CXXFLAGS) $^ > $@
debug:
@echo "DEPS: "$(DEPS)"\n"
@echo "OBJ: " $(addprefix ${BUILD_DIR}/,$(OBJECTS))"\n"
@echo "EXE: " $(addprefix ${EXE_DIR}/,$(EXE))"\n"
.PHONY:clean
clean:
rm -f $(EXE) $(addprefix ${BUILD_DIR}/,$(DEPS)) $(addprefix ${BUILD_DIR}/,$(OBJECTS))
ifneq ($(MAKECMDGOALS),clean)
-include $(addprefix ${BUILD_DIR}/,$(DEPS))
endif
最佳答案
您没有正确编译目标文件。 g++
不会将文件输出到stdout,而是将它们直接写入本地。如果要将目标文件放在特定目录中,则需要使用-o
选项:
$(BUILD_DIR)/%.o: %.cpp | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $^ -o $@
^^^^^^
$(BUILD_DIR):
@mkdir -p $@
另外,您正在错误地构建可执行文件。依赖关系不足,您没有列出目标。您会想要这样的:
$(EXE_DIR)/$(EXE) : $(addprefix $(BUILD_DIR),$(OBJECTS)) | $(EXE_DIR)
$(CXX) $(CXXFLAGS) -o $@ $^
$(EXE_DIR):
@mkdir -p $@
这将从目录中的二进制文件创建仅订购的依赖项,并正确构建二进制文件。请注意,您不应从目标上依赖
.d
文件。那没有什么意义。相反,您构建.o
的规则也应该简单地构建.d
(该规则当前遭受与.o
规则相同的问题):# build the .o and the .d in one go
$(BUILD_DIR)/%.o : %.cpp | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -o $@ -c $< -MP -MMD -MF $(@:.o=.d)
从编辑的角度来看,通常存在这样的倾向,即在SHOUTY_CAPS中的MAKEFILES中写入所有变量。这比仅使用
snake_case
困难得多。小写字母可以正常工作。关于c++ - Makefile-.o : file not recognized: File truncated?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39438064/