Let me ask you a question. Let’s say you’ve written the code for your AIR Native Extension, native library, AIR library and all that. How many steps does it take to build and package this in an .ANE file?
- Build your native library or libraries: one per platform that your ANE supports.
- Build your AIR library.
- If your ANE needs to support the AIR Simulator, build your default implementation.
- Extract library.swf from your AIR library:
- make a copy of your AIR library’s SWF file;
- rename that to .ZIP;
- unzip it;
- keep library.swf that came out of the .ZIP;
- delete the .ZIP and catalog.xml that came out of the .ZIP.
- Repeat step 4 for your default implementation.
- Copy all ANE ingredients to the same folder.
- Run Adobe’s ADT tool on the command line to package all of the above into an .ANE file.
I’m known for passionately hating any build process that involves more than one mouse click… So I say let’s scrap all that and replace it with clicking Build Project in Flash Builder.
In this article we’ll build a template build script that you can customize and use to package any of your ANEs. Let’s get started.
1. Create a build script file
We will be using an Ant script, which can be nicely integrated with Flash Builder and other Eclipse-based IDEs.
1. 1. Add a folder to the root of the AIR Library project for your native extension and call it build_scripts. It’s actually OK to have space in the name and call the folder ‘build scripts’, but let’s keep things simple.
1.2. Inside build_scripts create a new file and call it local.properties. Here you’ll define the paths to Adobe’s compc and adt tools. compc is the compiler that will build your AIR library and adt is the tool that you’ll use for packaging it into an ANE. Change the paths below to match where things are on your machine:
FLEX_HOME=/Applications/Adobe Flash Builder 4.6/sdks/4.6.0
1.3. Add another file and call it build.properties. This file will contain parameters that are specific to your project. Having the project-specific stuff separate from the actual build script means you can reuse the build script in all of your ANE projects by replicating and customizing build.properties.
Let’s start the file with a couple of helpful comments. We’ll add some meat to that later:
# 1. All paths set in this file
# are relative to where build.xml is.
# 2. You can override any of the values in this file by passing a new value
# on the command line, prefixed with -D, when you call ant.
# ant -Dbuild.debug=false
1.4. In the same folder add a new XML, called build.xml, and have it import the two .properties files. In this file we will put together the Ant script that will do a clean build of your ANE and package it. Start with the following shell:
In the next steps we’ll add Ant build targets and configure them.
2. Add a way of choosing between debug and release builds
When you build a native library for iOS, Mac OS or Windows, your library binary file ends up in a different folder, depending on whether you do a debug or a release build. We’ll need to be able to build the binary we want and find it, so it can be packaged with the ANE.
2.1. Add a parameter to help you kick off a debug or a release build.
Open build.properties and add the following:
# Set this to true for a Debug build and to false for a Release build
2.2. Add targets for checking build.debug‘s value.
Add this inside the <project> entity in build.xml, in place of the highlighted
<!– Add build targets here –>:
iOS.library.build.type is a property that helps you with two things:
- it determines whether you request a debug or a release build from Xcode;
- it helps you find the folder in your Xcode project where the built library ends up: Debug-iphoneos/ or Release-iphoneos/.
You can add similar properties for Mac OS and Windows. On Android your native .jar lib normally ends up in the same place.
3. Add targets for building your native library
3.1. Let’s start with a target that will clean your native library project. Again, the example here is for iOS and you can extend it to include other platforms:
All this does is call Xcode’s xcodebuild tool with a command line like this:
Note: This relies on Xcode being in your path. It normally is. Relax.
Note also that this target depends on the “set build type” target that we configured earlier. This means that “set build type” will be executed before “clean ios”, which will ensure that iOS.library.build.type is set to Debug or to Release.
3.2. Next, add a target that will build the native library:
You can add similar targets to build your native libraries for other platforms: set executable to the name of the compiler or tool you use for building and replace the string in <arg line/> with the command line parameters that you need to pass to that compiler or tool.
3.3. And, for convenience, add a target that will let you execute the clean and build step in one go:
3.4. Add the properties that will configure these targets:
You have probably noticed that the targets you just added use a few properties that haven’t been defined yet. Let’s add them to build.properties:
# iOS project paths:
# Check Xcode > Preferences > Locations > Advanced to see where Xcode will store build products:
Make sure you set these to your actual project name and path.
3.5. Set up a folder where build products will be collected for the ANE packaging:
There is one property we haven’t defined yet: iOS.project.outputdir. This is where your script will copy the iOS library when it gets built, so that it’s available for the next part of the script which will package the ANE. I tend to use a temporary folder for that. The structure is the same for every project I develop, so isn’t project-specific, so let’s define this directly in our build script. Add the definitions to the top of build.xml, in place of <!– Add property definitions here –>
4. Add a target for building your AIR Library
Native library built, it’s the AIR library’s turn.
4.1. The build swc target will build an AIR library that you point it to by calling Adobe’s compc compiler.
In most of your projects you will probably want to build two AIR libraries: a SWC that takes care of calling native code and a default SWC with simulator support. I bet that you love code repetition as much as I do… which is to say about as much as a dentist appointment. So, instead of having to make the same target for each SWC you want to build, you are going to add smaller targets that just configure and execute this one (steps 4.3. and 4.4.).
4.2. Add another generic target to extract library.swf from a given SWC file. See Recipe for packaging an ANE if you want a reminder for why we do this.
4.3. Add a target that will build your main SWC, by configuring and executing the “extract swf library” generic target, which in turn will cause “build swc” to be executed first:
Here you’ll need to configure the parameters that tell Ant where your AIR library is and what it’s called. Add these to build.properties:
# AIR Library paths:
#Your extension descriptor files:
4.4. Do you have a default implementation for your ANE?
If you answered ‘I do’, repeat step 4.3. to build your default implementation SWC. Come on, you don’t expect me to do copy and paste here, right?
5. Add targets for collecting the files we’ll need to package the ANE
Are you still with me? That’s probably the most tedious bit of the whole exercise, so if you decide to abandon the article at this point, I won’t blame you.
For the three people still reading, let’s roll up our sleeves and get on with it. Mum, dad, I’ll explain what Ant is when I next speak with you on Skype…
5.1. The following two targets will make sure you have a temporary folder for packaging to copy files into. Unless it exists already.
5.2. The next target automates what you did by hand in steps 1.a. to 1.d. in Recipe for packaging an ANE.
6. Add a target to package your ANE
Finally. Let us now automate the command line that you would normally have to run by hand. Like the rest of this example, the following will package an ANE for iOS. You can extend that to cover other platforms.
Add these last two properties to build.properties to tell Ant what your .ANE file should be called and where you want it to end up and you are done:
# File name and folder for the packaged ANE:
7. Run the script
Are you ready?
Open a Terminal window and navigate to your build.xml file, then run
If all went to plan, you should see something like this at the end of the long log that ADT spits out:
If there were build or packaging errors instead, give us a shout in the comments below. We want to help.
Hey, didn’t we say a single click build?
That’s so far a single command-line build… Don’t worry, it doesn’t end here. Being a man, well, a woman of my word, I’ll take you along that last mile, should you like to join me.
You have so far done the hard work, the rest is quick and easy: head over to Package your ANE in Flash Builder.