xref: /aosp_15_r20/external/skia/toolchain/ndk_linux_arm64_toolchain_config.bzl (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1"""
2This file is copied from the SkCMS repository. Original file:
3https://skia.googlesource.com/skcms/+/ba39d81f9797aa973bdf01aa6b0363b280352fba/toolchain/ndk_linux_arm64_toolchain_config.bzl
4
5This module defines the ndk_cc_toolchain_config rule.
6
7This file is based on the `external/androidndk/cc_toolchain_config.bzl` file produced by the
8built-in `android_ndk_repository` Bazel rule[1], which was used to build the SkCMS repository up
9until this revision[2].
10
11The paths in this file point to locations inside the expanded Android NDK ZIP file (found at
12external/ndk_linux_amd64), and must be updated every time we upgrade to a new Android NDK version.
13
14[1] https://github.com/bazelbuild/bazel/blob/4710ef82ce34572878e07c52e83a0144d707f140/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java#L422
15[2] https://skia.googlesource.com/skcms/+/30c8e303800c256febb03a09fdcda7f75d119b1b/WORKSPACE#22
16"""
17
18load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
19load(
20    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
21    "feature",
22    "flag_group",
23    "flag_set",
24    "tool_path",
25    "with_feature_set",
26)
27load(":download_ndk_linux_amd64_toolchain.bzl", "NDK_PATH")
28
29# Supported CPUs.
30_ARMEABI_V7A = "armeabi-v7a"
31_ARM64_V8A = "arm64-v8a"
32
33_all_compile_actions = [
34    ACTION_NAMES.c_compile,
35    ACTION_NAMES.cpp_compile,
36    ACTION_NAMES.linkstamp_compile,
37    ACTION_NAMES.assemble,
38    ACTION_NAMES.preprocess_assemble,
39    ACTION_NAMES.cpp_header_parsing,
40    ACTION_NAMES.cpp_module_compile,
41    ACTION_NAMES.cpp_module_codegen,
42    ACTION_NAMES.clif_match,
43    ACTION_NAMES.lto_backend,
44]
45
46_all_link_actions = [
47    ACTION_NAMES.cpp_link_executable,
48    ACTION_NAMES.cpp_link_dynamic_library,
49    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
50]
51
52def _get_default_compile_flags(cpu):
53    if cpu == _ARMEABI_V7A:
54        return [
55            "-D__ANDROID_API__=29",
56            "-isystem",
57            NDK_PATH + "/sysroot/usr/include/arm-linux-androideabi",
58            "-target",
59            "armv7-none-linux-androideabi",
60            "-march=armv7-a",
61            "-mfloat-abi=softfp",
62            "-mfpu=vfpv3-d16",
63            "-gcc-toolchain",
64            NDK_PATH + "/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64",
65            "-fpic",
66            "-no-canonical-prefixes",
67            "-Wno-invalid-command-line-argument",
68            "-Wno-unused-command-line-argument",
69            "-funwind-tables",
70            "-fstack-protector-strong",
71            "-fno-addrsig",
72        ]
73    if cpu == _ARM64_V8A:
74        return [
75            "-gcc-toolchain",
76            NDK_PATH + "/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64",
77            "-target",
78            "aarch64-none-linux-android",
79            "-fpic",
80            "-isystem",
81            NDK_PATH + "/sysroot/usr/include/aarch64-linux-android",
82            "-D__ANDROID_API__=29",
83            "-no-canonical-prefixes",
84            "-Wno-invalid-command-line-argument",
85            "-Wno-unused-command-line-argument",
86            "-funwind-tables",
87            "-fstack-protector-strong",
88            "-fno-addrsig",
89        ]
90    fail("Unknown CPU: " + cpu)
91
92def _get_default_link_flags(cpu):
93    if cpu == _ARMEABI_V7A:
94        return [
95            "-target",
96            "armv7-none-linux-androideabi",
97            "-gcc-toolchain",
98            NDK_PATH + "/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64",
99            "-L",
100            NDK_PATH + "/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a",
101            "-no-canonical-prefixes",
102            "-Wl,-z,relro",
103            "-lm",
104        ]
105    if cpu == _ARM64_V8A:
106        return [
107            "-gcc-toolchain",
108            NDK_PATH + "/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64",
109            "-target",
110            "aarch64-none-linux-android",
111            "-L",
112            NDK_PATH + "/sources/cxx-stl/llvm-libc++/libs/arm64-v8a",
113            "-no-canonical-prefixes",
114            "-Wl,-z,relro",
115            "-lm",
116        ]
117    fail("Unknown CPU: " + cpu)
118
119def _get_default_dbg_flags(cpu):
120    if cpu == _ARMEABI_V7A:
121        return ["-g", "-fno-strict-aliasing", "-O0", "-UNDEBUG"]
122    if cpu == _ARM64_V8A:
123        return ["-O0", "-g", "-UNDEBUG"]
124    fail("Unknown CPU: " + cpu)
125
126def _get_default_opt_flags(cpu):
127    if cpu == _ARMEABI_V7A:
128        return ["-mthumb", "-Os", "-g", "-DNDEBUG"]
129    if cpu == _ARM64_V8A:
130        return ["-O2", "-g", "-DNDEBUG"]
131    fail("Unknown CPU: " + cpu)
132
133def _get_toolchain_identifier(cpu):
134    if cpu == _ARMEABI_V7A:
135        return "ndk-armeabi-v7a-toolchain"
136    if cpu == _ARM64_V8A:
137        return "ndk-arm64-v8a-toolchain"
138    fail("Unknown CPU: " + cpu)
139
140def _get_target_system_name(cpu):
141    if cpu == _ARMEABI_V7A:
142        return "arm-linux-androideabi"
143    if cpu == _ARM64_V8A:
144        return "aarch64-linux-android"
145    fail("Unknown CPU: " + cpu)
146
147def _get_builtin_sysroot(cpu):
148    if cpu == _ARMEABI_V7A:
149        return NDK_PATH + "/platforms/android-29/arch-arm"
150    if cpu == _ARM64_V8A:
151        return NDK_PATH + "/platforms/android-29/arch-arm64"
152    fail("Unknown CPU: " + cpu)
153
154def _get_tool_paths(cpu):
155    # The cc_common.create_cc_toolchain_config_info function expects tool paths to point to files
156    # under the directory in which it is invoked. This means we cannot directly reference tools
157    # under external/android_ndk. The solution is to use "trampoline" scripts that pass through
158    # any command-line arguments to the NDK binaries under external/android_sdk.
159
160    if cpu == _ARMEABI_V7A:
161        return [
162            tool_path(
163                name = "ar",
164                path = "android_trampolines/arm-linux-androideabi-ar.sh",
165            ),
166            tool_path(
167                name = "cpp",
168                path = "android_trampolines/clang.sh",
169            ),
170            tool_path(
171                name = "dwp",
172                path = "android_trampolines/arm-linux-androideabi-dwp.sh",
173            ),
174            tool_path(
175                name = "gcc",
176                path = "android_trampolines/clang.sh",
177            ),
178            tool_path(
179                name = "gcov",
180                path = "/bin/false",
181            ),
182            tool_path(
183                name = "ld",
184                path = "android_trampolines/arm-linux-androideabi-ld.sh",
185            ),
186            tool_path(
187                name = "nm",
188                path = "android_trampolines/arm-linux-androideabi-nm.sh",
189            ),
190            tool_path(
191                name = "objcopy",
192                path = "android_trampolines/arm-linux-androideabi-objcopy.sh",
193            ),
194            tool_path(
195                name = "objdump",
196                path = "android_trampolines/arm-linux-androideabi-objdump.sh",
197            ),
198            tool_path(
199                name = "strip",
200                path = "android_trampolines/arm-linux-androideabi-strip.sh",
201            ),
202        ]
203    if cpu == _ARM64_V8A:
204        return [
205            tool_path(
206                name = "ar",
207                path = "android_trampolines/aarch64-linux-android-ar.sh",
208            ),
209            tool_path(
210                name = "cpp",
211                path = "android_trampolines/clang.sh",
212            ),
213            tool_path(
214                name = "dwp",
215                path = "android_trampolines/aarch64-linux-android-dwp.sh",
216            ),
217            tool_path(
218                name = "gcc",
219                path = "android_trampolines/clang.sh",
220            ),
221            tool_path(
222                name = "gcov",
223                path = "/bin/false",
224            ),
225            tool_path(
226                name = "ld",
227                path = "android_trampolines/aarch64-linux-android-ld.sh",
228            ),
229            tool_path(
230                name = "nm",
231                path = "android_trampolines/aarch64-linux-android-nm.sh",
232            ),
233            tool_path(
234                name = "objcopy",
235                path = "android_trampolines/aarch64-linux-android-objcopy.sh",
236            ),
237            tool_path(
238                name = "objdump",
239                path = "android_trampolines/aarch64-linux-android-objdump.sh",
240            ),
241            tool_path(
242                name = "strip",
243                path = "android_trampolines/aarch64-linux-android-strip.sh",
244            ),
245        ]
246    fail("Unknown CPU: " + cpu)
247
248def _ndk_cc_toolchain_config_impl(ctx):
249    default_compile_flags = _get_default_compile_flags(ctx.attr.cpu)
250    unfiltered_compile_flags = [
251        "-isystem",
252        NDK_PATH + "/sources/cxx-stl/llvm-libc++/include",
253        "-isystem",
254        NDK_PATH + "/sources/cxx-stl/llvm-libc++abi/include",
255        "-isystem",
256        NDK_PATH + "/sources/android/support/include",
257        "-isystem",
258        NDK_PATH + "/sysroot/usr/include",
259    ]
260    default_link_flags = _get_default_link_flags(ctx.attr.cpu)
261    default_fastbuild_flags = [""]
262    default_dbg_flags = _get_default_dbg_flags(ctx.attr.cpu)
263    default_opt_flags = _get_default_opt_flags(ctx.attr.cpu)
264
265    opt_feature = feature(name = "opt")
266    fastbuild_feature = feature(name = "fastbuild")
267    dbg_feature = feature(name = "dbg")
268    supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True)
269    supports_pic_feature = feature(name = "supports_pic", enabled = True)
270    static_link_cpp_runtimes_feature = feature(name = "static_link_cpp_runtimes", enabled = True)
271
272    default_compile_flags_feature = feature(
273        name = "default_compile_flags",
274        enabled = True,
275        flag_sets = [
276            flag_set(
277                actions = _all_compile_actions,
278                flag_groups = [flag_group(flags = default_compile_flags)],
279            ),
280            flag_set(
281                actions = _all_compile_actions,
282                flag_groups = [flag_group(flags = default_fastbuild_flags)],
283                with_features = [with_feature_set(features = ["fastbuild"])],
284            ),
285            flag_set(
286                actions = _all_compile_actions,
287                flag_groups = [flag_group(flags = default_dbg_flags)],
288                with_features = [with_feature_set(features = ["dbg"])],
289            ),
290            flag_set(
291                actions = _all_compile_actions,
292                flag_groups = [flag_group(flags = default_opt_flags)],
293                with_features = [with_feature_set(features = ["opt"])],
294            ),
295            flag_set(
296                actions = [ACTION_NAMES.cpp_compile],
297                flag_groups = [flag_group(flags = ["-std=c++17"])],
298            ),
299        ],
300    )
301
302    default_link_flags_feature = feature(
303        name = "default_link_flags",
304        enabled = True,
305        flag_sets = [
306            flag_set(
307                actions = _all_link_actions,
308                flag_groups = [flag_group(flags = default_link_flags)],
309            ),
310        ],
311    )
312
313    user_compile_flags_feature = feature(
314        name = "user_compile_flags",
315        enabled = True,
316        flag_sets = [
317            flag_set(
318                actions = _all_compile_actions,
319                flag_groups = [
320                    flag_group(
321                        flags = ["%{user_compile_flags}"],
322                        iterate_over = "user_compile_flags",
323                        expand_if_available = "user_compile_flags",
324                    ),
325                ],
326            ),
327        ],
328    )
329
330    sysroot_feature = feature(
331        name = "sysroot",
332        enabled = True,
333        flag_sets = [
334            flag_set(
335                actions = _all_compile_actions + _all_link_actions,
336                flag_groups = [
337                    flag_group(
338                        flags = ["--sysroot=%{sysroot}"],
339                        expand_if_available = "sysroot",
340                    ),
341                ],
342            ),
343        ],
344    )
345
346    unfiltered_compile_flags_feature = feature(
347        name = "unfiltered_compile_flags",
348        enabled = True,
349        flag_sets = [
350            flag_set(
351                actions = _all_compile_actions,
352                flag_groups = [flag_group(flags = unfiltered_compile_flags)],
353            ),
354        ],
355    )
356
357    features = [
358        default_compile_flags_feature,
359        default_link_flags_feature,
360        supports_dynamic_linker_feature,
361        supports_pic_feature,
362        static_link_cpp_runtimes_feature,
363        fastbuild_feature,
364        dbg_feature,
365        opt_feature,
366        user_compile_flags_feature,
367        sysroot_feature,
368        unfiltered_compile_flags_feature,
369    ]
370
371    cxx_builtin_include_directories = [
372        NDK_PATH + "/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.9/include",
373        "%sysroot%/usr/include",
374        NDK_PATH + "/sysroot/usr/include",
375    ]
376
377    # https://bazel.build/rules/lib/cc_common#create_cc_toolchain_config_info
378    return cc_common.create_cc_toolchain_config_info(
379        ctx = ctx,
380        toolchain_identifier = _get_toolchain_identifier(ctx.attr.cpu),
381        host_system_name = "local",
382        target_system_name = _get_target_system_name(ctx.attr.cpu),
383        target_cpu = ctx.attr.cpu,
384        target_libc = "local",
385        compiler = "clang9.0.9",
386        abi_version = ctx.attr.cpu,
387        abi_libc_version = "local",
388        features = features,
389        tool_paths = _get_tool_paths(ctx.attr.cpu),
390        cxx_builtin_include_directories = cxx_builtin_include_directories,
391        builtin_sysroot = _get_builtin_sysroot(ctx.attr.cpu),
392    )
393
394ndk_cc_toolchain_config = rule(
395    implementation = _ndk_cc_toolchain_config_impl,
396    attrs = {
397        "cpu": attr.string(
398            mandatory = True,
399            values = [_ARMEABI_V7A, _ARM64_V8A],
400            doc = "Target CPU.",
401        ),
402    },
403    provides = [CcToolchainConfigInfo],
404)
405