我的Makefile在BSD make报错但GNU make正常,如何实现兼容?
Makefile兼容GNU make与BSD make的问题处理
问题描述
我的Makefile在GNU make环境下可正常编译运行,但在BSD make中执行时报错:
bmake: don't know how to make .force_rebuild. Stop
希望调整Makefile以兼容BSD make,目前暂无移植计划,但预留未来兼容空间。
原Makefile内容
# Use the latest version of the compiler on Debian 12 OS, arm64 platform: CXX=g++-12 # Use the official standard; # Optimize for speed; # Stop on all warnings; # Do not include debug symbols: CXXFLAGS=-std=c++17 -O3 -Wall -Wextra -Werror -Wpedantic -pedantic-errors # The name of the resulting executable file: APP_NAME=auto-fan-control # The name of the C++ source code file: SRC_FILE=$(APP_NAME).cpp # Possibly not doing anything when using GNU make; # You may see this for an explanation: # https://www.gnu.org/software/make/manual/html_node/Special-Targets.html#index-POSIX_002dconforming-mode_002c-setting .POSIX: # You may see this for an explanation: # https://stackoverflow.com/a/70199176/1997354 # Force re-build work-around: .PHONY: .force_rebuild $(APP_NAME): .force_rebuild $(APP_NAME): $(SRC_FILE) @printf '%s' 'Compiling...' @$(CXX) $(CXXFLAGS) $(SRC_FILE) -o $(APP_NAME) @printf '%s\n' ' Done.' @strip -s $(APP_NAME) @printf '%s\n' 'Running program... ' @./$(APP_NAME)
测试环境(GNU make)
$ apt-cache policy make make: Installed: 4.3-4.1build2 Candidate: 4.3-4.1build2 Version table: *** 4.3-4.1build2 500 500 https://archive.ubuntu.com/ubuntu noble/main amd64 Packages 100 /var/lib/dpkg/status
GNU make下运行结果
$ learn-cpp /home/vlastimil/Development/cpp/rpi4-temperature-moninor--and-fan-control $ make Compiling... Done. Running program... 25.0°C
问题原因与修复
错误原因
GNU make允许标记为.PHONY的伪目标没有对应的规则定义,默认认为该目标始终需要更新;但BSD make对.PHONY目标的处理更严格,若伪目标没有对应的规则(哪怕是空规则),会尝试查找实际文件或可执行构建规则,找不到就会报错。
兼容修改方案
给.force_rebuild伪目标添加一个空规则,同时将目标的依赖合并为一个规则(提升兼容性)。修改后的Makefile如下:
# Use the latest version of the compiler on Debian 12 OS, arm64 platform: CXX=g++-12 # Use the official standard; # Optimize for speed; # Stop on all warnings; # Do not include debug symbols: CXXFLAGS=-std=c++17 -O3 -Wall -Wextra -Werror -Wpedantic -pedantic-errors # The name of the resulting executable file: APP_NAME=auto-fan-control # The name of the C++ source code file: SRC_FILE=$(APP_NAME).cpp .POSIX: # Force re-build work-around, compatible with GNU make and BSD make .PHONY: .force_rebuild .force_rebuild: # Combine dependencies into one rule for better compatibility $(APP_NAME): .force_rebuild $(SRC_FILE) @printf '%s' 'Compiling...' @$(CXX) $(CXXFLAGS) $(SRC_FILE) -o $(APP_NAME) @printf '%s\n' ' Done.' @strip -s $(APP_NAME) @printf '%s\n' 'Running program... ' @./$(APP_NAME)
修改说明
- 给
.force_rebuild添加空规则:.force_rebuild:,让BSD make能识别该目标的构建规则(空操作),同时不影响GNU make的行为。 - 将原有的两个
$(APP_NAME)规则合并为一个,显式声明所有依赖,避免不同make工具对多规则依赖合并的处理差异。
修改后,Makefile即可同时在GNU make和BSD make环境下正常运行。
内容的提问来源于stack exchange,提问作者Vlastimil Burián
相关产品推荐
相关产品推荐

