我只是在学习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/

10-09 01:06