terça-feira, 14 de agosto de 2007

GNU Autotools (parte II) - Utilitários

Na continuação da apresentação dos conceitos básicos de funcionamento das Autotools, conjunto de ferramentas usadas para automatização de geração de builds de software, veremos os arquivos fundamentais presentes numa distribuição que se aproveita da infraestrutura makefile. Observando um projeto típico que usa das autoconfs, alguns arquivos são característicos, e muitos deles são de presença mandatória:


data/
debian/
m4/
samples/
src/
tests/
AUTHORS
COPYING
ChangeLog
INSTALL
Makefile.am
NEWS
README
aminclude.am
autogen.sh
configure.ac
doxygen.cfg
gmyth.pc.in


A estrutura de diretórios acima foi obtida de: http://gmyth.svn.sourceforge.net/viewvc/gmyth/trunk/gmyth/. Os arquivos com nomes em maiúsculas são documentos texto, caracteres no formato ASCII, e são descritivos do projeto, contém metadados com informações importantes, como o nome dos autores do projeto (AUTHORS) e a licença de cópia e distribuição do código (COPYING). Eles são obrigatórios, e em alguns passos de processamento, é possível que ferramentas como autoconf retornem com erro, caso não encontrem tais arquivos, apesar da aparente função de baixa prioridade que seria a de informação sobre releases de software e nomes de autores.

A seguir, por ordem de importância, temos o Makefile.am. Esse arquivo é uma espécie de Makefile, tal como visto no último post, porém em estágio de pré-processamento, ou seja, contém estruturas e macros que ainda devem ser processadas, e utiliza de variáveis definidas na sequência de montagem de build comandada pelo arquivo configure.ac (que por sua vez gera o configure). O trecho seguinte de Makefile.am apresenta algumas estruturas fundamentais:

SUBDIRS= src samples tests

(...)

if HAVE_INDENT
indent:
cd src; \
make indent; \
cd ..
endif

include aminclude.am

EXTRA_DIST = \
autogen.sh \
gmyth.pc.in \
AUTHORS \
COPYING \
README

Esse arquivo Makefile.am será utilizado como entrada no utilitário automake, as macros chamadas a partir dele serão processadas como devido, e o arquivo texto resultante será transformado no arquivo Makefile, com estruturas semelhantes àquelas vistas no post passado, porém bem mais detalhada e complexa, Por sinal, os resultados de processamento das autotools costumam ser de leitura BEM difícil para quem não estiver habituado a Makefiles e programação em Shell Script, mas depurar uma distribuição com autoconf algumas vezes necessita-se inspecionar arquivos Makefile e configure auto-gerados a fim de identificar inconsistência ou erros (como um path de biblioteca inválido, ou variável de ambiente mal definida).

Ao rodar em cima desse arquivo Makefile.am, o automake definirá, na ordem, uma variável SUBDIRS, que listará os subdiretórios do projeto que contém outras definições Makefile.am. A variável SUBDIRS é padrão, e deve sempre ser definida quando se lida com projetos mais complexos, com vários Makefiles, porque é através dele que será determinada a abrangência e a forma como o build vai ser gerado: um diretório faltando pode prejudicar a release final, bem como a inclusão de um módulo em SUBDIRS que não seja possível de ser compilado em determinada arquitetura, pode gerar problemas na execução em alguma etapa de processamento das autotools... Durante a execução, serão processados, respectivamente, arquivos Makefile.am nos subdiretórios src, samples e tests.

Pode-se, dentro de um Makefile.am, determinar a criação condicional de targets, ou adição de qualquer trecho de código, usando variáveis definidas numa etapa anterior do automake, como o uso de variáveis definidas no configure.ac (autoconf). Aqui temos que a variável HAVE_INDENT é verificada com relação ao seu valor verdade e, caso a avaliação seja positiva, o target indent é criado. Essa variável será definida TRUE caso a opção de identação de código tenha sido informada em linha de comando (durante a chamada inicial aos autotools), bem como se a ferramenta indent foi encontrada na distribuição alvo. Abaixo, vemos o trecho de código do configure.ac que cria a variável HAVE_INDENT com o valor apropriado:

# checks if the indent tool can be found
AC_CHECK_PROG(HAVE_INDENT, indent, [Found!])
if test -n "$HAVE_INDENT"; then
AC_DEFINE(HAVE_INDENT, 1, [AutoIndent found!])
fi

AM_CONDITIONAL(HAVE_INDENT, test -n "$HAVE_INDENT")

A macro M4 "AC_CHECK_PROG" funciona da seguinte forma: a variável HAVE_INDENT será declarada caso o aplicativo indent possa ser executado com sucesso em prompt de comando, imprimindo uma mensagem "Found!" em caso afirmativo. A macro AM_CONDITIONAL faz com que a variável HAVE_INDENT seja visível em escopo de arquivos de entrada Automake (Makefile.am), o que a torna passível de ser usada em expressões condicionais, como o trecho de avaliação do if no Makefile.am.

Na sequência, e voltando ao arquivo Makefile.am, temos a definição da macro EXTRA_DIST, que irá informar ao utilitário automake quais os arquivos que devem ser disponibilizados quando da geração do build de distribuição (aquele que fará parte do pacote de distribuição ao usuário do sistema de software). No caso da biblioteca GMyth acima, os arquivos distribuídos são aqueles que incorporam meta-dados de informação ao pacote (AUTHORS, COPYING), além de scripts úteis à geração do build (autogen.sh) e um arquivo de configuração para resolução de dependências (gmyth.pc.in), que serve como arquivo de entrada para o utilitário pkg-config, que procura resolver as dependências de biblioteca no ambiente constante à distribuição. Detalharemos depois o uso dessas outras ferramentas.

No próximo post, detalharei mais a respeito do processamento do configure.ac através do autotools...

Marcadores: , , ,