ANT: Ferramenta de build

Table of Contents

1 Introdução

1.1 Objectivo

Automatizar várias tarefas típicas associadas ao desenvolvimento de software: compilação, distribuição, instalação e limpeza.

1.2 Características do Ant

O Ant é uma ferramenta de open source para automatizar o processo de construção de aplicações, semelhante ao make.

O processo de construção é definido num ficheiro de construção (build file) em formato XML, evitando os problemas inerentes às makefiles.

As operações que é possível executar como parte do processo de construção estão implementadas em Java, sendo facilmente extensível e possibilitando a introdução de novas operações sempre que necessário. Esta característica leva a que haja uma fraca dependência do sistema operativo em uso, visto que tudo é executado através da máquina virtual Java.

2 Conceitos

2.1 Projecto (Project)

Cada ficheiro de construção contém um único projecto, que define o processo de construção.

Um projecto (project) define um ou mais alvos (targets) que executam tarefas (tasks), parametrizadas por propriedades (properties).

O projecto permite ainda a definição do seu nome; o alvo de omissão, quando nenhum é estipulado na invocação do Ant; e o directório base, a utilizar sempre que houver referências a caminhos relativos.

Todas as tarefas definidas fora de um alvo são associadas a um alvo implícito invocado sempre como parte da inicialização do projecto.

2.2 Alvos (Targets)

Num projecto podem definir-se um ou mais alvos. Cada alvo é um contentor de tarefas que cooperam para realizar parte do processo de construção.

Um alvo pode definir dependências em relação a outros alvos que devem ser executados antes, sendo a ordem por que são definidas as dependências a seguida durante a execução (excepto se houver outras dependências). Convém notar que cada alvo apenas é executado a primeira vez, mesmo que seja referido em vários pontos do grafo de dependências.

É ainda possível condicionar a execução de um alvo à existência (ou não) de propriedades definidas.

2.3 Tarefas (Tasks)

Uma tarefa (task) é um procedimento, tipicamente executado dentro de um alvo. Cada um tem diversos atributos específicos, que funcionam como argumentos para a sua execução.

O Ant fornece um conjunto de tarefas pré-definidas que satisfazem as necessidades de grande parte dos processos de construção. Existe também a possibilidade de estender o Ant com novas tarefas.

2.4 Propriedades (properties)

Uma propriedade (property) é um par nome, valor. Uma vez definida, uma propriedade não pode ser modificada, excepto de forma temporária na execução da tarefa antcall.

Sempre que se refere o nome de uma propriedade em texto, este é substituido pelo valor que lhe está associado.

3 Utilização

3.1 Execução do Ant

O Ant é executado através do comando ant e por omissão procura um ficheiro de construção chamado build.xml. Este comportamento pode ser alterado através do uso da opção -f seguida do nome do ficheiro de construção que se pretende utilizar.

 $ ant
executa o alvo de omissão do ficheiro de construção build.xml

 $ ant -f another-build.xml
executa o alvo de omissão do ficheiro de construção another-build.xml

Este vídeo apresenta o uso do Ant a partir da linha de comandos para executar um projecto exemplo.

3.1.1 Execução de alvos específico

Para executar um alvo indica-se ao Ant qual (ou quais) os alvos a executar:

 $ ant A
executa o alvo A definido no ficheiro de construção de omissão.

 $ ant A B C
executa primeiro o alvo A, seguido do alvo B e terminando com a execução do alvo C definidos no ficheiro de construção de omissão.

3.1.2 Listar alvos disponíveis

Para saber os alvos definidos num projecto pode utilizar-se a opção -p (ou -projecthelp) do Ant:

 $ ant -p

3.1.3 O Ant e o Eclipse

O IDE Eclipse suporta o uso de ficheiros de construção Ant através da View Ant (para a tornar visível: menu Window -> Show View -> Ant). No entanto não utiliza esses ficheiros para definir internamente como será o processo de construção de um projecto definido no IDE, pelo que o seu uso tem de ser explícito.

Este vídeo apresenta o uso do Ant a partir do Eclipse para executar um projecto exemplo.

3.2 Definição de propriedades

