bazelembedded / bazel-embedded

Tools for embedded/bare-metal development using bazel
https://www.nb.rough.run/tags/bazel/
MIT License
103 stars 31 forks source link

Objcopy executable path not found? #58

Closed gbalke closed 2 years ago

gbalke commented 2 years ago

I've been trying to use objcopy from the existing toolchains generated through this system. I'm a bit surprised to see that the path for objcopy is just empty... Am I doing something wrong? I want to create a simple rule to make a binary from the generated elf... Would love alternate suggestions:

def _impl(ctx):                           
    toolchain = find_cc_toolchain(ctx)    
    print(toolchain.cc.objdump_executable)
    print(toolchain.cc.objcopy_executable)

gen_binary = rule(                                   
    implementation = _impl,                          
    toolchains = [                                   
    ·   "@rules_cc//cc:toolchain_type",              
    ],                                               
    attrs = {                                        
    ·   "_cc_toolchain": attr.label(                 
    ·   ·   default = Label(                         
    ·   ·   ·   "@rules_cc//cc:current_cc_toolchain",
    ·   ·   ),                                       
    ·   ),                                           
    ·   "src": attr.label(allow_single_file = True), 
    },                                               
    outputs = {                                      
    ·   "elf": "%{name}.elf",                        
    ·   "bin": "%{name}.bin",                        
    },                                               
)                                                    

With the command:

bazel build //bootloader --platforms=@bazel_embedded//platforms:cortex_m4_fpu

and I get the following:

DEBUG: /.../project/toolchains/platforms.bzl:29:10: external/bazel_embedded/toolchains/gcc_arm_none_eabi/gcc_wrappers/nix/objdump
DEBUG: /.../project/toolchains/platforms.bzl:30:10:  <--- This is the objcopy print statement
nathaniel-brough commented 2 years ago

Hmm, I mustn't have defined the path for objcopy. So this is definitely a bug. However, I'd recommend using this workaround for now.

Here is how I use bazel-embedded to generate separate elfs/binaries.

The way that I do things is just to use the elf, or if I need the raw binary I just use the stripped target e.g. If I have the following build definition;

cc_binary(
    name = "main",
    srcs = ["main.cc"],
)

To get the elf file I run something like this (it won't have the .elf extension unless you name the cc_binary 'main.elf'); bazel build //:main --platforms=@bazel_embedded//platforms:cortex_m4_fpu

However, if I want the binary file I use the stripped sub-target which is configured to strip all ELF sections leaving the binary e.g.

bazel build //:main.stripped --platforms=@bazel_embedded//platforms:cortex_m4_fpu

You can use strip or objcopy to achieve the same result in this case.

gbalke commented 2 years ago

I think the main concern is keeping the build and debug symbols in the same step. If the binary is generated in a separate build step than the elf, there may be issues when going to debug via gdb. I'd rather have this copy step. I think fixing the definition here is probably the right way to do it. I'll see if I can submit a fix.

nathaniel-brough commented 2 years ago

Yeah technically they are preserved e.g. it already looks like elf->stripped. So if you go elf(with embedded debug dwarf section)->stripped it'll still produce the same binary minus the elf headers and dwarf sections. But in any case that PR looks fine, and is fixing what I would consider a bug.