kylemanna / docker-aosp

🏗 Minimal Android AOSP build environment with handy automation wrapper scripts
https://registry.hub.docker.com/u/kylemanna/aosp/
MIT License
507 stars 239 forks source link

Consider declaring environment variables to fix builds where java version is in transition #15

Closed hamiltont closed 7 years ago

hamiltont commented 7 years ago

Currently, the container tags (e.g. for 6.0) will fail on some 6.0 builds. Similarly, older versions (e.g. KK to Lollipop) will fail on some builds. This is caused by java version mismatch - When transitioning K to L to M, the AOSP team doesn't immediately switch to the new java version. For example, Android M 6.0.0_r26 builds with Java 7 by default, while M 6.0.1_r26 builds with Java 8 by default.

These 'in transition' builds allow you to try and build with the newer build system by setting environment variables that are picked up by build/core/main.mk e.g.

# Check for the correct version of java, should be 1.7 by
# default, and 1.8 if EXPERIMENTAL_USE_JAVA8 is set
ifneq ($(EXPERIMENTAL_USE_JAVA8),)
required_version := "1.8.x"
required_javac_version := "1.8"
java_version := $(shell echo '$(java_version_str)' | grep 'openjdk .*[ "]1\.8[\. "$$]')
javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.8[\. "$$]')
else # default
required_version := "1.7.x"
required_javac_version := "1.7"
java_version := $(shell echo '$(java_version_str)' | grep '^java .*[ "]1\.7[\. "$$]')
javac_version := $(shell echo '$(javac_version_str)' | grep '[ "]1\.7[\. "$$]')
endif # if EXPERIMENTAL_USE_JAVA8

The only two variables they have ever used for this purpose are LEGACY_USE_JAVA6 and EXPERIMENTAL_USE_JAVA8

There are basically two ways to fix this - either set some environment variables in the currently-failing images that cause the build system to pick up the java version you have installed and give it a try (e.g. for 6.0 container set EXPERIMENTAL_USE_JAVA8=true so in transition builds pick this up), or add some documentation to the README about this issue and let users know that errors of this sort are probably caused by this and they should just try a different container:

============================================
Checking build tools versions...
************************************************************
You are attempting to build with the incorrect version
of java.

Your version is: openjdk version "1.8.0_111" OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14) OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode).
The required version is: "1.7.x"

Please follow the machine setup instructions at
    https://source.android.com/source/initializing.html
************************************************************
build/core/main.mk:171: *** stop.  Stop.
make: Leaving directory '/aosp'
kylemanna commented 7 years ago

Interesting, and frustrating to maintain a matrix of what builds with what across minor releases.

In theory, using Docker means that we can safely avoid transitional and legacy build options as we can create variations of the container to support whatever the default is.

Another option might be to include both java versions and provide a wrapper or documentation on how to switch the system default assuming no major release will have more then 2 possible java versions.

Thoughts?

hamiltont commented 7 years ago

In general, I think small simple containers and more container tags is the right solution e.g. having tags like 6.0-java7 in addition to the current 6.0 tags. Then add a tiny blurb to the readme about why you would want to use these "different java version" containers.

In risk of being overly general, I'll say that for a number of containers I've encountered, putting scripts inside the container (even with highly customizable env vars) tends to make the overall result less flexible because those env vars are combined in one specific manner, which makes the overall image less flexible. It's also quite a bit of work to dig into how someone's specific script could be tweaked/image rebuilt/tricked with env vars to do exactly what I want. So, mainly for flexibility and simplicity, I prefer a container that does one thing really well without too many options, and providing any helper scripts externally for more complex setups (e.g. build-lollipop runs your image in one particular way. I've just had some luck modifying that script to run in it a way I want - allowing partial builds inside the container instead of only full builds. This is because the container is simple. ~For the later images, you added an ENTRYPOINT and some helper script inside the container, and now I cannot override those in the same way. (Not being critical, just pointing out an example of what I mean)~ Edit: Turns out there is now a new (to me) --entrypoint flag that addresses this concern

Side note: 6.0.0_r27 will not compile with java8, so google is not just BSing with these 'default java version' things, they really have not finished the transition yet.

kylemanna commented 7 years ago

I think that individual developers are going to have to pick their AOSP_IMAGE for their build. Trying to figure out all the permutations for each and every build sounds like a waste of time. The tests are just that -- tests. Should be considered a reference implementation for people to use as a template for the real builds.

If someone wants to propose and potentially implement a way to figure out all the permutations, lets chat.