이 글은 Flex Builder 3환경에서 ANT를 사용하여 개발의 효율성을 높이는 방법을 이해하는데 목적이 있다. 처음 ANT를 접하는 사람을 위해서 ANT가 무엇이고 사용해야하는 필요성도 언급한다.

 

ANT란?

 

ANT(http://ant.apache.org/)는 자바기반의 빌드 자동화 툴이다. 자바개발자라면 한번쯤은 사용해봤을 것이다. ANT는 일반 개발툴의 개발한계를 극복하는데 유용하다. ANT를 이용하면 여러가지로 분산된 일을 단 한번에 처리할 수 있고 또한 처리 순서를 쉽게 배치할 수 있어 매우 유용하다. 가령 어떤 작업을 처리를 위한 프로세스를 아래와 같이 한다고 하자.

 

  • build 폴더 생성
  • build 폴더 안에 classes 폴더 생성
  • src폴더 안에 있는 소스를 컴파일한 뒤 결과를 classes 폴더로 전송
  • 결과물을 테스트 공용 FTP 서버로 전송
  • 문서제작

 

위와 과정을 손수 하나씩 처리하려고 하면 귀찮기 짝이 없을 것이다. ANT는 이러한 처리를 단 한번에 처리할 수 있도록 해서 작업의 능률을 높여준다.

 

ANT는 ANT자체로도 충분히 사용할 수 있으나  Eclipse나 Flex Builder등에 플러그인으로 설치하여 사용할 수도 있다. ANT는 기존 개발툴에서 개발시 극복하지 못하는 상황을 해결해주는 좋은 도구이다.

 

ANT는 XML형태로 작성된 문서를 이용하며 기본적인 문법만 익히면 쉽게 활용이 가능하다. 여기서는 ANT에 대한 전반적인 지식을 다루기에는 무리가 있으므로 해당 문서를 검색하거나 관련서적을 구입해서 학습하면 좋겠다.

 

 

Flex Builder 3의 개발환경 이해하기

ANT를 사용하기에 앞서 Flex Builder 3의 개발 환경에 대해 어느 정도 이해가 필요하다. Flex Builder 3는 별다른 어려운 설정이 없이 Flex/AIR 프로젝트, 라이브러리 프로젝트, ActionScript 3.0프로젝트 등의 개발 환경을 구성해준다. Eclipse Flex Builder 3 Plugin을 설치해도 이와 동일하게 개발이 가능하다.

 

Flex Builder를 사용하지 않는다면 여러분은 다음과 같은 방법으로 콘솔 환경에서 컴파일을 해야한다. (이는 한가지 예시일 뿐이다.)

 

compc -namespace http://www.adobe.com/2006/foo manifest.xml -source-path .
	-include-namespaces http://www.adobe.com/2006/foo -include-classes mx.containers.MyWindow
	-include-file MyWindow.png mx/containers/MyWindow.png
	-output='MyWindow.swc'

 

아래는 위 컴파일시 사용되는 manifest.xml이다.

<?xml version="1.0"?>
<componentPackage>
	<component id="MyWindow" class="mx.containers.MyWindow"/>
</componentPackage>

 

위에서 compc 명령어는 Flex SDK의 bin폴더에 있는 컴파일러로 AS3 라이브러리의 결과물인 SWC를 만들 때 사용하는 명령어이다. Flex Builder는 개발자가 이런 명령에 대한 자세한 내용을 모르더라도 아주 간단하게 SWC를 만들 수 있도록 한다. Flex Builder를 사용하지 않으면 해당 명령어를 알아야 한다고 하니 Flex Builder가 고마워진다. ^^;

 

위처럼 SWC를 만들때 사용하는 라이브러리 프로젝트 외에 애플리케이션을 만드는 Flex 프로젝트나 ActionScript 3.0 프로젝트의 경우에는 mxmlc 명령어를 사용한다. mxmlc 명령어는 일반 애플리케이션 이외에도 CSS, 리소스 모듈, 모듈 등을 컴파일할 때도 사용한다. 또한 Class별 문서제작은 asdoc 명령어를 사용한다. Flex Builder를 이용하면 compc, mxmlc 등을 몰라도 최소한의 개발이 가능하다는 것을 아는 것이 중요하다.

 

compc, mxmlc, asdoc과 같은 명령어는 Flex Builder가 설치해 있는 MS Window 환경이라면 C:/Program Files/Adobe/Flex Builder 3/sdks/{Flex SDK 버전}/bin 폴더 내에 있다. 여기서 {Flex SDK 버전} 부분은 언제든지 Flex SDK의 다른 버전을 설치해 사용할 수 있다는 것을 의미한다. Flex SDK 다운로드 페이지에서 다운받아 여기에 복사한 뒤 사용하면 되겠다.

 

아래는 Flex Builder 3에 있는 Flex SDK들이다. 개발자는 필요에 따라 여기에 최신 SDK를 복사해서 사용한다.

 

 

아래는 각각 SDK폴더의 bin 폴더 내에 있는 명령어들을 보여준다. 여기에 위에서 언급한 mxmlc, compc등이 있다는 것을 확인하자. Flex Builder는 이들 명령어를 이용해 개발자가 구체적으로 알 필요 없이 내부적으로 SWF, SWC등과 같은 결과물을 만들어 낸다.

 

위 경로는 MS Window XP일 때이다. 다른 운영체제(Mac OS, Linux)의 경우는 다르다.

 

ANT를 언제 사용해야하는가?

Flex Builder 3가 개발의 편의성을 제공함에도 불구하고 Builder에서 제공하는 컴파일 방법만 이용하면 개발 규모 및 방향에 따라 개발의 한계에 도달할 수 있다. 예를 들어, 잦은 라이브러리 변경은 라이브러리가 수정될 때마다 그 라이브러리를 이용하는 프로젝트도 재컴파일하게 되어 결과물을 보여주므로 그만큼 결과를 보는데 오랜 시간이 걸리는 문제가 발생할 수 있다. 또는 Flex Builder 3에서 제공하는 컴파일 방식으로는 능동적으로 다른 프로젝트간에 결과물을 공유할 수 없다. 가령, 다른 프로젝트의 bin폴더의 swc를 참조해서 컴파일해야하는 경우나 만든 프로젝트 결과물을 FTP로 바로 올려야하는 경우, 또는 여러개의 SWF를 복사해서 다른 폴더에서 사용할 수 있도록 배치하는 경우는 Flex Builder 3에서 제공하는 기능만으로는 불가능하다.

 

몇가지 예만 들었지만 Flex Builder만으로 할 수 없는 일들이 종종 생긴다는 것을 이해하는 것이 중요하다. 이러한 이유로 개발 규모 및 방향에 따라 ANT를 도입하여 Flex Builder로만 개발할 때의 단점을 극복하여 능동적이고 가벼운 컴파일링 및 프로젝트간 컨텐츠 공유등을 할 수 있도록 한다.

 

ANT를 도입하게되면 Flex Builder가 하지 못하는 것을 극복하는 것은 사실이지만 개발 자체를 쉽게 해주는 것은 아니다. 왜냐하면 앞서 설명한 mxml, compc와 같은 명령어를 사용하는 방법을 익혀야하며 또한 ANT자체 문법도 익혀야하기 때문이다. 대신 앞서 설명한 한계를 극복하는데 ANT의 선택은 좋은 방법이 될 수 있다.  ANT를 분별없이 무조건 도입하면 오히려 개발 능률을 떨어뜨리게 된다. 그러므로 Flex Builder로 개발 한계에 도달했을 때만 도입하도록 한다.

 

Flex Builder에서 ANT 개발환경 구축하기

Flex Builder 3부터 ANT를 지원하고 있다. 이 말은 Flex Builder 3를 설치하면 ANT관련 Plugin이 설치가 되어 있다는 것을 의미한다. 아래는 Flex Builder 3의 plugins에 ANT가 설치되어 있는 것을 보여주고 있다. 

 

1. JDT(Eclipse Java Development Tools) 설치

 

Flex Builder 3부터는 ANT를 지원한다. 하지만 ANT를 사용하려면 Flex Builder에 JDT를 설치해야한다.  다음 문서에서 설명하는 것처럼 JDT를 설치하도록 한다.

 

Adding the ANT support in Flex Builder 3

 

또는

http://www.flex-tutorial.fr/2009/09/04/installer-ant-dans-flex-builder-3/

 

2. 설치된 ANT 확인

 

JDT를 설치한 후 Flex Builder를 재실행하면 Window->Other View에서 아래와 같이 Ant를 선택할 수 있다.

 

 

선택하면 Flex Builder에 아래와 같은 Ant View 창을 볼 수 있다. 이 창에 필요한 ANT XML문서를 놓아 사용하면 되겠다.

 

 

ANT에 관련된 설정은 Flex Builder 메뉴에서 Window->Preferences를 선택하면 아래와 같은 창이 나오고 좌측 메뉴에서 Ant를 선택하면 각종 설정을 할 수 있다. 대부분의 경우 기본설정으로 두면 되겠다.

 

 

 

Flex SDK 환경에서 ANT 개발 환경 구축하기

참고로 Flex Builder와 상관없이 Flex SDK로만 개발하거나 Flex Builder가 아닌 다른 개발툴을 사용하고자 한다면 아래와 같은 방법으로 환경을 조성하면 된다. (Window XP 기준)

 

1. Ant를 다운로드 받아 설치한다.

 

http://ant.apache.org/bindownload.cgi

 

현재 최신 버전은 1.7.1이다. C에 압축푼다.  그리고 C:/ant1.7.1에 설치한다. 다음으로 환경변수를 등록하는데 시스템 변수로 Path에 C:/ant1.7.1/bin;을 넣어주면 되겠다. 다른 운영체제의 경우는 환경변수 등록하는 방법이 다를 것이다.

 

 

환경변수 추가 후 다음과 같이 콘솔창 띄우고 ant 명령을 줘본다. build.xml이 없으므로 오류메시지 발생하며 정상적으로 실행된 것이다.

 

 

2. Flex SDK의 ant/lib 폴더에  flexTasks.jar를 Ant설치 폴더(C:/ant1.7.1)의 lib폴더에 복사한다.

 

3. build.xml를 구성하여 Flex,ActionScript 3.0로 개발된 것을 콘솔창에서 ant 명령을 이용해 컴파일 및 실행등을 하면 되겠다.

 

이에 대한 자세한 내용은 ANT관련 서적 및 Using Flex Ant Tasks(Flex 3) 문서를 참고한다.

 

Flex Builder 3 환경에서 ANT로 개발해보기

ANT를 이용해 mxmlc, compc, html-wrapper등을 이용하는 방법은 Flex Live docs의 Using Flex Ant Tasks 에 대부분 소개되어 있다. 그리고 Flex 컴파일러인 mxmlc, compc을 사용할 때 옵션은 Using the Flex Compliers문서에 대부분 나와 있다. 이 두 가지만 습득하면 ANT를 이용한 개발 방법은 대략 익히게 된다.

 

영어가 부족하다면 현 ACC(Adobe Community Champion)인 이만영님이 쓰신 Flex Ant Task를 이용한 자동화 빌드 구축하기 문서를 읽어보자. Flex Builder 2기준으로 만든 문서이긴 하지만 지금도 매우 유용하다.

Flex Builder에서 ANT를 이용한 개발은 소개한 문서만 익히면 어느 정도 알 수 있다. 중요한 것은 직접 따라 해보는 것이 중요하다.

 

여기서는 간단하게 Flex Builder 3에서 ANT를 활용하는 방법을 익혀본다.

개발목표는 여러 개의 위젯을 만들고 그 위젯을 로드하는 테스터 프로그램을 만드는 것이다. ActionScript 3.0 프로젝트로 개발할 것이다. 만들어진 결과물은 왼쪽 그림에서 보여주는 것과 같이 bin폴더에 들어가며 위젯의 경우 bin/widgets에 들어간다. 이러한 조건을 만족하도록 개발하려면 Flex Builder 3의 컴파일 기능만 가지고는 안 된다. 왜냐하면 Flex Builder 3에서 기본적으로 제공하는 컴파일 방식으로는 widgets폴더와 같이 다른 폴더에 들어가도록 만들 수 없기 때문이다. 이 조건 하나만으로도 수동작업을 해야 하는 개발의 어려움이 발생한다. 하지만 ANT를 사용하면 이 문제를 깔끔하게 해결할 수 있게 된다.

 

아래 예제 소스 다운로드 :  MyWidgets.zip

 

 

1. ActionScript 3 프로젝트를 만든다.

프로젝트 명은 MyWidgets 라고 하자.

 

2. src 폴더에 IWidget, AbstractWidget을 만들자.

IWidget는 init()함수만 선언한다.

package
{
	/**
	 * 위젯 인터페이스
	 */
	public interface IWidget
	{
		/**
		 * 초기화 함수
		 */
		function init():void;
	}
}

그리고 AbstractWidget는 IWidget을 구현하고 Sprite를 확장해서 만든다.

package
{
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;

	/**
	 * 위젯 추상 클래스
	 */
	public class AbstractWidget extends Sprite implements IWidget
	{
		/**
		 * 추상클래스 생성자
		 */
		public function AbstractWidget()
		{
			super();
			this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler );
		}

		/**
		 * @private
		 */
		private function addedToStageHandler( event:Event ):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler );
			init();
		}

		/**
		 * @inheritDoc
		 */
		public function init():void
		{
			throw new Error("Override 정의해서 사용가능합니다.");
		}

	}
}

 

