-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from irondash/precompiled_binaries
feat: add support for precompiling binaries
- Loading branch information
Showing
42 changed files
with
3,226 additions
and
839 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
on: | ||
pull_request: | ||
push: | ||
branches: | ||
- main | ||
|
||
name: Check and Lint | ||
|
||
jobs: | ||
Flutter: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: dart-lang/setup-dart@v1 | ||
- name: Pub Get | ||
run: dart pub get --no-precompile | ||
working-directory: build_tool | ||
- name: Dart Format | ||
run: dart format . --output=none --set-exit-if-changed | ||
working-directory: build_tool | ||
- name: Analyze | ||
run: dart analyze | ||
working-directory: build_tool | ||
- name: Test | ||
run: dart test | ||
working-directory: build_tool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
target | ||
target | ||
.dart_tool | ||
*.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
A sample command-line application with an entrypoint in `bin/`, library code | ||
in `lib/`, and example unit test in `test/`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# This file configures the static analysis results for your project (errors, | ||
# warnings, and lints). | ||
# | ||
# This enables the 'recommended' set of lints from `package:lints`. | ||
# This set helps identify many issues that may lead to problems when running | ||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic | ||
# style and format. | ||
# | ||
# If you want a smaller set of lints you can change this to specify | ||
# 'package:lints/core.yaml'. These are just the most critical lints | ||
# (the recommended set includes the core lints). | ||
# The core lints are also what is used by pub.dev for scoring packages. | ||
|
||
include: package:lints/recommended.yaml | ||
|
||
# Uncomment the following section to specify additional rules. | ||
|
||
linter: | ||
rules: | ||
- prefer_relative_imports | ||
- directives_ordering | ||
|
||
# analyzer: | ||
# exclude: | ||
# - path/to/excluded/files/** | ||
|
||
# For more information about the core and recommended set of lints, see | ||
# https://dart.dev/go/core-lints | ||
|
||
# For additional information about configuring this file, see | ||
# https://dart.dev/guides/language/analysis-options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import 'package:build_tool/build_tool.dart' as build_tool; | ||
|
||
void main(List<String> arguments) { | ||
build_tool.runMain(arguments); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import 'src/build_tool.dart' as build_tool; | ||
|
||
Future<void> runMain(List<String> args) async { | ||
return build_tool.runMain(args); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import 'dart:io'; | ||
import 'dart:isolate'; | ||
import 'dart:math' as math; | ||
|
||
import 'package:collection/collection.dart'; | ||
import 'package:path/path.dart' as path; | ||
import 'package:version/version.dart'; | ||
|
||
import 'target.dart'; | ||
import 'util.dart'; | ||
|
||
class AndroidEnvironment { | ||
AndroidEnvironment({ | ||
required this.sdkPath, | ||
required this.ndkVersion, | ||
required this.minSdkVersion, | ||
required this.targetTempDir, | ||
required this.target, | ||
}); | ||
|
||
static void clangLinkerWrapper(List<String> args) { | ||
final clang = Platform.environment['_CARGOKIT_NDK_LINK_CLANG']; | ||
if (clang == null) { | ||
throw Exception( | ||
"cargo-ndk rustc linker: didn't find _CARGOKIT_NDK_LINK_CLANG env var"); | ||
} | ||
final target = Platform.environment['_CARGOKIT_NDK_LINK_TARGET']; | ||
if (target == null) { | ||
throw Exception( | ||
"cargo-ndk rustc linker: didn't find _CARGOKIT_NDK_LINK_TARGET env var"); | ||
} | ||
|
||
runCommand(clang, [ | ||
target, | ||
...args, | ||
]); | ||
} | ||
|
||
/// Full path to Android SDK. | ||
final String sdkPath; | ||
|
||
/// Full version of Android NDK. | ||
final String ndkVersion; | ||
|
||
/// Minimum supported SDK version. | ||
final int minSdkVersion; | ||
|
||
/// Target directory for build artifacts. | ||
final String targetTempDir; | ||
|
||
/// Target being built. | ||
final Target target; | ||
|
||
bool ndkIsInstalled() { | ||
final ndkPath = path.join(sdkPath, 'ndk', ndkVersion); | ||
final ndkPackageXml = File(path.join(ndkPath, 'package.xml')); | ||
return ndkPackageXml.existsSync(); | ||
} | ||
|
||
void installNdk({ | ||
required String javaHome, | ||
}) { | ||
final sdkManagerExtension = Platform.isWindows ? '.bat' : ''; | ||
final sdkManager = path.join( | ||
sdkPath, | ||
'cmdline-tools', | ||
'latest', | ||
'bin', | ||
'sdkmanager$sdkManagerExtension', | ||
); | ||
|
||
runCommand(sdkManager, [ | ||
'--install', | ||
'ndk;$ndkVersion', | ||
], environment: { | ||
'JAVA_HOME': javaHome, | ||
}); | ||
} | ||
|
||
Future<Map<String, String>> buildEnvironment() async { | ||
final hostArch = Platform.isMacOS | ||
? "darwin-x86_64" | ||
: (Platform.isLinux ? "linux-x86_64" : "windows-x86_64"); | ||
|
||
final ndkPath = path.join(sdkPath, 'ndk', ndkVersion); | ||
final toolchainPath = path.join( | ||
ndkPath, | ||
'toolchains', | ||
'llvm', | ||
'prebuilt', | ||
hostArch, | ||
'bin', | ||
); | ||
|
||
final minSdkVersion = | ||
math.max(target.androidMinSdkVersion!, this.minSdkVersion); | ||
|
||
final arKey = 'AR_${target.rust}'; | ||
final arValue = ['${target.rust}-ar', 'llvm-ar', 'llvm-ar.exe'] | ||
.map((e) => path.join(toolchainPath, e)) | ||
.firstWhereOrNull((element) => File(element).existsSync()); | ||
if (arValue == null) { | ||
throw Exception('Failed to find ar for $target in $toolchainPath'); | ||
} | ||
|
||
final targetArg = '--target=${target.rust}$minSdkVersion'; | ||
|
||
final ccKey = 'CC_${target.rust}'; | ||
final ccValue = path.join(toolchainPath, 'clang'); | ||
final cfFlagsKey = 'CFLAGS_${target.rust}'; | ||
final cFlagsValue = targetArg; | ||
|
||
final cxxKey = 'CXX_${target.rust}'; | ||
final cxxValue = path.join(toolchainPath, 'clang++'); | ||
final cxxfFlagsKey = 'CXXFLAGS_${target.rust}'; | ||
final cxxFlagsValue = targetArg; | ||
|
||
final linkerKey = | ||
'cargo_target_${target.rust.replaceAll('-', '_')}_linker'.toUpperCase(); | ||
|
||
final ranlibKey = 'RANLIB_${target.rust}'; | ||
final ranlibValue = path.join(toolchainPath, 'llvm-ranlib'); | ||
|
||
final ndkVersionParsed = Version.parse(ndkVersion); | ||
final rustFlagsKey = 'CARGO_ENCODED_RUSTFLAGS'; | ||
final rustFlagsValue = _libGccWorkaround(targetTempDir, ndkVersionParsed); | ||
|
||
final runRustTool = | ||
Platform.isWindows ? 'run_build_tool.cmd' : 'run_build_tool.sh'; | ||
|
||
final packagePath = (await Isolate.resolvePackageUri( | ||
Uri.parse('package:build_tool/buildtool.dart')))! | ||
.toFilePath(); | ||
final selfPath = path.canonicalize(path.join( | ||
packagePath, | ||
'..', | ||
'..', | ||
'..', | ||
runRustTool, | ||
)); | ||
|
||
// Make sure that run_build_tool is working properly even initially launched directly | ||
// through dart run. | ||
final toolTempDir = | ||
Platform.environment['CARGOKIT_TOOL_TEMP_DIR'] ?? targetTempDir; | ||
|
||
return { | ||
arKey: arValue, | ||
ccKey: ccValue, | ||
cfFlagsKey: cFlagsValue, | ||
cxxKey: cxxValue, | ||
cxxfFlagsKey: cxxFlagsValue, | ||
ranlibKey: ranlibValue, | ||
rustFlagsKey: rustFlagsValue, | ||
linkerKey: selfPath, | ||
// Recognized by main() so we know when we're acting as a wrapper | ||
'_CARGOKIT_NDK_LINK_TARGET': targetArg, | ||
'_CARGOKIT_NDK_LINK_CLANG': ccValue, | ||
'CARGOKIT_TOOL_TEMP_DIR': toolTempDir, | ||
}; | ||
} | ||
|
||
// Workaround for libgcc missing in NDK23, inspired by cargo-ndk | ||
String _libGccWorkaround(String buildDir, Version ndkVersion) { | ||
final workaroundDir = path.join( | ||
buildDir, | ||
'cargokit', | ||
'libgcc_workaround', | ||
'${ndkVersion.major}', | ||
); | ||
Directory(workaroundDir).createSync(recursive: true); | ||
if (ndkVersion.major >= 23) { | ||
File(path.join(workaroundDir, 'libgcc.a')) | ||
.writeAsStringSync('INPUT(-lunwind)'); | ||
} else { | ||
// Other way around, untested, forward libgcc.a from libunwind once Rust | ||
// gets updated for NDK23+. | ||
File(path.join(workaroundDir, 'libunwind.a')) | ||
.writeAsStringSync('INPUT(-lgcc)'); | ||
} | ||
|
||
var rustFlags = Platform.environment['CARGO_ENCODED_RUSTFLAGS'] ?? ''; | ||
if (rustFlags.isNotEmpty) { | ||
rustFlags = '$rustFlags\x1f'; | ||
} | ||
rustFlags = '$rustFlags-L\x1f$workaroundDir'; | ||
return rustFlags; | ||
} | ||
} |
Oops, something went wrong.