Getting started with Haxe/C++

Haxe code can be transformed into C++ and then compiled using your system's C++ toolchain into a native executable.

Console applications

Before using Haxe to target C++, you first need to install the hxcpp library on your computer. From a terminal:

haxelib install hxcpp

Let's see our first HelloWorld example:

class Test {
    static function main() {
        trace("Hello World !");
    }
}

Put this class into a file named Test.hx and create the file compile.hxml in the same directory with the following content:

-cpp cpp
-debug
-main Test

The -debug switch is to make sure it traces (and may only be needed on a mac). To produce 64 bit binaries the file should define the HXCPP_M64 compile variable:

-cpp cpp
-main Test
-D HXCPP_M64

To compile this from terminal:

haxe compile.hxml

If an error occurs, it will be displayed. If everything went smoothly like it should, this will produce a folder named cpp with your application inside. You can now run your application from terminal:

cpp/Test-debug

The application will print the trace in the console and exit:
Hello World

C++ target troubleshooting

Cannot open program database


This happens on Windows when your code resides in a Dropbox synced folder.
fatal error C1033: cannot open program database 'vc100.pdb'
Called from ? line 1
Called from BuildTool.hx line 1265
Called from BuildTool.hx line 554
Called from BuildTool.hx line 591
Called from BuildTool.hx line 710
Called from BuildTool.hx line 783
Uncaught exception - Error in building thread
Error : Build failed

In this scenario dropbox starts to sync the pdb file, but then the compiler can't write it. Do NOT compile in Dropbox.

Quotation mark in PATH environment variable on Windows


Called from ? line 1
Called from BuildTool.hx line 1265
Called from BuildTool.hx line 554
Called from BuildTool.hx line 588
Called from Setup.hx line 84
Uncaught exception - Could not automatically setup MSVC
Error : Build failed

The build tool fails on Win7+ when the PATH contains the quotation mark character ("). Removing the quotation mark (") characters from the PATH will fix the problem.

Graphical applications (ie. games) with NME

Building a game or application with NME is almost like writing for a single platform with a Flash-like display list. However, when you are ready to publish your application, you can choose between targets like iOS, webOS, Android, Windows, Mac, Linux and Flash Player.

Instead of using the lowest common denominator between platforms with a "universal" runtime, NME projects are compiled as SWF bytecode or C++ applications, using the Haxe language compiler and the standard C++ compiler toolchain for each platform.

NME includes an install tool that automatically handles the build, packaging and install process for each target, so you don't need to do it yourself. Cross-platform really is easy and native.

Code sample

This sample, taken from haxenme.org tutorials will display an image in the middle of the screen. Notice that:

  • we're using the Flash API but in the nme.* package,
  • assets management is abstracted to be identical on all platforms: the bitmap is actually embedded when targeting Flash.

package;

import nme.display.Bitmap;
import nme.display.Sprite;
import nme.display.StageAlign;
import nme.display.StageScaleMode;
import nme.events.Event;
import nme.Assets;
import nme.Lib;

class DisplayingABitmap extends Sprite {
    
    private var logo:Bitmap;
    
    public function new () {
        super ();
        addEventListener (Event.ADDED_TO_STAGE, this_onAddedToStage);
    }
    
    private function construct () {
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        
        logo = new Bitmap (Assets.getBitmapData ("assets/nme.png"));
        resize ();
        addChild (logo);
        
        stage.addEventListener (Event.RESIZE, stage_onResize);    
    }
    
    private function resize () {
        logo.x = (stage.stageWidth - logo.width) / 2;
        logo.y = (stage.stageHeight - logo.height) / 2;    
    }
    
    private function stage_onResize (e):Void {
        resize ();    
    }
    
    private function this_onAddedToStage (e):Void {
        construct ();    
    }
    
    // Entry point
    public static function main () {
        Lib.current.addChild (new DisplayingABitmap ());
    }    
}

Buiding

NME includes a custom build tool, mainly to handle the crossplatform assets management. The application isn't configured using a .HXML file but with a .NMML config file:

<?xml version="1.0" encoding="utf-8"?>
<project>

  <app title="Displaying A Bitmap" main="DisplayingABitmap" package="org.haxenme.tutorial.displayingabitmap" version="1.0.0" company="NME" />
  
  <window width="640" height="480" fps="30" orientation="portrait" resizable="true" />
 
  <set name="BUILD_DIR" value="Export" />
  <classpath name="Source" />

  <haxelib name="nme" />

  <assets path="Assets" rename="assets" include="*" exclude="nme.svg" />

  <ndll name="std" />
  <ndll name="regexp" />
  <ndll name="zlib" />
  <ndll name="nme" haxelib="nme" />

  <icon name="Assets/nme.svg" />
</project>

Now to build the project, open the terminal and type one of these lines, depending on the desired target:
'nme' is a shortcut to 'haxelib run nme'

nme test sample.nmml flash
nme test sample.nmml cpp
nme test sample.nmml android
nme test sample.nmml webos

IOS is a bit trickier as you can it is only possible to automate build & test for the simulator but not for the device; 'nme update' will just create a Xcode project that you will have to open & run in Xcode:

nme test sample.nmml ios -simulator
nme update sample.nmml ios

Yep it's that simple to create a desktop or mobile application with the same codebase.

version #16033, modified 2013-02-22 09:48:43 by kalevi