В gnu make могут ли предпосылки в статическом шаблонном правиле иметь разные суффиксы - PullRequest
7 голосов
/ 22 октября 2009

Наш make-файл компилирует исходные файлы .c с правилом статического шаблона:

OBJECTS = foo.o bar.o baz.o

$(OBJECTS): %.o: %.c
    $(CC) $< $(C_OPTIONS) -c -o $@

Мне нужно изменить один из файлов .c на файл Objective-C .m. Вызов компилятора одинаков для обоих типов источников, поэтому я хотел бы использовать одно и то же правило и просто настроить его, чтобы сделать его более гибким. Я бы не хотел менять переменную OPTIONS, потому что она также используется для шага связывания и т. Д.

Есть ли способ сделать указанное выше правило более гибким для размещения как файлов .c, так и .m?

Спасибо

Ответы [ 3 ]

7 голосов
/ 22 октября 2009

Мы можем добавить это или-или поведение в список вещей, которые Make должен делать легко, но это не так. Вот способ сделать это, используя «eval» для создания отдельного правила для каждого объекта.

define RULE_template
$(1): $(wildcard $(basename $(1)).[cm])
endef

OBJECTS = foo.o bar.o baz.o

$(foreach obj,$(OBJECTS),$(eval $(call RULE_template,$(obj))))

$(OBJECTS):
    $(CC) $&lt $(C_OPTIONS) -c -o $@ 

Обратите внимание, что это зависит от исходных файлов, которые уже существовали до запуска Make (foo.c или foo.m, но не оба). Если вы генерируете эти источники на одном шаге, это не сработает.

Вот менее умный, более надежный метод .

CPP_OBJECTS = foo.o bar.o
OBJECTIVE_OBJECTS = baz.o
OBJECTS = $(CPP_OBJECTS) $(OBJECTIVE_OBJECTS)

$(CPP_OBJECTS): %.o: %.c 

$(OBJECTIVE_OBJECTS): %.o: %.m 

$(OBJECTS):
    $(CC) $&lt $(C_OPTIONS) -c -o $@ 

РЕДАКТИРОВАТЬ: исправлено назначение объектов, благодаря Джонатан Леффлер.

1 голос
/ 22 октября 2009

Не просто скопировать в

$(OBJECTS): %.o: %.m
  $(CC) $< $(C_OPTIONS) -c -o $@
0 голосов
/ 22 октября 2009

Обращение к одному и тому же компилятору - просто счастливое событие. Обычно вы не компилируете код Objective-C с $(CC). Это просто странно.

Но так как вы идете жестким путем, я не буду публиковать решение «сделай правильно», в котором ты разделяешь цели С-цели от целей С на две разные $(OBJECTS) -подобные переменные и создаю два правила (что вы действительно должны сделать) . Слишком скучно. Взять взломать!

OBJC_FILES:=$(subst $(wildcard *.m))

real_name = `(test -h $(1) && readlink $(1) ) || echo $(1)`

$(OBJECTS): %.o: %.c
  $(GCC) $< $(C_OPTIONS) -c -o $(call real_name,$@)

$(OBJC_FILES): %.c: %.m
  ln -s $< $@

И Бог поможет тем, кто его поддерживает!

Кстати, это очевидно не сработает, если ваши m-файлы генерируются.

...