Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Android versions 5-11. #1023

Merged
merged 1 commit into from
Nov 1, 2022

Conversation

Alexhuszagh
Copy link
Contributor

@Alexhuszagh Alexhuszagh commented Sep 15, 2022

Configuration

We provide the following arguments to configure the Android version:

  • ANDROID_NDK
  • ANDROID_SDK (note that this is dependent on `ANDROID_VERSION)
  • ANDROID_VERSION
  • ANDROID_SYSTEM_COMPLETE: do a complete Android build
  • ANDROID_SYSTEM_NONE: do not build the Android system, disables runner support

Version Support

We now support NDK versions r10e-r25b, SDK versions 21-33, and Android versions 5.0, 5.1, 6.0, 7.0, 8.0, 8.1, 9.0, 10.0, and 11.0. We also validate that the NDK, SDK, and Android versions are compatible.

For Android 12+, we do support using the NDK with the proper API level, allowing cross-compilation for the desired target, however, running or testing the generated binary is currently not supported without a complete build. Note that support for non-complete builds with Android versions 12+ is unlikely to ever occur, due to issues with APEX in the build system.

Implementation Details

Next, we've improved the removal of unittests during the build process, to ensure fast builds while maintaining compatibility with various newer Android versions. To do this, we've implemented a Python library and a script. The Python library contains a complete parser (correctly parses all valid input) for Soong blueprint files, using an LALR grammar, and a rudimentary parser for Makefiles.

The Soong parser removes any gtest dependencies, as well as any subdirectories or scope names containing test. For example:

cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
cc_test {
    name: "test",
    defaults: ["target"],
    srcs: ["test.cc"],
}

Will become:

cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}

The Makefile parser first splits the file based on conditional directives (ifeq, endif, etc.) to ensure any subsequent processing doesn't lead to unbalanced directives. Next, we split the text within each directive based on comment sections used in the Android source tree. For example:

test_tags := tests

include $(call subdir,$(LOCAL_PATH))

c_flags := \
  -g \
  -Wall

We can therefore remove the Benchmarks and Unit tests sections without removing the Other section.

The Python library is reasonably performant (it adds no noticeable overhead to the build process) and is compact (in total, < 60KB). Also, it is much more resilient than a series of sed scripts.

Finally, extensive unittests have been added for the Python library, for both code linting (flake8) and unittests (via tox). Since we cannot assume the presence of Python on the host machine, the tests can be optionally enabled via the --python flag (or PYTHON environment variable, to hook into the git hooks), and custom overrides for the flake8 and tox commands are provided (since the user may wish to specify a specific Python version, such as python3.7 -m flake8).

Linker

For Android 10+, since we use a minimal Android build, we only support the bootstrap and ASAN linkers unless using a complete Android build. Supporting the APEX linker requires a nearly complete Android runtime, requiring 60+GB image sizes, slow builds, and other prohibitive factors.

Complete Builds

Complete builds are currently untested, for Androids version 12+ they exceed the default storage capacity of WSL2 images (250GB). They should work and properly install both the /system and /apex directories, however, the builds are slow and untested.

@Alexhuszagh
Copy link
Contributor Author

Alexhuszagh commented Sep 15, 2022

Currently only tested on 9.0.0_r1, needs testing on a few more versions:

  • 5.0.0_r1
  • 5.1.1_r38
  • 6.0.1_r81
  • 7.0.0_r36
  • 8.0.0_r51
  • 8.1.0_r81
  • 9.0.0_r1
  • 10.0.0_r47
  • 11.0.0_r48
  • 12.1.0_r27
  • 13.0.0_r6

This should also simplify migrating to newer Android NDK and SDK versions in the future. This will also need a wiki entry, I believe.

I've also tested the Android NDK versions:

  • r10e (version 5.0.0_r1 only)
  • r13b (version 5.0.0_r1 only)
  • r21d
  • r25b

Also, the ANDROID_SYSTEM_COMPLETE isn't tested, nor will it, since the entire build requires ~100GB of memory and the build process is glacial. Note that we cannot use Android 7.1 builds, since they require API level 25, which does not seem to be supported by most (any?) NDK versions.

We also have added ANDROID_SYSTEM_NONE, for a very lightweight image without any runners.

docker/Dockerfile.aarch64-linux-android Outdated Show resolved Hide resolved
docker/android-system.sh Outdated Show resolved Hide resolved
@Alexhuszagh

This comment was marked as outdated.

bors bot added a commit that referenced this pull request Sep 22, 2022
@bors

This comment was marked as outdated.

@Alexhuszagh

This comment was marked as outdated.

bors bot added a commit that referenced this pull request Sep 22, 2022
@bors

This comment was marked as outdated.

@Alexhuszagh
Copy link
Contributor Author

I've restored using Python for the Android NDK install steps, since it's a bit more resilient than making all the symlinks outself manually. We could probably speed it up slightly making manual symlinks, but considering the major bottleneck is the Android build itself, and this adds no size to the resulting image, I don't see any reason to remove it. I've added python3 since newer Android NDK versions use it by default and it also has effectively no change in the build times or performance.

@Alexhuszagh
Copy link
Contributor Author

bors try --target aarch64-linux-android

bors bot added a commit that referenced this pull request Sep 23, 2022
@bors
Copy link
Contributor

bors bot commented Sep 23, 2022

try

Build succeeded:

@Alexhuszagh Alexhuszagh force-pushed the android_versions branch 6 times, most recently from f74d84b to 17c074a Compare October 15, 2022 04:06
@Alexhuszagh Alexhuszagh force-pushed the android_versions branch 3 times, most recently from 16dee77 to 75870b7 Compare October 17, 2022 21:06
@Alexhuszagh Alexhuszagh force-pushed the android_versions branch 4 times, most recently from 79fb560 to 97d747e Compare October 25, 2022 18:38
bors bot added a commit that referenced this pull request Oct 28, 2022
@Alexhuszagh
Copy link
Contributor Author

There might be other things I'm missing: I've tried to run through this numerous times, but at 4k lines of code, there may be something I've overlooked. I've re-run the tests for the entire suite of Android versions on aarch64-linux-android on the latest version of the build scripts, so it should work for the tested versions for all targets, but there could be subtle logic errors.

@bors
Copy link
Contributor

bors bot commented Oct 28, 2022

try

Build succeeded:

@Emilgardis
Copy link
Member

since these scripts are very android specific and most of it would not be used in CI, would it make sense to move this to cross-toolchain?

@Alexhuszagh
Copy link
Contributor Author

since these scripts are very android specific and most of it would not be used in CI, would it make sense to move this to cross-toolchain?

Sure, that could work. We can then also cherry pick pieces if we say, want to upgrade to Android 11.

@Alexhuszagh
Copy link
Contributor Author

If we do migrate this to cross-toolchains, it would be nice if we could have some basic CI to test the additions, however:
cross-rs/cross-toolchains#24

Copy link
Member

@Emilgardis Emilgardis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks amazing, some minor comments

I'm not super familiar with the android build system so can't comment to much on the approach, but this seems great!

This might now be the most complete containerized build system for c/c++/rust projects in android available anywhere 😅

i'm fine with merging this into this repo

docker/Dockerfile.aarch64-linux-android Outdated Show resolved Hide resolved
xtask/src/hooks.rs Outdated Show resolved Hide resolved
xtask/src/hooks.rs Outdated Show resolved Hide resolved
docker/android-system.sh Outdated Show resolved Hide resolved
**Configuration**

We provide the following arguments to configure the Android version:
- `ANDROID_NDK`
- `ANDROID_SDK` (note that this is dependent on `ANDROID_VERSION)
- `ANDROID_VERSION`
- `ANDROID_SYSTEM_COMPLETE`: do a complete Android build
- `ANDROID_SYSTEM_NONE`: do not build the Android system, disables runner support

