Проблема создания "функции" gnu makefile - PullRequest
0 голосов
/ 03 февраля 2011

У меня есть большой кусок моего make-файла (~ 50 строк), который нужно скопировать 5 раз для другого случая (разные используемые библиотеки).Можно ли создать функцию в make-файле и просто вызвать эту функцию вместо вставки копии?

Это пример того, что я пробовал.В основном это пытается найти правильный путь для установленной библиотеки.

define Flags_template
$(1)_include_home      := $(HOME)/usr/include
$(1)_include_home_name := $(HOME)/usr/include/$(1)

ifneq ($$(wildcard $($(1)_include_home)/$(2)),)
    $(1)_Include := $$($(1)_include_home)
else
    ifneq ($$(wildcard $($(1)_include_home_name)/$(2)),)
        $(1)_Include := $$($(1)_include_home_name)
    endif
endif

CFLAGS += -I$$($(1)_Include)

endef

$(eval $(call Flags_template,stdcout,StdCout.hpp))

.PHONY: test
test:
    # stdcout_include_home_name = $(stdcout_include_home_name)
    # stdcout_Include = $(stdcout_Include)
    # CFLAGS: $(CFLAGS)

Набрав «make», я получаю следующий вывод:

# stdcout_include_home_name = /home/nicolas/usr/include/stdcout
# stdcout_Include = 
# CFLAGS: -I

Это так близко.Но обратите внимание на последнее "-I", я всегда получаю дубликаты, один полностью израсходован, один пустой ...

Я не понимаю, что нужно оценить, экранировать двумя $ и т. Д.

Как мне этого добиться?

Большое спасибо.

1 Ответ

1 голос
/ 04 февраля 2011

Помогает ли §8.8 руководства GNU Make (3.82)?

[...] Хотя в этом примере использование eval может показаться слишком сложным, Вместо того, чтобы просто писать правила, рассмотрим две вещи: во-первых, определение шаблона (в PROGRAM_template) может быть намного сложнее, чем здесь; а во-вторых, ты может поместить сложную «общую» часть этого примера в другой make-файл, а затем включить это во всех отдельных make-файлах. Теперь ваши индивидуальные make-файлы довольно просты.

PROGRAMS = server client
server_OBJS = server.o server_priv.o server_access.o
server_LIBS = priv protocol
client_OBJS = client.o client_api.o client_mem.o
client_LIBS = protocol
# Everything after this is generic
.PHONY: all
all: $(PROGRAMS)
define PROGRAM_template =
        $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
        ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
$(PROGRAMS):
        $(LINK.o) $^ $(LDLIBS) -o $@
clean:
        rm -f $(ALL_OBJS) $(PROGRAMS)

Это работает (для меня)

Это вывод из сборочного файла GNU чуть ниже:

stdcout_include_home = /work4/jleffler/usr/include
stdcout_include_home_name = /work4/jleffler/usr/include/stdcout
stdcout_Include = /work4/jleffler/usr/include
CFLAGS: -I/work4/jleffler/include -I/work4/jleffler/usr/include

GNU Makefile

CFLAGS = -I${HOME}/include

define Flags_template
$(1)_include_home      := $(HOME)/usr/include
$(1)_include_home_name := $(HOME)/usr/include/$(1)

ifneq ($$(wildcard $$($(1)_include_home)/$(2)),)
    $(1)_Include := $$($(1)_include_home)
else
    ifneq ($$(wildcard $$($(1)_include_home_name)/$(2)),)
        $(1)_Include := $$($(1)_include_home_name)
    else
        $(1)_Include := Neither $$($(1)_include_home) nor $$($(1)_include_home_name) contains $2
    endif
endif

CFLAGS += -I$$($(1)_Include)

endef

$(eval $(call Flags_template,stdcout,StdCout.hpp))

.PHONY: test
test:
        @echo stdcout_include_home = $(stdcout_include_home)
        @echo stdcout_include_home_name = $(stdcout_include_home_name)
        @echo stdcout_Include = $(stdcout_Include)
        @echo CFLAGS: $(CFLAGS)

Разница заключается в вызовах с подстановочными знаками:

ifneq ($$(wildcard  $($(1)_include_home)/$(2)),)    # Fails
ifneq ($$(wildcard $$($(1)_include_home)/$(2)),)    # Works

У меня есть половина интуиции о том, когда нужны двойные доллары и когда нужны одни доллары; Я не уверен, что могу сформулировать решение, хотя.

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