Skip to content

make: add architecture features and feature blacklisting#9081

Merged
kaspar030 merged 3 commits intoRIOT-OS:masterfrom
kaspar030:add_arch_features
Oct 14, 2019
Merged

make: add architecture features and feature blacklisting#9081
kaspar030 merged 3 commits intoRIOT-OS:masterfrom
kaspar030:add_arch_features

Conversation

@kaspar030
Copy link
Copy Markdown
Contributor

@kaspar030 kaspar030 commented May 4, 2018

Contribution description

This PR adds negative feature dependencies (feature blacklisting), allowing a test or module to specify that it will not work if a certain feature is provided.

This is then used to specify architectures or some of their traits as features, and as a next step, use those to blacklist tests.

Previously, if a module or test did not work on e.g., <32bit platforms or with the msp430 toolchain, all boards had to be specified in BOARD_BLACKLIST, and that list needed to be maintained.

With this PR it is possible to blacklist a whole architecture using e.g., FEATURES_BLACKLIST += arch_avr8 arch_msp430.
edit Also, it is now possible to do e.g., FEATURES_REQUIRED += arch_32bit.

Issues/PRs references

#8062

@kaspar030 kaspar030 added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: build system Area: Build system Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels May 4, 2018
@kaspar030 kaspar030 requested a review from cladmi May 4, 2018 14:36
@kaspar030 kaspar030 added the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label May 4, 2018
@kaspar030
Copy link
Copy Markdown
Contributor Author

(accidently added some leftover test folders, fixing...)

@kaspar030 kaspar030 force-pushed the add_arch_features branch from 3bc93d5 to 3e33a4b Compare May 4, 2018 14:52
@kaspar030 kaspar030 removed the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label May 4, 2018
Copy link
Copy Markdown
Contributor

@cladmi cladmi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As said IRL I really like this.
It extends the functionality to the existing BOARD_BLACKLIST/WHITELIST.

For tests it will be useful to define supported/unsupported things. Even directly in modules/packages, like right now 'micro-ecc' does not work on 16bit.

In the future I would also re-export these FEATURES_USED because having arch_16bit macros available in C code would help configure different behaviors in tests.
But it is another PR.

I just did some naming remarks inline.

endif

# turn provided but blacklisted features into required "!<feature>"
FEATURES_REQUIRED += $(addprefix !,$(sort $(filter $(FEATURES_PROVIDED), $(FEATURES_BLACKLIST))))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer adding another variable name and/or other if case for this check.
These sections are hard enough to read, so adding an explicit name simplify this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean, instead of directly adding the blacklisted but available features to FEATURES_REQUIRED, create an intermediate FEATURES_BLACKLISTED and use that in the if below?

I thought about that, but decided to rather go with a nice comment... I think warning: feature "!arch_16bit" missing, expect errors pretty much explains what is happening, and extra variables clutter code.

Do you insist?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed

include $(RIOTBASE)/Makefile.dep

FEATURES_MISSING := $$(sort $$(filter-out $$(FEATURES_PROVIDED), $$(FEATURES_REQUIRED)))
FEATURES_MISSING += $$(addprefix !,$$(sort $$(filter $$(FEATURES_PROVIDED), $$(FEATURES_BLACKLIST))))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here I would prefer adding another variable name and/or other if case for this check.
These sections are hard enough to read, so adding an explicit name simplify this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is now gone as it'll be handled in Makefile.features

@cladmi
Copy link
Copy Markdown
Contributor

cladmi commented May 8, 2018

I found the problem why the naming, features re-usage and definition did not fit me. The lack of clarity was hiding the problem. I think it is currently incorrectly using the feature concepts.

The arch definitions and the blacklisting are done on provided features, and not on used features which is for me wrong.

From my understanding:

FEATURES_PROVIDED are hardware (including toolchain) features that are available for this board. It can require having code to make them available to the application. In that case, it means first enabling this feature by having it put in FEATURES_USED, which currently happens only if it is mentioned in FEATURES_REQUIRED or FEATURES_OPTIONAL.

Then the build system only process them if they are in FEATURES_USED.
It was even reinforced when changing the FEATURES_CONFLICT handling: #8925 as there was no reason to care about disabled provided features.

