sábado, 14 de maio de 2011

Makefiles (arquivos make)

O make é um programa geral que constrói destinos a partir de pré-requisitos. O destino pode ser um programa executável, um documento ou uma outra coisa. Os pré-requisitos poderão ser o código Fortran, um arquivo de texto TEX, etc.

Embora você possa escrever scripts do shell simples para executar os comandos do fxx construindo um programa executável, o make é especial pelo fato de conhecer quais destinos precisam ser reconstruídos e quais não precisam.

Por exemplo: digamos que você tem um programa que consiste em três arquivos de origem Fortran. Se você construir o executável usando o comando:

$ gfortran -o teste.exe teste.f90 sub1.f90 sub2.f90

sempre que alterar qualquer um dos arquivos de origem, todos os três serão recompilados, gerando o executável. Se você alterou apenas um arquivo de origem, isto será uma verdadeira perda de tempo (especialmente se o programa em questão for muito maior). O que você deseja fazer de fato é recompilar apenas o arquivo de origem que foi alterado em um arquivo-objeto e ligar todos os arquivos-objeto no programa para formar o executável. O make pode automatizar este processo para você.

O que o make faz

O objetivo básico do make é permitir que você construa um arquivo em pequenas etapas. Se muitos arquivos de origem compuserem o executável final, você poderá alterar um e reconstruir o executável sem ter que recompilar tudo. Para fornecer tal flexibilidade, o make registrará quais arquivos você precisará para fazer a sua construção.

O texto abaixo é um exemplo de arquivo make comum. Denomine-o como makefile ou Makefile e mantenha-o no mesmo diretório dos arquivos de origem.

programa: teste.o sub1.o sub2.o
 gfortran -o teste.exe teste.o sub1.o sub2.o

teste.o: teste.f90
 gfortran -c teste.f90

sub1.o: sub1.f90
 gfortran -c sub1.f90

sub2.o: sub2.f90
 gfortran -c sub2.f90


Este arquivo irá construir um programa denominado teste.exe a partir de três arquivos de origem, teste.f90, sub1.f90 e sub2.f90. Você não está restrito à programação Fortran 90 em um arquivo make.

Quatro entradas aparecem no arquivo. Cada uma contém uma linha de dependência que mostra como um arquivo é construído. Assim, a primeira linha informa que o programa (nome antes dos dois pontos) é construído a partir dos três arquivos-objeto teste.o, sub1.o e sub2.o (os nomes depois dos dois pontos). O que esta linha informa ao make é que ele deverá executar a linha gfortran seguinte sempre que um destes arquivos-objeto for alterado. As linhas que contêm os comandos precisam começar com tabulações (não espaços).

Os arquivos depois dos dois pontos são chamados de dependentes ou de pré-requisitos. Os arquivos objeto serão construídos se eles não existirem ou se algum dos arquivos de origem associado for mais recente.

Como o make saberá se um arquivo é novo? Ele analisará o instante de modificação, que o sistema de arquivos associa a todo arquivo. Você pode ver esta informação executando o comando ls -l. Como a informação de instante de tempo tem uma precisão de um segundo, ele informará precisamente ao make se você editou um arquivo de origem desde a última compilação ou se compilou um arquivo objeto desde a última vez que o executável foi construído.

Numa primeira execução, teremos:

$ make programa
gfortran -c teste.f90
gfortran -c sub1.f90
gfortran -c sub2.f90
gfortran -o teste.exe teste.o sub1.o sub2.o


Se editarmos o sub1.f90 e executarmos de novo o comando make programa, ele irá reconstruir apenas os arquivos necessários, economizando tempo, ou seja,

$ make programa
gfortran -c sub1.f90
gfortran -o teste.exe teste.o sub1.o sub2.o


Não importa a ordem na qual as entradas estão no arquivo makefile. O make descobrirá quais arquivos dependem de quais e executará todos os comandos na ordem correta. Colocar uma entrada primeiro para o programa será conveniente, pois se tornará o arquivo construído por padrão (default). Em outras palavras, digitar make será o mesmo que digitar make programa.

Veja agora este outro exemplo:

programa: teste.o sub1.o sub2.o
 gfortran -o teste.exe teste.o sub1.o sub2.o

teste.o: teste.f90
 gfortran -c teste.f90

sub1.o: sub1.f90
 gfortran -c sub1.f90

sub2.o: sub2.f90
 gfortran -c sub2.f90

clean:
 rm -rf teste.exe teste.o sub1.o sub2.o

install:
 mkdir ./testeProg
 cp teste.exe testeProg


Neste exemplo, duas regras são adicionadas: clean e install. É comum encontrar regras de mesmo nome em códigos fontes de programas em Linux.

Algumas regras da sintaxe

A coisa mais difícil sobre manter os arquivos make, pelo menos se você não tiver experiência com eles, é ter a sintaxe correta. Se você usar espaços onde deveria colocar tabulações ou vice-versa, o seu arquivo make irá paralisar. E as mensagens de erro serão totalmente confusas.

Sempre coloque tabulação no começo de um comando, não espaços. E não use uma tabulação antes de qualquer outra linha.

Você poderá colocar uma cerquilha (#) em qualquer lugar em uma linha para iniciar um comentário. Tudo depois da cerquilha será ignorado.

Se você colocar uma barra invertida no final de uma linha, ela irá prosseguir na próxima linha. Isto funcionará em comandos longos e também em outros tipos de linhas do arquivo make.

Seção Mãos na Massa

Abaixo estão programas simples em Fortran 90 para você mesmo testar o que foi apresentado acima.

Salve o programa abaixo num arquivo chamado teste.f90:

program teste
implicit none

integer :: i,j
real :: x,y,resultado

x=1
y=2

call soma(x,y,resultado)
call imprime(resultado)

end program teste


O programa abaixo deverá ser salvo num arquivo chamado sub1.f90:

subroutine soma(valor1,valor2,resultado)
implicit none
real :: valor1,valor2,resultado

resultado = valor1 + valor2

end subroutine


E, por fim, salve o programa abaixo num arquivo chamado sub2.f90:

subroutine imprime(valor)
implicit none
real :: valor

print *,valor

end subroutine


Pronto! Com estes arquivos você pode testar a funcionalidade dos arquivos makefile.

3 comentários:

  1. Este comentário foi removido pelo autor.

    ResponderExcluir
  2. Caramba! Vai desculpando aí a remoção anteriormente feita (estava escrito erroneamente). Mas quero parabenizá-lo pelo texto. Sou iniciante em Linux mas uso fortran há bastante tempo. Agora sei fazer um makefile!

    ResponderExcluir
  3. Meus parabéns pelo texto! Me ajudou bastante.

    ResponderExcluir