quinta-feira, 16 de agosto de 2007

GNU Autotools (parte III) - Configure.ac

Chegamos à etapa mais interessante dessa rápida introdução aos recursos de deployment e geração de builds com autotools. Iniciaremos essa exposição detalhando a estrutura do arquivo de configuração configure.ac e as macros M4 úteis na sua composição. Relembrando, o configure.ac é um arquivo útil para se configurar as variáveis de ambiente, onde quer que o aplicativo em desenvovimento precisar ser empacotado. Dentro do configure.ac, declararemos coisas como o nome da distro, números de versão (minor e major versions), as bibliotecas que precisam se verificadas quanto da sua existência, passagem de parâmetros de compilação para os fontes, opções de debug e teste automatizado, etc. Abaixo temos um trecho útil do configure.ac:


# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.50)

AC_INIT([gmyth],[0.3])

AC_CONFIG_SRCDIR([src/gmyth.h])
AC_CONFIG_HEADER(config.h)

dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, SVN and prerelease does Werror too
AS_VERSION(gmyth, GMYTH, 0, 3, 0, 0, GMYTH_SVN="no", GMYTH_SVN="yes")
GMYTH_MAJORMINOR=$GMYTH_MAJOR_VERSION.$GMYTH_MINOR_VERSION
AC_SUBST(GMYTH_MAJORMINOR)

(...)



Logo no início do arquivo configure.ac, temos uma chamada à macro M4 AC_PREREQ, que irá definir como obrigatório o uso da versão 2.50 da ferramenta autoconf sobre esse arquivo específico de distribuição. Caso o desenvolvedor que baixe a versão da sua biblioteca no SVN da sua empresa, por exemplo, tentar gerar os builds automáticos e os arquivos Makefile, usando uma versão anterior a 2.50 do autoconf, o procedimento de build terminará com uma mensagem de erro ao usuário, informando a necessidade de uso de uma versão mais atual. A macro AC_INIT atribui um nome para a distro, além de uma versão inicial: isso será de extrema valia quando sua equipe de desenvolvimento estiver gerenciando o lançamento de novas releases do sistema, porque a versão presente nessa tag marcará a forma como funcionará o esquema de versionamento para todos os builds subsequentes. Logo abaixo dessa chamada, temos a AS_VERSION, que detalha a versão do build atual em seções de MAJOR e MINOR version, o que aumenta a precisão com que as releases do seu sistema de software em fase de deployment será lançado, o que costuma tornar mais fácil a comunicação com outras equipes importantes no processo de software, porque cria uma linguagem comum, onde uma equipe de teste, por exemplo, poderá discernir, através da numeração de 4 partes que compõe a versão, se o build representa uma nightly-build, ou um release M1 para usuário final, por exemplo.

A macro AC_SUBST é bastante comum, e representa num arquivo configure.ac a operação de declaração de variáveis, que poderão ser partilhadas entre inúmeros arquivos Makefile.am. Como, a priori, podemos supor que exista um arquivo Makefile.am para cada módulo que compôe o sistema, a importância dessa funcionalidade atribuída por AC_SUBST fica clara, pois aí teremos uma forma de espalhar entre os módulos dados que são de necessidade comum a todos eles (como nesse caso, os números de versão MINOR e MAJOR, que poderão ser usadas por diretivas de compilação em código, denotando compilação condicional de determinados trechos, baseados em versão de build).

Veremos depois mais macros M4 úteis. Mas a boa notícia, que serve sobremaneira na tarefa de gerar o arquivo configure.ac, e a ferramenta autoscan. Para usá-la, simplesmente rode-a dentro do seu diretório de projeto:


# autoscan


Essa ferramenta tem função dupla: caso você não tenha criado uma versão inicial do configure.ac, a ferramenta autoscan irá gerar automaticamente, baseado em inspeção do código da sua aplicação, um arquivo configure.ac exemplo, chamado configure.scan (basta renomeá-lo depois para configure.ac, caso ele atenda às suas necessidades). E caso contrário, você já tenha criado seu texto plenamente funcional para o configure.ac, mas deseja verificá-lo quanto à correção, e caso você não tenha esquecido de verificar alguma dependência, a autoscan poderá gerar um relatório de advertências, que poderão servir como dicas para que você melhore o seu configure.ac:


configure.ac: warning: missing AC_CHECK_FUNCS([gethostbyname]) wanted by: src/gmyth_vlc.c:227
configure.ac: warning: missing AC_CHECK_HEADERS([arpa/inet.h]) wanted by: gmyth_file_transfer.c:50
configure.ac: warning: missing AC_CHECK_HEADERS([netdb.h]) wanted by: gmyth_file_transfer.c:53
configure.ac: warning: missing AC_CHECK_HEADERS([netinet/in.h]) wanted by: src/gmyth_socket.c:52
configure.ac: warning: missing AC_CHECK_HEADERS([sys/param.h]) wanted by: src/gmyth_socket.c:44
configure.ac: warning: missing AC_CHECK_HEADERS([sys/time.h]) wanted by: src/gmyth_util.c:40
configure.ac: warning: missing AC_FUNC_REALLOC wanted by: src/gmyth_http.c:965
configure.ac: warning: missing AC_PROG_RANLIB wanted by: ltmain.sh:6817
configure.ac: warning: missing AC_TYPE_SIZE_T wanted by: src/gmyth_http.c:960


No log da autoscan acima, ela aconselha que eu faça a verificação de dependências de biblioteca para a minha aplicação, usando a macro AC_CHECK_FUNCS, que é bastante útil, e realiza uma busca nas bibliotecas (.so, .a, shared ou static libraries, etc.) por um determinado nome de função. Caso o nome de função solicitado seja encontrado, a biblioteca que o encapsula será incluída como parâmetro para que o GCC ou outro compilador a inclua como parâmetro de biblioteca.

Mais detalhes sobre a geração dos builds propriamente ditos no próximo post...

Marcadores: , , , , ,