Como passar a definição da macro de argumentos de linha de comando “make” (-D) para o código-fonte C?


107

Eu normalmente passo definições de macro de "make command line" para um "makefile" usando a opção: -Dname = value. A definição está acessível dentro do makefile.

Também passo definições de macro do "makefile" para o "código-fonte" usando a opção de compilador semelhante: -Dname = value (compatível com muitos compiladores). Esta definição está acessível no código-fonte.

O que eu preciso agora é permitir que o usuário do meu makefile seja capaz de passar definições arbitrárias de macro da "linha de comando make.exe" para o "código-fonte" imediatamente, sem ter que alterar nada no makefile.

para que o usuário possa digitar: make -f mymakefile.mk -SOMEOPTION var = 5

então diretamente o código main.c pode ver var:

int main()
{
  int i = var;
}

15
Por que o downvote? Parece uma pergunta perfeitamente legítima para mim.
Thomas

Respostas:


99

Chame o makecomando desta forma:

make CFLAGS=-Dvar=42

E certifique-se de usar $(CFLAGS)em seu comando de compilação no Makefile. Como @ jørgensen mencionou, colocar a atribuição da variável após o makecomando sobrescreverá o CFLAGSvalor já definido no Makefile.

Alternativamente, você pode definir -Dvar=42em outra variável CFLAGSe então reutilizar essa variável CFLAGSpara evitar a substituição completa CFLAGS.


8
Você não pode usar "CFLAGS = $ (CFLAGS) -Wall"; esta seria uma definição recursiva e o make não permite isso. Você poderia usar "CFLAGS: = $ (CFLAGS) -Wall" ou "CFLAGS + = -Wall", mas também não funcionarão porque uma atribuição na linha de comando tem uma precedência mais alta. Você pode usar "override CFLAGS + = -Wall", mas geralmente recomendamos que você apenas escolha variáveis ​​diferentes internamente. Os padrões de codificação GNU requerem que CFLAGS etc. sejam deixados para o usuário, e makefiles escolha outra variável, como "local_CFLAGS = $ (CFLAGS) -Wall".
MadScientist

2
Apenas para adicionar a nota @MadScientist, os padrões de codificação GNU também afirmam que $(CFLAGS)deve vir por último, de modo que qualquer opção especificada por um usuário irá sobrescrever qualquer coisa que o Makefile definir internamente. Isso significaria usar, por exemplo local_CFLAGS = -Wall $(CFLAGS). Por outro lado, se houver algo que você realmente deseja que tenha precedência, coloque-o depois $(CFLAGS), como no comentário @MadScientist.
Sam

1
Como definir várias macros por isso?
Woody Huang

2
@WoodyHuang por exemploCFLAGS="-Dvar1=42 -Dvar2=314"
ouah

1
CPPFLAGSpode representar um ajuste melhor do que CFLAGSou CXXFLAGS: stackoverflow.com/a/53527858/2278206
psq

11

Basta usar uma variável específica para isso.

$ cat Makefile 
all:
    echo foo | gcc $(USER_DEFINES) -E -xc - 

$ make USER_DEFINES="-Dfoo=one"
echo foo | gcc -Dfoo=one -E -xc - 
...
one

$ make USER_DEFINES="-Dfoo=bar"
echo foo | gcc -Dfoo=bar -E -xc - 
...
bar

$ make 
echo foo | gcc  -E -xc - 
...
foo

10

Ligue para fazer desta forma

make CFLAGS=-Dvar=42

porque você deseja substituir os CFLAGS do seu Makefile, e não apenas o ambiente (que tem uma prioridade mais baixa em relação às variáveis ​​do Makefile).


6

Devido à baixa reputação, não posso comentar a resposta aceita.

Eu gostaria de mencionar a variável predefinida CPPFLAGS. Pode representar um ajuste melhor do que CFLAGSou CXXFLAGS, uma vez que é descrito pelo manual GNU Make como:

Sinalizadores extras para fornecer ao pré-processador C e aos programas que o utilizam (os compiladores C e Fortran).

Exemplos de regras implícitas integradas que usam CPPFLAGS

  • n.oé feito automaticamente n.ccom uma receita do formulário:
    • $(CC) $(CPPFLAGS) $(CFLAGS) -c
  • n.oé feito automaticamente a partir de n.cc, n.cppou n.Ccom uma receita da forma:
    • $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

Alguém usaria o comando make CPPFLAGS=-Dvar=123para definir a macro desejada.

Mais informações


1
$ cat x.mak
tudo:
    echo $ (OPÇÃO)
$ make -f x.mak 'OPTION = -DPASSTOC = 42'
echo -DPASSTOC = 42
-DPASSTOC = 42

-4

Encontre o arquivo C e a implementação do Makefile abaixo para atender aos seus requisitos

foo.c

 main ()
    {
        int a = MAKE_DEFINE;
        printf ("MAKE_DEFINE value:%d\n", a);
    }

Makefile

all:
    gcc -DMAKE_DEFINE=11 foo.c

a questão é passar definições arbitrárias da linha de comando do make diretamente para o código-fonte C "sem alterar o makefile". Então eu queria mudar meu makefile uma vez, para permitir que essas definições arbitrárias fossem feitas.
MohamedEzz

Não funciona para fazer. Isso é make -DMAKE_DEFINE = 11 diz opção inválida.
Ramakrishnan Kannan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.