【发布时间】:2022-01-11 11:06:50
【问题描述】:
我正在构建一个结构如下的项目:
- Makefile
- main.cpp
- util.h
- subsrc/
- one.cpp
- two.cpp
我将 Makefile 设置为输出到构建目录:
all: $(BIN_FILE)
$(BIN_FILE): $(OBJ_FILES)
mkdir -p $(BIN_DIR)
g++ $^ -o $@
$(OBJ_DIR)/%.o: %.cpp
mkdir -p $(OBJ_DIR)
g++ -c $^ -o $@
$(OBJ_DIR)/subsrc/%.o: subsrc/%.cpp
mkdir -p $(OBJ_DIR)/subsrc
g++ -c $^ -o $@
clean:
rm -rf $(BUILD_DIR)/*
但是,当我手动运行 g++ 时,我也看到了这个问题,所以我认为它与 Makefile 无关。
我可以从干净构建,一切正常。问题是当我更改其中一个 subsrc 文件并尝试通过 make 或自己运行这些命令重新编译时:
g++ -c subsrc/one.cpp -o build/obj/subsrc/one.o
g++ build/obj/main.o build/obj/subsrc/one.o build/obj/subsrc/two.o -o build/bin/prog
如果我这样做,在 one.cpp 中所做的更改不会反映在二进制输出中。如果我重新编译main.cpp(或者,当然,整个项目),它工作正常。这不是 g++ 没有正确覆盖文件的问题,因为即使我在运行上述命令之前rm build/obj/subsrc/one.o 和/或rm build/bin/prog,我仍然看不到更改。这对我来说毫无意义,我也不知道发生了什么。
编辑:我在这里上传了一个最小的可重现示例。 https://github.com/scatter-dev/so_70242118_min_repro
复制说明:
- 使用
make或运行上面的 g++ 命令进行构建。 - 运行程序以确保它已正确构建。
- 在
one.cpp中更改doWork函数的输出。保存到磁盘。 - 重新运行
make并注意one.o文件已重新编译,prog已使用链接器重新创建。 - 再次运行程序,看到输出没有变化。
在评论者的建议下,我在步骤 1 和步骤 4 之间检查了 one.o 和 prog 的 md5sum,它们确实是相同的。 即使我在重新编译之前删除了one.o,情况仍然如此。是的,我确信 one.cpp 正在保存到磁盘(它的 md5sum 确实发生了变化,而且 make clean && make 将使用新的更改进行编译)。
【问题讨论】:
-
你怎么知道修改没有反映在二进制文件中?
-
请显示minimal reproducible example。更改可能在头文件中吗?
-
一个常见的原因是更改只在编辑器中,并没有保存到磁盘。
-
您可以在更改前后检查 build/bin/prog 的 md5sum,看看它是否正在更新。对 one.o 和 one.cpp 执行相同的操作。这可能会缩小您对问题发生位置的搜索范围(注意:假设 one.cpp 中没有
__DATE__字符串...) -
@AlanBirtles 我添加了一个最小的可重现示例。更改不在头文件中。