Haxe, iPhone & C++ At Last

Hxcpp 1.0, neash 1.0, NME 1.0

The release this week of haXe version 2.0.4 officially includes c++ as a build target, for Windows, Mac, Linux and iPhone. You can download and install from haxe.org. In addition to the standard includes, you will need the “hxcpp” library, which can be insatlled with the included haxelib management tool.

Coincident with the hxcpp release, I have updated the neash and NME libraries to versions 1.0. You can also download these via the haxelib tool too. There are several incrental improvements, and the iPhone target has been added!

Getting started with the iPhone

Getting started with the iPhone is quite tricky at the moment, mainly because of the pain of setting up an Xcode project. Also, getting the simplest program onto the device is hard due to the code signing requirements. So if you can already get one of the existing application templates to work, you are half way there.

Note that this solution uses the “SDL” library, and must statically link against this. SDL is covered by the LGPL license, and this has implications should you choose to release your software. I am hoping to remove the LGPL restiction at a later date.

The binaries used here are have been compiled for the “2.2.1″ iPhone SDK. So choose this version when compiling for simulator or device.

  1. Download and install components
    • Get haxe & neko: Visit haxe.org
    • Get hxcpp: haxelib install hxcpp
    • Get nme: haxelib install nme
    • Get neash: haxelib install neash
    • Get the sdl-static libs for iphone: I have created a project with binary builds of these. You can get the latest builds directly from subversion svn code at:
      http://code.google.com/p/sdl-static/source/checkout.
      Or get the snapshot bundle from this site and install somewhere handy:
      sdl-static-iphone-1.0.zip
  2. Get Xcode with iphone sdk support – visit apple.com
  3. Get a Developer key (you can try simulator without it). You will need to pay to sign up as a developer on the apple site.
  4. Fire up Xcode and do File > New Project.

    Choose iPhone OS > Application. Here choose a “Windows-Based Application
    but infact we will use the delegate setup in the SDL code, so we will have
    to delete the one created by the wizard.

    Select a name & directory for the project. I’m calling it “Haxe Test”.

    Now as it stands, you should be able to build for the Simulator and
    get a lovely white screen and a program called “Haxe Test” in the simulator
    start screen.

    Next thing is to delete(to trash) the “…AppDelegate.h” “…AppDelegate.m”,
    the “Nib Files” group, Resources/MainWindow.xib and “main.m”.
    Finally, select the “Haxe Test” executable (in the Targets section) and from the “Get Info” –
    “Properties” tab, clear the reference to “MainWindow”.

    We will add replacements for these soon.

  5. Add “main.cpp” from the NME project.
    Select the top-level project folder and then use Action > Add > Existing Files.
    It is probably in /usr/lib/haxe/lib/nme/1,0/ndll/iPhone/ or
    similar depending on which version of NME you have installed. It can be
    very painful to get xcode to load from this location, unless you hit
    Command-Shift-G at the “Add” dialog and type (at least some) of this filename in.
    Choose to “Copy to destinations folder” so
    that you can mess with it if you wish. Note: you need to have a cpp mainline
    in order to automatically link in the correct runtime libraries.

  6. Add the libNME.iphoneos.a and libNME.iphonesim.a files from the haxelib NME project.
    You can add them both and the linker
    will select the correct on depending on your build. They are in the same place
    as main.cpp, you you should be able to use “iPhone” from the pull-down box
    in the add dialog. Probably best not to copy these files – in case you want
    to change them at some stage.
  7. Add the whole sdl-static/lib/iPhone directory.
    Again probably best not to copy.
    I used the “Recursively create groups” option. These will be where you stored them
    in step 1.

  8. Add the whole hxcpp/bin/iPhone directory like above.
    Again, this will
    be in a path like /usr/lib/haxe/lib/hxcpp/1,0,2/bin/iPhone/.
  9. Add the hxcpp include directory to the include path.
    Use the “Info” button
    to get the project properties, and on the build tab, under “Search Paths”
    add something like /usr/lib/haxe/lib/hxcpp/1,0,2/include/ to “Header Search Path”
  10. Now we are ready for the haxe code. If you have and existing project,
    then you can adapt the following instructions.

    Create a new file from Xcode (Other/Empty File] Here I have called it “HaxeTest.hx”, and unticked the “Targets” option. I’m prety sure there is a way to get “Haxe File” to appear as on option here – but I don’t know the details.

    In the haxe file, enter something like (Note the window size):

    import flash.display.Sprite;
    import flash.display.Shape;
    
    class HaxeTest extends Sprite
    {
    
       public function new()
       {
          super();
          flash.Lib.current.addChild(this);
    
          var circle:Shape = new Shape( );
          circle.graphics.beginFill( 0xff9933 , 1 );
          circle.graphics.drawCircle( 0 , 0 , 40 );
          circle.x = 150;
          circle.y = 200;
          addChild( circle );
       }
    
       static public function main()
       {
          neash.Lib.mOpenGL = true;
          neash.Lib.Init("HaxeTest",320,480);
          neash.Lib.SetBackgroundColour(0x447733); 
    
          new HaxeTest();
    
          neash.Lib.ShowFPS();
          neash.Lib.Run();
       }
    }
    

    This is the “main” file for haxe, and the hxcpp compile will create a library matching
    this class name.

  11. Set up a build script to build changes you make to your haxe files into a library.
    Xcode has a few issues with a straight custom build script order due to incorrect
    dependency checking. This can be worked around by first adding a custom target.

    Highlight the “Targets” in the Groups & Files and use the “Action > Add > New Target..
    Choose “Other > Shell Script Target” and call it something like “Compile Haxe”.
    Close the pop-up and go back to the explorer. There should be a “Run Script”
    entry under the “Compile Haxe” target if you expand it out.

    Get info on “Run Scipt” and enter the following script

       if [ "$CURRENT_ARCH" = "i386" ]
       then
          haxe -main HaxeTest -cpp cpp -lib neash -lib nme  --remap neko:cpp --remap flash:neash -D iphonesim
       else
          haxe -main HaxeTest -cpp cpp -lib neash -lib nme  --remap neko:cpp --remap flash:neash -D iphoneos
       fi
    


    You can untick the “Show Environment” if you do not need to debug this.

    One last step – drag the “Compile Haxe” target into the “Haxe Test” target.
    It should now also show up as first item “under” the “Haxe Test” target.
    The build order should now be correct. (See image at end of post)

  12. Now you are ready to do the build. The first time you build, the build
    results will show “Running custom shell script…” for quite a while.
    Haxe compiles to cpp very quickly, but it take a while for the cpp files
    to compile to a library. You can see the progress if you expand out the
    middle tab bit.

    At this stage, you should get a bunch or errors when linking, but also haxe
    should have created a library for you. Add this library to the project -
    it should be in the local cpp/HaxeTest.iphonesim.a.

  13. Compiling now gets a bunch of unresolved functions from frameworks.
    Add the following frameworks to the project (Add > Existing Frameworks):
    • QuartzCore
    • OpenGLES
    • AudioToolbox

    These can be found in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/.

  14. Run!
    So you should be good to go. Open up the debug console so you can see
    any traces/printfs.

  15. Change the target to “Device – IPhone OS” from the pull-down and hit “Build and Go”.
    Again, this takes quite a while the first time.
    Now add the new cpp/HaxeTest.iphoneos.a library to the project.

  16. Now you need to sort out your code signing. If you have not done so already,
    setup you apple developer account & certificates on the apple web site.
    Go to the info of the “Haxe Test” executable and the “properties” tab.
    Change the “Identifier” to match one of your cerificates. Make sure to
    match your company URL. You may want to use “*” when creating your
    profile for easy changing.

    Under the “Build” tab, under the “Code Signing” bit
    in the “Any iPhone Device” pull down your profile. If you don’t have one then
    you will need to create one on the apple website.

  17. Connect up your iPhone(iPod touch) and build! W00t!

HaxeTest

I have had all sorts of errors when trying to upload to the device.
So far, they have been solved by getting out of the car, walking around it and getting back in.
ie, Disconnect and power down ipod. Fully exit Xcode and the start it all up and try again. Also, uninstalling the app from the “Windows > Orgainiser” directory can help.

But now the easy bit. Change to HaxeTest.hx file, and hit Build & Go. It is that simple.
Errors should show up nicely in xcode.

You can add data files (eg, pngs, xml etc) to the project and they will be copied to device so you can open them with a relative path.

In the properties of the “Info.plist” you can set a Icon File – don’t forget to add the icon to the project too.

Not covered here (because I have not fully sorted it out myself):

  • Syntax highlighting in XCode
  • Debug build (hxcpp can do then – it’s a matter of setting up Xcode)
  • Code completion in Xcode
  • Automating this procedure!

Edit: Add framework path, SDL version, MainWindow clearing.

This entry was posted in hxcpp, iphone, neash, nme and tagged , , , , , . Bookmark the permalink.

146 Responses to Haxe, iPhone & C++ At Last

  1. Dan says:

    Awesome work! Can’t wait to get home and try it out! :)

  2. Teri says:

    Can you show Xcode project?

  3. Gary Suyemoto says:

    Sweeet! Great job, Hugh!

  4. Sam says:

    Hoooly awesome!

    Installing now :D Thank you so much for getting this all to work!

  5. tonypee says:

    oooooooooow… a long walk to freedom! lets see how far my little legs can take me.
    thanks again!

  6. Sam says:

    Hmm I can’t seem to compile HaxeTest.iphonesim.a… The build script is running but I’m getting a whole lot of errors when it trys to build the C++ code.

    Errors in nme/display/JointStyle.cpp:
    “wchar.h: no such file or directory”
    “string.h: no such file or directory”

    “declaration of ‘operator new’ as non-function”

    I’m getting 18 errors in total from that.

    Any ideas where I could have gone wrong?

  7. Simon says:

    Hi Hugh,

    Excellent work!

    Is there any notes about what API is implemented? i.e. I’m pretty sure
    that perlin noise is missing from the BitmapData class?

  8. Huge says:

    Hi Sam,
    Have you updated to the 1.0.2 hxcpp? I think I fixed it there.

  9. Huge says:

    Simon,
    Sorry, I don’t have a proper coverage document at this stage. Sadly, the source code is the best resource here. Things should settle down soon, and then I can get onto that sort of thing.

  10. Sam says:

    Hugh,
    Yeah I just installed hxcpp today, as well as uninstalling it and reinstalling it.

  11. nathan says:

    nice one and thanks hugh – makes me wanna buy an iphone ;)

  12. Huge says:

    Sam, Ok it does look like you have the latest versions – it’s just that it can’t find these includes.
    It is probably to do with development paths – perhaps version numbers. I will have to have a think about this.

  13. IanT says:

    Fantastic work, Hugh!

  14. Huge says:

    nathan – You can get away with an ipod touch – big problem is if you have to buy a mac too :)

  15. Huge says:

    Hi Sam,
    I use this in the makefile:
    -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk which is set with the “IPHONE_VER” in the BuildCommon.xml

    Do you have this directory in your:
    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ ?

    You could try changing this in the BuildComon.xml

    Hugh

  16. Nick says:

    Fantastic stuff and keep up the excellent work!

    … now I just need to get a Mac… ;)

  17. Rick Minerich says:

    How does Haxe handle C++ and ObjectiveC’s lack of memory management?

  18. tonypee says:

    Hey hugh – I am thinking about the LGPL thing and how it affects making an iphone game. afaik it means that ALL of the generated c++ code would need to become LGPL. This would not necessarily mean that hx code, or releasing a compiled .a for linking (altho people could obviously recompile and link, but it would take a fair bit of work, and without graphics, would be more work for the average person that is probably worth while. The c++ code is a little obfuscated too as its generated (a little harder to understand)
    SO i’d have no issues with this atm. I’ll probably release the code to any game a month or two after releasing it anyway, just not as soon as its released.
    An LGPL solution would be good too – but not the highest priority i guess… just thinking aloud

  19. Huge says:

    Tony, my understanding of the LGPL is that you need to allow people to *Relink* your application with their versions of the LGPL code (eg, put a “printf” in the *SDL* code). For this, your HaxeTest.iphoneos.a and main.cpp is all that is required. I think you have to make this practically possible too (rather than just theoretically possible) with enough project doco to allow it to happen. You keep copyright of all images etc (you could even encrypt them), so they can’t go publishing an app themselves, although I guess they need to be able to upload them to their own phone. I don’t think this is going to stop any sales.
    I think you can get a commercial license for SDL – not sure how much it costs.
    For the iphone, most of the SDL code is a thin layer over the OS code but presented though the “SDL” interface. Since NME has its own interface, it should be reasonably easy to go straight to the OS – at least for the iphone.

  20. Huge says:

    Rick,
    The c++ code contains its own garbage collection code. Initially I tried “Boehm GC”, but that was too slow, so haxe generates it own code. I hope the problems with Boehm GC can be fixed (by someone else!) and it will all just magically run faster. As it stands, the GC is probably one of the weakest points of the current system, and I will look at speeding it up.
    ObjectiveC is only used where it is needed to interact with the OS. The haxe code is pure c++.

  21. wonderwhy-er says:

    Hmm so it seems it is not truly multi platform haxe solution. Rather way of coding for iPhone in MacOS XCode using haxe language.

    I wonder when someone will come up with polished way of doing it in say Eclipse on all platforms(Linux/Windows/MacOS) so that need for switching platform would be eliminated.

  22. Huge says:

    Sam,
    I think you do not have the 2.2.1 SDK installed. Yuu can either get it from apple, or change the “IPHONE_VER” in the BuildCommon.hxml.

  23. Huge says:

    Wonderwhy-er,
    It is mostly cross platform. The haxe code is still the same, it’s only the final bit of getting it onto the device. The problem is that apple has locked down this final step.
    This tutorial may give you the impression that most of the work is iPhone specific but that is only because the program is trivial.
    Once set up, the only remaining work you have to do the the haxe code.
    Another way to do it would be to write your code in eclipse (or FlashDevelop) and get it working in a broswer, and then do this final step to get it on the iPhone.
    You can compile for Mac, Linux and Windows from the command-line – no need for xcode.

  24. Sam says:

    Hugh, thank you very much :D I upgraded to the 3.0 SDK and it all works nice and smooth.

  25. Idden says:

    Great job Huge.

    I might finally start using Haxe for a real project.

  26. Brett Walker says:

    Interesting stuff. This is potentially pretty game-changing, but what’s the performance like compared to doing native Obj C code? I saw your previous post where you were getting sub-10 fps on some demo code. I’m assuming we have no access to the UIKit stuff through haxe? What about OpenGLES?

  27. Fedor says:

    Hi, Hugh.

    Probably there is a problem in the socket_send function of the std.dll at the line

    val_check(data,string);

    - validation is not passed.

    I think this is because haxe.io.BytesData is defined in neko as NativeString
    and defined in cpp as Array

  28. Huge says:

    Fedor,
    Thanks again, I hope i have fixed this with the latest 1.0.4 hxcpp

  29. Pingback: Philippe.me » haXe – what’s in it for you

  30. Fedor says:

    Hi, Hugh.

    Thanks for fix.
    There is problem with next code:

    package ;

    class TestClass{
    public static var AAA = 0;
    public static var BBB = 1.3;
    public static var CCC = “”;
    public static var DDD = true;
    public static var EEE : Dynamic = null;
    public static var FFF = new Hash();

    }

    class TestSwitch
    {
    static function printType(args : Array){
    for( i in 0…args.length ) {
    var a : Dynamic = args[i];
    switch (a) {
    case TestClass.AAA: trace(“AAA”);
    case TestClass.BBB: trace(“BBB”);
    case TestClass.CCC: trace(“CCC”);
    case TestClass.DDD: trace(“DDD”);
    case TestClass.EEE: trace(“EEE”);
    case TestClass.FFF: trace(“FFF”);
    }
    }
    }

    static function main() {
    var a : Array = [TestClass.AAA, TestClass.BBB, TestClass.CCC, TestClass.DDD, TestClass.EEE, TestClass.FFF];
    printType(a);
    }

    }

    When compiled as Neko target – it works ok.
    TestSwitch.hx:24: AAA
    TestSwitch.hx:25: BBB
    TestSwitch.hx:26: CCC
    TestSwitch.hx:27: DDD
    TestSwitch.hx:28: EEE
    TestSwitch.hx:29: FFF

    But as cpp target it gives next:
    TestSwitch.hx:24: AAA
    TestSwitch.hx:25: BBB
    TestSwitch.hx:24: AAA
    TestSwitch.hx:27: DDD
    TestSwitch.hx:28: EEE
    TestSwitch.hx:24: AAA

  31. Pingback: iPhone development alternatives « Nick

  32. Huge says:

    Fedor,
    Looks like it is making a comparison using “doubles”, without checking the types of both sides are numeric. It should not be too hard to fix in hxcpp.

  33. HaxeTrouble says:

    When I try to compile it says haxe command not found. Where is the shell script executed so that I can explicitly set the path to haxe in the shell script? Please help.

  34. Sebastian says:

    Hello Hugh,

    this project sounds really interesting. I did some first steps with haxe and wanted to try and compile some c++ with your libraries. I followed the instructions on the touchmypixel-blog to download & install the hxcpp libraries.

    The installer seems to perform fine, i am on windows vista and run the command line as administrator. The lib folder is created and the subfolders ‘hxcpp’ and ’1,0,5′ too. But it seems to me as if the .exe Files are missing, e.g. hxcpp.exe. All i find inside ’1,0,5′ are:
    -haxelib.xml
    -LICENSE.txt
    -run.n

    and subfolders: bin, build-tool, include, runtime.

    Do you have any idea what might have happened here?

    kind regards,
    Sebastian

  35. Huge says:

    HaxeTrouble,
    What system are you on? Mac? I think it installs in /usr/bin/haxe which links to /usr/lib/haxe/haxe. This should be in your path – maybe a permissions problem somewhere? Windows, it is in the “Motion-Twin” programe files directory.

  36. Huge says:

    Sebastian,
    I think you have a correct install!
    The project is generally run from the normal “haxe” compiler, which in turn runs “haxelib run hxcpp”, which in turn runs “neko” on the “run.n” file found in the current hxcpp directory.
    You can run, for example:
    haxelib run hxcpp BuildLibs.xml
    On its own, but normally you would just do:
    haxe -main Main -cpp cpp

    Hugh

  37. James says:

    Great work! Functions rather nicely on my iPhone.

    My only criticisms currently are:

    1) It takes a significant time to build. Perhaps

    2) The licensing of the various components (e.g. SDL, NME) leaves many questions with regards to exploiting this in a real app store app.

    Other than that, rock on! :D

  38. Jarrad says:

    Huge,

    fantastic work!!
    Im loving it so far,

    I have noticed some issues with bitmaps?

    var mLdr:Loader = new Loader();
    mLdr.load(new URLRequest(“blah.png”));
    addChild(mLdr);

    i’ve tried jpg and both png outputs from photoshop and they display, but they come out black n white with weird lines going thru them, and a little distorted.

    I AM using the 2.2 framework (not 2.2.1) so maybe thats it? (im grabbing 3.0 now)

    Also is it possible to receive ‘mouse’/finger input yet?

  39. Jarrad says:

    heres a screenshot of the problem
    http://jarradhope.com/tmp/gamehaxe.png

  40. Phil Harvey says:

    This looks great.

    I’ve just tried it on a Windows XP machine, eventually got one of the samples to complile (neash sample 1). But when I try to run the simple.exe which is in the cpp directory I get a crash.

    Do I need to copy over dlls?

    But in general this looks great, and I will test on the iphone later today once I get the pc version working.

    Thanks for your hard work.

    Phil

  41. Phil Harvey says:

    k, I managed to get it working on the iphone nicely. A couple of issues, were location of the hx file, needed to be in the root not the classes directory where it was created.

    Other than that runs nicely on my 3GS phone.

    Now for the pc version.

    Phil

  42. Phil Harvey says:

    One question, when compiling do you set the compile for thumb flag off? As I’ve seen in the past on other opengl games, that you can get a huge speed improvement with this flag turned off.

    Phil

  43. Huge says:

    Hi Jarrad,
    That looks like a clasic case of wrong-number-of-bits-per-pixel (24/32). I have a “Convert to preferred format” call in nme that must be getting missed, or has a bug somewhere. Should be easy to fix.

  44. Huge says:

    Phil,
    I used to have the thumb flag on, but I got a jump-out-of-bounds. I think the runtime + nme + neash + user code is too big. I’m not sure how to mix small jumps and long-jumps? But I’m always keen on some optimisations, so I will have a look at some stage.

  45. Jarrad says:

    Huge, thanks! works perfectly now

    I saved png with Pixelmator instead of photoshop, how bizaare!

    Sorry to be high maintenance, but when do you think there will be MouseEvent’s?

    That and sound and this is my dream come true!

  46. Huge says:

    Jarrad,
    By mouse events, you are talking about mouse-over/mouse out etc? The problem is that because the iPhone mouse is “Down” when it moves (ie, you press the screen), it is a “drag” event, not a “move” event. I guess I did not consider this a possibility, and it can be fixed. The events should get as far as neash, where it converts it into “mouse over” style events – you could have a sniff around there – otherwise the next version of neash should fix this.

    Hugh

  47. Jarrad says:

    Yah, specifically mouse_down and mouse_move.

    How I see it is mouse_down would be when you touch the screen, mouse_move would be your finger down and moving and mouse_up when your picking your nose/scratching your head

    I had a poke around neash Lib.hx and the event .hx’s and saw a OnMouseDrag but i couldnt find an event that it fires.

  48. Matthew says:

    Okay, I followed your instructions to the letter, and I’m using the latest sdl-static (rev 27), hxcpp 1.0.5, neash 1.0 and nme 1.0. Building it doesn’t bring up any errors, but when trying to launch the app it just crashes, every time, on launch. Any recommendations?

    Also, I didn’t understand your “cpp mainline” comment in the instructions. I’m very new to anything more advanced than actionscript, so apologies if that’s a stupid question. I tried googling it but nothing appropriate came up. Perhaps that’s my problem?

    I copied all your code exactly, except for the Header Include stuff which I changed to 1,0,5 instead of 1,0,2 for obvious reasons.

  49. Matthew says:

    Edit: Here’s the crash report, if it helps.

    http://pastebin.com/m4a33bb5f

    Any help you can give genuinely is very much appreciated.

  50. Matthew says:

    Okay, so I’ve now resolved my previous problem. Basically, I can only get this working at the moment under the 2.2.1 Simulator. Which is fine, except that I only own a iPhone 3.0, and, more to the point, it has to be able to work on *all* iPhones.

    I have no idea where my problem is, and I suspect it is indeed my problem and not something wrong with the project itself, but if you could point me in the right direction I’d be grateful.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>