Separate compilation of native c++ source files

Hi there! I’ve been away from OpenFL for a while, but lately I’ve been thinking of diving back in to update an old app that has basically died of code rot. Hopefully I’ll pop in from time to time with questions.

One of the things I definitely want in this rewrite is a native c++ backend to perform the intensive geometric calculations I’m using (currently, with the help of Boost.Geometry and GLM).

What’s the current best practice for getting OpenFL/hxcpp/etc to recognize my .cpp file as a compilation unit? Following one of the native tests in hxcpp, I currently have code like this:

@:include( './test.cpp' )
extern class Test
    @:native( 'test_function' )
    public static function doTest( name: String ) : Array<Float>;

That works, but when I update test.cpp and then perform openfl test mac, my new c++ code isn’t compiled into the app. I end up performing a much slower openfl clean mac; openfl test mac. Is there a better way to tell OpenFL about this .cpp file? Perhaps I can mention my cpp file somewhere in Project.hxproj, but I don’t understand where.

I’m used to using lime create extension NameOfMyExtension then putting the extra C++ code into it’s own library – this is the only way to do it for Neko or HashLink but linking directly for the C++ target makes a lot of sense

This seems to have more information:

Maybe there’s an extra tag required in the Haxe file or perhaps it does need to go in an HXCPP XML file in order to be compiled as well?

Thanks for the response. Using a lime extension seems quite heavyweight to me. In particular, is it easy to create a pure c++ extension that works across Mac, iOS, and Android? I feel like the extensions system is designed for platform-specific native code, not platform-agnostic native code. Is there a good reference example of a pure c++ lime extension that I could look at?

I think that hxcpp’s build.xml file lets you specify additional compilation units via the <file> tag, so it may be possible to inject the necessary XML into that file indirectly within a haxe source file. I was just wondering whether there was a natural way to do so from within OpenFL’s existing build system.

Here’s a quick update, with the benefit of some more experience.

The general approach in my initial message works. You create a Haxe class that stands in as a proxy for the underlying c++ code, forcing it to be included and compiled. But I was using the tools available to me incorrectly. In particular, @:keep doesn’t make sense with an extern class, since from Haxe’s point of view there’s no dead code to eliminate. Similarly, I think that Haxe ignores the @:include directive for an extern class, because it’s not generating any of its own code.

In fact, I’m finding that extern classes are really more trouble than they’re worth, and should be avoided in favour of crafting a real Haxe-level class and finessing the extern stuff through c++ code injection. For example, I’d now write the example above thus:

@:include( './test.cpp' )
@:headerInclude( './test.h' )
class Test
    @:functionCode( 'return test_function( name.c_str() );' )
    public static function doTest( name: String ) : Array<Float>
    { return null; }

With this approach it seems like there’s no way to get around including a dead return in the Haxe function body, but the c++ compiler ignores it and that’s a small price to pay for more reliable coding.

Hope that’s useful.

Lots of inspiration taken from this ancient forum post: