Создание подкаталогов в Makefile без mkdir -p - PullRequest
1 голос
/ 05 октября 2019

Стандарт GNU гласит, что не рекомендуется использовать команду -p для mkdir:

Например, не используйте 'mkdir -p ', как бы удобно это ни было, поскольку некоторые системы вообще не поддерживают его, а с другими это небезопасно для параллельного выполнения

Я бы хотел придерживаться этого стандарта и поэтомуЯ столкнулся с проблемой в моем Makefile.

Я рекурсивно компилирую все источники C из всех каталогов в каталоге src и хотел бы поместить их в каталог obj. Та же самая структура каталогов отражается внутри каталога obj, однако эти каталоги изначально не существуют.

Я мог бы очень легко сделать mkdir -p $(@D) для создания своих каталогов, но, следуя стандарту GNU, я не могу этого сделать,что подводит меня к моему вопросу: как я могу обойти это в Makefile?

Мой Makefile ниже:

SRCDIR=src
OBJDIR=obj

CC=cc

CFLAGS=
CFLAGS=-g -O2 -pedantic -Wall
ALL_CFLAGS=-std=c89 $(CFLAGS)

# Copied from /2161247/rekursivnye-simvoly-v-gnu-delayt#2161255
rwildcard=$(foreach d, $(wildcard $1/*), $(call rwildcard, $d, $2) $(filter $(subst *, %, $2), $d))

SOURCES=$(call rwildcard, $(SRCDIR), *.c)
OBJECTS=$(subst $(SRCDIR),$(OBJDIR),$(SOURCES:.c=.o))

all: $(OBJECTS)

$(OBJDIR)/%.o: $(SRCDIR)/%.c
    $(CC) $(ALL_CFLAGS) -c -o $@ $<

Ответы [ 2 ]

1 голос
/ 05 октября 2019

Стандарты GNU во многих местах устарели. Кажется, это одно из этих мест.

В настоящее время mkdir -p является частью POSIX . Это даже не недавнее изобретение, потому что оно пришло из System V.

Поскольку ваш make-файл предполагает, что компилятор C является GCC (или, по крайней мере, имеет GCC-совместимый синтаксис командной строки), вы также можете предположить, чтоmkdir -p работает. Если вы хотите, чтобы пользователи могли легко переопределить его, если это не так, вы можете добавить это:

MKDIR_P = mkdir -p

и использовать $(MKDIR_P) в рецептах вместо mkdir -p.

Но все это действительно не должно быть необходимым. Даже предположительно переносимый скрипт GNU mkinstalldirs использует mkdir -p долгое время.

0 голосов
/ 08 октября 2019

Вы можете просто использовать сделать зависимости. Перетащите файл, скажем .created, в каждую папку. Создайте файлы .created с шаблоном, который естественным образом создает папку как побочный эффект.

SOURCES=$(call rwildcard, $(SRCDIR), *.c)
OBJECTS=$(subst $(SRCDIR),$(OBJDIR),$(SOURCES:.c=.o))

.PHONY: all
all: $(OBJECTS)

%/.created:
    mkdir -p ${@D}
    touch $@

$(OBJDIR)/%.o: $(SRCDIR)/%.c | ${OBJDIR}/.created
    $(CC) $(ALL_CFLAGS) -c -o $@ $<

Это означает, что папки создаются один раз с помощью make и только тогда, когда онинужны. Параллельный сейф тоже.

[Это всего лишь эскиз. Ваша замена мне не подходит - я предполагаю, что у вас нет папки src/ в другой папке src/ (???), и ваш шаблон %.o не совсем правильный.]

...