In the current implementation these arch_% features will almost never be in FEATURES_REQUIRED and still be always enabled because of course, the architecture is 16bit.

If it is required to have this information available in the code, like for examples in tests where it would be easier to use a macro than a sizeof(int) == 2, it would somehow require re-exporting these enabled features. As done before #8292

However, it means only exporting used features, not the available but unused ones.

Also, if for any reason, some module needs to blacklist against another feature than arch_ it would complained about disabled features as in #8925.

Ideas

Re-using the concept of FEATURES is I think adapted here, but not as provided ones.
I would add these arch_ ones directly to a used/enabled features list, or a new adapted name and not in the provided list.

@cladmi
Copy link
Copy Markdown
Contributor

cladmi commented May 8, 2018

The problem is even more hidden because both feature blacklisting, which should be global to all features, and adding arch features was done in the same pr.

@kaspar030
Copy link
Copy Markdown
Contributor Author

I found the problem why the naming, features re-usage and definition did not fit me. The lack of clarity was hiding the problem. I think it is currently incorrectly using the feature concepts.

I don't see a problem.

FEATURES_PROVIDED -> "the platform provides a feature"
FEATURES_REQUIRED -> "this feature must be provided"
FEATURES_OPTIONAL -> "this feature will be used if available"
FEATURES_USED -> "list of all required or optional and provided features"

The latter two are used for periph_* in order to select periph_% modules when appropriate.

This PR adds:

FEATURES_BLACKLIST -> "this feature must not be provided by the platform"

In order to re-use fiddly make loops, each feature in FEATURES_BLACKLIST gets added to FEATRUES_REQUIRED with prefixed "!" as "!<feature_name>".

The arch definitions and the blacklisting are done on provided features, and not on used features which is for me wrong.

Some features are provided and can lead to code linked in when used, some are "always there". It is a matter of definition.
We can argue about the naming, or the meaning, or definition, or personal feelings, or whatever, forever. Or we can add two lines of dokumentation and take a useful improvement.

@kaspar030
Copy link
Copy Markdown
Contributor Author

@cladmi You issue seems to be rooted in the assumption that features should be exported to code. If we consider features a build-system only "feature", there is no issue, right?

@cladmi cladmi mentioned this pull request May 11, 2018
@cladmi
Copy link
Copy Markdown
Contributor

cladmi commented May 11, 2018

My view is that the way it is implemented here, BLACKLISTED works perfectly with arch_ because of course they are always present.

But if for any reason, you want to do an app/library that should not work if, for example periph_pm is not included. Then the blacklisting as it is now would prevent using it if the board/cpu as pm support even if not activated and compiled.

What I was thinking maybe one of these solutions:

  • iglobally add in the build system that arch_% are required, blacklisting could be done against FEATURES_USED.
  • Define them in FEATURES_USED directly and adapt the required parts
  • Add a new variable for this specific case FEATURES_INCLUDED or something they are provided and used without possibility to deactivate them.

@kaspar030 kaspar030 closed this May 11, 2018
@kaspar030 kaspar030 deleted the add_arch_features branch May 11, 2018 21:35
@kaspar030 kaspar030 restored the add_arch_features branch May 18, 2018 08:46
@kaspar030 kaspar030 reopened this May 18, 2018
@kaspar030
Copy link
Copy Markdown
Contributor Author

Huh, why did I close this?

But if for any reason, you want to do an app/library that should not work if, for example periph_pm is not included. Then the blacklisting as it is now would prevent using it if the board/cpu as pm support even if not activated and compiled.

If an app should not work if periph_pm is not included, that turns into it should only work if it is included. Thus periph_pm should be a required feature.

If you meant, an app or library should only work if periph_pm is not included (even though it is available as a feature), then this is out of scope for features, and should be handled by the module system. periph_pm is both a module and a feature. If actually used, the feature turns into a used module.

@cladmi
Copy link
Copy Markdown
Contributor

cladmi commented Jun 15, 2018

If you meant, an app or library should only work if periph_pm is not included (even though it is available as a feature), then this is out of scope for features, and should be handled by the module system. periph_pm is both a module and a feature. If actually used, the feature turns into a used module.

As said, I personally understand that BLACKLIST should be applied to used features not on available ones, like FEATURES_CONFLICT.

As we have different understanding on the semantic, I would like to have other point of view on this. It is an API design, where there are subjective choices, so having other developers feedback could help.

