我的bash脚本中有此命令
find . -type f -name "*.c" -execdir bash -c "f={}; kos-cc $KOS_CFLAGS -c {} -o $PWD/\${f%.c}.o" \;
它的工作是递归地在当前目录($ PWD)中搜索.c文件,用我的“ kos-cc”编译器进行编译,然后将所有.o文件输出到当前工作目录中。
我想将我的bash脚本的一部分移到一个makefile中,这行是最后一个使我难堪的行。我知道如何制定规则来编译目录A中的c文件并将.o文件输出到目录B中,但是这里目录A并不总是相同的(因为我也需要处理子目录)。如何使用规则或命令在Makefile中执行等效任务?
答案 0 :(得分:0)
这不是一件容易的事,因为您的源位于不同的目录中,简单的make模式规则无法轻松地处理此问题。但是使用slightly more advanced make features可以做到:
SRC := $(shell find . -type f -name "*.c")
OBJ := $(patsubst %.c,%.o,$(notdir $(SRC)))
.PHONY: all
all: $(OBJ)
define COMPILE_rule
$$(patsubst %.c,%.o,$$(notdir $(1))): $(1)
kos-cc $$(KOS_CFLAGS) -c -o $$@ $$<
endef
$(foreach s,$(SRC),$(eval $(call COMPILE_rule,$(s))))
.PHONY: clean
clean:
rm -f $(OBJ)
当心:您可能在不同目录中有多个具有相同基本名称的源文件。如果发生这种情况,最终将导致对象文件名的致命冲突...
编辑(添加冲突检测):
以下内容可检测到冲突情况并发出错误消息(将error
替换为warning
或info
,具体取决于您为这些冲突分配的严重性级别):
SRC := $(shell find . -type f -name "*.c")
OBJ := $(patsubst %.c,%.o,$(notdir $(SRC)))
ifneq ($(words $(OBJ)),$(words $(sort $(OBJ))))
$(error object file name conflicts detected)
endif
({sort
进行排序并删除重复项,words
返回其字符串参数中以空格分隔的单词数)。