HXCPP uses an xml-based build system. When you launch haxe -cp src --cpp bin/cpp path.to.Main:
- Haxe files are transpiled to C++ and a
Build.xml is produced in the output directory, i.e. bin/cpp/Build.xml;
- everything is then built by HXCPP, merging the newly generated project
Build.xml with the global default xml definitions and then calling the compiler toolchain(s).
You can inject compiler flags, libraries to link, includes directories, etc., through the @:buildXml metadata, as described on the manual:
@:buildXml("
<target id='haxe'>
<lib name='-lncurses' if='linux'/>
<lib name='ncurses.lib' if='windows'/>
</target>
")
class Main{ ...
These tags will be appended to the project Build.xml. The haxe target is the default target. Keep in mind that every toolchain (MSVC, gcc, Xcode, etc.) has its own syntax. You can see examples in the build.xml of cross-platform low-level projects like Systools or Lime.
You can add -D HXCPP_VERBOSE to the haxe command line to see which commands are actually launched: haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main.
As for externs, the simpler case is:
- you write your C++ code, with #includes and everything needed, inside a
@:cppFileCode() block; everything you write here is pasted as-is in the generated cpp file;
- you mark one of your haxe functions, defined on one of the haxe classes, as
@:native("nameOfTheCppFunction"), and the build system will join them together.
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest();
}
@:native("nativeCppTest")
extern static function myCppTest():Void;
}
If you open the generated file (in this case bin/cpp/src/Main.cpp) you'll see that the haxe myCppTest() call is changed to its native version nativeCppTest().
If you would like to pass function arguments, and receive return values, you'll have to wrap those using the cpp.* standard library types. For example:
@:cppFileCode("
#include <ncurses.h>
void nativeCppTest(const char* myString){
/* here goes your ncurses code */
return;
}
")
class Main{
public static function main()
{
myCppTest("print this");
}
@:native("nativeCppTest")
extern static function myCppTest(myString:cpp.ConstCharStar):Void;
}
Some of the conversions will be automatic (like, in this case, from a constant string to ConstCharStar), some will require an explicit cast; if you need to pass pointers to the C++ code, you can get it via cpp.RawConstPointer.addressOf(<haxe object>) (or RawPointer if not const):
public static function main()
{
var myString:String = "print this";
myCppTest(cast cpp.RawConstPointer.addressOf(myString));
}
Useful references: