Working with AIR Native Extensions on the Mac
December 3, 2011
Posted by on
As I said in my previous blog post, creating the ArduinoConnector ANE for the MacOS X platform was frustrating. It turns out that Apple ships a slightly modified version of GCC that is close to what is offered on the Linux/Unix and Windows platforms, but not 100% the same. When I approached the project, I thought it would be a cake-walk — simply take CDT (or gcc command-line), and point it to my POSIX C code, and I should be a few clicks away from creating the .framework file needed for AIR.
Turns out that the only way to make a .framework file is by using Apple’s Xcode (unless I’m really missing something in the gcc man pages). I wasn’t really in the mood to learn yet another coding IDE, but I did want to post some of the gotcha’s I found in creating the Mac version of the ANE. These are not step-by-steps, but rather things that tripped me up.
- When you create a new Xcode project, you must choose a Cocoa Framework project (under Framework & Library).
- Add the “Adobe AIR.framework” by clicking on the project name, and then going to Add, Existing Frameworks. The Adobe AIR Framework file is found in your “Flash Builder App Dir -> sdks -> 4.6.0 -> runtimes -> air -> mac” folder.
- The Adobe AIR Framework file auto-includes the header file, and the external library that you need to link to. Don’t go searching for another header file, you don’t need it.
- Create/Import your .c and .h files and attempt to compile before setting your project settings. If you don’t try to compile before you set your project files, you won’t see 3/4 of the compiler settings you need to make things right. This one threw me into a loop for at least a day.
- All of the examples have you including the <Adobe AIR/Adobe AIR.h> file in your project — I found this works, but all it is doing is including the FlashRuntimeExtensions.h that exists within the Adobe AIR framework. I decided to resist change and include the Adobe AIR.h file. It works.
- There are two places you need to set your compiler and project settings. One is on the project itself (the top-most node in the Groups & Files tree), and the other is in the Targets -> ProjectName.framework node. Set all settings in both places (they don’t cascade once it has been compiled once, which you have to do to get the GCC settings to show up right).
- Make sure your project is compiling 32-bit frameworks, targeted to the 10.5 SDK. I never found that documented anywhere, and it was sheer luck I tried those combos.
- Make sure that you turn the optimization level to None (0). If you don’t do this, things will seem to work, but if you use any of the FREGet or FRENew functions, they will produce seemingly random numbers (I was convinced it was passing me back pointers casted as integers, but who knows).
- Make the following target and project settings changes that deviate from the defaults :
- Architetures : 34-bit Universal
- Base SDK : Mac OS X 10.5
- Build Active Architecture Only – Checked
- C/C++ Compiler Version : GCC 4.2
- Linking Compatibility Version : 1
- Linking Current Library Version : 1
- Other Linker Flags : -flat_namespace -weak_Framework “Adobe AIR”
- Runpath Search Paths :
- Packaging Framework Version: A
- Wrapper Extension : framework
- Framework Search Paths :
- /Applications/Adobe\ Flash\ Builder\ 4.6/sdks/4.6.0/runtimes/air/mac
- Library Search Paths: /Library/Frameworks/Adobe\ AIR.framework/Versions/1.0
- GCC 4.2, Generate Position-Dependent Code: Unchecked
- Optimization Level : None [-O0]
- Other C Flags : -fvisibility=hidden
- Other C++ Flags: -fvisibility=hidden
- Precompile Prefix Header : checked
- In order to export the proper function names for your initialization and finalization functions, prefix them with __attribute__((visibility(“default”)))
Once you are creating your .framework properly, you should be all set. If you created truly POSIX or standard C code, there should be very little changes you should need to make your project work.
I do have to make one additional note about a bug people have been finding with Flash Builder 4.6, as it was released on 11/30. If you are attempting to include an ANE into a project, the project will compile, but if you debug the project, it will complain that it can’t find the method name (not the initilizer or finalizer, but one of your other method names). If you debug your project from ANT or the command line, it will work fine. The work-around for this is the following steps :
- Make sure you have ADL in your search path. Edit the /etc/paths file and add a new line with /Applications/Adobe Flash Builder 4.6/sdks/4.6.0/bin
- Create a new folder on your desktop, Document folder, or somewhere where you will find it. Copy your .ANE into it.
- Create a new folder within this folder, and name it MyTestANE.ane (make sure to include the .ane — that is very important)
- cd into that new .ane directory, and execute the following command : unzip ..\ArduinoConnector.ane (assuming you named your .ane ArduinoConnector.ane)
- Go into the bin-debug folder of your project, and run the following command : adl -profile extendedDesktop -extdir ~/Documents/Extensions/ Main-app.xml assuming that the directory you created in the second step was named Extensions and was located in your Documents folder.
- You can repeat the last step as often as you need with no additional work, assuming you don’t need to update your .ane. If you need to attach the debugger / profiler , you can follow the steps outlined on this blog (but use about:blank instead of http://localhost)
Well, I think that is about it. I hope I can help alleviate some of the frustration that I suffered for somebody else in working with all this :)