ANT 기초

 

앤트(ANT)란?

ANT는 자바 언어를 사용하여 필요한 일련화된 과정을 자동화하는 소프트웨어 빌드 도구입니다.

ANT를 동작하기 위해서는 자바를 설치하거나 자바를 다운로드 받거나 실행을 위하여 환경변수에 설정하여 주어야 하며

ant는 기본적으로 xml을 지향하므로 xml에 관한 기본적인 지식이 필요합니다.

자바(JAVA) 설치

ANT는 자바를 사용하여 작성된 툴이기 때문에 ANT를 사용하기 전 먼저 JAVA를 다운받거나 등록 하여야 합니다.

자바 설치는 이 포스팅에서 하지 않으며 공식 오라클 또는 openJDK를 다운 받아 설치 도는 경로를 잡아 주도록 하세요

앤트(ANT) 설치

이번에는 빌드하기 위한 ANT를 설치해 보도록 하겠습니다.

앤트(ANT)를 다운로드하자

자바를 설치 하였다고 가정하여 기본적으로 ant를 사용할수 있는 기초가 만들어 졌습니다.

먼저 ant를 사용하기 위해서는 자바를 설치할 필요가 있다고 말하였습니다.

자바를 언제 사용할지 몰라 당황하였다면 이제 설치한 자바를 사용하는 ANT를 다운받아 보도록 하겠습니다.

ANT는 아파치 제단에서 만들어진 소프트웨어로써 아파치 제단의 기본적인 이념은 비영리적인 소프트웨어의 배포이기 때문에 2차 저작권에 대한 저작권법이 느슨한 편입니다.

아파치제단의 공식 사이트에서 직접 다운로드를 받거나 미리 다운로드 받아 놓은 본인의 깃 허브에서 앤트를 다운로드 받도록 합니다.

다운로드 받은 파일은 앤트를 사용할 폴더를 만든 다음 압축을 해제해 주세요.

환경변수로 등록(Windows)

다운로드가 완료 되었으면 이제는 환경변수를 등록하는 일이 남았습니다

자바를 설치할때 환경변수의 PATH를 등록한 경험이 있을 것입니다

환경변수에 경로를 등록한다는 것은 시스템(os)에서 사용 가능한 리소스로 등록 한다는 것입니다

쉽게 설명하여 간단한 경로를 등록하여 환경변수를 등록하는 이유를 알아 보도록 하겠습니다.

환경변수를 등록할 폴더를 하나 선택한 다음 마우스의 오른쪽을 클릭하여 빈 배치파일(eco.bat)을 생성 합니다.

생성 된 배치파일을 오른쪽 에디터를 사용하여 열도록 합니다.

다음으로 아래 코드를 작성하도록 합니다.

@ECHO OFF

echo %1

이제 이 파일을 실행해 보도록 하겠습니다.

해당 폴더에의 검색창에 cmd를 작성한 다음 엔터를 치게 되면 명령 프롬프트창이 오픈 되고 해당 폴더의 경로를 찾아 가도록 되어 있습니다.

다음으로

eco "hello ant"

hello ant

자 그럼 이제 드라이브의 루트 폴더로 이동합니다.

cd C:\

다음으로 echo.bat 파일을 실행하는 동일한 명령어를 실행하면 아래와 같은 에러를 발생시킵니다.

eco "hello ant"

'eco'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.

이렇듯이 기존 시스템에 없는 실행 파일이나 리소스를 시스템에서 사용 가능하도록 하려면 환경 변수에 등록 하여야 합니다.

다시 돌아가서 이제 환경변수의 PATH를 등록해 보도록 할까요?

먼저 우 버튼을 누른 다음 시스템 환경 변수 편집을 선택하도록 합니다.

열린 창에서 고급 탭으로 이동한 다음 하단에 환경 변수 항목이 보이실 것입니다.

환경 변수를 편집하기 전 먼저 알아야 될 것은 환경 변수는 사용자에 따른 변수와 시스템(모든 사용자)에 관한 환경변수가 있기 때문에

모든 사용자가 사용해야 할 것이라면 시스템 변수에 등록 할 것이며 해당 사용자만 사용할 것이라면 사용자 변수에 등록 하면 됩니다.

저는 여러 사용자가 같이 사용하는 공유 데스크톱이므로 사용자 변수에 등록해 보도록 하겠습니다.

새로 만들기 버튼을 클릭한 다음

변수 이름과 변수 값을 주어 보도록 하겠습니다.

(변수 이름은 TEST_HOME으로 변수 값을 eco.bat파일이 있는 폴더경로를 지정하도록 하겠습니다.)

