Аргумент командной строки Makefile не разрешается - PullRequest
0 голосов
/ 04 июля 2019

Мой make-файл выглядит так:

CC = gcc
CFLAGS = -g3
LIBS = `pkg-config --cflags --libs glib-2.0`
BINDIR = bin
OUTOBJ = $(addprefix $(BINDIR)/, main.o) 
$(info INCLUDE_PATH:$(INCLUDE_PATH))

$(BINDIR)/%.o : %.c 
                $(CC) -c $< $(CFLAGS) -o $@ $(LIBS)

# TODO: Merge with above rule
$(BINDIR)/%.o : */%.c 
                $(CC) -c $(INCLUDE_PATH) $< $(CFLAGS) -o $@ $(LIBS)


all: $(OUTOBJ)

$(OUTOBJ): | $(BINDIR)

$(BINDIR):
            mkdir $(BINDIR)

.PHONY : clean
clean:
        rm bin/*

Когда я запускаю make так:

make INCLUDE_PATH="/my/proj/dir"

Я получаю вывод, как это:

INCLUDE_PATH:/my/proj/dir
gcc -c main.c -g3 -o bin/main.o `pkg-config --cflags --libs glib-2.0`

.....
.....

ТакЕсли посмотреть на вывод, оператор $ (info INCLUDE_PATH: $ (INCLUDE_PATH)) в начале файла в основном разрешается нормально, но внутри переменной задачи $ (INCLUDE_PATH) не разрешается.Может ли кто-нибудь помочь мне с этим?

1 Ответ

1 голос
/ 04 июля 2019

Итак, глядя на вывод, оператор $ (info INCLUDE_PATH: $ (INCLUDE_PATH)) в начале файла в основном разрешается нормально, но внутри переменной задачи $ (INCLUDE_PATH) не разрешается.

Нет, это совсем не так.Как заметил @GM в комментариях, у вас есть два разных правила шаблона для построения объектных файлов в $(BINDIR), и они отличаются в зависимости от того, ссылаются ли их рецепты на $(INCLUDE_PATH).Вывод, который вы представляете, соответствует первому, а не второму.И это именно то, что я ожидал бы , потому что шаблон предварительных условий во втором правиле */%.c, не соответствует фактически используемому предварительному условию main.c, чье имяне содержит / символа.

Для вашего примера makefile вы можете заменить оба $(BINDIR)/%.o правила этим правилом ...

$(BINDIR)/%.o : %.c 
        $(CC) -c -I$(INCLUDE_PATH) $(CFLAGS) -o $@ $< $(LIBS)

..., чтобы решить проблему, но на самом деле это плохая форма по нескольким причинам.Прежде всего, в самом make-файле должно быть указано как минимум значение по умолчанию INCLUDE_PATH, особенно если оно относится к другой части того же проекта.Во-вторых, было бы более логично собирать директивы -I-D, -U и, возможно, некоторые другие) в переменную с именем CPPFLAGS и использовать , что , в ваших правилах сборки:

CPPFLAGS = -I$(INCLUDE_PATH)

$(BINDIR)/%.o : %.c 
        $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LIBS)

Полученное правило очень похоже на встроенное правило make для построения объектного файла из одного соответствующего исходного файла.

В общем, я небольшой поклонник создания объектов в другом каталоге, чем их соответствующие источники, поскольку это идет вразрез с зерном, и, следовательно, требует больше усилий для настройки и является гораздо более сложным.Является ли ваш реальный проект большим или маленьким, я действительно не понимаю, насколько эти усилия оправданы.Если вам нужны сборки из исходного кода, то пройдите весь путь и используйте VPATH .

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