Uma propriedade define-se utilizando a tarefa pré-definida <property> e os atributos name e value.

 <property name="greeting" value="Good day!"/>

3.2.1 Propriedades que definem caminhos relativos

As propriedades são muitas vezes utilizadas para guardar caminhos do sistema de ficheiros. Utilizando a forma normal de definir uma propriedade esta representará sempre um caminho absoluto. Caso se queira definir um caminho relativo ao directório base do projecto pode utilizar-se o atributo location em vez do atributo value:

 <property name="relative-filename" location="xpto.txt"/>

3.2.2 Propriedades obtidas a partir de um ficheiro

Para ler uma ou mais propriedades definidas num ficheiro de texto pode usar-se isoladamente o atributo file da tarefa. As propriedades e seus valores encontram-se definidos no ficheiro passado nesse atributo e seguindo o seguinte formato:

 # a comment
 name1=value1
 name2=value2

A execução da tarefa abaixo define, no contexto do projecto, todas as propriedades que se encontram definidas no ficheiro build.properties:

 <property file="build.properties"/>

3.2.3 Propriedades definidas na invocação

É sempre possível definir uma variável através da linha de comandos utilizando a opção -D do Ant tantas vezes quantas as propriedades a definir:

 $ ant -Dname1=value1 -Dname2=value2 target

Nota: Uma vez que esta é sempre a primeira definição da propriedade é bastante útil quando se pretende alterar momentaneamente uma propriedade que se encontra definida no ficheiro de construção.

3.3 Definição de um alvo

Um alvo define-se através da etiqueta <target>, podendo incluir ou não tarefas a executar no seu corpo:

 <target name="A"/>
 <target name="B">
 ...
 </target>

3.3.1 Dependências de outros alvos

O atributo depends indica os alvos que têm que ser executados antes do actual. Numa execução do Ant, cada alvo é executado apenas uma vez. A ordem definida é respeitada na execução, a não ser que existam outras dependências.

 <target name="A"/> 
 <target name="B" depends="A"/> 
 <target name="C" depends="B"/> 
 <target name="D" depends="C,B,A"/>
 
 ...

 $ ant D

Neste caso, qual a ordem de execução? C, B, A, D ? (D, C, B, A), (C, B, A), (B, A), (A) ? A, B, C, D? Em casos de dúvida (como este) é aconselhável construir o grafo de dependências.

3.3.2 Dependências de propriedades

Os atributos if / unless permitem a execução de um alvo condicionada pela existência/não existência de propriedades definidas.

Dado um ficheiro de construção que inclui o seguinte alvo:

 <target name="A" if="property.1"/>

 ...

Qual o resultado de executar o alvo A?

 $ ant A

E se a execução incluir a definição da propriedade?

 $ ant -Dproperty.1=anything A

No primeiro caso a propriedade não se encontra definida, pelo que o alvo A não chega a executar-se.

No segundo caso, a propriedade é explicitamente definida aquando da execução do alvo A, pelo que este será executado.

E o que sucede quando se misturam dependências de alvos e de propriedades?

 <target name="A" if="property.1"/>

 ...

 <target name="B" depends="A" unless="property.2"> 

 ...

 </target>

 $ ant B

Neste caso, é primeiro verificado que a propriedade property.1 está definida e, na afirmativa, executa-se o alvo A. Só depois das dependências de alvos terem sido verificadas é que se verifica se a propriedade property.2 está definida e, na afirmativa, se executa o alvo B.

Assim, a seguinte execução executa A, B:

 $ ant -Dproperty.1=avalue B

Do mesmo modo, a execução seguinte não executa nenhum alvo:

 $ ant -D property.2=something B

Por fim, a invocação seguinte executa apenas A:

 $ ant -Dproperty.1=avalue -Dproperty.2=anothervalue B 

3.3.3 Alvos internos e não invocáveis via linha de comandos

Um alvo para o qual não está definida uma descrição textual é considerado interno pelo Ant, não sendo apresentado quando se pede a listagem dos alvos disponíveis de um projecto.

Um alvo cujo nome comece por - não pode ser invocado pelo Ant directamente a partir da linha de comandos, uma vez que o carácter - é considerado pelo Ant indicador de que se segue uma opção.

