Hi,
We’re trying to integrate a third-party native library into our game and compile its sources directly with Flax.Build. But, we’re not sure what the intended approach is, especially when using a ThirdPartyModule.
Our concrete use case is TinyEXR v1.0.13. It is mostly a single-header C++ library, with Miniz as a C dependency.
We currently have something roughly like this:
public class GameTinyEXR : ThirdPartyModule
{
public override void Init()
{
base.Init();
LicenseType = LicenseTypes.BSD3Clause;
LicenseFilePath = Path.Combine(
"..", "..", "ThirdParty", "tinyexr", "LICENSE"
);
}
public override void Setup(BuildOptions options)
{
base.Setup(options);
var tinyexrPath = Path.Combine(
FolderPath, "..", "..", "ThirdParty", "tinyexr"
);
options.PublicIncludePaths.Add(tinyexrPath);
var minizPath = Path.Combine(
tinyexrPath, "deps", "miniz"
);
options.PrivateIncludePaths.Add(minizPath);
options.PublicDefinitions.Add("TINYEXR_USE_MINIZ");
options.SourceFiles.Add(
Path.Combine(minizPath, "miniz.c")
);
}
}
The module also contains a TinyEXR.cpp translation unit:
#define TINYEXR_IMPLEMENTATION
#include <tinyexr.h>
Our Game module has a private dependency on GameTinyEXR.
The sources themselves compile successfully with MSVC. However, with a clean/rebuild, Flax.Build tries to link Game.dll before the third-party module has produced its import library:
TinyEXR.cpp
miniz.c
...
Linking .../Game.dll
LINK : fatal error LNK1104: cannot open file '.../GameTinyEXR.lib'
Linking .../GameTinyEXR.dll
Creating library .../GameTinyEXR.lib
A non-clean incremental build can hide this because the .lib from a previous build already exists.
While looking through the Flax sources, we’ve noticed that Flax’s own TinyEXR module contains:
// Merge third-party modules into engine binary
BinaryModuleName = "FlaxEngine";
We therefore tried the equivalent:
BinaryModuleName = "Game";
However, GameEditorTarget uses TargetLinkType.Modular, and Flax.Build then throws:
Exception: Cannot output binary if it uses multiple modules.
This corresponds to the following code in Builder.NativeCpp.cs:
case TargetLinkType.Modular:
{
// Every module produces own set of binaries
if (binaryModule.Count() != 1)
throw new Exception(
"Cannot output binary if it uses multiple modules."
);
...
}
We’ve also noticed that the documentation example for using a native C library uses the lower-level environments:
options.CompileEnv.IncludePaths.Add(...);
options.LinkEnv.InputLibraries.Add(...);
options.DependencyFiles.Add(...);
but that example appears to deal with an already-built .lib/.dll, whereas in our case we would like Flax.Build to compile the third-party sources itself.
So our questions are:
- What is the recommended way to compile a third-party C/C++ library from source as part of a Flax game build?
- Is
ThirdPartyModuleintended for this use case, or mainly for describing prebuilt/native dependencies? - With a modular target, should a source-built third-party library produce its own DLL/import library, or is there a supported way to compile its object files directly into the consuming
Gamebinary? - What is the intended use of
BinaryModuleNamefor third-party modules, particularly withTargetLinkType.Modular? - For a small library such as TinyEXR (one implementation
.cppplusminiz.c), would the recommended approach simply be to add those sources and include paths directly to theGamemodule instead?
We would prefer to keep the third-party dependency isolated in its own build definition if Flax.Build supports that cleanly, rather than putting all of its build configuration directly into Game.Build.cs.
Thanks!
