Tutorial para criar a estrutura de arquivos do autoconf & automake para seu projeto

Esse é um tutorial resumido para mover um programa baseado no Makefile para uma estrutura baseada nos arquivos autoconf, automake e libtool. Uma visão completa, baseada em um exemplo, será abordada aqui. Se sua estrutura inicial não for exatamente como a proposta, provavelmente você não precisará executar os passos seguintes.

Definindo o problema:

PRE: Você tem um diretório com a seguinte divisão

  • código-fonte em src/
  • documentação em doc/
  • man-pages em man/
  • Alguns scripts em scripts/ (em geral, coisas que serão instaladas mas não compiladas)
  • exemplos em examples/

POST: Você quer

  • checar a disponiblidade de bibliotecas necessárias
  • possivelmente ajustar algumas coisas (como alguns caminhos em scripts ou em documentação) em tempo de compilação
  • instalar tudo em seu lugar

Assim, isso é o que fazer para fazer tudo com o minimo esforço:

  1. Limpeza
    Remover qualquer Makefile que estiver no pacote (renomeie por enquanto)
  2. Gerar o arquivo configure.ac
    Executar autoscan:

    $ autoscan

    O autoscan tenta produzir uma arquivo configure.ac correto pela execução de analises simples nos arquivos do pacote. Isso é  o bastante no momento (muitas pessoas se satisfazem com isso permanentemente). O autoscan normalmente produz um arquivo conigure.scan, assim temos que renomear o arquivo dessa maneira:

    $ mv configure.scan configure.ac
  3. Ajustando os arquivos
    Para ajustar as poucas coisas que o autoscan deixa para você, abra o arquivo configure.ac em seu editor de texto preferido:

    $ vim configure.ac

    observe nas primeiras linhas pela linha abaixo:

    AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)

    e substitua pelos seus dados, por exemplo:

    AC_INIT(pippo, 2.6, paperino@staff.pippo.org)
  4. Gerando um script configure inicial
    Neste ponto, você tem tudo o necessário para que o autoconf produza o script configure:

    $ autoconf

    Isso produz dois arquivos: autom4te.cache e configure. O primeiro é um diretório usado para acelerar o trabalho das ferramentas, e pode ser removido quando o pacote for liberado. O outro é o script shell que é chamado pelos usuários finais.
    Nesse ponto, o  que o arquivo configure faz é somente checar por dependências como sugerido pelo autoscan, então nada muito conclusivo ainda.

  5. Gerando os Makefiles
    Nós já temos a parte de checagem do sistema. Agora queremos a parte de compilação e instalação. Isso é feito pela cooperação entre o automake e o autoconf. O automake gera alguns “modelos” que os scripts gerados pelo autoconf traduzirão nos MAkefiles. Um arquivo makefile inicial é necessário na raiz do pacote:

    $ vim Makefile.am

    liste os sub-diretórios onde o trabalho é necessário:

    AUTOMAKE_OPTIONS = foreign
    SUBDIRS = src doc examples man scripts

    a primeira linha configura o modo que o automake assumirá. O modo “foreign” significa não GNU, e é comum ser usado para evitar mensagens chatas sobre arquivos organizados de uma maneira que somente o gnu expera.
    A segunda linha mostra a lista de sub-diretórios onde se encontram os arquivos a serem trabalhados. O primeiro tem as coisas a serem compiladas, enquanto o resto apenas precisa ser instalado, mas nós não nos importamos com esse arquivo. Iremos preparar agora o arquivo Makefile.am para cada um desses diretórios. O automake irá passar por casa um deles para produzir o arquivo Makefile.in correspondente. Esses arquivos *.in serão usados pelos scripts do autoconf para produzir os arquivos Makefile finais. Edite o src/Makefile.am:

  6. $ vim src/Makefile.am

    e insira:

    # what flags you want to pass to the C compiler & linker
    CFLAGS = --pedantic -Wall -std=c99 -O2
    LDFLAGS =
    
    # this lists the binaries to produce, the (non-PHONY, binary) targets in
    # the previous manual Makefile
    bin_PROGRAMS = targetbinary1 targetbinary2 [...] targetbinaryN
    targetbinary1_SOURCES = targetbinary1.c myheader.h [...]
    targetbinary2_SOURCES = targetbinary2.c
    .
    .
    targetbinaryN_SOURCES = targetbinaryN.c

    Essa é a parte mais dificil. Em geral, os sufixos em letras maiusculas como “_PROGRAMS” são chamados primary e dizem parcialmente o que executar no seu argumento; os profixos, em letras minusculas (não tem um nome pré-fixado) dizem o diretório onde será instalado.
    Exemplo:

    bin_PROGRAMS

    instala os arquivos binários em $(PREFIX)/bin , e

    sbin_PROGRAMS

    instala-os em $(PREFIX)/sbin . Mais primárias irão aparecer mais abaixo, e aqui está uma lista comleta delas. Nem todas podem ser pré-fixadas.

    Vamos agora passar para as man-pages:

    $ vim man/Makefile.am

    insira a seguinte linha:

    man_MANS = firstman.1 secondman.8 thirdman.3 [...]

    sim, o automake deduzirá sozinho o que é necessário para a instalação a partir dessa linha. Agora para o scripts:

    $ vim scripts/Makefile.am

    insira:

    bin_SCRIPTS = script1.sh script2.sh [...]

    A primária “SCRIPTS” instrui o Makefile a apenas instalar os argumentos, sem nenhuma comilação.

    Até agora estamos indo bem. Duas coisa ainda faltam definir: a instalação dos exemplos e documentos de texto. Essa é a parte chata, já que o automake não tem primárias para processar a instalação desses arquivos. O jeito aqui é definir uma variável e usa-la como primária:

    $ vim doc/Makefile.am
    docdir = $(datadir)/doc/@PACKAGE@
    doc_DATA = README DONTS

    Se “abc” é necessário, “abcdir” deve ser especificado. Exemplo: o código acima será expandido para /usr/local/share/doc/pippo (“@PACKAGE@” será expandido pelo autoconf quando for produzido o arquivo Makefile final). $(datadir) é conhecido por todos os scripts configure gerados. Você pode checar a lista de variaveis de diretório aqui.

    De modo similar, para os exemplos queremos instala-los em $(PREFIX)/share/examples/pippo, então:

    $ vim examples/Makefile.am
    exampledir = $(datarootdir)/doc/@PACKAGE@
    example_DATA = sample1.dat sample2.dat [...]

    Todos os arquivos Makefile.am agora existem, mas o autoconf tem agora que tomar conhecimento deles.

  7. Integrando a parte da checagem (autoconf) com a parte da compilação (automake)
    Nós vamos inserir agora alguns macros no arquivo configure.ac para dizer ao autoconf que os arquivos Makefile devem ser produzidos depois do ./configure:

    $ vim configure.ac

    logo depois do AC_INIT(), vamos iniciar o automake:

    AM_INIT_AUTOMAKE(pippo, 2.6)

    depois, deixe o autoconf gerar um script configure cuja saida será Makefiles para todos os diretórios citados:

    AC_OUTPUT(Makefile src/Makefile doc/Makefile examples/Makefile man/Makefile scripts/Makefile)
  8. Making tools output the configure script and Makefile templates
    Nós temos nesse momento todas as instruções para gerar o famoso script configure executado pelos usuários para instalar aplicativos, que checa tanto por dependências de compilação/execução quanto gera Makefiles para compilar e instalar tudo no seu devido lugar. Vamos agora criar as ferramentas que geram cada script.

    $ aclocal

    Isso gera o arquivo aclocal.m4 que contém macros para as coisas do automake, por exemplo, AM_INIT_AUTOMAKE.

    $ automake --add-missing

    O automake lê nesse momento o configure.ac e o Makefile.am, interpreta-os e, para cada Makefile.am produz um Makefile.in. O argumento –add-missing diz ao automake para fornecer scripts padrão para qualquer erro reportado, assim pode ser omitido nas próximas execuções;
    Finalmente, deixe o autoconf gerar o script configure:

    $ autoconf

    Isso produz o script shell final e completo configure.