eclipse-cdt / cdt

Eclipse CDT™ C/C++ Development Tools
http://eclipse.org/cdt
Eclipse Public License 2.0
299 stars 197 forks source link

Support invoking objdump on binary files for 'MinGW GCC' and 'Cross GCC' toolchains #361

Closed jld01 closed 1 year ago

jld01 commented 1 year ago

When building CDT projects using a native Linux GCC or Cygwin GCC toolchain, the user can double click on the resulting binary file to invoke objdump and present the resulting output in a read-only editor part. It would be beneficial to provide equivalent behaviour when using MinGW GCC toolchains and Cross GCC toolchains.

For Linux GCC, this capability is implemented via the DefaultGnuToolFactory and CDT expects to find objdump on the global PATH.

A few issues:

jantje commented 1 year ago

my 2 cent

It is much less common for GNU tools to be located on the global PATH on Windows hosts or when using a cross compiler. We need a mechanism to lookup the project containing the binary file and from there lookup the per-project PATH.

You are probably aware but to be sure: The current MBS allows to extend the path environment variable in the settings. afbeelding

In Arduino world cross GCC, MinGW, MVC are called tool providers. These tool providers have a "tool path" property. All commands are executed with FQN (in MBS talk ${provider tool path including /}${COMMAND}). An environment variable provider can provide a value for the variable "provider tool path including /".

I have had no luck with the path extension used by MBS. I like the FQN approach.

jld01 commented 1 year ago

Thank you for your input, @jantje.

Ideally we should accommodate both MBS and non-MBS projects, both with or without a tool prefix. The IGnuToolFactory implementation could look up a provider of PATH and tool prefix information for a certain binary file path. There would need to be a more-specialized provider for the case of an MBS Cross GCC toolchain project that understood the MBS IOption providing the prefix string. It seems that a common provider could be used for most other CDT projects (both MBS and non-MBS).

Torbjorn-Svensson commented 1 year ago
* It is much less common for GNU tools to be located on the global `PATH` on Windows hosts or when using a cross compiler. We need a mechanism to lookup the project containing the binary file and from there lookup the per-project `PATH`.

I don't think "per-project" will do here as there might be more than one toolchain used within one CDT project. In embedded, it's not uncommon to have one build configuration per target permutation. It's also fairly common that you have some unit tests that might be executed on the developer system rather than on the target (PC toolchain instead of an embedded one). In this scenario, at least 2 different objdump instances needs to be pointed out for the single CDT project.

jld01 commented 1 year ago

I don't think "per-project" will do here...

Totally agree, @Torbjorn-Svensson. I have found a way to lookup an ICConfigurationDescription object and hence the per-configuration environment from DefaultGnuToolFactory. From here, I should be able to adapt to something with knowledge of the MBS cross toolchain that can return a toolchain prefix for a specified build configuration.

Torbjorn-Svensson commented 1 year ago

I don't think "per-project" will do here...

Totally agree, @Torbjorn-Svensson. I have found a way to lookup an ICConfigurationDescription object and hence the per-configuration environment from DefaultGnuToolFactory. From here, I should be able to adapt to something with knowledge of the MBS cross toolchain that can return a toolchain prefix for a specified build configuration.

Is there/Will there be any easy way for downstream to override how the path and prefix should be collected for a custom toolchain definition? It would be a bit sad to put in all this effort to support a few more toolchain definitions without having a generic way to allow downstream to hook in their custom logic to determine the right value for the 2 properties in their use-case.

jld01 commented 1 year ago

Is there/Will there be any easy way for downstream to override how the path and prefix should be collected for a custom toolchain definition?

Yes, I'm working on an optional CDT build variable to provide the GNU tool prefix so that:

jld01 commented 1 year ago

Is there/Will there be any easy way for downstream to override how the path and prefix should be collected for a custom toolchain definition?

@Torbjorn-Svensson does #368 address your concerns? Extenders at the org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point will be able to use an IConfigurationBuildMacroSupplier to provide an IBuildMacro named gnu_tool_prefix. For many such extensions, a String literal value for the macro (eg arm-none-eabi-) will be sufficient.

Torbjorn-Svensson commented 1 year ago

@Torbjorn-Svensson does #368 address your concerns? Extenders at the org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point will be able to use an IConfigurationBuildMacroSupplier to provide an IBuildMacro named gnu_tool_prefix. For many such extensions, a String literal value for the macro (eg arm-none-eabi-) will be sufficient.