3. Widget 3개를 만들자.

이것은 네모, , 세모의 모양을 가지는 위젯이다. 위젯 이름은 각각 Widget1, Widget2, Widget3로 만든다. 이들 위젯은 모두 AbstractWidget을 확장해서 구현한다. 그리고 IWidget init()함수를 override한 뒤 해당 모양을 그려준다.

 

package
{
	import flash.display.Shape;
	import flash.events.Event;

	[SWF(width='100', height='100',backgroundColor='#000000')]
	/**
	 * Widget1
	 */
	public class Widget1 extends AbstractWidget
	{
		/**
		 * 생성자
		 */
		public function Widget1()
		{
			super();
		}

		/**
		 * @inheritDoc
		 */
		override public function init():void
		{
			var shape:Shape = new Shape;
			shape.graphics.clear();
			shape.graphics.lineStyle( 2, 0xff0000, 1 );
			shape.graphics.beginFill( 0xffffff, 1 );
			shape.graphics.drawRect( 0, 0, 100, 100 );
			shape.graphics.endFill();
			addChild( shape );
		}

	}
}

 

4. MyWidgets에 만든 3개의 위젯을 로드하는 프로그램을 만든다.

MyWidgets는 일종의 위젯 테스트용이다. IWidget을 구현한 어떤 위젯이든 올릴 수 있다. 인터페이스 IWidget은 다형성을 고려하기 위한 것이다. 동작방식은 단순하다. 숫자 1부터 3까지 키를 누르면 해당 위젯이 Loader를 통해 로드되어 렌더링된다.

 

package {
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.KeyboardEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;

	/**
	 * 위젯 테스터
	 */
	public class MyWidgets extends Sprite
	{
		private var loader:Loader;
		private var loadedWidget:IWidget;

		private var widgetList:Array = [ 'Widget1', 'Widget2', 'Widget3' ];

		/**
		 * 생성자
		 */
		public function MyWidgets()
		{
			super();
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyboardEventHandler );
		}

		/**
		 * @private
		 * 키보드로부터 숫자를 받아 해당 위젯을 로드한다.
		 */
		private function keyboardEventHandler( event:KeyboardEvent ):void
		{
			var widgetNumber:int = event.charCode-48;
			if( widgetNumber < 0 || widgetNumber > widgetList.length ) return;

			var widgetURL:String = "widgets/" + widgetList[widgetNumber-1] + ".swf";
			if( loader == null )
			{
				loader = new Loader();
				addChild( loader );
			}

			var request:URLRequest = new URLRequest( widgetURL );
			var context:LoaderContext = new LoaderContext( false, new ApplicationDomain( ApplicationDomain.currentDomain ) );
			loader.load( request, context );
		}
	}
}

 

5. ANT를 구성한다.

프로젝트 폴더에 build폴더를 만들고 거기에 build.xml과 build.properties 파일을 만들고 다음과 같이 스크립트를 코딩한다.

 

아래는 build.properties이다.

# -----------------------------------------------------------------
# User-Defined Paths
#
# Modify these path values to reflect paths on your system
# -----------------------------------------------------------------

# The location of the Flex 2 SDK on your sytem.
flex3sdk.home.dir = C:/Program Files/Adobe/Flex Builder 3/sdks/3.3.0
flex3sdk.bin.dir = C:/Program Files/Adobe/Flex Builder 3/sdks/3.3.0/bin
flex3sdk.lib.dir = C:/Program Files/Adobe/Flex Builder 3/sdks/3.3.0/frameworks/libs

# Note that the locale dir uses the {locale} token at the end to specify the directory
# of language-specific files.  This is replaced by the compiler with the locale defined
# by the locale property below.
flex3sdk.locale = en_US
flex3sdk.locale.dir = C:/Program Files/Adobe/Flex Builder 3/sdks/3.3.0/frameworks/locale/{locale}

asdoc.exe = ${flex3sdk.bin.dir}/asdoc.exe
compc.exe = ${flex3sdk.bin.dir}/compc.exe
mxmlc.exe = ${flex3sdk.bin.dir}/mxmlc.exe

# The debug player is necessary here because it writes trace statements to a flashlog.txt
# file.  This allows us to examine the .txt file and determine the status of unit tests
# in an automated fashion.
flashDebugPlayer.exe = C:/Program Files/Adobe/Flex Builder 3/Player/10/win/FlashPlayer.exe