**Version Support**

We now support NDK versions r10e-r25b, SDK versions 21-33, and Android versions 5.0, 5.1, 6.0, 7.0, 8.0, 8.1, 9.0, 10.0, and 11.0. We also validate that the NDK, SDK, and Android versions are compatible.

For Android 12+, we do support using the NDK with the proper API level, allowing cross-compilation for the desired target, however, running or testing the generated binary is currently not supported without a complete build. Note that support for non-complete builds with Android versions 12+ is unlikely to ever occur, due to issues with APEX in the build system.

**Implementation Details**

Next, we've improved the removal of unittests during the build process, to ensure fast builds while maintaining compatibility with various newer Android versions. To do this, we've implemented a Python library and a script. The Python library contains a complete parser (correctly parses all valid input) for Soong blueprint files, using an LALR grammar, and a rudimentary parser for Makefiles.

The Soong parser removes any `gtest` dependencies, as well as any subdirectories or scope names containing `test`. For example:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
cc_test {
    name: "test",
    defaults: ["target"],
    srcs: ["test.cc"],
}
```

Will become:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
```

The Makefile parser first splits the file based on conditional directives (`ifeq`, `endif`, etc.) to ensure any subsequent processing doesn't lead to unbalanced directives. Next, we split the text within each directive based on comment sections used in the Android source tree. For example:

