The Haxe Target

When compiling from Haxe via hxcpp, a Build.xml file is generated in the output directory. The file lists the generated files and dependencies and ultimately includes the toolchain/haxe-target.xml file, which describes how to combine these files.

Include Order

There are a few complications when setting the order in which things are configured, since a particular build might want to:

  • set the compiler
  • override some compiler settings
  • make decisions based on the compiler or settings
  • set or use standard file prefixes/suffixes
Example Sequence

You can see which files are included by setting the HXCPP_VERBOSE define when compiling. One example is for a hypothetical user 'Hugh' on a Windows platform:

Using makefile: Build.xml
No specified toolchain
 - Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/setup.xml
 - Parsing include: C:\Users\Hugh\.hxcpp_config.xml (section "vars")
Using Windows compiler: MSVC
 - Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/finish-setup.xml
 - Parsing makefile: C:\Users\Hugh\test\proj\cpp\Build.xml
 - Parsing include: C:/Users/Hugh/dev/hxcpp/build-tool/BuildCommon.xml
 - Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/haxe-target.xml
 - Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/msvc-toolchain.xml
 - Parsing compiler: C:/Users/Hugh/dev/hxcpp/toolchain/common-defines.xml
 - Parsing include: C:\Users\Hugh\.hxcpp_config.xml (section "exes")
  1. setup.xml is read because no custom toolchain is specified, and this just includes .hxcpp_config.xml.
  2. The vars section of .hxcpp_config.xml is read - mainly to setup SDK locations.
  3. The hxcpp build tool then uses internal logic based on the host and defines to work out which compiler/toolchain to use. In this case, MSVC (Microsoft Visual Studio C++) is selected.
  4. finish-setup.xml then sets some standard defines for file extensions and linking flags based on the type of toolchain being used.
  5. The provided build file (Build.xml) is then processed. It can use the standard defines from finish-setup.xml.
  6. Build.xml imports the standard Haxe target build files (haxe-target.xml), which adds the files required for the Haxe runtime.
  7. The toolchain file (msvc-toolchain.xml) is then parsed - making use of any settings from the main Build.xml and finish-setup.xml. This file includes common-defines.xml inject standard Haxe compiler flags.
  8. The exes section of .hxcpp_config.xml is read. Historically to add libraries or build-paths to targets.
Standard Environment

finish-setup.xml is where the conventions are set. These variables include:

  • haxelink - dll, static_link, or exe
  • LIBPREFIX - lib or empty

    • .iphonesim-64
    • .iphonesim
    • .iphoneos
    • .iphoneos-v7
    • .iphoneos-v7s
    • .iphoneos-64
    • .appletvsim-64
    • .appletvsim
    • .watchos
    • .watchsimulator
    • -x86
    • -v7
    • -64

  • LIBEXT - .a, .lib
  • DBG - -debug or empty
  • OBJEXT - -list-of-config-ids depending on available options

These variables are used by haxe-target.xml - you can use them too. Haxe then builds the haxe target, which uses some code like:


  <target id="haxe" tool="linker" toolid="${haxelink}" output="${HAXE_OUTPUT_FILE}">
    <ext value="${LIBEXTRA}.a" if="static_link" />
    <!-- ... -->
    <files id="__main__" unless="static_link" />
    <files id="__lib__" if="static_link"/>
    <files id="__resources__" />
    <files id="__externs__" />
    <files id="runtime" unless="dll_import" />
    <files id="cppia" if="scriptable" />
    <lib name="-lpthread" if="linux" unless="static_link" />
    <lib name="-ldl" if="linux" unless="static_link" />

Here you can see the various file groups, which are enabled or disabled depending on the compiler mode, and some standard libraries that are needed for Linux.

Experimenting with hxcpp-generated code/Build.xml

If you are using external C++ code or using metadata to inject XML into the build process, and you are getting a compiler or linker error, then it can be useful to run the hxcpp build tool without re-running Haxe. This lets you manually edit the build file or generated C++ code until you get things to work. Once you have solved the issues using this technique, then you can move the changes back into the injected/external code.

First, invoke the Haxe compiler with the -v flag. This gives quite a bit of debug info, but will include a line like this:

haxelib run hxcpp Build.xml haxe -Dhaxe3="1" -Dhaxe_ver="4.000" -Dhxcpp_api_level="332" -Dsource-header="Generated by Haxe 4.0.0" -I"" -I"C:/Users/Hugh/dev/haxe/std/cpp/_std/" -I"C:/Users/Hugh/dev/haxe/std/"

To use this, first change directories to your output directory. This is the directory specified in the --cpp Haxe compiler option. Then copy and paste the haxelib run ... command into a shell, command or batch file.