# -----------------------------------------------------------------
# Project Paths - DO NOT MODIFY
# -----------------------------------------------------------------
build.dir = ${basedir}/build
src.dir = ${basedir}/src
bin.dir = ${basedir}/bin
docs.dir = ${basedir}/docs

 

아래는 build.xml이다.

 

<?xml version="1.0" encoding="utf-8"?>
<project name="MyWidgets" basedir="../">

	<!-- 이 build 스크립트에서 사용할 variable 및 path 정의  -->
	<property file="./build/build.properties" />

	<!-- 해당 properties가 설정 되어 있는가 확인 -->
	<target name="properties">
		<fail unless="asdoc.exe">The "asdoc.exe" property must be set in ${build.dir}/build.properties.</fail>
		<fail unless="compc.exe">The "compc.exe" property must be set in ${build.dir}/build.properties.</fail>
		<fail unless="mxmlc.exe">The "mxmlc.exe" property must be set in ${build.dir}/build.properties.</fail>
	</target>	

	<!-- bin 폴더 생성 -->
	<target name="mkdir bin">
		<mkdir dir="${bin.dir}"/>
		<mkdir dir="${bin.dir}/widgets"/>
	</target>

	<!-- bin 폴더 삭제 -->
    <target name="clean">
        <delete includeEmptyDirs="true">
            <fileset dir="${bin.dir}"/>
        </delete>
    </target>	

	<!-- 모두 컴파일 -->
	<target name="complie all" depends="complie MyWidgets, complie widget1, complie widget2, complie widget3"/> 

	<!-- 위젯 테스터 컴파일 -->
    <target name="complie MyWidgets" depends="properties,mkdir bin">
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/MyWidgets.as'" />
			<arg line="-o '${bin.dir}/MyWidgets.swf'" />
		</exec>
    </target>	

	<!-- 위젯 테스터 실행 -->
	<target name="run MyWidgets" depends="complie MyWidgets">
		<exec executable="${flashDebugPlayer.exe}" spawn="yes">
			<arg line="${bin.dir}/MyWidgets.swf" />
		</exec>
	</target>

	<!-- 위젯 1 컴파일 	-->
    <target name="complie widget1" depends="properties,mkdir bin">
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/Widget1.as'" />
			<arg line="-o '${bin.dir}/widgets/Widget1.swf'" />
		</exec>
    </target>

	<!-- 위젯 2 컴파일 	-->
    <target name="complie widget2" depends="properties,mkdir bin">
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/Widget2.as'" />
			<arg line="-o '${bin.dir}/widgets/Widget2.swf'" />
		</exec>
    </target>

	<!-- 위젯 3 컴파일	-->
    <target name="complie widget3" depends="properties,mkdir bin">
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/Widget3.as'" />
			<arg line="-o '${bin.dir}/widgets/Widget3.swf'" />
		</exec>
    </target>

</project>

 

만들어진 build.xml은 우측 화면과 같이 Ant View에 드래그해서 붙여 넣는다. 이로써 ANT를 이용해 만들어진 ANT 스크립트를 실행할 수 있게 된다.

 

build.xml은 ANT에서 구동되는 스크립트이다. <project>로 감싸져 있고 <property>와 <target>이 존재한다. <property file="./build/build.properties" />는 build.properties를 로드해서 build.xml에서 사용할 property를 참고하는 역할을 한다. <target>은 하나의 실행단위라고 생각하면 되겠다. <target>은 고유한 name을 가진다. 이 name이 Ant View에 표시되며 표시된 name을 더블클릭하면 <target>에 정의된 코드가 실행되는 것이다.

 

<target> name이 mkdir bin은 bin 폴더와 bin/widgets 폴더를 생성한다. 여기서 ${bin.dir}은 변수로서 build.properties에 정의했다.

 

<target> name이 clean인 것은 만들어진 bin폴더와 widgets폴더를 지운다.

 

<target> name이 complie widget1인 것은 src폴더내에 Widget1.as를 컴파일하여 bin/widgets에 Widget1.swf라는 이름으로 출력하도록 한다. 여기서 Flex SDK에서 제공하는 mxmlc를 사용하게 된다. 어떤 mxmlc를 사용할지는 build.properties에 정의했다.

 

