Portal do Governo Brasileiro

make

make [opções] alvo...

Descrição

O utilitário make é utilizado para verificar quais arquivos precisam ser compilados (foram alterados desde a última compilação ou nunca foram compilados) e para emitir a ordem de compilação (e de linkedição).

Algumas opções do comando

Makefile

Exemplo

Vejamos um exemplo.

1 Objetivo = Estudo do makefile
2 alvo1: alvo3
3 @echo $(Objetivo)
4 alvo2:
5 @echo este eh o alvo2 do $(Objetivo)
6 alvo3:
7 @echo alvo3 do makefile

Inicialmente é definida no makefile acima uma macro chamada Objetivo. Em seguida, são definidos três alvos: alvo1, alvo2 e alvo3. Note que apenas o alvo1 tem uma dependência: alvo3. Isto significa que antes de executar alvo1, o utilitário deverá executar alvo3. Além disso, observe que cada alvo usa o comando echo que exibe strings e conteúdo de macros (o símbolo @ antes do comando echo apenas evita que o comando também seja exibido).

No primeiro alvo temos o símbolo $ seguido pelo nome da macro entre parênteses. O símbolo $ informa ao comando @echo para substituir o nome da macro pelo seu conteúdo (os parênteses não são exigidos se o nome da macro tem apenas uma letra). No segundo alvo temos uma string seguida pela macro Objetivo. E no terceiro alvo temos apenas uma string. Abaixo mostramos possíveis linhas de comando e suas saídas para este makefile.

1) make

alvo3 do makefile
Estudo do makefile

2) make alvo1

alvo3 do makefile
Estudo do makefile

3) make alvo2

este eh o alvo2 do Estudo do makefile

4) make alvo3

alvo3 do makefile

5) make alvo1 alvo2 alvo3

