我有一个头文件列表,我想使用 Makefile 立即编译它们。然而,其中一些在汇编中具有外部定义的函数。如果是这种情况,则目录
.s
中存在一个同名文件(但扩展名为 ./asm
)。例如,如果./r1.hpp
需要将程序集文件链接到其中,那么也会有./asm/r1.s
。因此,我想出了以下 Makefile:
CXXFLAGS := @compile_flags.txt
SRC_FILE:= ./test.cpp
HDR_DIRS:= $(wildcard ./v[0-9]*)
.PHONY: help clean $(HDR_DIRS)
.DEFAULT_GOAL := help
help:
@echo "Please specify a target to run."
%.o: %.s
as $< -o $@
# rule 1
%.out: %.hpp ./asm/%.o $(SRC_FILE)
g++ $(CXXFLAGS) $(SRC_FILE) $(word 2, $^) -o $@ -I. -include $<
# rule 2
%.out: %.hpp $(SRC_FILE)
g++ $(CXXFLAGS) $(SRC_FILE) -o $@ -I. -include $<
$(HDR_DIRS): %:
$(MAKE) $(patsubst %.hpp,%.out,$(wildcard $@/r[0-9]*.hpp))
clean:
@if [ -z "$(DIR)" ]; then \
echo "Error: DIR is not specified. Please set DIR to the target directory."; \
exit 1; \
fi; \
echo "Cleaning files in $(DIR) ..."
@rm -f $(DIR)/*.out $(DIR)/asm/*.o
这里,我希望如果可能的话应用
rule1
,如果没有相应的汇编文件则应用rule2
(意味着.s
文件不需要链接它)。然而,无论我尝试什么,rule2
总是被调用。
我设法使其工作的唯一方法是将 .out
中的 rule1
更改为 .obj
但我需要相同的扩展来进行进一步处理。我还希望 .s
文件作为依赖项进行跟踪,因为它们可以更改,然后需要重新编译文件。
我怎样才能实现这个目标?
注意: 我也尝试过使用条件依赖:
%.out: %.hpp $(wildcard $(patsubst %.hpp,%.s,$(dir $<)asm/$(notdir $<)))
@echo $(word 2, $^)
但是这个通配符总是扩展为空字符串,我不明白为什么。
您可以让
make
生成一个 makefile,该文件显式覆盖适用于此情况的规则。
SFILES := $(wildcard *.s)
DEPDIR := .dep
DEPFILES := $(SFILES:%.s=$(DEPDIR)/%.d)
include $(DEPFILES)
$(DEPDIR): ; @mkdir $@
.PRECIOUS: $(DEPDIR)/%.d
$(DEPDIR)/%.d: %.cpp | $(DEPDIR)
echo "$*.out: $*.hpp ./asm/$*.o $$(SRC_FILE)" > $@
g++ $$(CXXFLAGS) $$(SRC_FILE) $$(word 2, $^) -o $$@ -I. -include $$<" >> $@