PathInterposer

Warnings

This page is a work in progress, so it might contains mistakes, inaccuracies, etc.

Introduction

Sometimes we need to use host tools for building Replicant.

This has several consequences:

Ideally we could make Replicant build most of the tools we need in a reproducible way to not use the host tools without having to trust prebuilt binaries, but this is not always practical as doing that could take a lot of time. In addition we do need tools to build replacement tools in the first place.

In any case when using tools from the host distribution, it's a really good idea to not hardcode the path of the tool (like /usr/bin/python) and instead make sure that the host distribution PATH is used instead.

This has several advantages:

This article shows how to use host tools in a way that makes use of the host PATH and also how Android implements (with PathInterposer) the isolation between the tools provided by the host distribution and Android.

how it works

During the build:

With Trisquel 8, and Replicant 11, here's an example of how the path looks like for applications being launched through the path interposer1:

/home/replicant/replicant-11/prebuilts/jdk/jdk11/linux-x86/bin
/home/replicant/replicant-11/prebuilts/jdk/jdk11/linux-x86/bin
/home/replicant/replicant-11/out/soong/host/linux-x86/bin
/home/replicant/replicant-11/out/host/linux-x86/bin
/home/replicant/replicant-11/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin
/home/replicant/replicant-11/development/scripts
/home/replicant/replicant-11/prebuilts/devtools/tools
/home/replicant/replicant-11/external/selinux/prebuilts/bin
/home/replicant/replicant-11/prebuilts/misc/linux-x86/dtc
/home/replicant/replicant-11/prebuilts/misc/linux-x86/libufdt
/home/replicant/replicant-11/prebuilts/clang/host/linux-x86/llvm-binutils-stable
/home/replicant/replicant-11/prebuilts/android-emulator/linux-x86_64
/home/replicant/replicant-11/prebuilts/asuite/acloud/linux-x86
/home/replicant/replicant-11/prebuilts/asuite/aidegen/linux-x86
/home/replicant/replicant-11/prebuilts/asuite/atest/linux-x86
/home/replicant/bin
/home/replicant/.local/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games

Here we can deduce that the paths set by the Android build system take precedence over the host paths.

1 This has been deduced by prints with the following patch:

--- a/cmd/path_interposer/main.go
+++ b/cmd/path_interposer/main.go
@@ -116,6 +116,10 @@ func Main(stdout, stderr io.Writer, interposer string, args []string, opts mainO
                return 1, fmt.Errorf("Failed to set PATH env: %v", err)
        }

+       fmt.Fprintln(os.Stderr, "####################################")
+       fmt.Fprintln(os.Stderr, os.Getenv("PATH"))
+       fmt.Fprintln(os.Stderr, "####################################")
+
        if config := opts.config(base); config.Log || config.Error {
                var procs []paths.LogProcess
                if opts.lookupParents != nil {

Launching host binaries without touching the prebuilts

In Replicant 10, we could use out/.path/python3 as python3 interpreter assuming that we enabled it in build/soong/ui/build/paths/config.go

for instance in the Mesa (external/mesa3d) Android.mk we had:

MESA_PYTHON2 := out/.path/python2
MESA_PYTHON3 := out/.path/python3

This worked because 'python2' and 'python3' were only available in the host path:

$ for path in $(echo /home/replicant/replicant-10/prebuilts/jdk/jdk9/linux-x86/bin:/home/replicant/replicant-10/prebuilts/jdk/jdk9/linux-x86/bin:/home/replicant/replicant-10/out/soong/host/linux-x86/bin:/home/replicant/replicant-10/out/host/linux-x86/bin:/home/replicant/replicant-10/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin:/home/replicant/replicant-10/development/scripts:/home/replicant/replicant-10/prebuilts/devtools/tools:/home/replicant/replicant-10/external/selinux/prebuilts/bin:/home/replicant/replicant-10/prebuilts/misc/linux-x86/dtc:/home/replicant/replicant-10/prebuilts/misc/linux-x86/libufdt:/home/replicant/replicant-10/prebuilts/android-emulator/linux-x86_64:/home/replicant/replicant-10/prebuilts/asuite/acloud/linux-x86:/home/replicant/replicant-10/prebuilts/asuite/aidegen/linux-x86:/home/replicant/replicant-10/prebuilts/asuite/atest/linux-x86:/home/replicant/bin:/home/replicant/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games | sed 's#:#\n#g') ; do ls "${path}/python3" ; done
ls: cannot access '/home/replicant/replicant-10/prebuilts/jdk/jdk9/linux-x86/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/jdk/jdk9/linux-x86/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/out/soong/host/linux-x86/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/out/host/linux-x86/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/development/scripts/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/devtools/tools/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/external/selinux/prebuilts/bin/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/misc/linux-x86/dtc/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/misc/linux-x86/libufdt/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/android-emulator/linux-x86_64/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/asuite/acloud/linux-x86/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/asuite/aidegen/linux-x86/python3': No such file or directory
ls: cannot access '/home/replicant/replicant-10/prebuilts/asuite/atest/linux-x86/python3': No such file or directory
ls: cannot access '/home/replicant/bin/python3': No such file or directory
ls: cannot access '/home/replicant/.local/bin/python3': No such file or directory
ls: cannot access '/usr/local/sbin/python3': No such file or directory
ls: cannot access '/usr/local/bin/python3': No such file or directory
ls: cannot access '/usr/sbin/python3': No such file or directory
/usr/bin/python3
ls: cannot access '/sbin/python3': No such file or directory
ls: cannot access '/bin/python3': No such file or directory
ls: cannot access '/usr/games/python3': No such file or directory

For instance prebuilts/python/linux-x86/2.7.5/bin/python wasn't in the path.