I took a look at the PR and overall, it looks good. There were a few small questions/suggestions. Let's handle them in the PR and I'm sure we will get a solution that will be extendable for downstream vendors.

jld01 commented 1 year ago

The initial objectives described in this issue are now met. I will work on a New & Noteworthy entry.

There is an outstanding item for discussion. Namely, a mechanism for updating the binary parser selection for existing MinGW GCC and Cross GCC projects:

baoruiqi commented 1 year ago

@jld01 Thanks for your effort, this is a very useful feature! Based on this, I have a question.

I downloaded the latest Embedded IDE from Eclipse's website, created a C managed project and selected the riscv-cross toolchain. In the project properties, I set the local toolchain path, and the binary file of the risc-v architecture can be successfully generated after the build.

However, when I double-click the elf file, the editor view only shows the header information, and there is no disassembly content.

image

Usually the disassembly is obtained through the objdump tool related to the toolchain, passing the -d parameter. However, the binary parser tab in the project configuration interface provided by CDT does not provide relevant parameter configuration entries.

If I want to double-click the binary file and display the disassembly, do I need to modify the cdt?

Below is my IDE info:

Eclipse IDE for Embedded C/C++ Developers (includes Incubating components)
Version: 2023-06 M2 (4.28.0 M2)
Build id: 20230504-1428
OS: Linux, v.5.19.0-40-generic, x86_64 / gtk 3.24.33, WebKit 2.38.6
Java vendor: Eclipse Adoptium
Java runtime version: 17.0.7+7
Java version: 17.0.7
jld01 commented 1 year ago

@baoruiqi, the architecture: UNKNOWN! output suggests that you are invoking a native objdump that exists somewhere on your PATH.

When using the Embedded CDT toolchain descriptions, you will need to define your own CDT Build Variable within the project properties dialog to specify the GNU tool prefix for the timebeing:

Name: gnu_tool_prefix Type: String Value: riscv64-unknown-elf-

Modify the value to suit your toolchain and be sure to include the trailing hyphen.

baoruiqi commented 1 year ago

@baoruiqi, the architecture: UNKNOWN! output suggests that you are invoking a native objdump that exists somewhere on your PATH.

When using the Embedded CDT toolchain descriptions, you will need to define your own CDT Build Variable within the project properties dialog to specify the GNU tool prefix for the timebeing:

Name: gnu_tool_prefix Type: String Value: riscv64-unknown-elf-

Modify the value to suit your toolchain and be sure to include the trailing hyphen.

I have previously configured the toolchain path on the property page of the project.

As you said, the header information is indeed generated by the native objdump in the PATH, so why doesn't eclipse use the tools in the riscv toolchain? If I hadn't configure the toolchain correctly, the project wouldn't be built correctly, but the fact is that the project was built successfully and generate the correct risc-v elf.

image

baoruiqi commented 1 year ago

@jld01 I found the reason for the unknown architecture. When I first created the c managed project, I chose RISC-V cross gcc, which is provided by the embedded cdt project. And the cross toolchain provided by CDT is Cross gcc.

However, when I create a new project based on the cross gcc toolchain and set the binary parser to gnu elf parser, the result of double-clicking the elf file is a mess characters.

image

image

image

image

jld01 commented 1 year ago

@baoruiqi does the Default Binary File Editor open correctly if you select it explicitly from the context menu of your generated binary in the Project Explorer view?

Open With > Other... > Internal Editors > Default Binary File Editor

baoruiqi commented 1 year ago

I found the reason, when creating a cross gcc project, the generated binary file has no suffix by default. If I add the elf suffix to the current Build artifact on the project properties page, then it works. In addition, double-clicking the .o format object file in the Debug folder does not need any modification though.

image

I'm reading the relevant source code to figure out how the cdt gets the prefix provided by the toolchain for its purpose. Because I wish to make some modifications to the RISC-V Cross GCC provided by Embedded CDT to meet the same purpose.

I would be very grateful if you could give me some pointers.

jld01 commented 1 year ago

@baoruiqi I already have a patch for Embedded CDT to generate the gnu_tool_prefix build variable. I will clean it up and create a PR.

baoruiqi commented 1 year ago

@jld01 Great, you are so familiar with Eclipse CDT, could you please give me some advice about this Issue?

https://github.com/eclipse-embed-cdt/eclipse-plugins/discussions/564

jld01 commented 1 year ago

... when creating a cross gcc project, the generated binary file has no suffix by default. If I add the elf suffix to the current Build artifact on the project properties page, then it works.

@baoruiqi, this issue has been fixed via #409