Pergunta

Eu estou tentando criar um modelo de construção genérico para o meu Makefiles, tipo como eles discutem na eval documentação .

Eu não consigo obter a função de curinga para trabalhar dentro de um eval. O código básico Estou tendo problemas com a aparência como esta.

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/)
  $(1)_SRC_FILES = $(wildcard $$($(1)_SRC_DIR)*.c)
endef

$(eval $(call PROGRAM_template, $(PROG_NAME)))

all:
    @echo $(test_SRC_DIR)
    @echo $(test_SRC_FILES)
    @echo $(wildcard $(wildcard $(test_SRC_DIR)*.c)

Quando eu executar make com isso, a saída é

./src/test

[correct list of all .c files in ./src/test/]

Basicamente, a chamada curinga dentro PROGRAM_template não está sendo eval'd como eu espera. A chamada resulta em uma lista vazia.
A chamada juntar está sendo eval'd corretamente embora.

Então, o que estou fazendo de errado? Meu palpite é que

$$($(1)_SRC_DIR) 

não é correto, mas eu não consigo descobrir o caminho certo para fazê-lo.

Editar Uma vez que isso foi resolvido, não demorou muito para me bater outro problema com eval. Eu postei isso como uma nova questão em Solução para o GNU Make 3,80 eval bug

Foi útil?

Solução

Você precisa dupla fuga praticamente todas as funções e variáveis ??quando você usa eval. Na maioria dos casos, as únicas coisas que não necessidade de estar com duplo escape são argumentos de função (porque a função call será totalmente expandi-las). Neste caso, você tecnicamente não precisa join duplo-escape ou SRC_DIR quer, mas vai simplificar a sua vida se você simplesmente sempre duas vezes escapar de todas as variáveis ??e funções ao usar eval.

A razão que você precisa os escapes duplos é que a expansão acontece duas vezes ao usar eval. A função eval si realiza expansão, e, em seguida, a expansão é feita novamente quando o bloco é finalmente analisada como makefile sintaxe (isto é, quando ela é realmente avaliada).

A forma como você tem isso por escrito, wildcard é chamado no $( test_SRC_DIR)*.c literal string. Se você quiser, você pode ver isso por si mesmo, substituindo wildcard com info na sua versão e ver o que acontece.

Você precisa adiar a verdade invocando wildcard até a segunda expansão, de modo que o argumento é o resultado da expansão da $(test_SRC_DIR).

Tente isto:

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $$(join $$(SRC_DIR),$(1)/)
  $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c)
endef

$(eval $(call PROGRAM_template,$(PROG_NAME)))

all:
    @echo $(test_SRC_DIR)
    @echo $(test_SRC_FILES)
    @echo $(wildcard $(test_SRC_DIR)*.c)

Editar : Depois de postar isso, eu pensei que eu iria testá-lo melhor para se certificar de que ele realmente funciona. Ao fazê-lo, descobri um outro problema. Você deve evitar colocar espaços entre a vírgula e argumento ao chamar funções. Isso faz com que um caractere de espaço literal para ser anexado ao argumento que é passado para a função e leva a resultados indesejados. Eu removi os espaços após as vírgulas nas chamadas de função na minha versão (enquanto isso não é um problema para a chamada para join, tirei o espaço lá também só porque ele é um bom hábito de entrar).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top