이제 다시 커맨드 창을 새로 오픈한 다음 아래 명령어를 입력해 보세요

echo %TEST_HOME%

C:\dev\test

tip

나오지 않는다면 커맨드 창을 새롭게 오픈한 다음 도전해 보세요


이번에는 Path에 등록해 보도록 하겠습니다 시스템 변수에서 Path항목을 찾으신 다음 더블클릭하여 오픈하세요.

다음으로 새로 만들기를 클릭하여 이전 변수로 등록한 경로를 지정합니다.

확인 버튼을 클릭하여 모두 나온 다음 이제 방금전에 실패하였던 eco.bat 파일을 실행해 보도록 하겠습니다.

eco "Hello Ant"

"Hello Ant"

이제 환경변수와 PATH에 관한 기본적인 사항을 이해하였을 것입니다.

그렇다면 실제 ANT의 환경변수를 등록해 보도록 할까요?

환경변수를 등록할 때에는 시스템(OS)에 따라 설정법이 다르며 설정 후에는 시스템과는 무관하게 작동하니 걱정하지 마세요.

순서는 아래와 같습니다.

  • 시스템 환경 변수 편집을 오픈합니다.

  • 환경 변수를 오픈합니다.

  • 새로 만들기 버튼을 클릭하여 ANT_HOME을 등록합니다.

  • Path경로를 찾아 더블클릭 한 다음 새로 만들기 버튼을 클릭하여 아래 코드를 추가 합니다.

%ANT_HOME%\bin

(마지막에 \bin을 등록하는 이유는 실행 파일이 bin폴더에 존재하기 때문입니다.)

어렵지는 않았을 것이라 생각합니다.

커맨트 창으로 돌아가서 아래 명령어를 실행하여 잘 반영 되었는지 확인합니다.

ant -version

Apache Ant(TM) version 1.10.8 compiled on May 10 2020

잘 반영이 되었다면 버전 정보와 함께 버전이 업데이트 된 일자를 출력할 것입니다.

환경변수로 등록(Mac)

다운로드가 완료 되었으면 이제는 환경변수를 등록하는 일이 남았습니다

자바를 설치할때 환경변수의 PATH를 등록한 경험이 있을 것입니다

환경변수에 경로를 등록한다는 것은 시스템(os)에서 사용 가능한 리소스로 등록 한다는 것입니다

쉽게 설명하여 간단한 경로를 등록하여 환경변수를 등록하는 이유를 알아 보도록 하겠습니다.

환경변수를 등록할 폴더를 하나 선택한 다음 아래 명령어를 사용하여 편집기를 여세요

> vi echo.sh

편집기가 열리면 a를 누른 다음 편집모드에 들어간 다음 아래 코드를 입력하세요.

#!/bin/bash
echo "echo >> $1"

그런 다음 shift + :를 눌러 확장모드로 돌아와 wq(저장 후 종료)를 사용하여 터미널로 돌아옵니다.

이제 권한을 주도록 하겠습니다.

> chmod +x eco.sh

이제 실행 권한이 있는 파일을 실행해보도록 하겠습니다.

> ./eco.sh "hello ant"

echo >> hello ant

자 그럼 이제 사용자의 루트 폴더로 이동합니다.

cd ~

다음으로 echo.sh 파일을 실행하는 동일한 명령어를 실행하면 아래와 같은 에러를 발생시킵니다.

> ./eco.sh "hello ant"

no such file or directory: ./eco.sh

이렇듯이 기존 시스템에 없는 실행 파일이나 리소스를 시스템에서 사용 가능하도록 하려면 환경 변수에 등록 하여야 합니다.

다시 돌아가서 이제 환경변수의 PATH를 등록해 보도록 할까요?

먼저 .bash_profile을 만들어야 합니다.

cd ~ | vi .bash_profile

이제 경로를 등록해 보겠습니다.

# eco.sh가 생성된 폴더의 경로를 지정합니다.
TEST_HOME=eco.sh의 폴더 경로

# 시스템에서 사용할 PATH에 기존 PATH를 추가합니다.
PATH=$PATH:$TEST_HOME

# 외부에서 사용할 수 있도록 TEST_HOME 변수를 노출합니다.
export TEST_HOME

이제 터미널로 돌아온 다음 변경 된 소스 파일을 반영합니다.

source .bash_profile

시스템에서 우리가 만든 eco.sh를 사용하기 위한 준비가 되었습니다.

이제 아무곳에 가서 이전 에러가 난 명령어를 실행해 보도록 하세요

