update native_toolchain_c/native_assets_cli to latest

This commit is contained in:
Nick Fisher
2025-04-02 22:24:46 +08:00
parent e407e75389
commit 374d2e5697
2 changed files with 82 additions and 79 deletions

View File

@@ -1,15 +1,25 @@
import 'dart:io'; import 'dart:io';
import 'package:archive/archive.dart'; import 'package:archive/archive.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:native_assets_cli/code_assets_builder.dart';
import 'package:native_assets_cli/native_assets_cli.dart'; import 'package:native_assets_cli/native_assets_cli.dart';
import 'package:native_toolchain_c/native_toolchain_c.dart'; import 'package:native_toolchain_c/native_toolchain_c.dart';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
void main(List<String> args) async { void main(List<String> args) async {
await build(args, (config, output) async { await build(args, (BuildInput input, BuildOutputBuilder output) async {
var pkgRootFilePath = final packageRoot = input.packageRoot;
config.packageRoot.toFilePath(windows: Platform.isWindows); var pkgRootFilePath = packageRoot
.toFilePath(windows: Platform.isWindows);
final config = input.config;
final buildMode = BuildMode.debug;
final dryRun = false;
final packageName = input.packageName;
final outputDirectory = input.outputDirectory;
final targetOS = config.code.targetOS;
final targetArchitecture = config.code.targetArchitecture;
var logPath = path.join( var logPath = path.join(
pkgRootFilePath, ".dart_tool", "thermion_dart", "log", "build.log"); pkgRootFilePath, ".dart_tool", "thermion_dart", "log", "build.log");
var logFile = File(logPath); var logFile = File(logPath);
@@ -24,37 +34,22 @@ void main(List<String> args) async {
mode: FileMode.append, mode: FileMode.append,
flush: true)); flush: true));
var platform = config.targetOS.toString().toLowerCase(); var platform = targetOS.toString().toLowerCase();
if (!config.dryRun) { if (!dryRun) {
logger.info( logger.info(
"Building Thermion for ${config.targetOS} in mode ${config.buildMode.name}"); "Building Thermion for ${targetOS} in mode ${buildMode.name}");
} }
// We don't support Linux (yet), so the native/Filament libraries won't be // We don't support Linux (yet), so the native/Filament libraries won't be
// compiled/available. However, we still want to be able to run the Dart // compiled/available. However, we still want to be able to run the Dart
// package itself on a Linux host(e.g. for dart_services backed), so if // package itself on a Linux host (e.g. for a wasm/dartdev backend compiler).
// we detect that we're running on Linux, add some dummy native code // TODO
// assets and exit early.
if (platform == "linux") { if (platform == "linux") {
final linkMode = DynamicLoadingBundled(); throw Exception("TODO");
final name = "thermion_dart.dart";
final libUri = config.outputDirectory
.resolve(config.targetOS.libraryFileName(name, linkMode));
output.addAsset(NativeCodeAsset(
package: config.packageName,
name: name,
file: libUri,
linkMode: linkMode,
os: config.targetOS,
architecture: config.dryRun ? null : config.targetArchitecture,
));
return;
} }
var libDir = config.dryRun ? "" : (await getLibDir(config, logger)).path; var libDir = (await getLibDir(packageRoot, targetOS, targetArchitecture, logger)).path;
final packageName = config.packageName;
var sources = Directory(path.join(pkgRootFilePath, "native", "src")) var sources = Directory(path.join(pkgRootFilePath, "native", "src"))
.listSync(recursive: true) .listSync(recursive: true)
@@ -62,8 +57,8 @@ void main(List<String> args) async {
.map((f) => f.path) .map((f) => f.path)
.where((f) => !(f.contains("CMakeLists") || f.contains("main.cpp"))) .where((f) => !(f.contains("CMakeLists") || f.contains("main.cpp")))
.toList(); .toList();
if (config.targetOS != OS.windows) { if (targetOS != OS.windows) {
sources = sources.where((p) => !p.contains("windows")).toList(); sources = sources.where((p) => !p.contains("windows")).toList();
} }
@@ -72,8 +67,6 @@ void main(List<String> args) async {
"unlit_fixed_size.c"), "unlit_fixed_size.c"),
path.join(pkgRootFilePath, "native", "include", "material", "image.c"), path.join(pkgRootFilePath, "native", "include", "material", "image.c"),
path.join(pkgRootFilePath, "native", "include", "material", "grid.c"), path.join(pkgRootFilePath, "native", "include", "material", "grid.c"),
path.join(pkgRootFilePath, "native", "include", "material", "unlit.c"),
path.join(pkgRootFilePath, "native", "include", "material", "gizmo.c"),
path.join(pkgRootFilePath, "native", "include", "resources", path.join(pkgRootFilePath, "native", "include", "resources",
"translation_gizmo_glb.c"), "translation_gizmo_glb.c"),
path.join(pkgRootFilePath, "native", "include", "resources", path.join(pkgRootFilePath, "native", "include", "resources",
@@ -109,15 +102,15 @@ void main(List<String> args) async {
"uberarchive", "uberarchive",
"zstd", "zstd",
"basis_transcoder", "basis_transcoder",
if (config.targetOS == OS.macOS) ...["matdbg", "fgviewer"] if (targetOS == OS.macOS) ...["matdbg", "fgviewer"]
]; ];
if (platform == "windows") { if (platform == "windows") {
// we just need the libDir and don't need to explicitly link the actual libs // we just need the libDir and don't need to explicitly link the actual libs
// (these are linked via ThermionWin32.h) // (these are linked via ThermionWin32.h)
libDir = Directory(libDir) libDir = Directory(libDir)
.uri .uri
.toFilePath(windows: config.targetOS == OS.windows); .toFilePath(windows: targetOS == OS.windows);
} else { } else {
libs.add("stdc++"); libs.add("stdc++");
} }
@@ -131,10 +124,10 @@ void main(List<String> args) async {
if (platform != "windows") { if (platform != "windows") {
flags.addAll(['-std=c++17']); flags.addAll(['-std=c++17']);
} else if (!config.dryRun) { } else if (!dryRun) {
defines["WIN32"] = "1"; defines["WIN32"] = "1";
defines["_DLL"] = "1"; defines["_DLL"] = "1";
if (config.buildMode == BuildMode.debug) { if (buildMode == BuildMode.debug) {
defines["_DEBUG"] = "1"; defines["_DEBUG"] = "1";
} else { } else {
defines["RELEASE"] = "1"; defines["RELEASE"] = "1";
@@ -142,8 +135,8 @@ void main(List<String> args) async {
} }
flags.addAll([ flags.addAll([
"/std:c++20", "/std:c++20",
if (config.buildMode == BuildMode.debug) ...["/MDd", "/Zi"], if (buildMode == BuildMode.debug) ...["/MDd", "/Zi"],
if (config.buildMode == BuildMode.release) "/MD", if (buildMode == BuildMode.release) "/MD",
"/VERBOSE", "/VERBOSE",
...defines.keys.map((k) => "/D$k=${defines[k]}").toList() ...defines.keys.map((k) => "/D$k=${defines[k]}").toList()
]); ]);
@@ -167,7 +160,7 @@ void main(List<String> args) async {
"Metal", "Metal",
]); ]);
if (!config.dryRun && config.buildMode == BuildMode.debug) { if (!dryRun && buildMode == BuildMode.debug) {
flags.addAll([ flags.addAll([
"-g", "-g",
"-O0", "-O0",
@@ -181,6 +174,8 @@ void main(List<String> args) async {
frameworks = frameworks.expand((f) => ["-framework", f]).toList(); frameworks = frameworks.expand((f) => ["-framework", f]).toList();
File("C:\\Users\\nickh\\thermion_sources.rsp").writeAsStringSync(sources.join("\n"));
final cbuilder = CBuilder.library( final cbuilder = CBuilder.library(
name: packageName, name: packageName,
language: Language.cpp, language: Language.cpp,
@@ -203,7 +198,8 @@ void main(List<String> args) async {
"/I${path.join(pkgRootFilePath, "native", "include")}", "/I${path.join(pkgRootFilePath, "native", "include")}",
"/I${path.join(pkgRootFilePath, "native", "include", "filament")}", "/I${path.join(pkgRootFilePath, "native", "include", "filament")}",
"/I${path.join(pkgRootFilePath, "native", "include", "windows", "vulkan")}", "/I${path.join(pkgRootFilePath, "native", "include", "windows", "vulkan")}",
...sources, "@C:\\Users\\nickh\\thermion_sources.rsp",
// ...sources,
'/link', '/link',
"/LIBPATH:$libDir", "/LIBPATH:$libDir",
'/DLL', '/DLL',
@@ -213,13 +209,13 @@ void main(List<String> args) async {
); );
await cbuilder.run( await cbuilder.run(
buildConfig: config, input: input,
buildOutput: output, output: output,
logger: logger, logger: logger,
); );
if (config.targetOS == OS.android) { if (targetOS == OS.android) {
if (!config.dryRun) { if (!dryRun) {
final archExtension = switch (config.targetArchitecture) { final archExtension = switch (targetArchitecture) {
Architecture.arm => "arm-linux-androideabi", Architecture.arm => "arm-linux-androideabi",
Architecture.arm64 => "aarch64-linux-android", Architecture.arm64 => "aarch64-linux-android",
Architecture.x64 => "x86_64-linux-android", Architecture.x64 => "x86_64-linux-android",
@@ -227,7 +223,7 @@ void main(List<String> args) async {
_ => throw FormatException('Invalid') _ => throw FormatException('Invalid')
}; };
var compilerPath = config.cCompiler.compiler!.path; var compilerPath = config.code.cCompiler!.compiler.path;
if (Platform.isWindows && compilerPath.startsWith("/")) { if (Platform.isWindows && compilerPath.startsWith("/")) {
compilerPath = compilerPath.substring(1); compilerPath = compilerPath.substring(1);
@@ -247,33 +243,37 @@ void main(List<String> args) async {
archExtension, archExtension,
"libc++_shared.so" "libc++_shared.so"
].join(Platform.pathSeparator)); ].join(Platform.pathSeparator));
output.addAsset(NativeCodeAsset( final libcpp = CodeAsset(
package: "thermion_dart", package: "thermion_dart",
name: "libc++_shared.so", name: "libc++_shared.so",
linkMode: DynamicLoadingBundled(), linkMode: DynamicLoadingBundled(),
os: config.targetOS, os: targetOS,
file: stlPath.uri, file: stlPath.uri,
architecture: config.targetArchitecture)); architecture: targetArchitecture);
output.assets.addEncodedAsset(libcpp.encode());
} }
} }
if (config.targetOS == OS.windows) { if (targetOS == OS.windows) {
var importLib = File(path.join(
config.outputDirectory.path.substring(1).replaceAll("/", "\\"),
"thermion_dart.lib"));
output.addAsset(NativeCodeAsset( var importLib = File(path.join(
package: config.packageName,
outputDirectory.path.substring(1).replaceAll("/", "\\"),
"thermion_dart.lib"));
final libthermion = CodeAsset(
package: packageName,
name: "thermion_dart.lib", name: "thermion_dart.lib",
linkMode: DynamicLoadingBundled(), linkMode: DynamicLoadingBundled(),
os: config.targetOS, os: targetOS,
file: importLib.uri, file: importLib.uri,
architecture: config.targetArchitecture)); architecture: targetArchitecture);
output.assets.addEncodedAsset(libthermion.encode());
for (final dir in ["windows/vulkan"]) { for (final dir in ["windows/vulkan"]) {
// , "filament/bluevk", "filament/vulkan" // , "filament/bluevk", "filament/vulkan"
final targetSubdir = final targetSubdir =
path.join(config.outputDirectory.path, "include", dir).substring(1); path.join(outputDirectory.path, "include", dir).substring(1);
if (!Directory(targetSubdir).existsSync()) { if (!Directory(targetSubdir).existsSync()) {
Directory(targetSubdir).createSync(recursive: true); Directory(targetSubdir).createSync(recursive: true);
} }
@@ -285,13 +285,14 @@ void main(List<String> args) async {
final targetPath = final targetPath =
path.join(targetSubdir, path.basename(file.path)); path.join(targetSubdir, path.basename(file.path));
file.copySync(targetPath); file.copySync(targetPath);
output.addAsset(NativeCodeAsset( final include = CodeAsset(
package: config.packageName, package: packageName,
name: "include/$dir/${path.basename(file.path)}", name: "include/$dir/${path.basename(file.path)}",
linkMode: DynamicLoadingBundled(), linkMode: DynamicLoadingBundled(),
os: config.targetOS, os: targetOS,
file: file.uri, file: file.uri,
architecture: config.targetArchitecture)); architecture: targetArchitecture);
output.assets.addEncodedAsset(include.encode());
} }
} }
} }
@@ -307,8 +308,8 @@ String _getLibraryUrl(String platform, String mode) {
// //
// Download precompiled Filament libraries for the target platform from Cloudflare. // Download precompiled Filament libraries for the target platform from Cloudflare.
// //
Future<Directory> getLibDir(BuildConfig config, Logger logger) async { Future<Directory> getLibDir(Uri packageRoot, OS targetOS, Architecture targetArchitecture, Logger logger) async {
var platform = config.targetOS.toString().toLowerCase(); var platform = targetOS.toString().toLowerCase();
// Except on Windows, most users will only need release builds of Filament. // Except on Windows, most users will only need release builds of Filament.
// Debug builds are probably only relevant if you're a package developer debugging an internal Filament issue // Debug builds are probably only relevant if you're a package developer debugging an internal Filament issue
@@ -318,13 +319,15 @@ Future<Directory> getLibDir(BuildConfig config, Logger logger) async {
// (these aren't present in Filament release builds). // (these aren't present in Filament release builds).
// However, if you know what you're doing, you can change "release" to "debug" below. // However, if you know what you're doing, you can change "release" to "debug" below.
// TODO - check if we can pass this as a CLI compiler flag // TODO - check if we can pass this as a CLI compiler flag
var mode = "release"; var mode = "debug";
if ({OS.windows, OS.macOS}.contains(config.targetOS)) { // var mode = "release";
mode = config.buildMode == BuildMode.debug ? "debug" : "release"; // if ({OS.windows, OS.macOS}.contains(targetOS)) {
} // mode = buildMode == BuildMode.debug ? "debug" : "release";
// }
var libDir = Directory(path.join( var libDir = Directory(path.join(
config.packageRoot.toFilePath(windows: Platform.isWindows), packageRoot.toFilePath(windows: Platform.isWindows),
".dart_tool", ".dart_tool",
"thermion_dart", "thermion_dart",
"lib", "lib",
@@ -333,7 +336,7 @@ Future<Directory> getLibDir(BuildConfig config, Logger logger) async {
mode)); mode));
if (platform == "android") { if (platform == "android") {
final archExtension = switch (config.targetArchitecture) { final archExtension = switch (targetArchitecture) {
Architecture.arm => "armeabi-v7a", Architecture.arm => "armeabi-v7a",
Architecture.arm64 => "arm64-v8a", Architecture.arm64 => "arm64-v8a",
Architecture.x64 => "x86_64", Architecture.x64 => "x86_64",
@@ -342,9 +345,9 @@ Future<Directory> getLibDir(BuildConfig config, Logger logger) async {
}; };
libDir = Directory(path.join(libDir.path, archExtension)); libDir = Directory(path.join(libDir.path, archExtension));
} else if (platform == "windows") { } else if (platform == "windows") {
if (config.targetArchitecture != Architecture.x64) { if (targetArchitecture != Architecture.x64) {
throw Exception( throw Exception(
"Unsupported architecture : ${config.targetArchitecture}"); "Unsupported architecture : ${targetArchitecture}");
} }
} }
@@ -352,7 +355,7 @@ Future<Directory> getLibDir(BuildConfig config, Logger logger) async {
var url = _getLibraryUrl(platform, mode); var url = _getLibraryUrl(platform, mode);
if (config.targetOS == OS.windows) { if (targetOS == OS.windows) {
url = url.replaceAll(".zip", "-vulkan.zip"); url = url.replaceAll(".zip", "-vulkan.zip");
} }
@@ -362,7 +365,7 @@ Future<Directory> getLibDir(BuildConfig config, Logger logger) async {
// If this file already exists, we assume everything has been successfully extracted and skip // If this file already exists, we assume everything has been successfully extracted and skip
final unzipDir = platform == "android" ? libDir.parent.path : libDir.path; final unzipDir = platform == "android" ? libDir.parent.path : libDir.path;
final successToken = File(path.join( final successToken = File(path.join(
unzipDir, config.targetOS == OS.windows ? "success-vulkan" : "success")); unzipDir, targetOS == OS.windows ? "success-vulkan" : "success"));
final libraryZip = File(path.join(unzipDir, filename)); final libraryZip = File(path.join(unzipDir, filename));
if (!successToken.existsSync()) { if (!successToken.existsSync()) {

View File

@@ -5,27 +5,27 @@ homepage: https://thermion.dev
repository: https://github.com/nmfisher/thermion repository: https://github.com/nmfisher/thermion
environment: environment:
sdk: ">=3.6.0-0 <4.0.0" sdk: ">=3.5.4 <4.0.0"
dependencies: dependencies:
vector_math: ^2.1.2 vector_math: ^2.1.2
plugin_platform_interface: ^2.0.0 plugin_platform_interface: ^2.0.0
ffi: ^2.1.2 ffi: ^2.1.2
animation_tools_dart: ^0.1.0 animation_tools_dart: ^0.1.0
native_toolchain_c: ^0.4.2 native_toolchain_c: ^0.9.0
native_assets_cli: ^0.6.1 native_assets_cli: ^0.12.0
archive: ^3.6.1 archive: ^3.6.1
web: ^1.0.0 web: ^1.0.0
logging: ^1.2.0 logging: ^1.2.0
http: ^1.2.2 http: ^1.2.2
path: ^1.9.0 path: ^1.9.0
image: ^4.3.0 image: ^4.3.0
dev_dependencies: dev_dependencies:
ffigen: ^13.0.0 ffigen: ^13.0.0
objective_c: ^1.1.0 # objective_c: ^1.1.0
test: test:
path: path:
mockito: ^5.0.0 mockito: ^5.0.0
build_runner: ^2.0.0 build_runner: ^2.0.0