```Makefile
test_tags := tests

include $(call subdir,$(LOCAL_PATH))

c_flags := \
  -g \
  -Wall
```

We can therefore remove the `Benchmarks` and `Unit tests` sections without removing the `Other section`.

The Python library is reasonably performant (it adds no noticeable overhead to the build process) and is compact (in total, < 60KB). Also, it is much more resilient than a series of `sed` scripts.

Finally, extensive unittests have been added for the Python library, for both code linting (`flake8`) and unittests (via `tox`). Since we cannot assume the presence of Python on the host machine, the tests can be optionally enabled via the `--python` flag (or `PYTHON` environment variable, to hook into the git hooks), and custom overrides for the `flake8` and `tox` commands are provided (since the user may wish to specify a specific Python version, such as `python3.7 -m flake8`).

**Linker**

For Android 10+, since we use a minimal Android build, we only support the bootstrap and ASAN linkers unless using a complete Android build. Supporting the APEX linker requires a nearly complete Android runtime, requiring 60+GB image sizes, slow builds, and other prohibitive factors.

**Complete Builds**

Complete builds are currently untested, for Androids version 12+ they exceed the default storage capacity of WSL2 images (250GB). They should work and properly install both the `/system` and `/apex` directories, however, the builds are slow and untested.
@Alexhuszagh
Copy link
Contributor Author

I've updated the NDK to r25b.
bors try --target -android

bors bot added a commit that referenced this pull request Nov 1, 2022
@bors
Copy link
Contributor

bors bot commented Nov 1, 2022

try

Build succeeded:

@Alexhuszagh
Copy link
Contributor Author

bors r=Emilgardis

bors bot added a commit that referenced this pull request Nov 1, 2022
1023: Add support for Android versions 5-11. r=Emilgardis a=Alexhuszagh

**Configuration**

We provide the following arguments to configure the Android version:
- `ANDROID_NDK`
- `ANDROID_SDK` (note that this is dependent on `ANDROID_VERSION)
- `ANDROID_VERSION`
- `ANDROID_SYSTEM_COMPLETE`: do a complete Android build
- `ANDROID_SYSTEM_NONE`: do not build the Android system, disables runner support

**Version Support**

We now support NDK versions r10e-r25b, SDK versions 21-33, and Android versions 5.0, 5.1, 6.0, 7.0, 8.0, 8.1, 9.0, 10.0, and 11.0. We also validate that the NDK, SDK, and Android versions are compatible.

For Android 12+, we do support using the NDK with the proper API level, allowing cross-compilation for the desired target, however, running or testing the generated binary is currently not supported without a complete build. Note that support for non-complete builds with Android versions 12+ is unlikely to ever occur, due to issues with APEX in the build system.

**Implementation Details**

Next, we've improved the removal of unittests during the build process, to ensure fast builds while maintaining compatibility with various newer Android versions. To do this, we've implemented a Python library and a script. The Python library contains a complete parser (correctly parses all valid input) for Soong blueprint files, using an LALR grammar, and a rudimentary parser for Makefiles.

The Soong parser removes any `gtest` dependencies, as well as any subdirectories or scope names containing `test`. For example:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
cc_test {
    name: "test",
    defaults: ["target"],
    srcs: ["test.cc"],
}
```

Will become:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
```

The Makefile parser first splits the file based on conditional directives (`ifeq`, `endif`, etc.) to ensure any subsequent processing doesn't lead to unbalanced directives. Next, we split the text within each directive based on comment sections used in the Android source tree. For example:

```Makefile
test_tags := tests

include $(call subdir,$(LOCAL_PATH))

c_flags := \
  -g \
  -Wall
```

We can therefore remove the `Benchmarks` and `Unit tests` sections without removing the `Other section`.

The Python library is reasonably performant (it adds no noticeable overhead to the build process) and is compact (in total, < 60KB). Also, it is much more resilient than a series of `sed` scripts.

Finally, extensive unittests have been added for the Python library, for both code linting (`flake8`) and unittests (via `tox`). Since we cannot assume the presence of Python on the host machine, the tests can be optionally enabled via the `--python` flag (or `PYTHON` environment variable, to hook into the git hooks), and custom overrides for the `flake8` and `tox` commands are provided (since the user may wish to specify a specific Python version, such as `python3.7 -m flake8`).

**Linker**

For Android 10+, since we use a minimal Android build, we only support the bootstrap and ASAN linkers unless using a complete Android build. Supporting the APEX linker requires a nearly complete Android runtime, requiring 60+GB image sizes, slow builds, and other prohibitive factors.

**Complete Builds**

Complete builds are currently untested, for Androids version 12+ they exceed the default storage capacity of WSL2 images (250GB). They should work and properly install both the `/system` and `/apex` directories, however, the builds are slow and untested.

Co-authored-by: Alex Huszagh <ahuszagh@gmail.com>
@bors
Copy link
Contributor

bors bot commented Nov 1, 2022

Build failed:

@Alexhuszagh
Copy link
Contributor Author

Currently waiting on the fix for -ar and -gcc-ar in #1105, and also we had a spurious network issue in the merge.

@Emilgardis
Copy link
Member

bors r+ p=1

bors bot added a commit that referenced this pull request Nov 1, 2022
1023: Add support for Android versions 5-11. r=Emilgardis a=Alexhuszagh

**Configuration**

We provide the following arguments to configure the Android version:
- `ANDROID_NDK`
- `ANDROID_SDK` (note that this is dependent on `ANDROID_VERSION)
- `ANDROID_VERSION`
- `ANDROID_SYSTEM_COMPLETE`: do a complete Android build
- `ANDROID_SYSTEM_NONE`: do not build the Android system, disables runner support