> eco.sh "hello ant"

echo >> hello ant

또는 노출된 경로를 사용할 수도 있습니다.

> eco.sh $TEST_HOME

echo >> 지정한 경로

이제 환경변수와 PATH에 관한 기본적인 사항을 이해하였을 것입니다.

그렇다면 실제 ANT의 환경변수를 등록해 보도록 할까요?

환경변수를 등록할 때에는 시스템(OS)에 따라 설정법이 다르며 설정 후에는 시스템과는 무관하게 작동하니 걱정하지 마세요.

먼저 .bash_profile 파일을 편집기로 엽니다.

cd ~ | vi .bash_profile

편집모드로 변경한 다음 ANT_HOMEPATH를 설정하도록 합니다.

ANT_HOME=~/dev/tools/ant/apache-ant-1.10.8

PATH=$PATH:$ANT_HOME/bin

export ANT_HOME

이제 터미널로 돌아온 다음 변경된 소스파일을 반영합니다.

source .bash_profile

어렵지는 않았을 것이라 생각합니다.

터미널로 돌아가서 아래 명령어를 실행하여 잘 반영 되었는지 확인합니다.

> ant -version

Apache Ant(TM) version 1.10.8 compiled on May 10 2020

잘 반영이 되었다면 버전 정보와 함께 버전이 업데이트 된 일자를 출력할 것입니다.

ANT 기본 속성들 및 기초

여기까지 잘 따라 오셨습니다.

이제부터가 ANT를 다루는 실제 구간입니다.

여기서 부터는 한걸음 한걸음씩 설명할 예정이니 어렵지 않게 따라하고 습득할수 있으실 것입니다.

먼저 ant 파일을 만들어 보겠습니다.

(원하는 곳에 폴더를 만든 다음 작업 하도록 합니다.)

파일의 명칭은 build.xml으로 하여 파일을 생성한 다음 build.xml 파일을 열어 수정 할 준비를 합니다.

(vscode, sublime와 ultra edit와 같은 편집기를 사용하시면 더욱 편합니다.)

가장 먼저 알아야 할 것은 ant에 최종 태그는 project라는 것입니다.

(빌드 스크립트안에서는 오직 하나의 project 태그만이 있습니다.)

따라서 먼저 최상단에 project 태그를 등록하겠습니다.

<project>

</project>

여기까지만 작성한 다음 명령어 실행기(cmd, terminal)을 실행한 다음 해당 경로로 이동하여 아래 명령어를 실행합니다.

ant

Buildfile: ...

BUILD SUCCESSFUL
Total time: 0 seconds

축하합니다.

ant 빌드를 처음으로 경험하였습니다.

우리는 지금 ant를 설치하고 ant의 빌드툴을 사용하여 실제 자동화된 빌드를 처리하는 일을 하였습니다.

하지만 현제는 아무런 기능도 없는 깡통으로 된 빌드입니다.

이 빌드툴에게 일을 하나씩 던져 주면서 빌드툴과 관련 된 내용을 하나씩 알아가 보도록 하겠습니다.

스크립트를 첫 작성(echo)

이번에 작성해볼 작업은 echo 태그를 사용하여 간단한 빌드 스크립트를 작성해 보도록 하겠습니다.

이전 작성한 스크립트 파일(build.xml)파일을 오픈합니다.

이제 project 태그 아래 target 태그를 추가해 주도록 하겠습니다.

target은 실제 빌드 시 작업 단위로써 여러개의 빌드 단위를 지닐 수 있습니다.

먼저 target태그를 추가해 보겠습니다.

<project>
    <target>

    </target>
</project>

방금전 말한 바와 같이 target은 빌드의 작업 단위이므로 여러개가 만들어 질 수 있다고 하였습니다.

따라서 각 타겟은 고유한 아이디를 지니고 있으며 이 아이디를 name 속성 값을 사용하여 나타냅니다.

(예제에서는 name을 default로 지정하였으며 다르게 지정하여도 무방합니다.)

<project>
    <target name="default">

    </target>
</project>

target의 고유 아이디가 주어졌으며 이 고유 아이디를 사용하여 default라는 속성값을 사용하여 빌드 스크립트의 기본 빌드를 지정해 보도록 하겠습니다.

(기본 빌드는 ant명령어를 실행하였을 경우 target을 지정하지 않을 경우 실행 되는 기본 실행 target을 말합니다.)

<!-- 아래 "default" name을 가진 target을 지정합니다 -->
<project default="default"> 
    <target name="default">

    </target>
