rules_android_ndk icon indicating copy to clipboard operation
rules_android_ndk copied to clipboard

Proposal to change `tools` to have absolute paths

Open widiba03304 opened this issue 11 months ago • 3 comments

Hi, I am building low-level software with this repository, and I found some problems here.

Some binaries do not return absolute paths

This can be problematic when some bazel rules use cc_common.get_tool_for_action and execute them. This is a use case that compiles a C code into an object and objcopy the content.

def _gen_c_bin_impl(ctx):
    """
    A rule that compiles C sources into an object, then extracts the .text section into a .bin file using objcopy.
    """
    toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]

    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )

    _, compilation_outputs = cc_common.compile(
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = toolchain,
        name = ctx.label.name,
        srcs = ctx.files.srcs,
        public_hdrs = ctx.files.hdrs,
    )

    object_files = compilation_outputs.objects + compilation_outputs.pic_objects
    if len(object_files) == 0:
        fail("No object files produced from srcs = %s" % (ctx.files.srcs))
    object_file = object_files[0]

    bin_file = ctx.actions.declare_file(ctx.label.name + ".bin")

    objcopy_tool = cc_common.get_tool_for_action(
        feature_configuration = feature_configuration,
        action_name = "objcopy_embed_data",
    )
    if objcopy_tool == None:
        fail("The C/C++ toolchain does not provide an objcopy tool.")

    ctx.actions.run_shell(
        inputs = [object_file],
        outputs = [bin_file],
        command = """
            '{objcopy}' --only-section=.text -O binary '{in_o}' '{out_bin}'
        """.format(
            objcopy = objcopy_tool,
            in_o = object_file.path,
            out_bin = bin_file.path,
        ),
        mnemonic = "Objcopy",
        progress_message = "Extracting .text section from %s" % (object_file.path),
    )

    return [
        DefaultInfo(
            files = depset([bin_file]),
        ),
    ]

widiba03304 avatar Jan 24 '25 07:01 widiba03304

What exactly is the failure that you see? Providing a self-contained repro example would be helpful here. Otherwise we can only guess how you've set up your build.

ted-xie avatar Jan 24 '25 14:01 ted-xie

Sorry for the incomplete issue, I'll give you the specific error message when I get back to this because I'm in middle of something.

The primary reason was the executables are set to have relative paths like "bin/objcopy" but the rule I made executes in the wrong directory, which is the sandboxed workspace where run_shell runs. So I modified overall code to propagate the "ndk_path" value to the toolchain configurations and prepend it to "bin/..."s, so that I can get "{ndk_path}/toolchains/llvm/prebuilt/bin/..." when I call "get_tool_for_action".

I'll make the PR when I am ready. There might be some drawbacks in this way as some hard coded paths lies in the prepended string like "toolchains/llvm/prebuilt".

Thanks for the reply!

widiba03304 avatar Jan 24 '25 17:01 widiba03304

By the way, I also found that the rules automatically add the flag "-ffunction-section" and other bunches of flags when compiling by default. Is this on purpose to reduce the binary size without certain considerations for common users? I expected for these rules to behave like the other toolchains, but it was not.

widiba03304 avatar Jan 24 '25 17:01 widiba03304