Как убедиться, что объектные файлы скомпилированы с правильными настройками в Makefile с несколькими целями MAKE - PullRequest
2 голосов
/ 02 июля 2010

У меня небольшой проект, который строит несколько целей из одних и тех же исходных файлов.Цели требуют сборки исходных файлов с разными флагами компиляции.Это на самом деле на Cygwin, поэтому я буду использовать это в качестве конкретного примера, хотя я полагаю, что это общая проблема.

Так что это будет пример Makefile:

a: CFLAGS =

a: a.o c.o

b: CFLAGS = -mno-cygwin

b: b.o c.o

Это работает вВ принципе, сборка компиляции с CFLAGS не установлена, а компиляция b компилируется с CFLAGS, установленным в -mno-cygwin.Но только если co не существует.

Таким образом, выполнение

> make a b

в первичном каталоге сначала скомпилирует ac и cc с использованием пустых CFLAGS.Затем он попытается собрать b, используя CFLAGS = -mno-cygwin.Но поскольку co уже существует, он не будет перекомпилировать cc, что приведет к ошибкам компоновщика, поскольку объектные файлы должны иметь одинаковую настройку этого флага.

Опять же, флаг cygwin является лишь одним конкретным примером, и я ищууниверсальное решение.

Я попытался ввести дополнительную цель, проверяющую текущий CFLAGS, и удалить все объектные файлы, если она не совпадает:

ARCH    = `echo $(CFLAGS)`
checkTarget:
-@if 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

Это, однако, перекомпилирует каждый объектный файл, который не нужен, и становится проблемой в большом проекте.

Есть ли лучший способ сделать это?

РЕДАКТИРОВАТЬ: В комментариях к одиночному ответу есть подсказка, что вы можете сделать объектные файлы зависимыми от содержимого CFLAGS.Я не могу понять, как это сделать, кроме как поместить их во временный файл и сравнить с предыдущими, а затем скопировать в зависимый файл.Нет лучшего способа?

Ответы [ 2 ]

2 голосов
/ 03 июля 2010

Здесь нам нужны две (или более) версии c.o, скомпилированные с разными флагами и связанные в разные исполняемые файлы.Вы можете сделать это с помощью надуманных имен файлов, таких как c_for_a.o, но лучше хранить их в разных каталогах, for_a/ и for_b/:

a for_a/%: CFLAGS =

a: a.o for_a/c.o

b for_b/%: CFLAGS = -mno-cygwin

b: b.o for_b/c.o

(Если это не ясно, я могу заполнитьостальная часть Makefile.)

EDIT:
Если вы не хотите хранить несколько c.o, вам иногда придется перекомпилировать co.Возможно небольшое улучшение идеи checkTarget.

Когда вы создаете цель, подобную b, а c.o уже существует, имеет значение, был ли этот c.o построен с * 1020.* подходит для b, и вы используете checkTarget для записи этой информации. Но вам все равно, какие CFLAGS использовались, только если они были b CFLAGS.Поэтому вам не нужно ничего записывать в файл checkTarget, просто обновите его при создании новой цели:

a: CFLAGS =

b: CFLAGS = -mno-cygwin

# You may be able to combine the a and b rules...
a: a.o c.o checkTarget
    # build c.o
    touch checkTarget
    # build the target

b: b.o c.o checkTarget
    # build c.o
    touch checkTarget
    # build the target

# Need this to create checkTarget the first time
checkTarget:
    @touch $@
0 голосов
/ 24 июля 2010

Хотя там, где некоторые предложения о том, как сделать то, что я изначально просил здесь (на что указывает slowdog ), я принял решение принять Beta схема с разными именами делает шаг вперед и помещает все объекты для различных вариантов в подкаталоги, следуя описанию во втором предложении Beta в своем ответе на этот вопрос .

По сути, из-за этого мой Makefile выглядел следующим образом:

A : AOBJDIR = .a
AOBJECTS = $(addprefix $(AOBJDIR)/,$(ASRCS:.c=.o))

$(AOBJECTS): $(AOBJDIR)/%o: %.c
    $(CC) $(CFLAGS) -MMD -o $@ -c $<

$(AOBJDIR) :
    @mkdir $(AOBJDIR)

-include $(AOBJECTS:.o=.d)

a: $(AOBJDIR) $(AOBJECTS)
    $(LINK) ...

Итак, первая часть называет подкаталог, который будет использоваться для объектных файлов 'a', и создает список объектных файлов в этом каталоге.путем преобразования исходных имен файлов и добавления префикса подкаталога.

Затем следует правило по умолчанию для этих объектных файлов (с добавлением генерации зависимостей для хорошей меры).

Следующие два гарантируют, что подкаталогсуществует, и что информация о зависимостях включена.

Наконец, правило ссылки с дополнительной зависимостью от самого подкаталога к enубедитесь, что он создан, если он не существует.

Этот блок может быть повторен для b, в моем примере, путем замены всех a.Поэтому, если бы я только мог понять, как упаковать этот блок во что-то более общее, что можно параметризировать, я был бы счастлив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...