</project>

이번에는 빌드스크립트를 진짜 살아 움직이게 해 보아야 겠죠?

빌드 시 사용되는 실제 동작은 task를 사용하여 동작하게 할 수 있습니다.

(각각의 task는 이 블로그에 나오는 부분들을 천천히 사용해보며 익숙해지면 되므로 어렵게 생각하지 마세요)

우리는 먼저 echo task를 사용해 보도록 하겠습니다.

사용하기 위해서는 target태그에 echo태그를 등록하는 일부터 시작하겠습니다.

<project default="default"> 
    <target name="default">
        <echo />
    </target>
</project>

이제 메시지를 하나 출력해 보겠습니다.

(메시지는 message 속성값을 사용하거나 태그 내부에 값을 등록하여 수행 할수 있습니다.)

<project default="default"> 
    <target name="default">
        <echo message="Hello Ant Build Tools"/>
    </target>
</project>

또는 태그 내부에 값을 등록 할 수도 있습니다.

<project default="default"> 
    <target name="default">
        <echo>Hello Ant Build Tools</echo>
    </target>
</project>

s∏∏

여러분의 첫번째 빌드 스크립트 자동화가 생성되었습니다.

이제 여러분이 생성한 빌드 스크립트를 ant를 사용하여 실행해 보세요

ant

Buildfile: ...


default:
     [echo] Hello Ant Build Tools

BUILD SUCCESSFUL
Total time: 0 seconds

어떠신가요 ant가 어려우셨나요?

별로 어렵지 않다고 느끼셨을꺼라 생각합니다.


tip

build.xml말고 다른 이름으로 빌드 파일을 만드셨다면 -f 옵션을 사용하여 빌드 스크립트를 실행 시 파일을 지정할 수 있습니다.

buildScript.xml 명으로 파일로 생성하였을 경우 아래 명령어로 ant를 실행 할수 있습니다.

ant -f buildScript.xml

이번에는 echo task를 좀더 확장해 보도록 하겠습니다.

echo를 활용하여 파일 로그를 작성해 보도록 하겠습니다.

파일 로그는 file, append, encoding 속성값을 추가 하여 사용할 수 있습니다.

<project default="default"> 
    <target name="default">
        <echo file="C:\dev\test\log" append="true" encoding="utf-8">Hello Ant Build Tools</echo>
    </target>
</project>

ant를 실행 후 해당 경로를 찾아가보면 파일이 생성되어 있는 것을 확인 하실수 있을 것입니다.

이번에는 로그에 레벨을 추가해 보겠습니다.

로그 레벨은 debug, verbose, info, warning, defaulterror가 있습니다.

각 로그레벨은 실행시 인자값을 사용하여 로그를 켜거나 끌수 있습니다.

자세한 사항은 아래 표로 정리하였습니다.

level default -q(quiet) -v(verbose) -d(debug)
error O O O O
default O O O O
warning O O O O
info X O O O
verbose X X O O
debug X X X O

level을 지정하는 방법은 level속성값을 사용하여 등록 할 수 있습니다.

<project default="default"> 
    <target name="default">
        <echo file="C:\dev\test\log" append="true" encoding="utf-8" level="debug">Hello Ant Build Tools</echo>
    </target>
</project>

다음으로 빌드 실행 시 인자값을 사용하여 출력 대상을 제한할 수 있습니다.

ant -q

BUILD SUCCESSFUL
Total time: 0 seconds

echo가 찍히지 않고 빌드가 실행 되는 것을 확인 할 수 있습니다.

설정값 등록(Properties)

이번에 알아볼것은 프로그래밍에서 가장 중요한 설정값입니다.

모든 프로그램에서는 다이나믹한 실행을 위하여 설정값을 등록하여 참조 하는것을 알고계실 것입니다.

기본적으로 설정값이라는 것은 룰을 지정하는 것이므로 ant는 설정에 의한 빌드자동화를 지원하고 있다고 할수 있습니다.

그러면 먼저 설정값을 추가하는 방법에 관하여 알아 보겠습니다.

ant는 다양한 설정값을 참조하는 방법을 지원하며 실제로 설정값을 등록하는 아래 방법은 3가지 방법이 있습니다.

  1. 내부의 설정 값(내부 파일에서 직접 참조)
  2. 외부의 설정 값(외부 파일을 참조)
  3. 인자로써의 설정 값(실행 시 참조)

먼저 내부 설정부터 알아보도록 하겠습니다.

내부의 설정 값 참조

설정 값을 property태그를 사용하여 등록 할 수 있습니다.

