diff --git a/extensions.bzl b/extensions.bzl index 8e199f1..bbedebf 100644 --- a/extensions.bzl +++ b/extensions.bzl @@ -2,6 +2,8 @@ load(":rules.bzl", "android_ndk_repository", "android_ndk_toolchain") _toolchain = tag_class( attrs = { + "name": attr.string(default = "androidndk"), + "exec_system": attr.string(), "urls": attr.string_list_dict( doc = "URLs to download a prebuilt android ndk where the key is the system name (os_arch) and the value is a list of URLs.", ), @@ -47,44 +49,46 @@ def _get_local_system(mctx): def _impl(mctx): if len(mctx.modules) != 1 or not mctx.modules[0].is_root: - fail("androidsdk is currently only available for the root module") - - if len(mctx.modules[0].tags.toolchain) != 1: - fail("ndk.toolchain can only be set once") - - toolchain = mctx.modules[0].tags.toolchain[0] - - for system_name, urls in toolchain.urls.items(): - android_ndk_repository( - name = "androidndk_%s" % system_name, - api_level = toolchain.api_level, - urls = urls, - clang_resource_version = toolchain.clang_resource_version, - exec_system = system_name, - sha256 = toolchain.sha256[system_name] if system_name in toolchain.sha256 else "", - strip_prefix = toolchain.strip_prefix[system_name] if system_name in toolchain.strip_prefix else "", + fail("androidndk is currently only available for the root module") + + direct_deps = [] + + for toolchain in mctx.modules[0].tags.toolchain: + if toolchain.name in direct_deps: + fail("androidndk toolchain already defined with name %s" % toolchain.name) + + for system_name, urls in toolchain.urls.items(): + android_ndk_repository( + name = "%s_%s" % (toolchain.name, system_name), + api_level = toolchain.api_level, + urls = urls, + clang_resource_version = toolchain.clang_resource_version, + exec_system = system_name, + sha256 = toolchain.sha256[system_name] if system_name in toolchain.sha256 else "", + strip_prefix = toolchain.strip_prefix[system_name] if system_name in toolchain.strip_prefix else "", + ) + + local_system = _normalize(toolchain.exec_system if toolchain.exec_system else _get_local_system(mctx)) + + direct_deps.extend([toolchain.name] + ["%s_%s" % (toolchain.name, system_name) for system_name in toolchain.urls.keys()]) + exec_system_names = [_normalize(key) for key in toolchain.urls.keys()] + + if not (local_system in [_normalize(key) for key in toolchain.urls.keys()]): + android_ndk_repository( + name = "%s_%s" % (toolchain.name, local_system), + api_level = toolchain.api_level, + path = toolchain.path, + exec_system = local_system, + ) + + direct_deps.append("%s_%s" % (toolchain.name, local_system)) + exec_system_names.append(local_system) + + android_ndk_toolchain( + name = toolchain.name, + exec_system_names = exec_system_names, ) - local_system = _get_local_system(mctx) - - direct_deps = ["androidndk"] + ["androidndk_" + system_name for system_name in toolchain.urls.keys()] - exec_system_names = [_normalize(key) for key in toolchain.urls.keys()] - - if not (_normalize(local_system) in [_normalize(key) for key in toolchain.urls.keys()]): - android_ndk_repository( - name = "androidndk_local", - api_level = toolchain.api_level, - path = toolchain.path, - ) - - direct_deps.append("androidndk_local") - exec_system_names.append(_normalize(local_system)) - - android_ndk_toolchain( - name = "androidndk", - exec_system_names = exec_system_names, - ) - return mctx.extension_metadata( root_module_direct_deps = direct_deps, root_module_direct_dev_deps = [], diff --git a/rules.bzl b/rules.bzl index 77ae92e..dcc934e 100644 --- a/rules.bzl +++ b/rules.bzl @@ -16,7 +16,7 @@ def _get_clang_directory(rctx): exec_system = rctx.attr.exec_system - os_name, _ = (exec_system if exec_system else rctx.os.name).split("_", 1) + os_name = (exec_system.split("_", 1)[0] if exec_system else rctx.os.name) if os_name == "linux": clang_directory = "toolchains/llvm/prebuilt/linux-x86_64" elif os_name == "mac os x" or os_name == "darwin" or os_name == "macos": @@ -106,6 +106,9 @@ def _android_ndk_repository_impl(rctx): executable = False, ) +CLANG_FILES = ["lib", "prebuilt_include", "share", "bin", "include", "libexec", "musl", "python3"] +SYSROOT_FILES = ["usr"] + # Manually create a partial symlink tree of the NDK to avoid creating BUILD # files in the real NDK directory. def _create_symlinks(ctx, ndk_path, clang_directory, sysroot_directory): @@ -113,20 +116,13 @@ def _create_symlinks(ctx, ndk_path, clang_directory, sysroot_directory): if not ndk_path.endswith("/"): ndk_path = ndk_path + "/" - for p in ctx.path(ndk_path + clang_directory).readdir(): - repo_relative_path = str(p).replace(ndk_path, "") - - # Skip sysroot directory, since it gets its own BUILD file - if repo_relative_path != sysroot_directory: - ctx.symlink(p, repo_relative_path) + for p in CLANG_FILES: + ctx.symlink(ndk_path + clang_directory + "/" + p, clang_directory + "/" + p) - for p in ctx.path(ndk_path + sysroot_directory).readdir(): - repo_relative_path = str(p).replace(ndk_path, "") - ctx.symlink(p, repo_relative_path) + for p in SYSROOT_FILES: + ctx.symlink(ndk_path + sysroot_directory + "/" + p, sysroot_directory + "/" + p) ctx.symlink(ndk_path + "sources", "sources") - - # TODO(#32): Remove this hack ctx.symlink(ndk_path + "sources", "ndk/sources") android_ndk_repository = repository_rule( @@ -174,6 +170,5 @@ android_ndk_toolchain = repository_rule( "exec_system_names": attr.string_list(), "_template_target_systems": attr.label(default = ":target_systems.bzl.tpl", allow_single_file = True), "_template_ndk_toolchain": attr.label(default = ":BUILD.ndk_toolchain.tpl", allow_single_file = True), - "_template_ndk_module": attr.label(default = ":MODULE.ndk_toolchain.tpl", allow_single_file = True), }, )