@cladmi
Copy link
Copy Markdown
Contributor

cladmi commented Jun 15, 2018

I will also do a documentation PR to summarize what was said here on the existing FEATURES variables.

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one minor alphabetical order comment. You can squash directly.

Copy link
Copy Markdown
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FEATURES_BLACKLIST_GLOBAL should also be part of info-build.

@fjmolinas
Copy link
Copy Markdown
Contributor

FEATURES_BLACKLIST_GLOBAL should also be part of info-build.

Sorry I think it is actually FEATURES_BLACKLIST here.

@kaspar030
Copy link
Copy Markdown
Contributor Author

Sorry I think it is actually FEATURES_BLACKLIST here.

addressed

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK, please squash.

I've based #12304 on this PR and I confirm the features blacklisting works as expected. @fjmolinas's comment is adressed but let's wait for this approval.

# features that are used but blacklisted (prepended with "!").
# Having features missing may case the build to fail.
FEATURES_MISSING = $(sort $(filter-out $(FEATURES_PROVIDED),$(FEATURES_REQUIRED)))
FEATURES_MISSING = $(sort $(filter-out $(FEATURES_PROVIDED),$(FEATURES_REQUIRED)) \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are changing the definition of FEATURES_MISSING and not updating the doc:

@echo 'FEATURES_MISSING (only non optional features):'

Also why is a used blacklisted feature a FEATURES_MISSING? To me the usage doesn't fit with the name. This would be more of a FEATURES_USED_BLACKLISTED.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@fjmolinas fjmolinas Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used but blacklisted features get missed as !<feature>. Doc is here:

https://github.com/kaspar030/RIOT/blob/3eae2f7b792d60f48006d8338c91a73cb4e0a99a/Makefile.features#L25-L29

I referenced RIOT/makefiles/info.inc.mk, not the code.

There's also _features_used_blacklisted.

I'm not arguing this, I'm saying names should make sense with the definiton. A missing FEATURE is not a blacklisted used FEATURE, why does it make sense adding _features_used_blacklisted to FEATURES_MISSING. Is this just to re-use the FEATURES_MISSING error handling?

If I do BOARD=esp8266-olimex-mod make -C tests/lwip info-build, I get:

FEATURES_MISSING (only non optional features):
         !arch_esp8266
FEATURES_BLACKLIST (blacklisted features):
         arch_esp8266

Before, FEATURES_MISSING was self-documented because the name made sense. Now if I do not look at the code, I do not undersand what is going on with !arch_esp8266, is !arch_esp8266 missing? its not missing? (I do not like double negation). In #11492 an effort was made for names to make sense, edit: to me now it doesn't that much.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now if I do not look at the code, I do not undersand what is going on with !arch_esp8266, is !arch_esp8266 missing?

Do you know or do you assume that is what's gonna happen to someone?
I think if this shows up:

FEATURES_MISSING (only non optional features):
         !arch_esp8266
FEATURES_BLACKLIST (blacklisted features):
         arch_esp8266

it is pretty clear what's happening.

But yes, this is re-using FEATURES_MISSING.

A missing FEATURE is not a blacklisted used FEATURE, why does it make sense adding _features_used_blacklisted to FEATURES_MISSING.

Well, it is adding !feature, not feature, to FEATURES_MISSING. For C devs there should be some meaning there.
Before, features could just be "missing" (e.g., "not provided"). Now, with !feature, they can be "used but blacklisted". A more fitting name might be FEATURE_REQUIREMENTS_UNFULFILLED" or something similar.

Again, we're in a situation where the machinery works but the names are not to everyone's liking.
How about we go with the functionality and move the naming struggle elsewhere?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know or do you assume that is what's gonna happen to someone?

Yes since I know, to me it doesn't make sense.

How about we go with the functionality and move the naming struggle elsewhere?

...

Copy link
Copy Markdown
Contributor

@fjmolinas fjmolinas Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we go with the functionality and move the naming struggle elsewhere?

I'll dismiss my review.

@fjmolinas fjmolinas dismissed their stale review October 14, 2019 12:50

There are already 2 ACK, so dismissing in favor of consensus.

@kaspar030
Copy link
Copy Markdown
Contributor Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: build system Area: Build system CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants