2016-08-01 65 views
0

我有一堆文件(*.txt),我使用python脚本来分析并生成代码(*.cpp)。代码生成完成后,我希望将生成的代码编译到目标文件(*.o)中。gnu make两步编译过程

我想用gnu-make来设置它。我的问题是,我无法弄清楚一个可行的Makefile语法来完成这个。

这里有一些额外的细节,使这个困难:

因为我不知道有多少* .TXT档案如何存在摆在首位,我想用一个shell find命令来发现它们。

files := $(shell find $(TXT_FILE_DIR) -type f -name '*.txt')

不过,我还是想GNU-make的罚款依赖功能在这里工作。也就是说,如果有任何txt文件发生更改,我希望make自动发现这些更改并仅为这些更改生成新的.cpp文件,并将它们重新编译为.o文件。

我正在寻找一个解决方案,其中make可以并行运行(并尊重-j标志)并调用python脚本将*.txt文件转换为*.cpp文件。

我的操作系统是Linux。

[新信息]

谢谢Grexis,为您解答!但是,因为我在src和dst-paths之间有一些奇怪的映射关系,所以实际上我正在寻找一种不同的解决方案。这里

$(TXT_DIR)/a/XXX.*XXX/b/c/file1.txt -> $(CPP_DIR)/a/YYY/b/c/file1.cpp $(TXT_DIR)/a/XXX.*XXX/b/c/file2.txt -> $(CPP_DIR)/a/YYY/b/c/file2.cpp $(TXT_DIR)/b/XXX.*XXX/c/d/file3.txt -> $(CPP_DIR)/b/YYY/c/d/file3.cpp

注意,路径被操纵两次:

在这里翻译我的src和dst的路径时是“异类”的一个例子。因此,两个:

  1. $(TXT_DIR)替换$(CPP_DIR)
  2. 正则表达式XXX.*XXX被替换为固定字符串YYY

然而,由于其很难做到多个字符串替换在gnu-make,例如,gnu-make一次只支持一个%(干)字符串替换,我想我必须使用更高级的gnu-make语法。因此,我正在寻找一种方法来定义“每个.txt - >.cpp对的不同配方”。我曾尝试以下:

cleanPath = $(shell echo $(1) | sed s/XXX.*XXX/YYY/g) txt2cpp = $(subst $(TXT_DIR),$(CPP_DIR),$(patsubst %.txt,%.cpp,$(call cleanPath,$(1)))) txt2obj = $(subst $(TXT_DIR),$(OBJ_DIR),$(patsubst %.txt,%.o,$(call cleanPath,$(1)))) define analyse = $(2): $(1) python.py $(2) $(3) endef txt_files := $(shell find $(TXT_DIR) -type f -name '*.txt') cpps := $(foreach file,$(txt_files),$(eval $(call analyse,$(file),$(call txt2cpp,$(file)),$(call txt2obj,$(file))))) all: $(cpps)

然而,似乎我的python.py脚本不会被调用。这是为什么?

如果我将python.py的呼叫附在shell命令中,例如$(shell python.py $(2) $(3)),则实际调用python.py脚本。但是,使用shell命令会使并行性不可行。不幸的是,无法并行执行python.py脚本不适合我。

回答

0

如果每个文本文件都创建一个具有匹配名称的C++源代码(即'foo.txt'被处理成'foo.cpp'然后'foo.o'),有点不清楚。

假设它是一个直接关系,您要查找的功能称为Pattern Rules

TXT_FILES := $(wildcard $(TXT_FILE_DIR)/*.txt) 
OBJ_FILES := $(patsubst $(TXT_FILE_DIR)/%.txt,$(OUT_DIR)/%.o,$(TXT_FILES)) 

main: $(OBJ_FILES) 
    $(CXX) $(LDFLAGS) -o [email protected] $^ 

$(SRC_DIR)/%.cpp: $(TXT_FILE_DIR)/%.txt 
    $(PYTHON) process.py $< 

$(OUT_DIR)/%.o: $(SRC_DIR)/%.cpp 
    $(CXX) -c $(CPPFLAGS) -o [email protected] $< 

分解上面的代码片段。 $(TXT_FILES)设置为每个*.txt文件中的$(TXT_FILE_DIR),并在make中使用通配符操作。 $(OBJ_FILES)使用$(TXT_FILES)中所有值的模式替换。然后将每个obj文件作为依赖项添加到main可执行文件中。

如上链接的模式规则链接文档中说明的那样,每.o文件需要在$(SRC_DIR)关联.cpp文件(的自动变量[email protected]$^,和$<也记录在所提供的链接)。反过来,每个.cpp文件都需要具有相同名称的.txt

尽管你可能需要调整python脚本的确切调用。如果需要指定特定的输出文件,则应使用[email protected]自动变量。

顶部用于检测所有源文件的部分源自this answer

+0

我喜欢这个答案,但我认为通过将模式规则更改为_static模式规则_将会得到改善。在这种情况下很容易:'$ {OBJ_FILES}:$ {OUT_DIR} /%。o:$ {SRC_DIR} /%。cpp' – bobbogo