alvo3 do makefile
Estudo do makefile
este eh o alvo2 do Estudo do makefile
make: `alvo3' is up to date.

6) make alvo3 alvo2 alvo1

alvo3 do makefile
este eh o alvo2 do Estudo do makefile
Estudo do makefile

7) Objetivo=teste make -e (ou make -e Objetivo=teste)

alvo3 do makefile
teste
Podemos fazer algumas observações em relação ao exemplo acima:
  1. Os comandos make e make alvo1 são idênticos pois quando o alvo não é especificado na linha de comando, o utilitário sempre executa o primeiro alvo especificado no arquivo makefile.
  2. O quinto exemplo acima mostra uma mensagem de advertência do make. Este exemplo solicita a execução de alvo1, alvo2 e então alvo3. Só que alvo3 é pré-requisito de alvo1 e portanto, o utilitário executa alvo3, alvo1 e alvo2, quando chega para executar o alvo3, ele verifica que este já foi executado e exibe a mensagem de advertência.
  3. O sexto exemplo executa inicialmente alvo3 e alvo2. Quando vai executar alvo1, verifica que este requer a execução de alvo3 antes de executar alvo1. Como alvo3 já foi executado, alvo1 é executado imediatamente.
  4. O último exemplo define uma variável de ambiente também chamada Objetivo; o uso da opção -e com o comando make, informa que o conteúdo desta variável de ambiente deve sobrepor o conteúdo da macro de mesmo nome definida dentro do arquivo makefile.

Observações

Embora não exista um padrão formal para nomes de alvos, normalmente, são adotados os seguintes nomes de alvos nos arquivos makefiles:

No exemplo mostrado acima, usamos uma macro de nome Objetivo. Esta macro foi definida pelo usuário dentro do makefile. Porém, podemos também fazer uso de macros embutidas, ou seja, de macros internamente mantidas pelo make e que portanto, podem ter o seu conteúdo alterado durante a execução e não precisam ser definidas pelo usuário. São alguns exemplos de macros embutidas:

O comando make baseia-se bastante no uso de sufixos de arquivo. São alguns sufixos de arquivos reconhecidos pelo make:

A partir dos sufixos de arquivo podemos definir regras de inferências nos arquivos makefiles. Estas regras definem como arquivos são gerados a partir de outros arquivos. Podemos, por exemplo, escrever
.c.o : gcc -c -o $@ $<
A regra de inferência acima define como um arquivo com sufixo .o é gerado a partir de um arquivo .c. Note que usamos duas macros embutidas: a primeira macro ($@) fornece o nome do arquivo final com sufixo .o e a segunda ($<) fornece o nome do arquivo original com sufixo .c. Para a regra de inferência mostrada acima poderíamos, por exemplo, criar o seguinte alvo
teste.o : teste.c funcoes.h
Neste caso, o comando make teste.o faz com que o utilitário make execute o seguinte comando
gcc -c -o teste.o teste.c funcoes.h
onde a opção -c define apenas compilação e a opção -o define o nome do arquivo de saída. Os arquivos teste.c e funcoes.h são os arquivos de entrada. Uma observação final em relação a regras de inferência é que não se deve definir dependências (pré-requisitos) para regras de inferência. Em algumas plataformas UNIX, a regra com pré-requisitos é interpretada como alvo.

Mais exemplos

Vejamos agora um exemplo completo de um makefile. O exemplo mostrado abaixo gera o executável solv a partir dos arquivos solvers.o, option_1.o, option_2.o, option_3.o e misc.o.

1 CC=gcc
2 INCLUDEDIR=.
3 FLAGS=-g -I${INCLUDEDIR}
4 .c.o:
5 ${CC} ${FLAGS} -c -o $@ $<
6 OBJS = solvers.o option_1.o option_2.o option_3.o misc.o
7 solv: objects
8 ${CC} -o $@ ${OBJS} -g -lm
9 objects: ${OBJS}
10 solvers.o: solvers.c define.h misc.c
11 option_1.o: option_1.c define.h misc.c
12 option_2.o: option_2.c define.h misc.c
13 option_3.o: option_3.c define.h misc.c
14 misc.o: misc.c define.h
15 clean:
16 rm -fr *.o

Inicialmente, são definidas 3 macros: CC, INCLUDEDIR e FLAGS. Na linha 4 é definida uma regra de inferência para gerar os arquivos com sufixo .o a partir dos arquivos com sufixo .c. Na linha 6 é definida a macro OBJS. Nas linhas de 7 a 16 são definidos 8 alvos: solv, objects, solvers.o, option_1.o, option_2.o, option_3.o, misc.o e clean. O primeiro alvo (solv) é o alvo padrão, ou seja, o alvo que será executado caso o usuário digite make. O alvo solv tem como pré-requisito o alvo objects e como linha de ação o comando gcc. O alvo objects não tem linhas de ação, apenas pré-requisitos: os alvos definidos nas linhas de 10 a 14. Note que estes alvos lista apenas as dependências, portanto será utilizada a regra de inferência definida nas linhas 4 e 5 na execução de cada alvo. Por exemplo, na geração do arquivo solvers.o o seguinte comando é executado

gcc -g -I. -c -o solvers.o solvers.c define.h misc.c
onde -g, -I e -c correspodem, respectivamente, as opções de depuração, inclusão de diretório no caminho de busca e apenas compilação. O alvo objects é usado para gerar os arquivos definidos na macro OBJS. Após a conclusão do alvo objects, o comando retorna ao alvo solv que executa a seguinte linha de ação
gcc -o solv solvers.o option_1.o option_2.o option_3.o misc.o
e finaliza a execução do makefile. Caso o usuário tenha digitado make clean, o alvo clean é executado. Este alvo apaga todos os arquivos com sufixo .o do diretório. Note que também é possível utilizar o makefile para gerar apenas os arquivos .o, pois existem alvos definidos com os nomes desses arquivos. Por exemplo, o comando
make option_1.o
gera o arquivo option_1.o.

Vejamos um segundo exemplo de makefile. O exemplo mostrado abaixo gera o executável teste a partir dos arquivos teste.o, prog1.o e prog2.o.

1 CC = gcc
2 OBJS = teste.o prog1.o prog2.o
3 .c.o:
4 $(CC) -c -o $@ $<
5 all: $(OBJS)
6 $(CC) $(OBJS) -o teste
7 clean:
8 rm -f *.o core
9 clobber: clean
10 rm -f teste

Inicialmente, são definidas 2 macros: CC e OBJS. Nas linha 3 e 4 é definida uma regra de inferência para gerar os arquivos com sufixo .o a partir dos arquivos com sufixo .c. Nas linhas de 5 a 10 são definidos 3 alvos: all, clean e clobber. O primeiro alvo (all) é o alvo executado caso o usuário digite apenas make. Este alvo tem como pré-requisito a lista dos arquivos com extensão .o. Para gerar estes arquivos o make fará uso da regra de inferência definida nas linhas 3 e 4. Por exemplo, na geração do arquivo teste.o o seguinte comando é executado:

gcc -c -o teste.o teste.c
Após a geração dos arquivos teste.o, prog1.o e prog2.o, o make gera o executável teste com o seguinte comando (linha 6)
gcc teste.o prog1.o prog2.o -o teste
O alvo clean (linhas 7 e 8) é utilizado para apagar os arquivos com extensão .o e o arquivo core (gerado pelo sistema em caso de erro de execução). O alvo clobber (linhas 9 e 10) é utilizado também para apagar estes arquivos além do arquivo executável teste (note que o alvo clobber tem o alvo clean como pré-requisito).

 

  Topo   |   Guia   |   Home