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: , , , , ,

sábado, 12 de maio de 2007

Real Case Application of Coverage Tests on Linux - Part 3

These special topics on coverage tests I made are based on real case situations of tests implementation, when I used to think about a nice way to certify that the user requirements needs related to a MythTV protocol API implementation I´m developing are well concerned. This API is not the official one, based on the MythTV server and client implementations, but another totally different effort based on GObject/GLib frameworks and object model.

The main test architecture I had developed is to allow that the test script's writer could develops the testing scripts with the minimum possible effort. So, I choose to use Python as the language of choice on the test scripts, because it's easier to learn, and removes the extra step of compiling code, because Python is interpreted. Each one of these Python scripts do, at least, one basic task: start a process with the testing program, compiled with the gcov program line arguments. A very simple strategy had been used to guarantee that the process testing stoped at a given known time, and the Python script could be signalized about the program termination.

You can see all these concepts, and see how to code gcov-based tests in practice, seeing my contribution on GMyth's SourceForge: http://sourceforge.net/projects/gmyth.

Have a lot of fun! :)

Marcadores: , , , , ,