Я работаю над довольно крупным проектом на чистом C, и по разным причинам мы не используем CMake.
У нас есть хорошая система, которая использует различные команды оболочки, требующие минимального обслуживания.Он автоматически найдет новые заголовки и файлы 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.
Как только я это выясню, я смогу убедиться, что это тоже идет вверх по цепочке заголовочных файлов, но пока ямогу понять это, у меня нет причин работать над этим.