먼저 property태그를 등록해 보도록 하겠습니다.

<project default="default"> 

    <property/>

    <target name="default">
        <echo file="C:\dev\test\log" append="true" encoding="utf-8" level="debug">Hello Ant Build Tools</echo>
    </target>
</project>

이전 target과 동일하게 설정 값을 하나이상이 등록 될 수 있으므로 name속성값을 사용하여 각 설정값을 구분할 수 있습니다.

(저는 log의 파일 경로를 설정값으로 추가해 보도록 하겠습니다.)

<project default="default"> 

    <property name="file_path"/>

    <target name="default">
        <echo file="C:\dev\test\log" append="true" encoding="utf-8" level="debug">Hello Ant Build Tools</echo>
    </target>
</project>

값은 value속성값을 사용하여 등록 할 수 있습니다.

<project default="default"> 

    <property name="file_path" value="C:\dev\test\log"/>

    <target name="default">
        <echo file="C:\dev\test\log" append="true" encoding="utf-8" level="debug">Hello Ant Build Tools</echo>
    </target>
</project>

이제 ant에서 사용하는 메타기호인 ${}를 사용하여 등록 된 property를 가져와보도록 하겠습니다.

<project default="default"> 

    <property name="file_path" value="C:\dev\test\log"/>

    <target name="default">
        <echo file="${file_path}" append="true" encoding="utf-8" level="info">Hello Ant Build Tools</echo>
    </target>

</project>

이제 빌드를 실행해 보도록 하겠습니다.

ant

BUILD SUCCESSFUL
Total time: 0 seconds

로그 파일을 열어 결과를 확인해 보면 잘 실행된다는 것을 알수 있습니다.

외부의 설정 값 참조

이번에는 외부의 파일을 사용하여 설정값을 참조해 보도록 하겠습니다.

먼저 external.properties 파일을 하나 생성해 한 다음 설정값을 아래와 같이 키=값 형태로 등록 합니다.

file_path=C:\dev\test\log

이렇게 등록 된 설정 파일을 불러오기 위해서는 file속성을 사용하여 불러올 수 있습니다.

<project default="default"> 

    <property file="external.properties"/>

    <target name="default">
        <echo file="${file_path}" append="true" encoding="utf-8" level="info">Hello Ant Build Tools</echo>
    </target>

</project>

의존성과 ANT의 기본 기능

target은 하나 이상이 생길 수 있다고 말한 적이 있습니다.

또한 하나 이상의 target들은 각각 다른 기능을 수행하지만

순차적또는 계층적으로 구분이 필요 할 수도 있습니다.

이번에는 이 target에 의존성을 추가하여 작업하도록 하겠습니다.

파일 복사 해보기

이번에는 의존성을 사용하여 파일을 복사하는 tasks를 만들어 보도록 하겠습니다.

먼저 build.xml 파일이 있는 곳으로 가서 data.h파일을 하나 생성한 다음 생성 된 파일을 메모장으로 열어 아래 글을 입력합니다.

hello ant this is dependency task !!

이제 파일을 닫은 다음 이 파일을 복사하여 dist라는 곳에 붙여넣기 해 보도록 하겠습니다.

먼저 build.xml파일을 생성한 다음 project 태그를 등록합니다.

(처음부터 작성 할 것이니 이전에 build.xml파일이 있을 경우 모두 제거 하세요)

<project>

</project>

다음으로 두가지의 target을 만들도록 하겠습니다.

첫번째로는 build target과 두번째로는 copy target을 만든 다음 default target을 copy로 지정하여 줍니다.

<project default="copy">
    <target name="build">
    </target>
    <target name="copy">
    </target>
</project>

두 target의 기능은 아래와 같습니다.

  1. build target에서는 echo task를 사용하여 dest 폴더에 build.log를 생성합니다.
  2. build target에서는 이전 생성한 data.h 파일을 dest 폴더에 복사합니다.
  3. data.h파일과 build.log 파일을 copy target에서 copy task를 사용하여 dist 폴더로 복사합니다.

먼저 build target의 build.log를 생성하는 코드를 작성해 보도록 하겠습니다.

(echo task는 이전 작성한 코드를 가져와 사용하겠습니다.)

<project default="copy">
    <target name="build">
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
    </target>
    <target name="copy">
    </target>
</project>

다음으로 이전에 만들어 놓은 data.h 파일을 복사해 보도록 하겠습니다.

Copy - 복사를 위한 작업

복사는 copy task를 사용하여 복사할 수 있습니다.