<target> name이 complie MyWidgets는 src폴더내에 MyWidgets.as를 컴파일해서 bin에 MyWidgets.swf라는 이름으로 출력한다.

 

<target> name이 complie all은 <target> name이 complie MyWidgets, complie widget1, complie widget2, complie widget3 로된 <target>을 전부 실행한다. 이처럼 target은 depends 옵션을 이용해 다른 target과 묶어서 실행이 가능하다.

 

<target> name이 run MyWidget은 MyWidget.as를 컴파일한 뒤에 bin/MyWidget.swf를 실행하도록 한다.

 

이것만 보더라도 ANT를 이용해서 프로젝트를 어떻게 관리할 수 있을지 대략적으로 느껴질 것이다. 이처럼 하나의 프로젝트에서 다양한 애플리케이션을 원하는 경로에 컴파일하여 출력할 수 있고 활용해볼 수 있다. ANT에서는 copy, delete등과 같은 명령어를 지원하므로 이들을 적극 활용하면 프로젝트 관리가 더욱간편해질 수 있다. 게다가 결과물을 FTP 전송, SVN 공유, 다른 프로젝트간에 연동도 아주 쉽게 적용할 수 있다. 지금 예제는 debug 용이 아니지만 원한다면 debug도 할 수 있게 꾸밀 수 있다. 또한 위젯들 간에 중복되는 클래스에 대한 최적화(Optimization) 과정이 들어간다면 더욱 깔끔하지 되지 않을까 생각한다. html-template에 대한 것도 모두 ANT로 개발이 가능하므로 자세한 내용은 Flex Live Docs를 참고하길 바란다.

 

Flex ANT Task 활용해보기

지금까지 mxmlc 명령을 구동하기 위해 build.xml에서 <exec>를 이용했다. 이것은 매우 범용적인  방법으로 mxmlc뿐 아니라 어떤 것이든 구동하는데 쓸 수 있다. 그러나 Flex 환경에서 개발할 때 <exec>를 이용해 mxmlc를 구동 하는 것은 복잡한 설정이 들어가는 경우 관리가 힘들어지는 경우가 발생할 수 있다. 다행히 Flex SDK에서는 더욱 간편하게 mxmlc를 사용할 수 있는 기능 제공하고 있다. Flex SDK에 보면 아래 그림과 같이 ant폴더가 존재하는 것을 확인할 수 있다. ant폴더에는 Flex전용 ANT 환경을 구성해주는 Flex ANT Task가 존재한다. 소스가 공개되어 있어서 ant/src에는 Java로 만들어진 소스가 있고 ant/lib에는 flexTasks.jar가 있어 ANT구성시 이 JAR를 활용하여 Flex 전용 ANT 환경을 구성할 수 있다.

 

 

기존 build.xml에서 <properties file=./build/build/properties/> 아래에 다음 코드와 같이 <taskdef>을 추가한다. 이 부분은 Flex SDK에 있는 flexTasks.jar를 활용해 <exec> 대신 <mxmlc>, <compc> 형태로 사용할 수 있도록 한다. <target> name compile MyWidgets인 부분을 찾아 <exec>부분을 주석처리하고 대신 <mxmlc>을 삽입한다.

 

<?xml version="1.0" encoding="utf-8"?>
<project name="MyWidgets" basedir="../">

	<!-- 이 build 스크립트에서 사용할 variable 및 path 정의  -->
	<property file="./build/build.properties" />

	<!-- Flex ANT Task 사용 -->
	<taskdef resource="flexTasks.tasks" classpath="${flex3sdk.home.dir}/ant/lib/flexTasks.jar"/>
	<property name="FLEX_HOME" value="${flex3sdk.home.dir}"/>

	..... (생략) ....

	<!-- 위젯 테스터 컴파일 -->
    <target name="complie MyWidgets" depends="properties,mkdir bin">
        <mxmlc
            file="${src.dir}/MyWidgets.as"
            output="${bin.dir}/MyWidgets.swf"
        >
        	<!-- Get default compiler options. -->
        	<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>

        	<!-- List of path elements that form the roots of ActionScript
        	class hierarchies. -->
			<source-path path-element="${FLEX_HOME}/frameworks"/>        

            <!-- List of SWC files or directories that contain SWC files. -->
            <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                <include name="libs" />
                <include name="../bundles/{locale}" />
            </compiler.library-path>

            <!-- Set size of output SWF file. -->
            <default-size width="500" height="600" />
        </mxmlc>
    	<!--
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/MyWidgets.as'" />
			<arg line="-o '${bin.dir}/MyWidgets.swf'" />
		</exec>
		-->
    </target>	

	..... (생략) ....

