gmake компилирует все файлы в каталоге - PullRequest
13 голосов
/ 28 августа 2009

у нас есть некоторый код C ++, в котором нам нужно создать файл make. Каждая пара .h и .C создает объект, а затем некоторые объекты связываются вместе, образуя исполняемый файл. Довольно стандартные вещи.

Эта не-GNU make команда просто встраивает все файлы в объект в каталоге

%.o:%.C
    $(CC) $(CPFLAGS)  -c  $<

Для каждого файла% .C (т.е. для каждого файла .C) создается соответствующий файл .o.

Кто-нибудь знает, как это сделать с помощью gmake?

Приветствия

Mark

Ответы [ 2 ]

22 голосов
/ 28 августа 2009

Синтаксис, который вы показали, называется GNU make на языке шаблонов и является краеугольным камнем вашего решения. Все, что вам нужно, это добавить способ динамического получения списка файлов .C. Другие показали решения, которые используют $(shell) для этого, но это излишне неэффективно. Вместо этого я предлагаю использовать $ (подстановочный знак), встроенную в GNU make функцию, предназначенную именно для этой цели:

SRCS = $(wildcard *.C)
OBJS = $(patsubst %.C,%.o,$(SRCS))
foo: $(OBJS)
        $(CC) -o $@ $^

%.o: %.C
        $(CC) $(CPFLAGS)  -c  $<

Если вы ищете что-то более лаконичное, сработает также следующее:

foo: $(patsubst %.C,%.o,$(wildcard *.C))

Это просто исключает переменные и использует тот факт, что GNU make предоставляет правило шаблона %.o: %.C по умолчанию, а также правило по умолчанию для связывания исполняемого файла вместе из набора объектов. Лично я бы использовал более многословную версию, так как мне легче читать и поддерживать, но каждому свою.

Надеюсь, это поможет,

Эрик Мелски

1 голос
/ 28 августа 2009

Это пример шаблонного правила , оно должно нормально работать в gmake. Для очень простых сборок, подобных этой, вы можете полагаться на неявные правила . Главное, что вы должны указать для цели, которую вы хотите построить, и ее зависимостей:

CXXFLAGS:=-g -O -Iincludes
LDFLAGS:=-lm

SRCS:=$(shell ls *.C)          # select all .C files as source
OBJS:=$(substr .C,.o,$(SRCS)   # list the corresponding object files

foo : $(OBJS)

Обратите внимание на использование просто расширенной переменной оператора присваивания (:=) вместо оператора рекурсивного присваивания (=), который может уменьшить количество операций повторной обработки в более сложных сборках.

...