gcc - Что означает ../ (точка-косая черта) в переменной в Makefile? - PullRequest
0 голосов
/ 20 сентября 2018

Я часами искал ответ на этот вопрос.Я новичок в GCC и Makefiles.

У меня есть Makefile в некотором исходном коде, который выглядит следующим образом:

CC=gcc
SRCDIR=src
BINDIR=../bin
CFLAGS= -flag
LIBS= -lthing
...
$(BINDIR)/program_name: $(SRCDIR)/program_name.c
    $(CC) $(CFLAGS) $(SRCDIR)/program_name.c -o $(BINDIR)/program_name $(LIBS)

Я понимаю, что все это означает, за исключением того, что ../ в BINDIR предназначается.Когда я создаю Makefile, я получаю сообщение об ошибке:

/usr/bin/ld: cannot open output file ../bin/program_name: No such file or directory
collect2: error: ld returned 1 exit status
Makefile:20: recipe for target '../bin/program_name' failed
make: *** [../bin/program_name] Error 1

Я предполагаю, что оригинальный автор этого Makefile подразумевал, что папка bin должна находиться в родительском каталоге, где находится Makefile.Я знаю, что при использовании команды CLI в Linux cd точка-точка означает перейти в каталог.Это то, что это пытается достичь?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Чтобы автоматически создать каталог $(BINDIR) до того, как он действительно понадобится, вы должны объявить его как условие (зависимость) любой цели, которая его использует.Но каждый раз, когда его содержание изменяется, его метка времени также изменяется.Таким образом, объявлять его как регулярное предварительное условие не лучшая вещь, потому что цели, зависящие от него, будут перестроены без реальной причины, просто потому, что изменилось содержимое $(BINDIR).

Вот почему make также поддерживает предварительные условия только для заказа (ООП):

$(BINDIR)/program_name: $(SRCDIR)/program_name.c | $(BINDIR)
    $(CC) $(CFLAGS) $< -o $@ $(LIBS)

$(BINDIR):
    mkdir -p $@

Обратите внимание на |, который вводит список ООП.ООП создается, если он не существует, что приводит к (пере) построению целей в зависимости от него.Но если он существует, make даже не учитывает время его последней модификации.Даже если какая-то цель, в зависимости от нее, старше, она не перестраивается только из-за этого.

Примечание: я также использовал автоматические переменные $< и $@ .В рецепте правила они расширяются как первая предпосылка ($(SRCDIR)/program_name.c) и цель ($(BINDIR)/program_name), соответственно.Настоятельно рекомендуется: меньше печатать, меньше подвержено ошибкам, более общие правила ... у них много хороших свойств.

0 голосов
/ 20 сентября 2018

В вашем make-файле отсутствует правило для создания каталога BINDIR - если он не существует, ваша строка ссылок не сможет поместить полученный бинарный файл туда!Такое правило должно выполняться следующим образом:

$(BINDIR): 
    mkdir -p $(BINDIR)

Просто убедитесь, что любые другие правила (например, те, что в вашем вопросе) также зависят от этого каталога!

...