</project>

 

위 코드에서<taskdef> 아래에 <property>로 FLEX_NAME을 정의했는데 이것을 정의하지 않으면 <mxmlc>가 제대로 동작하지 않는다.

 

<mxmlc> 내부에 들어간 <load-config>, <compiler.library-path>, <default-size>등은 <mxmlc>를 구동하기 위한 설정들이다. 사실 이 프로젝트에서는 이러한 설정이 필요없다. 왜냐하면 <mxmlc>가 이러한 기본 설정을 내부적으로 대신 해주기 때문이다. 만약 설정에 변동사항이 존재한다면 이 설정들을 추가해서 수정하면 된다. 이외에도 많은 설정 옵션들이 있는데 자세한 내용은 Using Flex Ant TaskUsing the Flex Complier를 참고한다.

 

ANT를 이용해 ASDoc 만들어 보기

build.xml에 아래 코드를 추가하고 실행해보자.

 

<!-- ASDoc 만들기 -->
<target name="asdoc">
	<!-- Clean out the contents of the doc directory, without delete "docs" -->
	<!--
	<delete includeemptydirs="true">
		<fileset dir="${docs.dir}" includes="**/*" />
	</delete>
	-->
	<mkdir dir="${docs.dir}"/>

	<exec executable="${asdoc.exe}" spawn="no">
		<!-- Place the documentation in the "docs" directory -->
		<arg line="-o ${docs.dir}" />

		<!-- Specify the main source path as "src" -->
		<arg line="-sp ${src.dir}" />

		<!-- Document all of the classes in the "src" tree -->
		<arg line="-ds ${src.dir} " />

		<!-- Include the library name in the window title -->
		<arg line="-window-title 'ANT Widget Test' "/>
	</exec>
</target>

 

프로젝트내에 doc폴더가 생기고 그 안에 아래와 같이 Asdoc를 만들어진 문서를 볼 수 있을 것이다.

 

 

ANT를 이용하면 build.xml 문서 하나만 가지고 얼마나 많은 일을 한번에 처리할 수 있는가 알 수 있다.

 

 

Ant Contrib Task를 이용하여 반복 작업 줄이기

지금까지 만들어본 build.xml을 자세히 살펴보면 반복되는 작업이 있다는 것을 발견할 수 있다.  <target>의 name이 compile MyWidgets, compile widget1, compile widget2, compile widget3가 그것이다. 이들 <target>은 동일하게 mxmlc를 구동하면서 설정값도 동일하다. 이런 경우에는 하나의 <target name="compile">로 묶어주고 컴파일 대상을 번갈아가면서 <target name="compile">를 구동하게 하면 build.xml이 훨씬 간단해질 것이다. 하지만 기본 ANT와 Flex ANT Task만으로는 이런 작업이 불가능하다.

반복되는 <target>코드를 단순화 시키기 위해 주로 사용하는 것이 Ant Contrib Task이다. 이것도 Flex ANT Task와 마찬가지로 <taskdef>로 정의하여 사용할 수 있다. Ant Contrib Task는 http://ant-contrib.sourceforge.net/ 에서 제공하고 있다. 받아야하는 것은 ant-contrib-1.0b3.jar이다.

편의를 위해 아래와 같이 build에 복사해 두었다.

 

 

build.xml을 다음과 같이 수정한다.

 

