From 1974bc7b00f943fd0d1197247a0eedb0fb930418 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 16 Aug 2024 17:33:28 +0200 Subject: [PATCH] Add some more options to `RustBuilder` --- native_toolchain_rust/lib/src/builder.dart | 93 ++++++++++++++++------ 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/native_toolchain_rust/lib/src/builder.dart b/native_toolchain_rust/lib/src/builder.dart index da88fa6..928706b 100644 --- a/native_toolchain_rust/lib/src/builder.dart +++ b/native_toolchain_rust/lib/src/builder.dart @@ -104,9 +104,12 @@ class RustToolchain { class RustBuilder { RustBuilder({ required this.package, - this.toolchain, - required this.cratePath, required this.buildConfig, + this.buildMode = CargoBuildMode.build, + this.toolchain, + this.cratePath, + this.crateType, + this.crateName, this.extraCargoArgs = const [], this.release = true, this.assetName, @@ -118,6 +121,8 @@ class RustBuilder { /// Custom Rust toolchain to use (optional). final RustToolchain? toolchain; + final CargoBuildMode buildMode; + /// Package name. This will be part of asset Id. /// For example package `my_package` with crate name `my_crate` will have /// asset id `package:my_package/my_crate`: @@ -132,7 +137,12 @@ class RustBuilder { final String? assetName; /// Path to the Rust crate directory relative to the package root. - final String cratePath; + final String? cratePath; + + /// Name of the crate to be built. + final String? crateName; + + final CrateType? crateType; /// Build config provided to the build callback from `native_assets_cli`. final BuildConfig buildConfig; @@ -158,24 +168,37 @@ class RustBuilder { /// Optional logger for verbose output. final Logger? logger; - Future run({required BuildOutput output}) async { + Future run({required BuildOutput output, String? linkInPackage}) async { + assert( + buildConfig.linkingEnabled || linkInPackage == null, + 'linkInPackage can only be provided if config.linkingEnabled is true.', + ); + final toolchain = this.toolchain ?? await RustToolchain.withName('stable'); - final manifestPath = buildConfig.packageRoot - .resolve(cratePath) - .makeDirectory() - .resolve('Cargo.toml'); - final manifestInfo = CrateManifestInfo.load(manifestPath); + final manifestPath = cratePath != null + ? buildConfig.packageRoot + .resolve(cratePath!) + .makeDirectory() + .resolve('Cargo.toml') + : null; + final manifestInfo = + manifestPath != null ? CrateManifestInfo.load(manifestPath) : null; + final packageName = crateName ?? manifestInfo?.packageName; + + if (packageName == null) { + throw ArgumentError('Either `crateName` or `cratePath` must be set.'); + } + final outDir = buildConfig.outputDirectory.resolve('native_toolchain_rust/'); - final dylibName = - buildConfig.targetOS.dylibFileName(manifestInfo.packageName); + final dylibName = buildConfig.targetOS.dylibFileName(packageName); if (buildConfig.dryRun) { output.addAsset(NativeCodeAsset( package: package, - name: assetName ?? manifestInfo.packageName, + name: assetName ?? packageName, linkMode: DynamicLoadingBundled(), os: buildConfig.targetOS, file: Uri.file(dylibName), @@ -202,17 +225,17 @@ class RustBuilder { 'run', toolchain.name, 'cargo', - 'build', - '--manifest-path', - manifestPath.toFilePath(), - '-p', - manifestInfo.packageName, + buildMode.name, + if (manifestPath != null) ...[ + '--manifest-path', + manifestPath.toFilePath(), + ], + ...['-p', packageName], if (effectiveBuildMode == BuildMode.release) '--release', '--verbose', - '--target', - target.triple, - '--target-dir', - outDir.toFilePath(), + ...['--target', target.triple], + ...['--target-dir', outDir.toFilePath()], + if (crateType != null) ...['--crate-type', crateType!.rustName], ...extraCargoArgs, ], environment: await _buildEnvironment( @@ -230,13 +253,16 @@ class RustBuilder { final asset = NativeCodeAsset( package: package, - name: assetName ?? manifestInfo.packageName, + name: assetName ?? packageName, os: buildConfig.targetOS, architecture: buildConfig.targetArchitecture, linkMode: DynamicLoadingBundled(), file: effectiveOutDir.resolve(dylibName), ); - output.addAsset(asset); + output.addAsset( + asset, + linkInPackage: linkInPackage, + ); if (!buildConfig.dryRun) { _addDependencies( output: output, @@ -313,3 +339,24 @@ extension on Uri { } } } + +enum CargoBuildMode { + build, + rustc; +} + +enum CrateType { + bin, + lib, + rlib, + dylib, + cdylib, + staticlib, + procMacro('proc-macro'); + + String get rustName => _rustName ?? name; + + final String? _rustName; + + const CrateType([this._rustName]); +}