mirror of
https://mirror.ghproxy.com/https://github.com/StarCitizenToolBox/app.git
synced 2024-12-24 01:13:40 +08:00
199 lines
5.5 KiB
Dart
199 lines
5.5 KiB
Dart
/// This is copied from Cargokit (which is the official way to use it currently)
|
|
/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
|
|
|
|
import 'package:collection/collection.dart';
|
|
import 'package:logging/logging.dart';
|
|
import 'package:path/path.dart' as path;
|
|
|
|
import 'android_environment.dart';
|
|
import 'cargo.dart';
|
|
import 'environment.dart';
|
|
import 'options.dart';
|
|
import 'rustup.dart';
|
|
import 'target.dart';
|
|
import 'util.dart';
|
|
|
|
final _log = Logger('builder');
|
|
|
|
enum BuildConfiguration {
|
|
debug,
|
|
release,
|
|
profile,
|
|
}
|
|
|
|
extension on BuildConfiguration {
|
|
bool get isDebug => this == BuildConfiguration.debug;
|
|
String get rustName => switch (this) {
|
|
BuildConfiguration.debug => 'debug',
|
|
BuildConfiguration.release => 'release',
|
|
BuildConfiguration.profile => 'release',
|
|
};
|
|
}
|
|
|
|
class BuildException implements Exception {
|
|
final String message;
|
|
|
|
BuildException(this.message);
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BuildException: $message';
|
|
}
|
|
}
|
|
|
|
class BuildEnvironment {
|
|
final BuildConfiguration configuration;
|
|
final CargokitCrateOptions crateOptions;
|
|
final String targetTempDir;
|
|
final String manifestDir;
|
|
final CrateInfo crateInfo;
|
|
|
|
final bool isAndroid;
|
|
final String? androidSdkPath;
|
|
final String? androidNdkVersion;
|
|
final int? androidMinSdkVersion;
|
|
final String? javaHome;
|
|
|
|
BuildEnvironment({
|
|
required this.configuration,
|
|
required this.crateOptions,
|
|
required this.targetTempDir,
|
|
required this.manifestDir,
|
|
required this.crateInfo,
|
|
required this.isAndroid,
|
|
this.androidSdkPath,
|
|
this.androidNdkVersion,
|
|
this.androidMinSdkVersion,
|
|
this.javaHome,
|
|
});
|
|
|
|
static BuildConfiguration parseBuildConfiguration(String value) {
|
|
// XCode configuration adds the flavor to configuration name.
|
|
final firstSegment = value.split('-').first;
|
|
final buildConfiguration = BuildConfiguration.values.firstWhereOrNull(
|
|
(e) => e.name == firstSegment,
|
|
);
|
|
if (buildConfiguration == null) {
|
|
_log.warning('Unknown build configuraiton $value, will assume release');
|
|
return BuildConfiguration.release;
|
|
}
|
|
return buildConfiguration;
|
|
}
|
|
|
|
static BuildEnvironment fromEnvironment({
|
|
required bool isAndroid,
|
|
}) {
|
|
final buildConfiguration =
|
|
parseBuildConfiguration(Environment.configuration);
|
|
final manifestDir = Environment.manifestDir;
|
|
final crateOptions = CargokitCrateOptions.load(
|
|
manifestDir: manifestDir,
|
|
);
|
|
final crateInfo = CrateInfo.load(manifestDir);
|
|
return BuildEnvironment(
|
|
configuration: buildConfiguration,
|
|
crateOptions: crateOptions,
|
|
targetTempDir: Environment.targetTempDir,
|
|
manifestDir: manifestDir,
|
|
crateInfo: crateInfo,
|
|
isAndroid: isAndroid,
|
|
androidSdkPath: isAndroid ? Environment.sdkPath : null,
|
|
androidNdkVersion: isAndroid ? Environment.ndkVersion : null,
|
|
androidMinSdkVersion:
|
|
isAndroid ? int.parse(Environment.minSdkVersion) : null,
|
|
javaHome: isAndroid ? Environment.javaHome : null,
|
|
);
|
|
}
|
|
}
|
|
|
|
class RustBuilder {
|
|
final Target target;
|
|
final BuildEnvironment environment;
|
|
|
|
RustBuilder({
|
|
required this.target,
|
|
required this.environment,
|
|
});
|
|
|
|
void prepare(
|
|
Rustup rustup,
|
|
) {
|
|
final toolchain = _toolchain;
|
|
if (rustup.installedTargets(toolchain) == null) {
|
|
rustup.installToolchain(toolchain);
|
|
}
|
|
if (toolchain == 'nightly') {
|
|
rustup.installRustSrcForNightly();
|
|
}
|
|
if (!rustup.installedTargets(toolchain)!.contains(target.rust)) {
|
|
rustup.installTarget(target.rust, toolchain: toolchain);
|
|
}
|
|
}
|
|
|
|
CargoBuildOptions? get _buildOptions =>
|
|
environment.crateOptions.cargo[environment.configuration];
|
|
|
|
String get _toolchain => _buildOptions?.toolchain.name ?? 'stable';
|
|
|
|
/// Returns the path of directory containing build artifacts.
|
|
Future<String> build() async {
|
|
final extraArgs = _buildOptions?.flags ?? [];
|
|
final manifestPath = path.join(environment.manifestDir, 'Cargo.toml');
|
|
runCommand(
|
|
'rustup',
|
|
[
|
|
'run',
|
|
_toolchain,
|
|
'cargo',
|
|
'build',
|
|
...extraArgs,
|
|
'--manifest-path',
|
|
manifestPath,
|
|
'-p',
|
|
environment.crateInfo.packageName,
|
|
if (!environment.configuration.isDebug) '--release',
|
|
'--target',
|
|
target.rust,
|
|
'--target-dir',
|
|
environment.targetTempDir,
|
|
],
|
|
environment: await _buildEnvironment(),
|
|
);
|
|
return path.join(
|
|
environment.targetTempDir,
|
|
target.rust,
|
|
environment.configuration.rustName,
|
|
);
|
|
}
|
|
|
|
Future<Map<String, String>> _buildEnvironment() async {
|
|
if (target.android == null) {
|
|
return {};
|
|
} else {
|
|
final sdkPath = environment.androidSdkPath;
|
|
final ndkVersion = environment.androidNdkVersion;
|
|
final minSdkVersion = environment.androidMinSdkVersion;
|
|
if (sdkPath == null) {
|
|
throw BuildException('androidSdkPath is not set');
|
|
}
|
|
if (ndkVersion == null) {
|
|
throw BuildException('androidNdkVersion is not set');
|
|
}
|
|
if (minSdkVersion == null) {
|
|
throw BuildException('androidMinSdkVersion is not set');
|
|
}
|
|
final env = AndroidEnvironment(
|
|
sdkPath: sdkPath,
|
|
ndkVersion: ndkVersion,
|
|
minSdkVersion: minSdkVersion,
|
|
targetTempDir: environment.targetTempDir,
|
|
target: target,
|
|
);
|
|
if (!env.ndkIsInstalled() && environment.javaHome != null) {
|
|
env.installNdk(javaHome: environment.javaHome!);
|
|
}
|
|
return env.buildEnvironment();
|
|
}
|
|
}
|
|
}
|