Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface compiler flags for a given platform #1090

Closed
ianfixes opened this issue Nov 30, 2020 · 9 comments
Closed

Surface compiler flags for a given platform #1090

ianfixes opened this issue Nov 30, 2020 · 9 comments
Labels
conclusion: declined Will not be worked on type: enhancement Proposed improvement

Comments

@ianfixes
Copy link

Feature Request

arduino_ci has logic for building Arduino libraries with mocked hardware.
Part of this is setting the proper compiler #define values for a given board, which I currently hard code in a yaml file. __AVR_ATmega328P__ becomes the compiler flag -D__AVR_ATmega328P__, and so on.

I'd like a way to ask arduino-cli for these instead, if possible.

@per1234 per1234 added the type: enhancement Proposed improvement label Dec 1, 2020
@matthijskooijman
Copy link
Collaborator

This seems challenging to implement.

One problem is that arduino-cli doesn't really know about compiler flags. It knows about all kinds of variables which it collects from various places (platform.txt, boards.txt, compiler commandline, maybe even some builtin defaults or backward compatibility fixups). Then, to run the compiler, it takes a "recipe" from platform.txt and instantiates it with all collected variables. This produces the complete commandline, not just the defines, or just compiler flags, etc. There are likely some of these variables that might be relevant (i.e. a variable that contains all compiler flags or all defines), but (names of) these variables are not standardized, only the recipe that generates the full commandline.

So, that means that at best arduino-cli could give you all the relevant variables for a given board, or the complete compiler commandline for a given board and source file. If you know how the platform.txt for a given platform is written, you might be able to extract the flags you need from specific variables, but this needs platform-specific configuration Arduino-CI and might need changes to the platform (e.g. the AVR core has no separate variable for the defines you would need, they are coded directly into the recipe).

Regarding the specific example you give, __AVR_ATmega328P__, that is even more tricky, since the compiler commandline only has -mmcu=m328p or something like that, which gcc interprets by defining __AVR_ATmega328P__. So that define is simply unknown to arduino-cli and platform.txt. You could maybe run gcc with options to let it print all (pre)defined macros, but then you'll probably get a lot more than you need and run into problems again if you do not have a long list of macros you need to filter out (and then you're probably better off just hardcoding the macros you need in the first place...)

@ianfixes
Copy link
Author

OH! That line from the recipe is a perfect illustration of what I'm after!

recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"

Just being able to get ahold of the contents of compiler, build, includes, etc (as a JSON object, with all their sub-properties) would be a huge boost for me -- it will show me which variables are being set at the "top level", and make it easier for me to navigate the rest of the platform libraries.

I assume surfacing this info is as easy as copying the process for examples compilation -- then instead of plugging the data into the recipe and running the compiler, just print out any & all variables that a typical recipe would access. Is that more reasonable?

@matthijskooijman
Copy link
Collaborator

I assume surfacing this info is as easy as copying the process for examples compilation -- then instead of plugging the data into the recipe and running the compiler, just print out any & all variables that a typical recipe would access. Is that more reasonable?

Yup, that's probably easy to implement. Not sure what the (CLI or GRPC) interface for this would look like exactly, though (and I'm not familiar enough with the code to really suggest anything or be really sure that this is indeed easy :-p).

There is some work on creating a compilation database as a side effect of compilation (see #1081), which might be an ideal interface for what you need. From that PR, it seems @cmaglie even added an option to generate just a compilation database without actually running the compilation commands (except for the preprocessor for library detection)? OTOH you might need a little more high-level view of the various flags, extracting them from a compilation database might require a bit of reverse engineering maybe?

@ianfixes
Copy link
Author

Linking Arduino-CI/arduino_ci#242 for visibility. I'm hopeful that this sort of feature would support a more robust approach to defining board constants during mock compilation

@umbynos
Copy link
Contributor

umbynos commented Nov 25, 2022

Hi @ianfixes, unfortunately this cannot be done since it's compiler dependent.

@umbynos umbynos closed this as completed Nov 25, 2022
@umbynos umbynos added the conclusion: declined Will not be worked on label Nov 25, 2022
@ianfixes
Copy link
Author

I'm not sure I understand this resolution. At some point you know what the compiler flags are, because you have to pass them to the actual compiler. You "cannot" print them to STDOUT instead (hard-coding "gcc" as the compiler if necessary)?

@cmaglie
Copy link
Member

cmaglie commented Nov 25, 2022

Many definitions are builtin in the compiler itself, for example, the __AVR_ATmega328P__ is given automatically by avr-gcc, we did not provide any -D__AVR_ATmega328P__ flag to the compiler. You may obtain the full list by running:

avr-gcc -mmcu=atmega328p -E -dM -x c /dev/null

Another problems is that a compiler for a specific platform may have a set of flags that is different from a compiler of another, the first example that comes to mind is the -mmcu that will be different for avr and arm.

The only "official" definitions flags made by Arduino are:

-DARDUINO={runtime.ide.version}    // e.g. ARDUINO=10813, this is no more updated after the release of IDE 2.0.0
-DARDUINO_{build.board}            // e.g. ARDUINO_UNO
-DARDUINO_ARCH_{build.arch}        // e.g. ARDUINO_ARCH_AVR

I don't know if those are useful for your purposes, they seem too generic.

@ianfixes
Copy link
Author

If I'm understanding this correctly, in your example -D__AVR_ATmega328P__ is really coming from within avr-gcc as a consequence of some other argument (my guess is the -mmcu=atmega328p argument). Is that accurate? If so I may be able to simply record some of the avr-gcc args as hints.

Overall though, it sounds like I might be stuck with the YAML definitions... and that might be the most straightforward method of resolving this.

@cmaglie
Copy link
Member

cmaglie commented Jan 30, 2023

If I'm understanding this correctly, in your example -D__AVR_ATmega328P__ is really coming from within avr-gcc as a consequence of some other argument (my guess is the -mmcu=atmega328p argument). Is that accurate?

Yes, correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
conclusion: declined Will not be worked on type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests

7 participants