3.3.4 Tarefas comuns

Alguns exemplos de tarefas básicas incluidas no Ant são:

  • javac - permite compilar código-fonte Java
  • java - permite executar um programa Java
  • mkdir, copy, delete - operações sobre o sistema de ficheiros
  • echo - permite imprimir mensagens para o terminal
  • replace - permite fazer substituições de texto em ficheiros
  • tstamp - define um conjunto de propriedades pré-definidas com informação sobre o instante em que foi invocada

3.4 Definição de um projecto

Um projecto define-se recorrendo à etiqueta XML <project>. Esta pode ainda ser configurada com qualquer dos seguintes atributos: name (nome do projecto), default (alvo de omissão) e/ou basedir (directório de omissão):

 <project name="MyProject" default="build" basedir=".">

   ...

 </project>

Por omissão, o Ant procura a definição do projecto num ficheiro de construção chamado build.xml, no entanto é possível dar-lhe qualquer outro nome, bastando para tal invocar o Ant com a opção -f seguida do nome do ficheiro de construção.

 $ ant -f another-build-file.xml

3.5 Uso de propriedades

Para se utilizar o valor de uma propriedade num texto deve usar-se a notação ${nome}. Por exemplo, se a propriedade dir tiver o valor c:/proj, então ${dir}/classes é substituído por c:/proj/classes.

4 Exemplo

Uma estrutura de directórios tipicamente associada a um projecto Ant tem o seguinte aspecto:

Em src fica o código-fonte e ficheiros de propriedades (*.java, *.properties).

Em etc ficam scripts e outros ficheiros que não são código fonte (*.txt, *.sql, etc).

Em lib ficam bibliotecas extra (*.jar).

O directório build é temporário e serve para guardar as classes do programa compiladas (*.class) e outros ficheiros auxiliares.

O directório dist é temporário e serve para guardar os resultados finais da compilação, por exemplo, um arquivo JAR.

4.1 Exemplo completo de ficheiro de construção: build.xml

 <project name="MyProject" default="run" basedir=".">

     <description>simple example build file</description>

     <property name="src.dir" location="src"/>
     <property name="build.dir" location="build"/>
     <property name="inputFile" location="etc\input_file.txt"/>
     <property name="outputFile" location="etc\output_file.txt"/>

     <property name="run.mainclass" value="example.OrderPropertyFile"/>
     <property name="run.args" value="${inputFile} ${outputFile}"/>

     <target name="init">
         <mkdir dir="${build.dir}"/>
     </target>

     <target name="clean" description="Delete the build directory" >
         <delete dir="${build.dir}"/>
     </target>

     <target name="compile" depends="init" description="Compiles the source code" >
         <javac srcdir="${src.dir}" destdir="${build.dir}"/>
     </target>

     <target name="run" depends="compile" description="Runs the program" >
         <java classname="${run.mainclass}" fork="true">
             <arg line="${run.args}"/>
             <classpath>
                 <pathelement location="${build.dir}"/>
             </classpath>
         </java>
     </target>

     <target name="show" description="Shows property values" >
         <echo message="src.dir = ${src.dir}"/>
         <echo message="build.dir = ${build.dir}"/>
         <echo message="run.mainclass = ${run.mainclass}"/>
         <echo message="run.args = ${run.args}"/>
     </target>

 </project>

A definição de propriedades na linha de comandos permite alterar o comportamento observado, sem alterar o ficheiro de construção.

4.2 Aplicação de exemplo

A aplicação JavaPares é utilizada nos vídeos explicativos como exemplo de uma aplicação de consola e pode ser utilizada para exercitar o uso do Ant. Os vídeos explicativos mostram uma versão antiga desta aplicação.

5 Links úteis

Homepage e Manual do Ant

Demonstração da utilização do Ant na consola e no Eclipse

ImportAnt - para simplificar os ficheiros de construção Ant e a configuração de aplicações Web e Web Services


Partes © 2009, 2010 Docentes de Sistemas Distribuídos e de Engenharia de Software, DEI, IST, UTL

Author: < >

Date: 2010/02/24 02:12:45 AM