Как правильно написать make-файл? (для множества файлов с однотипными именами)
Модератор: Модераторы разделов
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Как правильно написать make-файл?
Имеется куча примеров и учебных задач по языку Си.
Каждый пример оформляется в отдельный исходный файл.
Решение каждой задачи также оформляется в отдельный исходный файл.
В результате для листингов примеров имеем множество исходных файлов с именами типа
list1.1.c
list1.2.c
list1.3.c
list2.1.c
list2.2.c
list3.1.c
.....
Для решений задач
task1.1.c
task1.2.c
task3.1.c
task3.2.c
task3.3.c
task4.2.c
Количество файлов и полные имена заранее неизвестны.
Известно лишь, что имя состоит из префикса (list или task) и номера, состоящего из двух цифр, разделенных точкой.
Вопрос:
Возможно ли написать make-файл, который позволит скомпилировать любой из файлов по отдельности или (при необходимости) все сразу?
Я попробовал использовать маски в make-файле, но как-то не очень получилось.
Каждый пример оформляется в отдельный исходный файл.
Решение каждой задачи также оформляется в отдельный исходный файл.
В результате для листингов примеров имеем множество исходных файлов с именами типа
list1.1.c
list1.2.c
list1.3.c
list2.1.c
list2.2.c
list3.1.c
.....
Для решений задач
task1.1.c
task1.2.c
task3.1.c
task3.2.c
task3.3.c
task4.2.c
Количество файлов и полные имена заранее неизвестны.
Известно лишь, что имя состоит из префикса (list или task) и номера, состоящего из двух цифр, разделенных точкой.
Вопрос:
Возможно ли написать make-файл, который позволит скомпилировать любой из файлов по отдельности или (при необходимости) все сразу?
Я попробовал использовать маски в make-файле, но как-то не очень получилось.
-
- Модератор
- Сообщения: 20996
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Как правильно написать make-файл?
Напишите скрипт, который сгенерирует такой makefile.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
Код: Выделить всё
CC=gcc
CFLAGS=-c -Wall -O2
LDFLAGS=
EXECUTABLE=program
SOURCES=1.c 2.c 3.c 4.c
OBJECTS=$(SOURCES:.c=.o)
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $@ $(LDFLAGS)
.c.o:
$(CC) -MD $(CFLAGS) $< -o $@
include $(wildcard *.d)
clean:
rm --force *.o
спрашивайте, что вам непонятно...
-
- Сообщения: 3321
- Статус: Красный глаз тролля
- ОС: ArchLinux
Re: Как правильно написать make-файл?
Вот у меня для моих сниппетов такое:
Код: Выделить всё
cat ./C-snippets/Makefile
CC = gcc
LDFLAGS =
DEFINES = -DSTANDALONE -DEBUG
CFLAGS = -Wall -Werror
all : fifo_lifo bidirectional_list B-trees simple_list
%: %.c
$(CC) $(LDFLAGS) $(CFLAGS) $(DEFINES) $< -o $@
RTFM
-------
KOI8-R - патриотичная кодировка
-------
KOI8-R - патриотичная кодировка
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Всем спасибо.
Ваши ответы подтолкнули меня к правильному варианту.
Ваши ответы подтолкнули меня к правильному варианту.
-
- Модератор
- Сообщения: 20996
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Как правильно написать make-файл?
Поделитесь, что за вариант-то? :-)
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Ничего особенного.
Код: Выделить всё
PATH2 = /path/to/bins
PATH3 = /path/to/source
bins := $(basename $(wildcard *.c))
CFLAGS=-g
vpath % $(PATH2)
all: $(PATH2) $(bins)
$(PATH2):
/bin/mkdir -p $@
$(bins): %: %.o
gcc $(PATH3)/$? -o $(PATH2)/$@
clean:
rm -f *.o
Для сравнения. Изначально это выглядело вот так (дети, никогда так не делайте! Это неправильно!):
Spoiler
Код: Выделить всё
PATH2 = /path/to/bins
PATH3 = /path/to/source
objects := bins list3.1 list3.2 list3.3 list3.4 list3.5 list3.6\
list4.1 list4.2 list4.3 list4.4 list4.5\
list5.1 list5.2 list5.3 list5.4 list5.5 list5.6 list5.7 list5.8 list5.9\
list6.1 list6.2 list6.3 list6.4 list6.5 list6.6 list6.7 list6.8 list6.8A list6.9 list6.10 list6.10A\
task3.1 task3.2 task3.3 task3.4 task3.5\
task4.4 task4.5 task4.6 task4.7 task4.8\
task5.2 task5.3 task5.4 task5.5 task5.6 task5.7 task5.8\
task5.9_l5.2 task5.9_l5.3 task5.9_l5.4 task5.9_l5.5 task5.11\
task6.2 task6.3 task6.4
all: $(objects)
bins:
/bin/mkdir -p /path/to/bins
list3.1: list3.1.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list3.2: list3.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list3.3: list3.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list3.4: list3.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list3.5: list3.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list3.6: list3.6.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list4.1: list4.1.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list4.2: list4.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list4.3: list4.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list4.4: list4.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list4.5: list4.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.1: list5.1.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.2: list5.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.3: list5.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.4: list5.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.5: list5.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.6: list5.6.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.7: list5.7.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.8: list5.8.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list5.9: list5.9.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.1: list6.1.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.2: list6.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.3: list6.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.4: list6.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.5: list6.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.6: list6.6.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.7: list6.7.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.8: list6.8.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.8A: list6.8A.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.9: list6.9.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.10: list6.10.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
list6.10A: list6.10A.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task3.1: task3.1.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task3.2: task3.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task3.3: task3.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task3.4: task3.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task3.5: task3.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task4.4: task4.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task4.5: task4.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task4.6: task4.6.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task4.7: task4.7.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task4.8: task4.8.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.2: task5.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.3: task5.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.4: task5.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.5: task5.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.6: task5.6.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.7: task5.7.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.8: task5.8.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.9_l5.2: task5.9_l5.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.9_l5.3: task5.9_l5.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.9_l5.4: task5.9_l5.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.9_l5.5: task5.9_l5.5.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task5.11: task5.11.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task6.2: task6.2.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task6.3: task6.3.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
task6.4: task6.4.o
cc -g $(PATH3)/$@.c -o $(PATH2)/$@
clean:
rm -f *.o
Имя каждого вновь создаваемого файла я дописывал в objects и писал команду для соответствующей цели, копируя одну из предыдущих. И у меня было постоянное ощущение, что можно использовать шаблоны, поскольку имена и команды однотипные. Пробовал сделать, но не получалось. Когда это разрослось до представленного состояния, терпение моё лопнуло.
Поскольку тема для начинающих, пусть этот вариант будет иллюстрацией как не надо делать.
Кстати, есть какая-то заморочка с шаблонами.
Например, вот так
Код: Выделить всё
$(bins): %.o
gcc $(PATH3)/$? -o $(PATH2)/$@
Хотя в статьях такие примеры есть.
А вот так
Код: Выделить всё
$(bins): %: %.o
gcc $(PATH3)/$? -o $(PATH2)/$@
Вариант, предложенный drBatty тоже не заработал, потребовал правило для 1.c хотя вот это
Код: Выделить всё
.c.o:
$(CC) -MD $(CFLAGS) $< -o $@
Версия make у меня из репов, судя по выводу make -v вроде GNU.
Ну, в общем, некоторые варианты не срабатывают, почему - не понял. Примеры из статей опробовать не удаётся.
Поэтому так долго не удавалось написать компактный вариант make-файла.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
очевидно, что и правила есть для каждого %.o
Например в моём примере есть строка
Код: Выделить всё
include $(wildcard *.d)
которая включает d файлы, а их -- ровно для каждого o файла
В них как раз те правила, которых у вас нет:
Код: Выделить всё
main.o: main.c /usr/include/stdc-predef.h /usr/include/stdio.h \
/usr/include/features.h /usr/include/sys/cdefs.h \
/usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
/usr/include/gnu/stubs-32.h \
... (многобукв)
Эти файлы создаёт сам gcc -MD, вытаскивая зависимости из C кода. Т.о. если я поменяю main.c, или /usr/include/gnu/stubs-32.h, то make это заметит, и будет собирать main.o.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
это правило для *.c файлов, а для *.o тоже надо своё правило. Т.е. сначала это срабатывает для изменённых *.c файлов, вытягивая оттуда их зависимости. А потом срабатывает *.o правило, которое уже собирает o файлы (точнее оно само ничего не собирает, собирает правило выше, а правило o файлов нужно только для того, что-бы пересобирать o файлы даже когда c файлы не меняются, а меняются зависимости, например h файлы. Ну например вы обновили систему с новой glibc/printf -- надо пересобирать все ваши helloworld'ы)
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Так они в статьях упоминаются, как неявные. То есть существуют, даже если я их не написал.
А если существуют, то почему не срабатывают?
Стало быть, make не находит эти самые неявные.
От чего это зависит - непонятно.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
телепаты всё ещё в отпуске. В каких статьях? С какого вообще перепугу? Это у меня .c.o: старый синтаксис данной подстановки: http://www.gnu.org/software/make/manual/ma...l#Pattern-Rules Правило говорит ЧТО делать с *.o файлами, точнее, как надо делать из *.c файла *.o файл.
А вот КАКИЕ *.o файлы обработать -- это правило не говорит. Вот она вам и пишет: "что мне делать, хозяин? Какие файлы собирать программой $(CC)?"
Вроде-бы так, хотя точно я сам уже не помню...
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
В обыкновенных, которые в Сети нашлись.
Например, вот .
Цитата
Перечень имеющихся неявных правил
........
Компиляция программ на языке Си
`n.o' автоматически получается из `n.c' при помощи команды `$(CC) -c $(CPPFLAGS) $(CFLAGS)'.
Оттуда же
Примеры шаблонных правил
Вот несколько примеров шаблонных правил, в действительности предопределенных в make. Сперва, правило, компилирующее файлы `.c' в файлы `.o':
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
Логика моя была примерно такая:
Согласно первой цитате, make знает, как полчить o-файл из c-файла (имеется неявное правило)
Согласно второй цитате допустимо использование шаблонов типа %.o.
Тогда, указав шаблон %.o где-то в другом правиле как зависимость, по идее можно ожидать, что make создаст из каждого c-файла соответствующий о-файл, то есть сработает неявное правило.
То есть вот это
Код: Выделить всё
$(bins): %.o
gcc $(PATH3)/$? -o $(PATH2)/$@
Но не работает.
Вот примерно так.
Хотя допускаю, что я чего-то не так понял и в результате "поделил на ноль", как Вы любите говорить.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
между прочим, я своё написал ВМЕСТО него. А остальные правила кто писать будет?
типа того.
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Ну так, а я-то ВМЕСТО ничего не писал.
Я просто использовал шаблон.
Код: Выделить всё
$(bins): %.o
gcc $(PATH3)/$? -o $(PATH2)/$@
и ожидал что по %.o будет обработан каждый o-файл, а недостающие будут созданы из с-файлов в соответствии с неявным правилом.
Однако, не то что недостающие, даже существующие не обработались.
Так что этот момент достаточно неочевидный, на мой взгляд.
С одной стороны, есть шаблоны, с другой - не всегда они работают.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
да, вспомнил: неявное правило заставит make собрать main.o, в случае, если мы поменяли main.c, в этом случае УНВР. А что будет, если поменять other.h, который включён в main.c? Ничего. В лучшем случае нас обматерит ld, увидев, что у него other.o не лепится с main.o. Но это смотря как поменять, может и слепится, но криво.
Вот именно потому, я и использую фичу препроцессора cpp -MD, вытягивая main.d файл, в котором записано правило, для сборки main.o в случае, если поменялся other.h. Этот файл включается в Makefile, и заставляет make пересобрать main.o в случае, когда поменялся other.h.
Фича cpp -MD не имеет никакого отношения к компиляции, потому-то я и переопределяю правило компиляции в Makefile, а не добавляю опцию в $(CFLAGS).
Вот как раз основная задача make -- НЕ создавать каждый раз новый файл. А создавать тогда, и только когда оно НУЖНО. Т.е. если вы поменяли какой-то файл, то make собирает ТОЛЬКО то, что зависит от этого файла.
Вот именно потому, я и использую фичу препроцессора cpp -MD, вытягивая main.d файл, в котором записано правило, для сборки main.o в случае, если поменялся other.h. Этот файл включается в Makefile, и заставляет make пересобрать main.o в случае, когда поменялся other.h.
Фича cpp -MD не имеет никакого отношения к компиляции, потому-то я и переопределяю правило компиляции в Makefile, а не добавляю опцию в $(CFLAGS).
Вот как раз основная задача make -- НЕ создавать каждый раз новый файл. А создавать тогда, и только когда оно НУЖНО. Т.е. если вы поменяли какой-то файл, то make собирает ТОЛЬКО то, что зависит от этого файла.
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Ну как это - какие? Те, которые подходят под шаблон. Какие же ещё?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
вы моё правило написали ВМЕСТО дефолтного, а потом удивлялись, почему не работает ДРУГОЕ правило.
это не баг, а фича. Шаблоны(как и просто правила) срабатывают тогда, и только тогда, когда это нужно из-за изменения файла и/или из-за того, что какая-то зависимость изменилась.
Если ничего не изменилось, make скажет -- "делать нечего".
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Да я не возражаю. Замечательно.
Огорчает другое: Как Вы заметили выше, make не знает, какие файлы обрабатывать по шаблону, хотя, казалось бы, это не должно вызывать затруднений.
Если бы просто не нашлось файлов, подходящих под шаблон - это ладно, но ведь вообще не отрабатывает, даже существующие файлы.
Ругается на отсутствие правила - вот что плохо.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
шаблон -- дело десятое. Если просто под шаблон подходит, то make ничего с этим делать не будет, она будет делать из *.c файл *.o ТОЛЬКО если видит, что *.o нету, или он есть, но слишком старый по сравнению *.c. Ну или зависимость изменилась -- какой-нить *.h файл например. Линкер вообще не видит header'ов, он видит только obj файлы. Потому, если вы изменили header, то вам нужно пересобрать все obj, которые его прямо или косвенно включают.
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Не-не. Не Ваше правило. Из Ваших я ничего не брал.
Я попробовал использовать Ваш код целиком как есть, он ругнулся на отсутствие правила и я пошёл читать маны, чтобы в нём разобраться.
Больше я его не использовал.
А не сработало моё правило с шаблоном %.o, которое я писал, ориентируясь на маны и статьи.
Я же специально привёл строчку кода.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
fflatx писал(а): ↑25.11.2013 23:16Код: Выделить всё
$(bins): %: %.o gcc $(PATH3)/$? -o $(PATH2)/$@
Работает совершенно спокойно.
fflatx писал(а): ↑26.11.2013 14:47Код: Выделить всё
$(bins): %.o gcc $(PATH3)/$? -o $(PATH2)/$@
вроде должно работать.
Но не работает.
во втором случае она не может раскрыть процент. Т.е. вы ей сказали, что надо "взять файлы $(bins)", но не сказали, что делать с их именами. Хотя потом имеете наглость писать $@, хотя
$@
The file name of the target of the rule. If the target is an archive member, then ‘$@’ is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ‘$@’ is the name of whichever target caused the rule's recipe to be run.
рассчитывая, что она распарсит как Pattern Rules, но процентик, который и будет считаться за имя исполняемого файла вы забыли написать.
можно на "ты"? Меня корёжет Ваше ВЫ (:
потому-что %.o это не шаблон, а то, НА ЧТО нужно менять шаблон(в вашем случае просто %).
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Да ради Бога, я разве против?
Есть цель: получить бинарник. Бинарника в наличии нету. Значит, выполняются инструкции, указанные для данной цели.
Но данная цель зависит от o-файла. Если о-файл есть - пожалуйста, создавай бинарник.
И шаблон типа %.o здесь помехой быть не должен. Под него подходят все файлы с расширением .o Нашлись - используй.
Но не использует, просит правило персонально для %.o.
Не то, что файлы не изменились, а именно правило просит.
Вот что сбивает с толку.
Всё-таки корёжит? Хотя я в своё время пытался прояснить этот момент.
Ладно, договорились. Можно на "ты". В обе стороны.
А вот это что-то новое, по крайней мере, в той статье, что я цитировал это называют шаблоном.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
ты не правильно понимаешь то, что там дальше написано:
Код: Выделить всё
gcc $(PATH3)/$? -o $(PATH2)/$@
вот тут $? меняется на %.o, а $@ меняется на %, а в этот % по очереди вставляются все цели из списка $(bins). Т.е. если у тебя $(bins)==="x y z", то она создаёт три команды
Код: Выделить всё
gcc path3/x.o -o path2/x
gcc path3/y.o -o path2/y
gcc path3/z.o -o path2/z
конечно если файлов цели x y z нет, или они старые.
Но для этого ей надо знать три вещи:
1. список целей (x y z)
2. шаблон имени цели %
3. шаблон имени исходного файла %.o (тут исходником выступает obj, потому-что это линкер работает)
так только боты пишут.
ИМХО
м... Как раз таки это шаблон(template), а вот просто % -- это pattern. Т.е. % это ЧТО ИСКАТЬ, а %.c это НА ЧТО МЕНЯТЬ. В русских источниках перепутано часто... Нет у нас слова pattern в таком смысле. Близко "образец", но не то.
-
- Сообщения: 3728
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
Re: Как правильно написать make-файл?
Во! Вот это как раз и не очевидно.
Вроде бы $? - это список зависимостей, которые новее, чем цель. Сюда подставляется %.c - это ясно.
А вот $@ - это сама цель, т.е. $(bins) и с чего вдруг $@ меняется на % - непонятно.
Может оно и так, но вот не очевидно ни разу.
А кстати, эту кухню (что на что заменяется) можно как-нибудь увидеть в режиме отладки или ещё как?
Я пробовал make -d, но проясняет не очень, если честно.
Ну вот, дожили. Правила вежливости соблюдаются только ботами. Больше некому.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Как правильно написать make-файл?
то, что на $ начинается, это никакой не список, а одно имя. Вот $? это одно имя из списка $(bins)
потом из имени выдёргивается % (в нашем случае это всё имя), и пихается в шаблон %.c ; что получилось вставляется вместо $@
похожая схема используется в программе rename(1), её сейчас рядом обсуждают.
без понятия. Я сам не знал про make -d.