xref: /aosp_15_r20/external/skia/toolchain/android_trampolines/gen_trampolines/gen_trampolines.go (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1// This file is copied from the SkCMS repository. Original file:
2// https://skia.googlesource.com/skcms/+/ba39d81f9797aa973bdf01aa6b0363b280352fba/toolchain/android_trampolines/gen_trampolines/gen_trampolines.go
3//
4// Helper program to generate trampoline scripts for NDK tools.
5//
6// This program is meant to be run by hand when making changes to the hermetic Android NDK
7// toolchain, e.g. when upgrading to a new Android NDK version.
8//
9// Trampoline scripts are necessary because the `cc_common.create_cc_toolchain_config_info`[1]
10// built-in Bazel function expects tool paths to point to files under the directory in which it is
11// invoked, thus we cannot directly reference tools under `external/ndk_linux_amd64`. The solution is
12// to use trampoline scripts that pass through any command-line arguments to the NDK binaries under
13// `external/android_sdk`.
14//
15// [1] https://bazel.build/rules/lib/cc_common#create_cc_toolchain_config_info
16package main
17
18import (
19	"errors"
20	"flag"
21	"fmt"
22	"os"
23	"path/filepath"
24)
25
26const bazelNdkPath = "external/ndk_linux_amd64"
27
28// Paths relative to the Android NDK root directory. These paths can be determined by inspecting
29// the Android NDK ZIP file downloaded by the `download_toolchains` macro defined in
30// //toolchains/download_toolchains.bzl.
31var tools = []string{
32	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar",
33	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-dwp",
34	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld",
35	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-nm",
36	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objcopy",
37	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump",
38	"toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip",
39	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar",
40	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-dwp",
41	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld",
42	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-nm",
43	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objcopy",
44	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump",
45	"toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip",
46	"toolchains/llvm/prebuilt/linux-x86_64/bin/clang",
47}
48
49const trampolineScriptTemplate = `#!/bin/sh
50# Copyright 2023 Google LLC
51#
52# Use of this source code is governed by a BSD-style license that can be
53# found in the LICENSE file.
54
55%s $@
56`
57
58func main() {
59	ndkDirFlag := flag.String("ndk-dir", "", "Path to a local copy of the NDK. Used only to verify that the tool paths assumed by this program are valid. Required.")
60	outDirFlag := flag.String("out-dir", "", "Directory where to save the trampoline scripts. Required.")
61	flag.Parse()
62
63	if *ndkDirFlag == "" || *outDirFlag == "" {
64		flag.Usage()
65		os.Exit(1)
66	}
67
68	for _, tool := range tools {
69		// Verify that the tool exists in the NDK.
70		ndkPath := filepath.Join(*ndkDirFlag, tool)
71		if _, err := os.Stat(ndkPath); errors.Is(err, os.ErrNotExist) {
72			fmt.Fprintf(os.Stderr, "File %s not found.", ndkPath)
73			os.Exit(1)
74		}
75
76		// Generate trampoline script.
77		trampolineScript := fmt.Sprintf(trampolineScriptTemplate, filepath.Join(bazelNdkPath, tool))
78		trampolineScriptPath := filepath.Join(*outDirFlag, filepath.Base(tool)+".sh")
79		if err := os.WriteFile(trampolineScriptPath, []byte(trampolineScript), 0750); err != nil {
80			fmt.Fprintf(os.Stderr, "Error writing file %s: %s", trampolineScriptPath, err)
81		}
82	}
83}
84