Как написать более простой make-файл для большого количества однофайловых программ? - PullRequest
1 голос
/ 16 июля 2011

Я хочу написать множество крошечных примеров программ для одной и той же библиотеки, каждая нуждается в gcc $(OtherOpt) -o xxx -lthelibname xxx.c.

Как написать Makefile без десятков строк tagret?

Ответы [ 3 ]

3 голосов
/ 16 июля 2011

Шаблонные правила - ваш друг в таких ситуациях.Пока все ваши цели соответствуют предсказуемому шаблону - и в этом случае они соответствуют, поскольку все они имеют форму «create foo from foo.c» - вы можете написать одно правило шаблона, которое будет использоваться длявсе цели:

OtherOpt=-Wall -g
all: $(patsubst %.c,%,$(wildcard *.c))
%: %.c
        gcc $(OtherOpt) -o $@ -lthelibname $<

Теперь вы можете либо просто запустить make, чтобы создать все ваши приложения, либо make appname, чтобы создать определенное приложение.Здесь я создал единственное шаблонное правило, которое будет использоваться в любое время, когда вы захотите создать something из something.c.Я использовал автоматическую переменную $@, которая будет расширяться до имени выходных данных, и переменную $<, которая будет расширяться до имени первой предпосылки, чтобы командная строка была правильной независимо от конкретного приложения.в процессе постройки.Технически вам не нужна строка all, но я подумал, что вы, вероятно, не хотите, чтобы всегда приходилось вводить названия приложений, которые вы хотите создать.

Кроме того, технически вы, вероятно, можете уйти, не имея любого этого make-файла, потому что в GNU make уже есть встроенное правило шаблона для отношения %: %.c!Я упоминаю эту опцию только для полноты;лично я предпочитаю делать то, что я показал здесь, потому что это немного более ясно, что происходит.

1 голос
/ 16 июля 2011

Я учусь на http://sourceforge.net/projects/gcmakefile/

LDLIB     = -lpthread
LDFLAGS   = -Wl,-O1 -Wl,--sort-common -Wl,--enable-new-dtags -Wl,--hash-style=both $(LDLIB)
SRCDIRS   =

SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp

CFLAGS  = -pipe -march=core2 -mtune=generic -Wfloat-equal \
#-Wall -pedantic

ifeq ($(SRCDIRS),)
  SRCDIRS = .
endif
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
TARGET  = $(addprefix bin/,$(basename $(SOURCES)))

all: $(TARGET)
    ls -l $(TARGET)

bin/%: %.c dir
    gcc $(CFLAGS) $(LDFLAGS) -o $@ $<

dir:
    @-mkdir bin

.PHONY : clean
clean:
    -rm $(TARGET)
    -rmdir bin
1 голос
/ 16 июля 2011
%.o: %.c
    gcc $(OtherOpt) -c -o $@ -lthelibname $<

Это компилирует все файлы .c в их файлы .o (объектный код) с одинаковым базовым именем. Затем в вашей фактической цели вы должны включить все необходимые файлы .o в качестве зависимостей и использовать gcc $(OtherOpt) -o $@ $^ -lthelibname, при условии, что я не пойму неправильно, как настроена ваша сборка.

Некоторые версии make также поддерживают правило суффикса .c.o, чтобы быть ПОЧТИ тем же, что и %.o: %.c, но правила суффикса не могут иметь никаких зависимостей. Запись .c.o: foo.h говорит make для компиляции "foo.h" в "foo.c.o", а не требует "foo.h" в качестве зависимости любого файла с суффиксом .c, как правильно будет %.o: %.c foo.h.

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