Если честно; некоторые люди предпочитают это. Я знаю, что лучше использовать Concat, так как + на самом деле не очень интуитивно понятен. Особенно просто смотреть на код в глубине; Трудно сказать, являются ли вы числами, которые вы добавляете, двумя строками или двумя точками, с которыми вы добавляете вектор. :)
Мы можем добавить это поведение «или-или» в список вещей, которые 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) $< $(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) $< $(C_OPTIONS) -c -o $@
EDIT: исправлено назначение OBJECTS, благодаря Джонатану Леффлеру.
Не просто копировать в
$(OBJECTS): %.o: %.m
$(CC) $< $(C_OPTIONS) -c -o $@
Вызов того же компилятора - просто счастливый случай. Обычно вы не компилируете код objective-c с $ (CC)
. Это просто кажется странным.
Но поскольку вы идете жестким путем, я не буду публиковать правильное решение, в котором вы разделяете цели объекта C и цели C на две разные $ (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-файлы созданы.