我正在使用纯C开展一个相当大的项目,由于各种原因我们没有使用CMake。
我们有一个很好的系统,它使用各种shell命令来要求很少的维护。它将自动查找新的标头和C文件,并将标头添加到依赖项中,并将编译C文件并将它们包含在输出中。但是,我们已经达到了对头文件所做的任何更改都成为问题的程度,因为它需要重新编译整个项目,而不仅仅是直接或间接包含它的C文件。
我已经在一个系统上工作,以确保作为依赖项添加的唯一头文件是C文件本身所需的头文件(递归地在树上)。
我原本以为我能够自己解决这个问题,但似乎make对扩展变量的规则相当不一致。
我提出的解决方案是尝试使用ag并从文件中获取所有包含。这按预期工作,我将它传输到tr中,以便我可以确保不添加任何换行符,从而搞乱make。我遇到的问题是确定要搜索的文件。这是它用于相关部分的配方:
$(GAMEOBJDIR)/%.o : $(GAMEDIR)/%.c $(shell ag -o '(?<=(^#include "))(.*?)(?=("$$))' $(GAMEDIR)/%.c | tr '\n' ' ')
$(CC) $(CFLAGS) $(if $(RELEASE),$(RELFLAGS),$(DBFLAGS)) -c -o $@ $<
问题是$(GAMEDIR)/%.c
正在扩展到src/game/%.c
而不是src/game/<filename>.c
。我不确定如何根据make的扩展规则来解决这个问题。
一旦我能弄明白这一点,我就能确保这一点也能解决这个问题,但是直到我能解决这个问题,我没有理由继续这样做。
答案 0 :(得分:1)
制定扩张的规则是完全一致的......但有时它们并不是人们想要的。这不是一回事:)
解释扩展规则in the manual。在您的情况下,您正在使用先决条件列表,这意味着在解析makefile时会扩展变量。这包括shell命令和所有其他变量。因为您正在使用模式规则,这意味着在解析makefile时它并不匹配任何特定文件,它只是定义模式规则本身。因此,%
无法在此展开。稍后,当make开始遍历依赖图并尝试找到构建目标的方法时,它将被扩展。
通常,您的方法无法有效工作。您可以使用Secondary Expansion推迟先决条件列表的这些部分的扩展。但是,这意味着每次make想要尝试使用这种模式时,它都会运行这些命令 - 这只会很慢。
您是否考虑过使用更标准的方法来管理检测先决条件?请尝试阅读this description,例如,看看它是否适合您。