@@ -3,33 +3,32 @@ import 'dart:io';
33import 'package:code_assets/code_assets.dart' ;
44import 'package:hooks/hooks.dart' ;
55import 'package:logging/logging.dart' ;
6+ import 'package:meta/meta.dart' ;
67import 'package:native_toolchain_rs/native_toolchain_rs.dart' ;
8+ import 'package:native_toolchain_rs/src/build_environment.dart' ;
9+ import 'package:native_toolchain_rs/src/config_mapping.dart' ;
10+ import 'package:native_toolchain_rs/src/crate_info_validator.dart' ;
711import 'package:native_toolchain_rs/src/crate_resolver.dart' ;
812import 'package:native_toolchain_rs/src/process_runner.dart' ;
9- import 'package:native_toolchain_rs/src/toml_parsing.dart' ;
1013import 'package:path/path.dart' as path;
1114
12- // NOTE: this is an internal implementation detail
13- // ignore_for_file: public_member_api_docs
14-
15- final class RustBuildRunner {
15+ @internal
16+ interface class RustBuildRunner {
1617 const RustBuildRunner ({
1718 required this .config,
1819 required this .logger,
1920 required this .crateDirectoryResolver,
20- required this .tomlDocumentWrapperFactory,
21- required this .toolchainTomlParser,
22- required this .cargoManifestParser,
2321 required this .processRunner,
22+ required this .buildEnvironmentFactory,
23+ required this .crateInfoValidator,
2424 });
2525
2626 final RustBuilder config;
2727 final Logger ? logger;
2828 final CrateDirectoryResolver crateDirectoryResolver;
29- final TomlDocumentWrapperFactory tomlDocumentWrapperFactory;
30- final ToolchainTomlParser toolchainTomlParser;
31- final CargoManifestParser cargoManifestParser;
3229 final ProcessRunner processRunner;
30+ final BuildEnvironmentFactory buildEnvironmentFactory;
31+ final CrateInfoValidator crateInfoValidator;
3332
3433 Future <void > run ({
3534 required BuildInput input,
@@ -49,7 +48,8 @@ final class RustBuildRunner {
4948 }
5049
5150 logger? .info ('Gathering all data required for the build' );
52- final CodeConfig (: targetOS, : targetTriple, : linkMode) = input.config.code;
51+ final codeConfig = input.config.code;
52+ final CodeConfig (: targetOS, : targetTriple, : linkMode) = codeConfig;
5353 final RustBuilder (
5454 : assetName,
5555 : cratePath,
@@ -65,7 +65,10 @@ final class RustBuildRunner {
6565 );
6666 final outputDir = path.join (path.fromUri (input.outputDirectory), 'target' );
6767 final manifestPath = path.join (crateDirectory.path, 'Cargo.toml' );
68- final (: crateName, : toolchainChannel) = fetchAndValidateCrateInfo (
68+ final (
69+ : crateName,
70+ : toolchainChannel,
71+ ) = crateInfoValidator.fetchAndValidateCrateInfo (
6972 targetTriple: targetTriple,
7073 manifestPath: manifestPath,
7174 toolchainTomlPath: path.join (crateDirectory.path, 'rust-toolchain.toml' ),
@@ -98,7 +101,7 @@ final class RustBuildRunner {
98101 ...extraCargoBuildArgs,
99102 ],
100103 environment: {
101- ...createBuildEnvVars (input.config.code ),
104+ ...buildEnvironmentFactory. createBuildEnvVars (codeConfig ),
102105 ...extraCargoEnvironmentVariables,
103106 },
104107 );
@@ -133,158 +136,4 @@ final class RustBuildRunner {
133136 ], workingDirectory: crateDirectory),
134137 );
135138 }
136-
137- ({String crateName, String toolchainChannel}) fetchAndValidateCrateInfo ({
138- required String manifestPath,
139- required String toolchainTomlPath,
140- required String targetTriple,
141- }) {
142- final [
143- String crateName,
144- String toolchainChannel,
145- ] = RustValidationException .compose <dynamic >([
146- () {
147- final (: crateName, : libCrateTypes) = cargoManifestParser.parseManifest (
148- manifestPath,
149- );
150-
151- const requiredTypes = ['staticlib' , 'cdylib' ];
152- if (! requiredTypes.every (libCrateTypes.contains)) {
153- throw RustValidationException ([
154- 'Cargo.toml must specify $requiredTypes under lib.crate-types' ,
155- ]);
156- }
157-
158- return crateName;
159- },
160- () {
161- final (: channel, : targets) = toolchainTomlParser.parseToolchainToml (
162- toolchainTomlPath,
163- );
164-
165- final toolchainIssues = < String > [];
166-
167- const deniedChannels = {'stable' , 'beta' , 'nightly' };
168- if (deniedChannels.contains (channel)) {
169- toolchainIssues.add (
170- 'Your current channel in rust-toolchain.toml is $channel ; '
171- 'this is dangerous and consequently is not allowed! '
172- 'Please specify an exact version to fix this issue.' ,
173- );
174- }
175-
176- if (! targets.contains (targetTriple)) {
177- toolchainIssues.add (
178- '$targetTriple is not one of the supported targets: $targets ' ,
179- );
180- }
181-
182- return channel;
183- },
184- ]);
185-
186- return (crateName: crateName, toolchainChannel: toolchainChannel);
187- }
188-
189- Map <String , String > createBuildEnvVars (CodeConfig codeConfig) {
190- final CodeConfig (: targetOS, : targetTriple, : cCompiler) = codeConfig;
191- final targetTripleEnvVar = targetTriple.replaceAll ('-' , '_' );
192-
193- String getBinary (String binaryName) {
194- if (cCompiler == null ) {
195- throw UnsupportedError (
196- 'CCompilerConfig was not provided but is required for $targetTriple ' ,
197- );
198- }
199-
200- final binaryPath = path.join (
201- path.dirname (path.fromUri (cCompiler.compiler)),
202- OS .current.executableFileName (binaryName),
203- );
204-
205- if (! File (binaryPath).existsSync ()) {
206- throw RustValidationException ([
207- 'Binary $binaryPath not found; is your installed compiler too old?' ,
208- ]);
209- }
210-
211- return binaryPath;
212- }
213-
214- return {
215- // NOTE: XCode makes some injections into PATH that break host build
216- // for crates with a build.rs
217- // See also: https://github.com/irondash/native_toolchain_rust/issues/17
218- if (Platform .isMacOS) ...{
219- 'PATH' : Platform .environment['PATH' ]!
220- .split (':' )
221- .where ((e) => ! e.contains ('Contents/Developer/' ))
222- .join (':' ),
223- },
224-
225- // NOTE: we need to point to NDK >=27 vended LLVM for Android.
226- // The `${targetTriple}35-clang`s were introduced in NDK 27,
227- // so using these binaries:
228- // 1. Ensures we are using a compatible NDK
229- // 2. Also fixes build issues when just using the `clang`s directly
230- if (targetOS == OS .android) ...{
231- 'AR_$targetTripleEnvVar ' : getBinary ('llvm-ar' ),
232- 'CC_$targetTripleEnvVar ' : getBinary ('${targetTriple }35-clang' ),
233- 'CXX_$targetTripleEnvVar ' : getBinary ('${targetTriple }35-clang++' ),
234- 'CARGO_TARGET_${targetTripleEnvVar .toUpperCase ()}_LINKER' : getBinary (
235- '${targetTriple }35-clang' ,
236- ),
237- },
238- };
239- }
240- }
241-
242- extension on CodeConfig {
243- String get targetTriple {
244- return switch ((targetOS, targetArchitecture)) {
245- // Android
246- (OS .android, Architecture .arm64) => 'aarch64-linux-android' ,
247- (OS .android, Architecture .arm) => 'armv7-linux-androideabi' ,
248- (OS .android, Architecture .x64) => 'x86_64-linux-android' ,
249-
250- // iOS
251- (OS .iOS, Architecture .arm64)
252- when iOS.targetSdk == IOSSdk .iPhoneSimulator =>
253- 'aarch64-apple-ios-sim' ,
254- (OS .iOS, Architecture .arm64) when iOS.targetSdk == IOSSdk .iPhoneOS =>
255- 'aarch64-apple-ios' ,
256- (OS .iOS, Architecture .arm64) => throw UnsupportedError (
257- 'Unknown IOSSdk: ${iOS .targetSdk }' ,
258- ),
259- (OS .iOS, Architecture .x64) => 'x86_64-apple-ios' ,
260-
261- // Windows
262- (OS .windows, Architecture .arm64) => 'aarch64-pc-windows-msvc' ,
263- (OS .windows, Architecture .x64) => 'x86_64-pc-windows-msvc' ,
264-
265- // Linux
266- (OS .linux, Architecture .arm64) => 'aarch64-unknown-linux-gnu' ,
267- (OS .linux, Architecture .x64) => 'x86_64-unknown-linux-gnu' ,
268-
269- // macOS
270- (OS .macOS, Architecture .arm64) => 'aarch64-apple-darwin' ,
271- (OS .macOS, Architecture .x64) => 'x86_64-apple-darwin' ,
272-
273- (_, _) => throw UnsupportedError (
274- 'Unsupported target: $targetOS on $targetArchitecture ' ,
275- ),
276- };
277- }
278-
279- LinkMode get linkMode {
280- return switch (linkModePreference) {
281- LinkModePreference .dynamic ||
282- LinkModePreference .preferDynamic => DynamicLoadingBundled (),
283- LinkModePreference .static ||
284- LinkModePreference .preferStatic => StaticLinking (),
285- _ => throw UnsupportedError (
286- 'Unsupported LinkModePreference: $linkModePreference ' ,
287- ),
288- };
289- }
290139}
0 commit comments