Linux 使用不同目录中的源/对象文件生成文件
我有一个具有以下目录结构的项目:Linux 使用不同目录中的源/对象文件生成文件,linux,makefile,compilation,Linux,Makefile,Compilation,我有一个具有以下目录结构的项目: $tests/ $doc/ | |-makefile +------+-------+ | | | | tests/ test1/ test2/ test3/ | | | | test1.rst, test2.rst,
$tests/ $doc/
| |-makefile
+------+-------+ |
| | | tests/
test1/ test2/ test3/ |
| | | test1.rst, test2.rst, test3.rst
test1.e test2.e test3.e
$doc/tests
目录中的文件,例如test1.rst
是从$tests/test1/test1.e
创建的。makefile指定源文件在$tests/*/*.e
中,目标文件在$doc/tests/*.rst
中时出现问题
我看到过几个类似的问题,但还没有找到正确的makefile语法
此makefile适用于单个文件示例
SOURCES = $(wildcard $(tests)/*/*.e)
OBJECTS = $(addprefix $(doc)/tests/,$(notdir $(SOURCES:.e=.rst)))
# single file trial
SRC = $(tests)/test1/test1.e
OBJ = $(doc)/tests/test1.rst
$(OBJ): $(SRC)
debugvars:
@echo SOURCES=$(SOURCES)
@echo OBJECTS=$(OBJECTS)
# define how to create any RST file from a testcase
%.rst:
$(scripts)/wr_rst.py --infile $<
# define how to create an RST file from a testcase
%.rst: %.e
$(scripts)/wr_rst.py --infile $<
.e.rst:
$(scripts)/wr_rst.py --infile $<
.SUFFIXES: .e .rst
(这个问题看起来很熟悉——我几乎可以发誓,有人问过并回答了一个基本相同的问题。)
让我们分阶段进行。我们可以一次写一条规则:
$(doc)/tests/test1.rst: $(tests)/test1/test1.e
...
但那太乏味了。这种情况迫切需要一种通配符解决方案,例如模式规则,但是Make的一个严重缺点是它对通配符的粗糙处理。重复使用通配符的模式规则:
$(doc)/tests/%.rst: $(tests)/%/%.e
...
这是不允许的。但是我们可以使用eval
编写规则:
define template
$(doc)/tests/$(1).rst: $(tests)/$(1)/$(1).e
use some tool to build $$@ from $$<
endef
$(eval $(call template,test1))
$(eval $(call template,test2))
...
然后,我们可以将其委托给通配符
,并使用相同的列表来构建目标文件列表,而不是编写测试列表:
TESTS := $(notdir $(wildcard $(tests)/*))
TARGETS := $(patsubst %,$(doc)/tests/%.rst,$(TESTS))
all: $(TARGETS)
把所有这些放在一起很简单,但是这个答案越来越长了。事实上,在本例中是
$(tests)。test1.test1.e
。感谢Beta,这非常有效。在我的教育中,没有办法创建新的规则,以便对于任何目标.rst文件,make在e源上以相同的名称启动脚本,而不管源/目标目录如何.e.rst:$(脚本)/wr_rst.py--infle$
define template
$(doc)/tests/$(1).rst: $(tests)/$(1)/$(1).e
use some tool to build $$@ from $$<
endef
$(eval $(call template,test1))
$(eval $(call template,test2))
...
TESTS := test1 test2 ...
$(foreach TEST,$(TESTS),$(eval $(call template,$(TEST)))
TESTS := $(notdir $(wildcard $(tests)/*))
TARGETS := $(patsubst %,$(doc)/tests/%.rst,$(TESTS))
all: $(TARGETS)