From bd8a2b8e63bae790cc21c8d43e6cb252c5b79570 Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Wed, 30 Aug 2023 16:16:21 +0200 Subject: [PATCH] feat: infer library name from Cargo.toml --- build_pod.sh | 3 -- build_tool/lib/src/artifacts_provider.dart | 8 ++-- build_tool/lib/src/build_pod.dart | 9 +++-- build_tool/lib/src/build_tool.dart | 24 +++-------- build_tool/lib/src/builder.dart | 10 +++-- build_tool/lib/src/cargo.dart | 45 +++++++++++++++++++++ build_tool/lib/src/environment.dart | 3 -- build_tool/lib/src/precompile_binaries.dart | 15 +++---- build_tool/lib/src/verify_binaries.dart | 7 ++-- build_tool/pubspec.lock | 16 ++++++++ build_tool/pubspec.yaml | 3 +- build_tool/test/cargo_test.dart | 28 +++++++++++++ cmake/cargokit.cmake | 1 - docs/precompiled_binaries.md | 4 +- gradle/plugin.gradle | 1 - 15 files changed, 125 insertions(+), 52 deletions(-) create mode 100644 build_tool/lib/src/cargo.dart create mode 100644 build_tool/test/cargo_test.dart diff --git a/build_pod.sh b/build_pod.sh index 2fc6527..4428f5a 100755 --- a/build_pod.sh +++ b/build_pod.sh @@ -22,9 +22,6 @@ export CARGOKIT_CONFIGURATION=$CONFIGURATION # Path to directory containing Cargo.toml. export CARGOKIT_MANIFEST_DIR=$PODS_TARGET_SRCROOT/$1 -# Name of Rust library being built. -export CARGOKIT_LIB_NAME=$2 - # Temporary directory for build artifacts. export CARGOKIT_TARGET_TEMP_DIR=$TARGET_TEMP_DIR diff --git a/build_tool/lib/src/artifacts_provider.dart b/build_tool/lib/src/artifacts_provider.dart index f2ecf3a..8976796 100644 --- a/build_tool/lib/src/artifacts_provider.dart +++ b/build_tool/lib/src/artifacts_provider.dart @@ -64,19 +64,19 @@ class ArtifactProvider { for (final target in targets) { final builder = RustBuilder(target: target, environment: environment); builder.prepare(rustup); - _log.info('Building ${environment.libName} for $target'); + _log.info('Building ${environment.crateInfo.packageName} for $target'); final targetDir = await builder.build(); // For local build accept both static and dynamic libraries. final artifactNames = { ...getArtifactNames( target: target, - libraryName: environment.libName, + libraryName: environment.crateInfo.packageName, aritifactType: AritifactType.dylib, remote: false, ), ...getArtifactNames( target: target, - libraryName: environment.libName, + libraryName: environment.crateInfo.packageName, aritifactType: AritifactType.staticlib, remote: false, ) @@ -119,7 +119,7 @@ class ArtifactProvider { for (final target in targets) { final requiredArtifacts = getArtifactNames( target: target, - libraryName: environment.libName, + libraryName: environment.crateInfo.packageName, remote: true, ); final artifactsForTarget = []; diff --git a/build_tool/lib/src/build_pod.dart b/build_tool/lib/src/build_pod.dart index c13006a..c599d59 100644 --- a/build_tool/lib/src/build_pod.dart +++ b/build_tool/lib/src/build_pod.dart @@ -52,16 +52,17 @@ class BuildPod { .where((element) => element.type == AritifactType.dylib) .toList(); + final libName = environment.crateInfo.packageName; + // If there is static lib, use it and link it with pod if (staticLibs.isNotEmpty) { - final finalTargetFile = - path.join(outputDir, "lib${environment.libName}.a"); + final finalTargetFile = path.join(outputDir, "lib$libName.a"); performLipo(finalTargetFile, staticLibs.map((e) => e.path)); } else { // Otherwise try to replace bundle dylib with our dylib final bundlePaths = [ - '${environment.libName}.framework/Versions/A/${environment.libName}', - '${environment.libName}.framework/${environment.libName}', + '$libName.framework/Versions/A/$libName', + '$libName.framework/$libName', ]; for (final bundlePath in bundlePaths) { diff --git a/build_tool/lib/src/build_tool.dart b/build_tool/lib/src/build_tool.dart index 092c5a0..ccbc463 100644 --- a/build_tool/lib/src/build_tool.dart +++ b/build_tool/lib/src/build_tool.dart @@ -106,11 +106,6 @@ class PrecompileBinariesCommand extends Command { mandatory: true, help: 'Directory containing Cargo.toml', ) - ..addOption( - 'lib-name', - mandatory: true, - help: 'Name of the library to build.', - ) ..addMultiOption('target', help: 'Rust target triple of artifact to build.\n' 'Can be specified multiple times or omitted in which case\n' @@ -192,7 +187,6 @@ class PrecompileBinariesCommand extends Command { final precompileBinaries = PrecompileBinaries( privateKey: PrivateKey(privateKey), githubToken: githubToken, - libName: argResults!['lib-name'] as String, manifestDir: manifestDir, repositorySlug: RepositorySlug.full(argResults!['repository'] as String), targets: targets, @@ -208,17 +202,11 @@ class PrecompileBinariesCommand extends Command { class VerifyBinariesCommand extends Command { VerifyBinariesCommand() { - argParser - ..addOption( - 'manifest-dir', - mandatory: true, - help: 'Directory containing Cargo.toml', - ) - ..addOption( - 'lib-name', - mandatory: true, - help: 'Name of the library to build.', - ); + argParser.addOption( + 'manifest-dir', + mandatory: true, + help: 'Directory containing Cargo.toml', + ); } @override @@ -232,10 +220,8 @@ class VerifyBinariesCommand extends Command { @override Future run() async { final manifestDir = argResults!['manifest-dir'] as String; - final libName = argResults!['lib-name'] as String; final verifyBinaries = VerifyBinaries( manifestDir: manifestDir, - libraryName: libName, ); await verifyBinaries.run(); } diff --git a/build_tool/lib/src/builder.dart b/build_tool/lib/src/builder.dart index 17a43d7..2d056de 100644 --- a/build_tool/lib/src/builder.dart +++ b/build_tool/lib/src/builder.dart @@ -2,6 +2,7 @@ import 'package:collection/collection.dart'; import 'package:path/path.dart' as path; import 'android_environment.dart'; +import 'cargo.dart'; import 'environment.dart'; import 'options.dart'; import 'rustup.dart'; @@ -39,7 +40,7 @@ class BuildEnvironment { final CargokitCrateOptions crateOptions; final String targetTempDir; final String manifestDir; - final String libName; + final CrateInfo crateInfo; final bool isAndroid; final String? androidSdkPath; @@ -52,7 +53,7 @@ class BuildEnvironment { required this.crateOptions, required this.targetTempDir, required this.manifestDir, - required this.libName, + required this.crateInfo, required this.isAndroid, this.androidSdkPath, this.androidNdkVersion, @@ -75,12 +76,13 @@ class BuildEnvironment { final crateOptions = CargokitCrateOptions.load( manifestDir: manifestDir, ); + final crateInfo = CrateInfo.load(manifestDir); return BuildEnvironment( configuration: buildConfiguration, crateOptions: crateOptions, targetTempDir: Environment.targetTempDir, manifestDir: manifestDir, - libName: Environment.libName, + crateInfo: crateInfo, isAndroid: isAndroid, androidSdkPath: isAndroid ? Environment.sdkPath : null, androidNdkVersion: isAndroid ? Environment.ndkVersion : null, @@ -135,7 +137,7 @@ class RustBuilder { '--manifest-path', manifestPath, '-p', - environment.libName, + environment.crateInfo.packageName, if (!environment.configuration.isDebug) '--release', '--target', target.rust, diff --git a/build_tool/lib/src/cargo.dart b/build_tool/lib/src/cargo.dart new file mode 100644 index 0000000..0d4483f --- /dev/null +++ b/build_tool/lib/src/cargo.dart @@ -0,0 +1,45 @@ +import 'dart:io'; + +import 'package:path/path.dart' as path; +import 'package:toml/toml.dart'; + +class ManifestException { + ManifestException(this.message, {required this.fileName}); + + final String? fileName; + final String message; + + @override + String toString() { + if (fileName != null) { + return 'Failed to parse package manifest at $fileName: $message'; + } else { + return 'Failed to parse package manifest: $message'; + } + } +} + +class CrateInfo { + CrateInfo({required this.packageName}); + + final String packageName; + + static CrateInfo parseManifest(String manifest, {final String? fileName}) { + final toml = TomlDocument.parse(manifest); + final package = toml.toMap()['package']; + if (package == null) { + throw ManifestException('Missing package section', fileName: fileName); + } + final name = package['name']; + if (name == null) { + throw ManifestException('Missing package name', fileName: fileName); + } + return CrateInfo(packageName: name); + } + + static CrateInfo load(String manifestDir) { + final manifestFile = File(path.join(manifestDir, 'Cargo.toml')); + final manifest = manifestFile.readAsStringSync(); + return parseManifest(manifest, fileName: manifestFile.path); + } +} diff --git a/build_tool/lib/src/environment.dart b/build_tool/lib/src/environment.dart index 413a2b1..1d267ed 100644 --- a/build_tool/lib/src/environment.dart +++ b/build_tool/lib/src/environment.dart @@ -21,9 +21,6 @@ class Environment { /// Path to the crate manifest (containing Cargo.toml). static String get manifestDir => _getEnvPath('CARGOKIT_MANIFEST_DIR'); - /// Crate library name. - static String get libName => _getEnv('CARGOKIT_LIB_NAME'); - /// Directory inside root project. Not necessarily root folder. Symlinks are /// not resolved on purpose. static String get rootProjectDir => _getEnv('CARGOKIT_ROOT_PROJECT_DIR'); diff --git a/build_tool/lib/src/precompile_binaries.dart b/build_tool/lib/src/precompile_binaries.dart index cfcd998..39ffafc 100644 --- a/build_tool/lib/src/precompile_binaries.dart +++ b/build_tool/lib/src/precompile_binaries.dart @@ -7,6 +7,7 @@ import 'package:path/path.dart' as path; import 'artifacts_provider.dart'; import 'builder.dart'; +import 'cargo.dart'; import 'crate_hash.dart'; import 'options.dart'; import 'rustup.dart'; @@ -20,7 +21,6 @@ class PrecompileBinaries { required this.githubToken, required this.repositorySlug, required this.manifestDir, - required this.libName, required this.targets, this.androidSdkLocation, this.androidNdkVersion, @@ -32,7 +32,6 @@ class PrecompileBinaries { final String githubToken; final RepositorySlug repositorySlug; final String manifestDir; - final String libName; final List targets; final String? androidSdkLocation; final String? androidNdkVersion; @@ -48,6 +47,8 @@ class PrecompileBinaries { } Future run() async { + final crateInfo = CrateInfo.load(manifestDir); + final targets = List.of(this.targets); if (targets.isEmpty) { targets.addAll([ @@ -68,7 +69,7 @@ class PrecompileBinaries { final release = await _getOrCreateRelease( repo: repo, tagName: tagName, - libName: libName, + packageName: crateInfo.packageName, hash: hash, ); @@ -87,7 +88,7 @@ class PrecompileBinaries { crateOptions: crateOptions, targetTempDir: tempDir.path, manifestDir: manifestDir, - libName: libName, + crateInfo: crateInfo, isAndroid: androidSdkLocation != null, androidSdkPath: androidSdkLocation, androidNdkVersion: androidNdkVersion, @@ -99,7 +100,7 @@ class PrecompileBinaries { for (final target in targets) { final artifactNames = getArtifactNames( target: target, - libraryName: libName, + libraryName: crateInfo.packageName, remote: true, ); @@ -172,7 +173,7 @@ class PrecompileBinaries { Future _getOrCreateRelease({ required RepositoriesService repo, required String tagName, - required String libName, + required String packageName, required String hash, }) async { Release release; @@ -189,7 +190,7 @@ class PrecompileBinaries { targetCommitish: null, isDraft: false, isPrerelease: false, - body: 'Precompiled binaries for crate $libName, ' + body: 'Precompiled binaries for crate $packageName, ' 'crate hash $hash.', )); } diff --git a/build_tool/lib/src/verify_binaries.dart b/build_tool/lib/src/verify_binaries.dart index 8e76d17..0094c64 100644 --- a/build_tool/lib/src/verify_binaries.dart +++ b/build_tool/lib/src/verify_binaries.dart @@ -4,6 +4,7 @@ import 'package:ed25519_edwards/ed25519_edwards.dart'; import 'package:http/http.dart'; import 'artifacts_provider.dart'; +import 'cargo.dart'; import 'crate_hash.dart'; import 'options.dart'; import 'precompile_binaries.dart'; @@ -12,13 +13,13 @@ import 'target.dart'; class VerifyBinaries { VerifyBinaries({ required this.manifestDir, - required this.libraryName, }); final String manifestDir; - final String libraryName; Future run() async { + final crateInfo = CrateInfo.load(manifestDir); + final config = CargokitCrateOptions.load(manifestDir: manifestDir); final precompiledBinaries = config.precompiledBinaries; if (precompiledBinaries == null) { @@ -34,7 +35,7 @@ class VerifyBinaries { final artifacts = getArtifactNames( target: target, - libraryName: libraryName, + libraryName: crateInfo.packageName, remote: true, ); diff --git a/build_tool/pubspec.lock b/build_tool/pubspec.lock index 5507b29..343bdd3 100644 --- a/build_tool/pubspec.lock +++ b/build_tool/pubspec.lock @@ -249,6 +249,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + url: "https://pub.dev" + source: hosted + version: "5.4.0" pool: dependency: transitive description: @@ -377,6 +385,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.6" + toml: + dependency: "direct main" + description: + name: toml + sha256: "157c5dca5160fced243f3ce984117f729c788bb5e475504f3dbcda881accee44" + url: "https://pub.dev" + source: hosted + version: "0.14.0" typed_data: dependency: transitive description: diff --git a/build_tool/pubspec.yaml b/build_tool/pubspec.yaml index 859edef..1afacce 100644 --- a/build_tool/pubspec.yaml +++ b/build_tool/pubspec.yaml @@ -3,7 +3,7 @@ description: A sample command-line application. version: 1.0.0 environment: - sdk: '>=3.0.0 <4.0.0' + sdk: ">=3.0.0 <4.0.0" # Add regular dependencies here. dependencies: @@ -22,6 +22,7 @@ dependencies: crypto: 3.0.3 convert: 3.1.1 http: 1.1.0 + toml: 0.14.0 dev_dependencies: lints: ^2.1.0 diff --git a/build_tool/test/cargo_test.dart b/build_tool/test/cargo_test.dart new file mode 100644 index 0000000..00afe29 --- /dev/null +++ b/build_tool/test/cargo_test.dart @@ -0,0 +1,28 @@ +import 'package:build_tool/src/cargo.dart'; +import 'package:test/test.dart'; + +final _cargoToml = """ +[workspace] + +[profile.release] +lto = true +panic = "abort" +opt-level = "z" +# strip = "symbols" + +[package] +name = "super_native_extensions" +version = "0.1.0" +edition = "2021" +resolver = "2" + +[lib] +crate-type = ["cdylib", "staticlib"] +"""; + +void main() { + test('parseCargoToml', () { + final info = CrateInfo.parseManifest(_cargoToml); + expect(info.packageName, 'super_native_extensions'); + }); +} diff --git a/cmake/cargokit.cmake b/cmake/cargokit.cmake index 51f29b7..8c61508 100644 --- a/cmake/cargokit.cmake +++ b/cmake/cargokit.cmake @@ -29,7 +29,6 @@ function(apply_cargokit target manifest_dir lib_name any_symbol_name) "CARGOKIT_CMAKE=${CMAKE_COMMAND}" "CARGOKIT_CONFIGURATION=$" "CARGOKIT_MANIFEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${manifest_dir}" - "CARGOKIT_LIB_NAME=${CARGOKIT_LIB_NAME}" "CARGOKIT_TARGET_TEMP_DIR=${CARGOKIT_TEMP_DIR}" "CARGOKIT_OUTPUT_DIR=${CARGOKIT_OUTPUT_DIR}" "CARGOKIT_TARGET_PLATFORM=${CARGOKIT_TARGET_PLATFORM}" diff --git a/docs/precompiled_binaries.md b/docs/precompiled_binaries.md index 7d754c8..2026e86 100644 --- a/docs/precompiled_binaries.md +++ b/docs/precompiled_binaries.md @@ -75,14 +75,14 @@ jobs: run: sudo apt-get update && sudo apt-get install libgtk-3-dev - name: Precompile if: (matrix.os == 'macOS-latest') || (matrix.os == 'windows-latest') - run: dart run build_tool precompile-binaries -v --lib-name=super_native_extensions --manifest-dir=../../rust --repository=superlistapp/super_native_extensions + run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=superlistapp/super_native_extensions working-directory: super_native_extensions/cargokit/build_tool env: GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} PRIVATE_KEY: ${{ secrets.RELEASE_PRIVATE_KEY }} - name: Precompile (with Android) if: (matrix.os == 'ubuntu-latest') - run: dart run build_tool precompile-binaries -v --lib-name=super_native_extensions --manifest-dir=../../rust --repository=superlistapp/super_native_extensions --android-sdk-location=/usr/local/lib/android/sdk --android-ndk-version=24.0.8215888 --android-min-sdk-version=23 + run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=superlistapp/super_native_extensions --android-sdk-location=/usr/local/lib/android/sdk --android-ndk-version=24.0.8215888 --android-min-sdk-version=23 working-directory: super_native_extensions/cargokit/build_tool env: GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }} diff --git a/gradle/plugin.gradle b/gradle/plugin.gradle index 9300dc3..a40cf56 100644 --- a/gradle/plugin.gradle +++ b/gradle/plugin.gradle @@ -62,7 +62,6 @@ abstract class CargoKitBuildTask extends DefaultTask { environment "CARGOKIT_ROOT_PROJECT_DIR", rootProjectDir environment "CARGOKIT_TOOL_TEMP_DIR", "${buildDir}/build_tool" environment "CARGOKIT_MANIFEST_DIR", manifestDir - environment "CARGOKIT_LIB_NAME", project.cargokit.libname environment "CARGOKIT_CONFIGURATION", buildMode environment "CARGOKIT_TARGET_TEMP_DIR", buildDir environment "CARGOKIT_OUTPUT_DIR", outputDir