<?xml version="1.0" encoding="utf-8"?>
<project name="MyWidgets" basedir="../">
	<!-- 이 build 스크립트에서 사용할 variable 및 path 정의  -->
	<property file="./build/build.properties" />

	<!-- Ant contrib 1.0b3를 사용한다 -->
	<taskdef resource="net/sf/antcontrib/antcontrib.properties">
		<classpath>
			<pathelement location="${build.dir}/ant-contrib/ant-contrib-1.0b3.jar"/>
		</classpath>
	</taskdef>		

	<!-- 해당 properties가 설정 되어 있는가 확인 -->
	<target name="properties">
		<fail unless="asdoc.exe">The "asdoc.exe" property must be set in ${build.dir}/build.properties.</fail>
		<fail unless="compc.exe">The "compc.exe" property must be set in ${build.dir}/build.properties.</fail>
		<fail unless="mxmlc.exe">The "mxmlc.exe" property must be set in ${build.dir}/build.properties.</fail>
	</target>	

	<!-- bin 폴더 생성 -->
	<target name="mkdir bin">
		<mkdir dir="${bin.dir}"/>
		<mkdir dir="${bin.dir}/widgets"/>
	</target>

	<!-- bin 폴더 삭제 -->
    <target name="clean">
        <delete includeEmptyDirs="true">
            <fileset dir="${bin.dir}"/>
        </delete>
    </target>	

	<!-- 모두 컴파일 -->
	<property name="compile_target_list" value="MyWidgets,Widget1,Widget2,Widget3" />
    <target name="compile all" depends="properties,mkdir bin">
        <foreach
            list="${compile_target_list}"
            param="compile_target"
            target="compile" />
    </target>

	<!-- 컴파일(단독구동 불가) -->
    <target name="compile">
    	<echo message="${compile_target}" />
		<exec executable="${mxmlc.exe}" dir="${basedir}">
			<arg line="'${src.dir}/${compile_target}.as'" />
			<arg line="-o '${bin.dir}/${compile_target}.swf'" />
		</exec>
    </target>	

	<!-- 위젯 테스터 실행 -->
	<target name="run MyWidgets">
		<exec executable="${flashDebugPlayer.exe}" spawn="yes">
			<arg line="${bin.dir}/MyWidgets.swf" />
		</exec>
	</target>

</project>

 

위 코드에서 <taskdef resource="net/sf/antcontrib/antcontrib.properties">부분은 Ant Contrib Task를 정의하는 부분이다. 기존 <target name="complie ...">과 같은 형태의 <target>은 모두 삭제하고 <target name="compile all">과 <target name="compile">를 만들었다. <target name="compile all">에 <foreach>를 이용해 반복하면서 MyWidgets,Widget1,Widget2,Widget3를 <target name="compile">에 대입해 구동하도록 짜여져 있다. 여기서 <foreach>는 Ant Contrib Task에서 지원하는 속성이다. 나중에 Widget4, Widget5, Widget6… 을 제작하는 일이 생기더라도 <property name="compile_target_list">value에만 추가하면 되기 때문에 작업이 훨씬 깔끔해졌다.

 

기존처럼 한개씩 컴파일하고 싶다면 build.xml에 다음 코드를 추가하면 되겠다.

 

<!-- MyWidgets 컴파일 -->
<target name="compile MyWidgets">
	<foreach list="MyWidgets" param="compile_target" target="compile" />
</target>	

<!-- widget1 컴파일 -->
<target name="compile widget1">
	<foreach list="Widget1" param="compile_target" target="compile" />
</target>	

<!-- widget2 컴파일 -->
<target name="compile widget2">
	<foreach list="Widget2" param="compile_target" target="compile" />
</target>	

<!-- widget3 컴파일 -->
<target name="compile widget3">
	<foreach list="Widget3" param="compile_target" target="compile" />
</target>

 

<target name="compile">를 그대로 사용하면서 한개씩 컴파일할 수 있도록 <foreach>를 그대로 사용했다.

Ant Contrib Task <foreach>외에도 <if>, <switch>등 유용한 것이 더 있다. 이에 대해서는 Ant Contrib Task 메뉴얼을 참고한다.

 

이렇게 기존 ANT를 보완하는 Ant Contrib Task를 사용함으로써 build.xml을 더욱 깔끔하게 만들 수 있게 되었다.


정리하기

지금까지 Flex Builder 3에서 ANT를 활용하는 방법에 대해서 간단한 예제를 통해 살펴보았다.  AS3 프로젝트가 아닌 라이브러리 프로젝트나 Flex프로젝트등에도 ANT가 매우 유용하게 쓰여질 수 있다는 것을 충분히 이해했다면 이 글의 목표를 달성한 것이라 생각한다.

 

Flex ANT를 최고의 학습 방법은 경험이다. 스스로 해당 자료를 찾아 직접해보는 것이 가장 중요하다.

Google Code Open Source Flex 프로젝트들이 꽤 있는데 SVN으로 Flex Builder에 등록해서 사용하다 보면 때때로 ANT를 사용한 소스를 접해볼 수 있다.  Flex ANT가 아니라 일반 ANT긴 하지만 as3corelib as3flexunitlib등이 그 예가 아닐까 생각한다.

 

실제로 실전 프로젝트에서 ANT는 매우 유용하다. 익혀두고 적절히 활용하면 몸과 마음이 편해지는 좋은 기술이겠다.

 

관련글

 

 

+ Recent posts