**Version Support**

We now support NDK versions r10e-r25b, SDK versions 21-33, and Android versions 5.0, 5.1, 6.0, 7.0, 8.0, 8.1, 9.0, 10.0, and 11.0. We also validate that the NDK, SDK, and Android versions are compatible.

For Android 12+, we do support using the NDK with the proper API level, allowing cross-compilation for the desired target, however, running or testing the generated binary is currently not supported without a complete build. Note that support for non-complete builds with Android versions 12+ is unlikely to ever occur, due to issues with APEX in the build system.

**Implementation Details**

Next, we've improved the removal of unittests during the build process, to ensure fast builds while maintaining compatibility with various newer Android versions. To do this, we've implemented a Python library and a script. The Python library contains a complete parser (correctly parses all valid input) for Soong blueprint files, using an LALR grammar, and a rudimentary parser for Makefiles.

The Soong parser removes any `gtest` dependencies, as well as any subdirectories or scope names containing `test`. For example:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
cc_test {
    name: "test",
    defaults: ["target"],
    srcs: ["test.cc"],
}
```

Will become:

```go
cc_library {
    name: "lib",
    srcs: ["lib.cc",],
}
```

The Makefile parser first splits the file based on conditional directives (`ifeq`, `endif`, etc.) to ensure any subsequent processing doesn't lead to unbalanced directives. Next, we split the text within each directive based on comment sections used in the Android source tree. For example:

```Makefile
test_tags := tests

include $(call subdir,$(LOCAL_PATH))

c_flags := \
  -g \
  -Wall
```

We can therefore remove the `Benchmarks` and `Unit tests` sections without removing the `Other section`.

The Python library is reasonably performant (it adds no noticeable overhead to the build process) and is compact (in total, < 60KB). Also, it is much more resilient than a series of `sed` scripts.

Finally, extensive unittests have been added for the Python library, for both code linting (`flake8`) and unittests (via `tox`). Since we cannot assume the presence of Python on the host machine, the tests can be optionally enabled via the `--python` flag (or `PYTHON` environment variable, to hook into the git hooks), and custom overrides for the `flake8` and `tox` commands are provided (since the user may wish to specify a specific Python version, such as `python3.7 -m flake8`).

**Linker**

For Android 10+, since we use a minimal Android build, we only support the bootstrap and ASAN linkers unless using a complete Android build. Supporting the APEX linker requires a nearly complete Android runtime, requiring 60+GB image sizes, slow builds, and other prohibitive factors.

**Complete Builds**

Complete builds are currently untested, for Androids version 12+ they exceed the default storage capacity of WSL2 images (250GB). They should work and properly install both the `/system` and `/apex` directories, however, the builds are slow and untested.

Co-authored-by: Alex Huszagh <ahuszagh@gmail.com>
@bors
Copy link
Contributor

bors bot commented Nov 1, 2022

Build failed:

@Emilgardis
Copy link
Member

bors retry

@Alexhuszagh
Copy link
Contributor Author

bors r=Emilgardis

@bors
Copy link
Contributor

bors bot commented Nov 1, 2022

Already running a review

@bors
Copy link
Contributor

bors bot commented Nov 1, 2022

Build succeeded:

@bors bors bot merged commit 35a1e17 into cross-rs:main Nov 1, 2022
@Alexhuszagh Alexhuszagh deleted the android_versions branch November 1, 2022 23:51
@Emilgardis Emilgardis added this to the v0.3.0 milestone Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants