Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@

## 0.2.1

* Fixed NDK path resolution on Windows by using `USERPROFILE` and normalizing path separators.
* Fixed NDK path resolution on Windows by using `USERPROFILE` and normalizing path separators. Thanks @kekland and @AttalliAyoub for the PRs and Issue (#2).
* Fixed `runProcess` failing with a `FormatException` on non-English Windows by decoding process output with the system encoding. Thanks @wyq0918dev for the PR / Issue (#4).
* The build hook now verifies that `libc++_shared.so` exists and is an ELF shared object before emitting it: thanks to @chillbrodev for the Issue (#5).
* An NDK that does not contain the library for the target architecture is now skipped in favour of the next installation, instead of failing the build.
* Added the legacy `sources/cxx-stl/llvm-libc++/libs/<abi>/` location used by NDK r22 and older as a fallback.
* The NDK the Flutter tool is building with is now used first, derived from the compiler in the build config.
* Added `sdk.dir` / `ndk.dir` from the project's `local.properties`, `flutter config --android-sdk`, `ndk-bundle` directories and more well known SDK locations to NDK discovery.
* Fixed NDK installations in `PATH` never being detected, because the search directory for `ndk-build` was incorrect.
* Added the `libcpp_shared_path` user define and the `ANDROID_LIBCPP_SHARED_PATH` environment variable to override where the library comes from.
* Failures report each NDK and file checked, and it is looged by the build hook.
* Added `ia32` mapped to `x86`.

## 0.2.0

Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ Dart / flutter package for Android to add the libc++_shared.so STL C++ shared ru

You obviously need dart/flutter installed, but in addition you must have the Android NDK installed. This package does its best to find the NDK install location during the build hook step.

### How the library is found

During the build hook, `libc++_shared.so` is looked for in this order:

1. An explicit override, if you have set one (see [Overriding the location](#overriding-the-location)).
2. The NDK that the Flutter tool itself is building with, derived from the compiler in the build config.
3. Every other NDK installation that can be found, highest version first. These come from `ndk-build` on your `PATH`, the `ANDROID_NDK`, `ANDROID_NDK_HOME`, `ANDROID_NDK_LATEST_HOME` and `ANDROID_NDK_ROOT` environment variables, `sdk.dir` / `ndk.dir` in your project's `local.properties`, the `ANDROID_HOME`, `ANDROID_SDK_ROOT` and `ANDROID_SDK_HOME` environment variables, `flutter config --android-sdk`, and the usual installation directories for your platform.

A candidate is only used once it has been verified to exist and to be an ELF shared object, so an incomplete NDK installation is skipped in favour of the next one rather than producing a build that fails later. If nothing usable is found the build hook fails with the full list of NDKs considered and files checked - please include that output when reporting an issue.

### Overriding the location

If the library lives somewhere this package does not look, point it at the file directly in your application's `pubspec.yaml`:

```yaml
hooks:
user_defines:
android_libcpp_shared:
libcpp_shared_path: /path/to/libc++_shared.so
```

The `ANDROID_LIBCPP_SHARED_PATH` environment variable does the same thing. Note that Gradle reuses a long lived daemon, so a variable exported after the daemon started will not reach the build hook; the user define is not affected by that.

Both settings also accept the root of an NDK installation, in which case that NDK is used in preference to any other.

## Adding the dependency

Add the package to your pubspec.yaml dependencies:
Expand Down
16 changes: 8 additions & 8 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -253,18 +253,18 @@ packages:
dependency: transitive
description:
name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
url: "https://pub.dev"
source: hosted
version: "1.17.0"
version: "1.18.0"
native_toolchain_c:
dependency: transitive
description:
name: native_toolchain_c
sha256: f59351d28f49520cd3a74eb1f41c5f19ae15e53c65a3231d14af672e46510a96
sha256: f9c168717100ae6d9fee9ffb0be379bf1f8b26b0f6bcbd4fdddcd931993a6a72
url: "https://pub.dev"
source: hosted
version: "0.19.1"
version: "0.19.2"
path:
dependency: transitive
description:
Expand Down Expand Up @@ -293,10 +293,10 @@ packages:
dependency: transitive
description:
name: posix
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
sha256: bc1bad54ad2b735816e31f8d4600cfde6c7839975085ddfbca48b6c9f7c4044e
url: "https://pub.dev"
source: hosted
version: "6.5.0"
version: "6.5.2"
process:
dependency: transitive
description:
Expand Down Expand Up @@ -378,10 +378,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
version: "0.7.11"
typed_data:
dependency: transitive
description:
Expand Down
31 changes: 17 additions & 14 deletions hook/build.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:android_libcpp_shared/src/locate_ndk.dart';
import 'package:android_libcpp_shared/src/resolve_libcpp.dart';
import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
Expand All @@ -24,22 +24,25 @@ void main(List<String> args) async {
final Architecture targetArchitecture =
input.config.code.targetArchitecture;

logger.info('Searching for android NDK...');
final ndkPaths = await NDKLocator.locate();
final ndk = ndkPaths.forBuildConfig(input.config);
if (ndk == null) {
logger.info('Searching for libc++_shared.so for $targetArchitecture...');
final resolution = await resolveLibcppShared(input, logger: logger);
final libcppSharedPath = resolution.libcppShared;
if (libcppSharedPath == null) {
throw StateError(
'No suitable NDK found for target architecture $targetArchitecture.',
resolution.describeFailure(
targetArchitecture,
input.config.code.android.targetNdkApi,
),
);
}
logger.info('Found NDK at ${ndk.path}, version ${ndk.version}.');
final libcppSharedPath = ndk
.hostArchitectures
.first
.targetArchitectures
.first
.sysrootLibPath
.resolve('libc++_shared.so');
final ndk = resolution.ndk;
if (ndk != null) {
logger.info('Using NDK ${ndk.version} at ${ndk.path.toFilePath()}.');
}
logger.info('Using ${libcppSharedPath.toFilePath()}.');

// Re-run the hook if the library path changes
output.dependencies.add(libcppSharedPath);

output.assets.code.add(
CodeAsset(
Expand Down
Loading