我目前正在编写一个更大的 makefile,它将处理源文件的递归结构,并将它们放在目标目录中的相同递归结构中。基本上你可以假设这个 makefile:
DESTINATION_DIR = out
SOURCE_DIR = src
OBJECTS = out/abc.o out/subdir/test.o out/subdir/subdir/xyz.o
.PHONY: all
all: $(OBJECTS)
$(DESTINATION_DIR)/%.o: $(SOURCE_DIR)/%.c
@echo "$@ --- $<"
正如您所看到的,我正在尝试将依赖项中的 $(DESTINATION_DIR) 替换为 $(SOURCE_DIR) ,但这不起作用。我该如何解决这个问题?我什至尝试以这种方式使用替换脚本:
%.o: $(shell myreplacementscript.py "%.c" "$(DESTINATION_DIR)" "$(SOURCE_DIR)")
@echo "$@ --- $<"
但是百分号将被传递到我的脚本而不进行替换。那么我如何告诉它输出动态依赖于源文件呢?我需要将子目录保留在 OBJECTS 变量中,我无法展平结构。并且子目录是动态的,不是预定义的。
我搜索了其他有同样问题的人,但他们要么有平面对象,要么有递归 make,这在我的例子中不太适合,因为目录之间根据依赖关系进行互连。
摘要/错误消息:
它不会用 src/替换 OBJECTS 中的 out/。因此,错误消息是“Keine Regel vorhanden,um das Target »out/abc.o«,benötigt von »all«,zu erstellen。Schluss。”这是典型的错误“没有规则来制定目标......”。
完整的 makefile 可以在这里看到: Full Makefile
每当我将冒号的右侧与左侧的 %.html 分开时,它就可以工作,但我需要将源文件作为依赖项才能获得有效的增量构建(希望不创建依赖项文件)。
亲切的问候,
丹尼尔
最佳答案
使用GNU make扩展的解决方案并不是一个好方法。我建议不要使用任何 GNU Make 特定功能。首先它不便携。其次,它的语法很糟糕。使用有史以来发明的标准工具和技术。你的解决方案是——壳牌。您可以将 Makefile 包装到 shell 脚本中,并使用通用 shell 语言执行所有计算和字符串操作。举个例子:
src_files="file1.c file2.c file3.c"
cat > Makefile <<EOF
-
-
YOUR MAKEFILE STATIC STUFF GOES HERE
-
all: $(OBJECTS)
EOF
for file in $src_files; do
src="src/$file"
obj=`echo $file | sed 's/\.c$/\.o/'`
sources="$sources $src"
objects="$objects out/$obj"
cat >>Makefile <<EOF
$obj: $src
YOUR CODE HERE
EOF
done
cat >>Makefile <<EOF
SOURCES = $sources
OBJECTS = $objects
EOF
将脚本命名为“mkmf”并运行./mkmf。它将生成 Makefile。您可以对其进行参数化,使其变得非常强大和智能。无需使用稀疏且肮脏的 gnu make 扩展。
关于GNU Make - 如何处理目标文件中的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26023920/