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

Mobile updates #50596

Merged
merged 17 commits into from Dec 24, 2018
Merged

Mobile updates #50596

merged 17 commits into from Dec 24, 2018

Conversation

svanderburg
Copy link
Member

@svanderburg svanderburg commented Nov 18, 2018

Motivation for this change

Replaces the androidenv implementation by a new implementation that uses:

  • The latest repository specs to generate expressions from (repository2-1.xml)
  • A more robust generation strategy that exposes many more plugins
  • A more robust autopatching strategy for ELF binaries
  • A function composition strategy that makes it easier to maintain androidenv.buildApp and the corresponding Android SDK features a build may need

Furthermore, it updates other mobile build aspects:

  • A refactored xcodeenv implementation (iphone build environment)
  • A refactored titaniumenv implementation using the new androidenv and xcodeenv environments
Status:

Done:

  • New androidenv implementation
  • Refactored xcodeenv implementation
  • Refactored titaniumenv implementation
  • Added docs for androidenv to the manual
  • Added docs for xcodeenv to the manual
  • Added docs for titaniumenv to the manual

Broken packages ported:

  • apktool
  • adbfs-rootless
  • adb-sync
  • flashtool
  • scrcpy
  • gnirehtet

Still to do:

  • Use modified autopatchelfHook that can also be used as a CLI
  • Add license accepted flag, because the Android SDK requires you to accept a license agreement
  • Readd androidenv.buildGradleApp
  • Fix cross compilation (stdenv.cross) and androidPkgs
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

@nixos-discourse
Copy link

This pull request has been mentioned on Nix community. There might be relevant details there:

https://discourse.nixos.org/t/my-revised-experimental-android-build-functions/923/12

@svanderburg
Copy link
Member Author

@Ericson2314 I could use your help for the stdenv.cross

@svanderburg
Copy link
Member Author

@matthewbauer I could use your help for readding androidenv.buildGradleApp

@svanderburg
Copy link
Member Author

@Mic92 I simplified the patch

@Ericson2314
Copy link
Member

CC @luigy. We should probably have a nixpkgs-master branch of reflex platform so when we upgrade to the next stable release there are no surprises.

@Ericson2314
Copy link
Member

@svanderburg so I think the "android ndk packages" file I made you'll basically want to keep as-is. The point of it is to take the NDK stuff, however that is gotten, and chop it up into things that we can replace normal nixpkgs derivations with (gcc, bionic libc, etc). Maybe with your new finer-grained plugin approach, it will be easier to get just those bits rather than downloading more and then throwing array the rest, but most of the complicatedness in that file has to do with the fact that tools and library overrides belong in different bootstrapping stages, and that much remains the same.

@svanderburg
Copy link
Member Author

I just rebased against the latest master. This resolves a conflict and allows me to use the modified autoPatchelf executable implemented in issue #50802

@svanderburg
Copy link
Member Author

@Ericson2314 Thanks! I'll start investigating a reintegration approach of these package soon.

The stdenv/cross environment is also broken because of the new packaging structure -- we now need to refer to the Android NDK (that is now bundled as a plugin with the Android SDK) in a different way.

@svanderburg
Copy link
Member Author

@Ericson2314 I did a preliminary investigation and there are some practical concerns for which I need to know your opinion.

The androidndk-pkgs.nix file is basically a set of packages that you want to cross compile with the Android NDK, right?

I'm not sure if putting this file in androidenv/ is the most logical place. For example, packages built with OpenJDK or Python are also not technically in the same "environment". The purpose of the androidenv component is to encapsulate the Android SDK manager and its plugins.

Do you mind if I put this expression in pkgs/development/androidndk-packages ? This is a location where also packages for other kinds of development environments reside, e.g. pkgs/development/python-modules/, pkgs/development/node-modules/ etc. I think this also makes it easier to implement future refactorings of the androidenv

The other problem is the Android NDK package -- the newest Android SDK also bundles the NDK as a plugin that you can install with the SDK manager. This is how I integrate the Android NDK in Nixpkgs.

I noticed that stdenv/cross supports various kinds of NDK versions. Unfortunately, the repository2-1.xml config file provided by Google (that I use in the new generation process) only provides one NDK version, namely: 18b

Is it still desired to support older NDK versions? If so, then we must package these older NDK versions differently somehow, by using the XML files of older SDK versions.

@Ericson2314
Copy link
Member

Firstly, it's fine to drop the other versions. I'd just ask that the code stay structured so that multiple SDK/NDK versions be supported in principle, so that once Google has more newstyle releases they can be simultaneously supported, but I assume you're doing that anyways :).

I don't mind if you move this file, but I don't think the comparison to the language packages is quite correct. The Android packages here are not, like, Java apps or something, but regular packages using prebuilt binaries. In other words the packages aren't really Android specific, only the platform they are built for and their provenance is. Language packages OTOH are different packages, but built in as normal a Nix approach as possible. That's almost the opposite.

I do appreciate trying to get it away from any autogenerated files, though, so move as you see fit.

@svanderburg
Copy link
Member Author

@Ericson2314 I now started investigating whether I can separate the androidndkPackages from androidenv (on the upstream master branch).

The idea is that I first try to separate it and check whether the functionality still works (e.g. whether there are no regressions). If this succeeds, then I apply the patches that provide my new SDK implementation. Finally, I will fix the androidndk packages to work with the NDK bundled with the new SDK implementation (version 18b).

Is there simple way to test how this cross compiling stuff works? I noticed that there is bionic in all-packages.nix, but I can't seem to build it by running:

$ nix-build -A bionic

The above command throws an assertion error.

I probably need to supply a bunch of cross compiling parameters, but from the documentation it is not clear to me how I can, for example, build on my x86_64-linux system a bionic implementation for ARM or x86_64 (or whatever targets are supported).

Is there simple testcase that I can run to make bionic build properly?

@Ericson2314
Copy link
Member

Ericson2314 commented Nov 28, 2018

$ nix-build -A pkgsCross.aarch64-android-prebuilt.hello

will build GNU hello with ndk's GCC and bionic.

[I pinged you on IRC if you have any follow-up questions.]

@svanderburg
Copy link
Member Author

@Ericson2314 I just created a new branch (forked from the current Nixpkgs) in which I implemented the separation (svanderburg@13d6088). Your testcase seems to pass.

What I basically did: I moved androidPkgs from androidenv to the top-level expression and moved all androidPkgs stuff to pkgs/development/androidndk-pkgs.

Next thing is trying to rebase my SDK changes on top of this change and fixing to make it work with the Android NDK 18b.

@Ericson2314
Copy link
Member

Ericson2314 commented Nov 28, 2018

Looks great! And btw, thank you for maintaining this.

@svanderburg
Copy link
Member Author

I just rebased again to include the android NDK pkgs separation.

@Ericson2314 I have managed to partially fix the cross compilation, but I need some help from you. The example package that you provided me now seems to properly evaluate. However, when I run the build, but the configure script still fails to properly detect the compiler. Inspecting config.log shows me that it can't find -lgcc, which makes sense since the newest Android NDK is clang-based.

