Grabbing conditional compilation values using macro functions

Code snippets, Haxe

This post is about grabbing conditional compilation values and print them in the output context using a macro function. Then we can use it at runtime.

Let’s say you want to display in runtime if your code is compiled in debug or release mode. You could do this, using conditional compilation tags:

var debug = #if debug “debug” #else “release” #end;
trace(‘This application is $debug build.’);

This is (maybe) good enough if there are two values, but in other cases where there are multiple values it will not work. A conditional compilation define can hold a value. Example: you can compile -D my_value=3 or -D my_value="nice". By default the Haxe compiler version is provided like this. The following works, but it looks messy and is not really maintainable:

var haxeCompilerVersion = #if (haxe_ver == “3.2”) “3.2” #elseif (haxe_ver == “3.1”) “3.1” #else “aarrggh I don’t know all the versions” #end;
trace(‘This application is build using haxe $haxeCompilerVersion’);

To make a function that works for both cases, we write a macro function that grabs a define value and returns it as expression of a String.

public static macro function getDefine(key:String, defaultValue:String = null):Expr {
var value = haxe.macro.Context.definedValue(key);
if (value == null) value = defaultValue;
return macro $v{value};
}

What’s happening here? The Context.definedValue provides us every conditional compilation value. We can grab the key we’re looking for, and return them as value expression for the ouput context. In case a value isn’t defined, a “fallback” value is used (defaultValue).

This allows us to grab all these values out of the box:

var debugValue = MacroUtils.getDefine(“debug”, “release”);
var haxeVersion = MacroUtils.getDefine(“haxe_ver”);
var deadCodeElimination = MacroUtils.getDefine(“dce”);

Of course, when we compile the application with a custom define like -D target=mobile or -D target=web, you can use MacroUtils.getDefine('target') in your code too.

Related posts

Say something interesting

Please link to code from an external resource, like gist.github.com.