copy task는 파일을 읽는 file속성과 복사할 파일 위치를 알리는 tofile(파일) 또는 todir(폴더) 속성을 사용하여 복사 할 수 있습니다.

(각 task는 중급편에서 더 자세히 다를 예정이므로 기초에서는 ant에서 자주 사용하는 필수적인 요소만을 다루도록 하겠습니다.)

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
    </target>
</project>

build 소스를 완료 하였으니 build target을 실행해보도록 하겠습니다.

커맨드 또는 터미널창을 열어 build.xml 파일이 존재 하는 곳으로 이동한 다음

아래 명령어를 작성하여 실행하도록 합니다.

ant build
Buildfile: 빌드 파일 경로

build:
     [copy] Copying 1 file to 빌드 파일 경로/dist

BUILD SUCCESSFUL
Total time: 0 seconds

빌드가 잘 실행 된다는 것을 알 수 있습니다.

이제 폴더를 확인해 보세요.

아마 dist폴더가 만들어졌으며 해당 폴더 내부에서는 data.h파일과 build.log 파일이 존재할 것입니다.

이번에는 copy target을 마저 작성하러 가볼까요?

copy target은 좀 쉽겠죠?

(copy task의 자세한 속성 정보는 공식 링크를 확인하세요)

Mkdir - 폴더 생성을 위한 작업

이번에는 복사하기 전 먼저 복사할 폴더를 만들어야 합니다.

폴더를 생성하는 일은 mkdir task를 사용하여 복사할 폴더를 생성할 수 있습니다.

(우리에는 복사할 폴더 dest를 만들어겠습니다.)

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
        <!-- mkdir task 는 dir속성 하나밖에 없는 단순한 task 입니다. -->
        <mkdir dir="dest"/>
    </target>
</project>

이제 copy task 태그를 등록하는 것부터 시작합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
        <mkdir dir="dest"/>
        <copy>
        </copy>
    </target>
</project>

build task에서 했던 작업은 파일 하나를 이동하기 위해서였다면 이번에는 하나의 폴더 내에 여러 파일 또는 파일을 선택하여 복사해 보도록 하겠습니다.


Tip

폴더를 생성하는 이유는 copy의 경우는 폴더 단위의 복사보다는 파일단위의 복사가 편리하게 작성되어 있기 때문입니다.

만일 폴더 단위의 복사가 잦은 유형이라면 copydir을 사용하여 복사할 수 있습니다.

copydir은 복사할 폴더를 src로 지정하고 복사할 폴더를 dest로 지정하여 폴더를 통채로 복사할 수 있습니다.

또한 뒤편에서 다룰 ant pattern을 사용하여 includes와 excludes를 지정하여 폴더내에 원하는 파일을 필터링 할수도 있습니다.

...
<copydir src="dist" dest="dest" [includes,excludes,...]/>
...

( copydir의 자세한 속성들은 공식 링크를 참조 하세요 )


FileSet과 Resources - 리소스 선택자

기존의 copy의 경우는 단일 file을 선택하여야 했을 것입니다.

하지만 파일을 복사하기 위해서는 하나 이상의 파일 또는 폴더를 선택하여 복사할 것입니다.

따라서 우리는 이제 File들의 묶음인 fileset과 Resource들의 묶음인 resources를 사용해볼 것입니다.

fileset을 사용하기 위해서는 기존의 소스내부에 fileset태그를 추가해 주도록 합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
        <mkdir dir="dest"/>
        <copy>
            <fileset>
            </fileset>
        </copy>
    </target>
</project>

다음으로 dir속성을 사용하여 복사할 대상인 dist 를 기준 디렉토리로 설정합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
        <mkdir dir="dest"/>
        <copy>
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
</project>

이제 copy task에 복사할 목적지를 지정하도록 하겠습니다.

복사할 목적지는 todir속성값을 사용하도록 합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
</project>

copy target의 소스 작업이 완료 되었습니다.

( fileset의 자세한 속성들은 공식 링크를 참조 하세요 )

이제 ant를 실행하게 되면 아마 dest폴더의 모든 파일을 dist에 복사할 것입니다.

하지만 dest의 모든 파일을 삭제한 다음 ant를 실행하게 되면 아래와 같은 에러를 만나게 될 것입니다.

ant
Buildfile: 폴더 경로/build.xml

copy:
    [mkdir] Created dir: 폴더 경로/dest

BUILD FAILED
폴더 경로/build.xml:9: 폴더 경로/dest does not exist.

Total time: 0 seconds

이 에러는 복사할 대상의 경로에 폴더를 찾을 수 없다는 에러 메시지로써

실제로 dist폴더는 build에서 만들어 지게 되므로 에러가 발생 되는게 당연합니다.

그렇다면 copy를 실행하기 전 build의 실행이 불가피 하다는 말이 됩니다.

따라서 아래와 같은 의존성이 존재하게 됩니다.

copy > build

이런식으로 의존성을 가지게 된 target을 계층으로 만들기 위해서는 depends라는 속성을 사용하여 의존성 계층을 부여할 수 있습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy" depends="build">
        <mkdir dir="deet"/>
        <copy todir="dest">
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
</project>

이제 모든 소스가 깔끔하게 정리 되었습니다.

ant실행하여 우리가 원하는 대로 dist와 dest가 잘 만들어 지는지 확인하세요.

Ant Pattern

이번에는 좀 더른 주제를 다뤄 보도록 하겠습니다.

fileset은 리소스를 선택한다고 주제를 정하고 글을 작성하였습니다.

하지만 fileset을 정작 사용한 것은 폴더를 지정할 때 뿐이라는것을 눈치 빠르신 분은 아셨을 것입니다.

그렇다면 dest폴더내부에 확장자가 h인 파일을 복사하기 위해서는 어떻게 해야 할까요?

그러기 위해서는 이제 ant의 막강한 기능인 ant pattern(정규식)을 알아야 합니다.

ant패턴은 아래 3가지로 요약할 수 있습니다.

패턴 기능
* 모든 매칭 성공
** 하위 폴더 허용
? 단일 매칭 성공

일단 제일 처음있는 *은 모든 매칭을 성공적으로 수행시킵니다.

먼저 테스트를 위하여 data.h 파일이 있는 곳에 body.h 파일을 하나 생성하도록 합니다.

(파일 내부의 값을 마음대로 적으셔도 됩니다.)

이제 확장자가 h인 파일만을 복사해 보도록 하겠습니다.

delete - 폴더, 파일을 삭제하기 위한 작업

복사하기 전 이전 작업물이 그대로 남아 있을 것입니다.

이전 데이터를 초기화 할 필요가 생겼습니다.

복사하기 전 먼저 초기화 하는 기능을 추가해 보도록 하겠습니다.

기존 build.xml에 값을 초기화 하는 target을 추가하겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy" depends="build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
    <target name="clean">
    </target>
</project>

기존에 작업하고 있던 copy target의 의존성에 추가하도록 합니다.

하나이상의 의존성을 등록 할 경우는 콤마(,)를 사용하여 지정 할수 있습니다.

먼저등록 된 순서대로 빌드가 진행 되니 유의 하세요.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
    <target name="clean">
    </target>
</project>

이제 기존에 생성된 결과물을 초기화 해보겠습니다.

삭제는 delete task를 사용하여 진행하며 delete는 폴더는 dir속성값을 파일은 file속성값을 지니므로 유의하여 진행하세요.

우리는 두 폴더 모두를 지울 것이므로 dir로 지정할 수 있습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

만일 특정 파일만을 지우길 원할 경우 아래와 같이 file 속성을 사용하도록 합니다.

<delete file="data.h"/>

자. 이제 준비가 되었으니 다시 돌아 가서 fileset에 h확장자로 파일만을 복사해 보도록 하겠습니다.

fileset 확장 - includes와 excludes

fileset에서 특정 파일을 골라내는 내기 위해서는 include를 사용하면 됩니다.

그렇다면 특정 파일만을 배제하고 싶다면요?

이 역시 exclude를 사용할 수 있습니다.

이제 include를 사용하여 h확장자 만을 골라내 보겠습니다.

먼저 기존 build 타겟에서 copy문을 추가 한 다음 body.h파일을 선택합니다.

그리고 fileset내부에 include태그를 추가해 주도록 합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include />
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

다음으로 name 속성값을 사용하여 .h로 된 모든 선택 즉 *.h를 등록 하도록 하겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

이제 ant를 실행하게 되면 확장자가 h일 파일이 복사 되는 것을 확인 할수 있습니다.

이번에는 exclude를 사용해 보도록 할까요?

exclude도 include와 동일합니다.

이번에는 body.h를 복사하여 head.h파일을 만들어 보도록 하겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

ant를 실행하면 파일 3개를 복사할 것입니다.(확장자가 h일 파일)

하지만 여기서 우리는 head로 된 파일을 배제해 보도록 하겠습니다.

먼저 exclude 태그를 추가합니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude />
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

다음으로 head.hname값으로 추가하면 head.h는 복사 대상에서 벗어 나게 됩니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude name="head.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

ant를 실행하여 두 파일만 복사 되는지 확인해보세요.

이번에는 좀더 들어가 볼까요?

다시 파일 하나는 복사하도록 하겠습니다.

이름은 html.h파일로 하겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
        <copy file="body.h" tofile="dist/html.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude name="head.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

이제 우리는 head와 html만을 배제해 보겠습니다.

먼저 동일점을 찾아 보겠습니다.

h로 시작하여 .h확장자를 지닌다는 것을 알수 있습니다.

그렇다면 아래와 같은 식이 만들어 질 수 있습니다.

h*.h (h로 시작하여 중간에 모든 문자를 허용하고 끝은 .h로 끝나는 모든 파일명)

이 표현식을 변경한 다음 ant를 실행해보세요.

head.h와 html.h가 정말 복사 되지 않고 있나요?

이번에는 좀 독특한걸 해 볼까요?

만일 htm.h라는 파일이 생긴다고 해보겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
        <copy file="body.h" tofile="dist/html.h"/>
        <copy file="body.h" tofile="dist/htm.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude name="head.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

이번에는 저 파일은 복사가 되어야 합니다.

하지만 h*.h의 정규식은 모든 문자를 매칭하므로 복사에서 배제가 되겠죠?

그래서 이번에는 ?를 사용하여 매칭을 변경해 보겠습니다.

?는 단문자를 매칭할 때 사용합니다.

만일 head.h를 단문자로 표현하자면 ??????가 될 것입니다.

우리는 head.h와 html.h가 모두 6자리수라는 것과 htm.h는 5자라는 것을 착안하여

정규식을 작성하도록 해보겠습니다.

정규식 공식은 아래와 같습니다.

h로 시작하여 중간 3자리는 모든 매칭이 통과하고 확장자는 .h인 파일 모두

이 정규식은 아래와 같이 표현할 수 있습니다.

h???.h

이제 exclude에 등록한 다음 ant를 실행해 보세요

htm.h가 잘 복사 되나요?

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
        <copy file="body.h" tofile="dist/html.h"/>
        <copy file="body.h" tofile="dist/htm.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude name="h???.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

마지막으로 ** 표현식은 폴더를 지정 할 때 사용합니다.

dist폴더 아래 child 폴더를 만든 다음 data.h파일을 복사해보겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/child/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
        <copy file="body.h" tofile="dist/html.h"/>
        <copy file="body.h" tofile="dist/htm.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="*.h"/>
                <exclude name="h???.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

그럼 다음 ant를 실행하게 되면 child 폴더 내부의 data.h는 복사 하지 않습니다.

네 그렇습니다. 지금까지는 선택한 단일 폴더를 기준으로 복사가 되고 있었습니다.

그렇다면 하위 폴더까지 선택하려면 어떻게 할까요?

답은 폴더를 선택한다. 입니다.

네 결국 하위 폴더를 선택해야 겠죠?

하지만 폴더 아래 또다른 폴더가 있으면요?

그래서 ant는 하위 모든 폴더를 선택하기 위하여 **(하위 모든 폴더 허용)이라는 표현식이 존재 합니다.

include에 하위 모든 폴더를 추가해 보겠습니다.

<project default="copy">
    <target name="build">  
        <echo file="dist/build.log" append="true" encoding="utf-8">Building...</echo>
        <copy file="data.h" tofile="dist/data.h"/>
        <copy file="body.h" tofile="dist/child/data.h"/>
        <copy file="body.h" tofile="dist/body.h"/>
        <copy file="body.h" tofile="dist/head.h"/>
        <copy file="body.h" tofile="dist/html.h"/>
        <copy file="body.h" tofile="dist/htm.h"/>
    </target>
    <target name="copy" depends="clean,build">
        <mkdir dir="dest"/>
        <copy todir="dest">
            <fileset dir="dist">
                <include name="**/*.h"/>
                <exclude name="h???.h"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="dest"/>
        <delete dir="dist"/>
    </target>
</project>

이제 ant를 실행하면 우리가 원하는 결과를 얻을 수 있습니다.

여기까지가 ant의 기본적인 기능입니다.

어려우셨나요? 빌드를 자동화하는 과정은 어렵지만 자동화 된 빌드를 사용하는 즐거움을 느껴 보셨으면 좋겠습니다.

다음은 ant를 활용 하여 jar파일의 전형적인 구조를 자동화하는 방법과

좀 더 나아가 war파일을 자동화하는 방법을 포스팅 하도록 하겠습니다.