У меня есть небольшой проект, который создает несколько целей из тех же исходных файлов. Цели требуют создания исходных файлов с различными флагами компиляции. Это на самом деле на cygwin, поэтому я буду использовать это как конкретный пример, хотя, я полагаю, это общая проблема.Как обеспечить, чтобы объектные файлы скомпилированы с правильными настройками в Makefile с несколькими целями MAKE.
Таким образом, это будет пример Makefile:
a: CFLAGS =
a: a.o c.o
b: CFLAGS = -mno-cygwin
b: b.o c.o
Это работает в принципе построение будет компилировать с CFLAGS неустановленным, а здание б откомпилироваться CFLAGS набора для -mno-Cygwin. Но только если c.o еще не существует.
Так делают
> make a b
в девственном каталоге первый будет компилировать a.c и к.ц с помощью пустого CFLAGS. Затем он попытается построить b, используя CFLAGS = -mno-cygwin. Но так как c.o уже существует, он не будет перекомпилировать c.c, что приведет к ошибкам компоновщика, поскольку объектные файлы должны иметь одинаковые настройки этого флага.
Опять же, cygwin-флаг - всего лишь один конкретный пример, и я ищу универсальное решение.
То, что я пытался это ввести дополнительную цель проверки текущего CFLAGS и удалить все объектные файлы, если он не соответствует:
ARCH = `echo $(CFLAGS)`
checkTarget:
[email protected] test "`cat .arch`" != "$(ARCH)"; then \
rm *.o; \
/bin/echo -n $(ARCH) > .arch; \
fi
Установки этой цели в качестве зависимости для двух целей гарантирует, что весь объект при необходимости файлы перекомпилируются.
a: CFLAGS =
a: checkTarget a.o c.o
b: CFLAGS = -mno-cygwin
b: checkTarget b.o c.o
Это, однако перекомпилирует каждый файл объекта, который является ненужным, и становится проблемой в более крупном проекте.
Есть ли лучший способ сделать это?
EDIT: В комментарии к единому ответу добавлен подсказку о том, что вы можете сделать объектные файлы зависимыми от содержимого CFLAGS. Я не могу понять, как это сделать, за исключением того, что они копят их во временный файл и сравниваются с предыдущими, а затем копируют это через зависящий файл. Нет ли лучшего способа?
Хороший ответ. Если проект большой, скажем, 50 объектных файлов, это будет работать, если количество файлов для перекомпиляции (c.c в примере) невелико. Если бы большинство потребовало перекомпиляции, эта стратегия стала бы неуклюжей, я думаю. Любые идеи для этого сценария? – thoni56
@ Томас Нильссон: это зависит от того, что вы пытаетесь оптимизировать. Если вы не хотите перекомпилировать 'c.c' больше, чем нужно, тогда вы должны хранить разные версии, и это лучший способ. Если вы не хотите хранить несколько 'c.o', но вы хотите перекомпилировать' c.o' только тогда, когда это необходимо, есть другой способ, небольшое улучшение вашего checkTarget. Я отредактирую свой ответ, чтобы включить его. – Beta
Хммм, если я правильно понимаю, checkTarget - это метка времени, чтобы, например, если вы создадите b, но b.o и c.o существует, checkTarget все равно вызовет правило сборки. Затем в командах вы устанавливаете сборку c.o в соответствии с CFLAGS. Если это ваше намерение, я не полностью удовлетворен (но опять же это может быть невозможно ;-), потому что мне постоянно нужно будет обновлять явные команды сборки по мере изменения моих требований. Я надеялся каким-то образом сделать каждый% .o зависимым от CFLAGS, используемого для его компиляции, и скомпилировать компиляцию, только если CFLAGS не совпадают. – thoni56