terça-feira, 21 de agosto de 2007

Mais sobre GNU Autotools (parte IV)

Continuando a superficial explanação acerca dos detalhes de definição de um arquivo configure.ac, que definirá como exatamente o build do nosso sistema em questão será gerado, e por quais bibliotecas precisará gerar dependências, veremos mais alguns exemplos de chamada de macros M4 que são de uso mais frequente.

As definições de arquivos configure.ac começam com chamadas de configuração ao autoconf. Para diferenciá-las em relação às macros comuns, remetesse à notação das macros, que assumem o prefixo AC. Por exemplo, a macro AC_CHECK_FUNCS realiza uma busca pelos nomes de funções passadas como parâmetro (listas de parâmetro em M4 são representadas não por vírgulas, mas por sequências de nomes de argumentos de função, separados por espaço e tendo por limites os símbolos especiais '[' e ']'). Após serem encontrados as origens dos nomes de função, o respectivo arquivo de biblioteca e adicionado como parâmetro de compilação dos fontes do sistema. Na chamada abaixo, as funções especificadas são verificadas e seus respectivos headers e binários de bibliotecas são referenciados para serem usados depois, através de variáveis execíficas, como CFLAGS e LDFLAGS:


AC_CHECK_FUNCS([memset socket stime strstr strtoul gethostname inet_ntoa localtime_r select strrchr localtime strptime])


Essa chamada em M4 é especialmente genérica, e pode ser usada de forma incondicional para todo nome de função que se suspeite estar presente no ambiente atual de desenvolvimento. Mas tem-se definidas outras chamadas mais particulares, que buscam por chamadas bem específicas de funções:


# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_STRFTIME
AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_FUNC_VPRINTF


Todas as funções acima (fork, strftime, malloc, mktime, vprintf) são buscadas no ambiente atual, e adicionadas por padrão aos campos CFLAGS e LDFLAGS (quando necessário).

Pode-se definir parâmetros que são passados ao autoconf para que ele instrua de forma adequada a geração dos Makefiles. No código abaixo usa-se a macro AC_ARG_ENABLE para verificar se o parâmetro de linha de comando --enable-coverage foi aplicado, no caso do desenvolvedor necessitar da funcionalidade de compilação usando os recursos de teste de cobertura (coverage):


AC_ARG_ENABLE(coverage,
AS_HELP_STRING([--enable-coverage],
[enable coverage (default = no)]),
[
if test $enableval = no; then
USE_COVERAGE=no;
else
USE_COVERAGE=yes;
fi
],[
USE_COVERAGE=no;
]
)

if [ test $USE_COVERAGE = yes ]; then
CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage -O0"
LDFLAGS="$LDFLAGS -lgcov"
fi


Caso o parâmetro --enable-coverage seja passado, a variável $USE_COVERAGE será definida com valor "yes", e serão adicionados os parâmetros necessários como atributos de compilação do gcc.

A chamada abaixo sinaliza ao utilitário automake que seja executado. Ele processará todos os arquivos texto com terminação ".am", e criará a partir deles os arquivos Makefile apropriados:


AM_INIT_AUTOMAKE($PACKAGE, $VERSION)


Tendo o arquivo configure.ac definido corretamente, além dos respectivos Makefile.am (que definirão os processos de compilação e geração das builds, rodando em cima do utilitário make), a execução de autogen.sh (um script de uso bastante difundido, apesar de não vir em distibuição padrão das principais GNU autotools - quase todo projeto autoconf usa um modelo similar de autogen.sh, que simplesmente irá executar os comandos autoconf, automake, libtool, etc. numa ordem pré-estabelecida e funcional).


# ./autogen.sh


O qual terminada a execução, pode vir acompanhado da chamada ao make para que o sistema de software seja compilado e instalado:


# make all install

Marcadores: , , , , ,

quinta-feira, 10 de maio de 2007

More on Coverage Tests on Linux - Generating Better Reports

At the last post, I showed up some code that could be interesting for testing purposes, and to see how the gcov do these automatic testing procedures. In fact, gcov uses a number of techniques to cover a given test code. Internally, we can say that gcov will insert into your program object file, some kind of meta-code, which will try for a large number of meaningful execution paths. So, it uses some know strategies to select what are the most effective paths he must to cover, because is theoretically impossible just try to cover all the possible situations when a program is running.

There are 2 main types of coverage: branch coverage and loop coverage. Just to give you an idea, in the branch coverage, it is important to verify that every branch has been taken. When it uses the loop coverage, gcov try to take all the execution paths through a loop. To see more about gcov and some information about some internal working issues, refer to http://gcc.gnu.org/onlinedocs/gcc/Gcov.html.

Since our gcov execution at the last article produced some files that encapsulates all the information above, we'd got almost all we need. But could be better if we could put all the data collected from gcov in a more beautiful and useful way. That is what a tool called lcov do:


lcov -d . -c -o test_gcov.info

This simple command will search for the files generated by gcov (*.gcda, *.gcno) at the current (".") directory (-d option), and put this in the test_gcov.info. This file has the collected information about the program execution and automatic testing, but is not yet in a human-readable form. But we can put this file as an input to a very useful tool, genhtml:

genhtml test_gcov.info

After this program script finishes execution, type "ls" on your prompt and see what it had just created: a lot of images (.png), CSS (cascading style sheets) and HTML files. Open the "index.html" in your preferable browser, and it will show you how powerful this tool can really be, as a valuable way to certify that your test scripts are covering the software requirements initially specified, which test cases are important, and if you can find some dead code that you can throw off.

Marcadores: , , , , , ,