I have created a separate WIP branch (https://github.com/svanderburg/nixpkgs/tree/mobile-updates-wip) that contains my changes so far: svanderburg@63f235c

I think quite a few things in the Android 18b NDK have changed compared to the latest previous version 17c. For example, symlinking to the cross compilation executables no longer seems to work because they are shell script that themselves are wrappers using relative paths.

Moreover, since the newest Android SDK distribution only supports NDK 18b so far, and the older NDK versions are no longer supported, we can probably also remove the code that is specific to these older version, e.g. 17c, 10e, 8e.

Can you have look at it?

@Ericson2314
Copy link
Member

I wonder if -lgcc has something to do with one of our wrapper scripts. hello itself ought not to care about those details.

@svanderburg
Copy link
Member Author

@Ericson2314 I think I have managed to make the fixes on my own. Apparently, what I learned is that libgcc.a is still required in a clang build if GNU Binutils are used for linking. I modified the bintools package in such a way that the required libgcc.a can be found.

Another problem I ran into is that the asm/types.h header can no longer be found when I try to compile GNU Hello with bionic. This is most likely caused by a slightly different sysroot directory organization in the Android NDK. I modified the bionic expression in such a way that these target specific ASM headers are copied in the right locations.

After making these modifications I have successfully compiled GNU Hello for aarch64 on Android.

Since I'm not using this stuff extensively, let me know if there is anything else that may require fixing. My changes are in revision 5142862

I think everything now is fixed and there are, as far as I can see, no breaking changes so I believe there is nothing preventing me from removing the WIP status of this pull request.

@Ericson2314
Copy link
Member

Great job! And sorry I didn't get to it before. I am taking a look now. BTW since you are doing xcode stuff, you may also want to checkout out what we did for ios cross here: https://github.com/nixos/nixpkgs/blob/master/pkgs/os-specific/darwin/xcode/default.nix using https://github.com/nixos/nixpkgs/blob/master/pkgs/os-specific/darwin/ios-sdk-pkgs/default.nix for the cross packages.

@@ -54,8 +56,15 @@ rec {
mkdir -p $out/bin
for prog in ${ndkBinDir}/${targetInfo.triple}-*; do
prog_suffix=$(basename $prog | sed 's/${targetInfo.triple}-//')
ln -s $prog $out/bin/${stdenv.targetPlatform.config}-$prog_suffix
cat > $out/bin/${stdenv.targetPlatform.config}-$prog_suffix <<EOF
Copy link
Member

Choose a reason for hiding this comment

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

Any particular reason you switched from a here-doc?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, symlinking does not work for the executables in Android NDK 18b. The executables we refer to are bash scripts that load executable from relative locations and have the expectation that they are loaded from the Android NDK directory. If we use symlinks, then it will look relative to the path of the symlinks, breaking the executable because these paths are invalid.

in
runCommand "bionic-prebuilt" {} ''
mkdir -p $out
cp -r ${includePath} $out/include
chmod u+w $out/include
cp -r ${asmIncludePath}/* $out/include
chmod +w $out/include
Copy link
Member

Choose a reason for hiding this comment

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

This chmod now happens twice?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm is not needed. Basically I needed to restore write permissions first before I could copy the asm headers, but I didn't bother to change the original statement that restores write permissions

@svanderburg
Copy link
Member Author

svanderburg commented Dec 19, 2018

@Ericson2314 I just removed the redundant chmod instruction. I also removed the WIP status from this pull request.

I will give people just a little while to provide their feedback. I think these changes can be integrated soon. We can always refine the infrastructure after we have integrated it if something appears to be missing.

@svanderburg svanderburg changed the title [WIP] Mobile updates Mobile updates Dec 19, 2018
@svanderburg
Copy link
Member Author

Since I have not received any further comments, I'm planning to integrate this PR tomorrow

@svanderburg svanderburg merged commit a27aa24 into NixOS:master Dec 24, 2018
@7c6f434c
Copy link
Member

Hm. It looks like adb per se has Apache2 source, and previously it was provided as a free package (while the SDK itself was unfree). I am trying to keep unfree stuff in a separately controlled user-owned package set and I want adb in a free and root-owned package set. Is it currently possible?

@nixos-discourse
Copy link

This pull request has been mentioned on Nix community. There might be relevant details there:

https://discourse.nixos.org/t/building-openwrt-with-nix-discuss-on-35c3/1777/2

@kirelagin
Copy link
Member

I’m not sure if it is this PR that changed it, but it looks like adb and other useful tools end up in libexec instead of bin in platform-tools, so they are no longer available on PATH.

Is this a bug, or is there some other recommended way of installing adb?

@bkchr
Copy link
Contributor

bkchr commented May 23, 2019

@svanderburg Did you ever tried the ndk-build? For me it is failing :( It seems to pick up the system ld.gold linker. Any ideas on how to fix this?

@Artturin
Copy link
Member

Artturin commented Sep 8, 2023

buildGradleApp was never readded

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/using-androidenv-error-functionargs-requires-a-function/32773/5

@Artturin
Copy link
Member

Artturin commented Sep 8, 2023

Readding in #254082

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.

None yet