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

makefiles/feature_precheck: check libc availability prior deciding usage #15993

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

kfessel
Copy link
Contributor

@kfessel kfessel commented Feb 12, 2021

Contribution description

Add a feature pre-check for picolibc and newlibc into the make process

Testing procedure

make things with either having or not having picolibc or newlib installed

Issues/PRs references

Fixes #15325

@maribu , @nmeum , @benpicco : might what to have a look at it

Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

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

this looks much less scary that I had imagined :-)

@@ -0,0 +1,17 @@
# Check if provided features are available

ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)) $(filter newlib,$(FEATURES_PROVIDED)))
Copy link
Member

Choose a reason for hiding this comment

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

The outer if can be dropped, can't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No it can (i wanted to avoid the rest of the check if not nesecary but the shell checks a only done if the feature is provided).

I will remove it

# Check if provided features are available

ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)) $(filter newlib,$(FEATURES_PROVIDED)))
ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
Copy link
Member

Choose a reason for hiding this comment

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

You need to white-list this file in dist/tools/buildsystem_sanity_check/check.sh:75. Please also update the comment in the line above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ack

Copy link
Contributor

Choose a reason for hiding this comment

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

You need to white-list this file in dist/tools/buildsystem_sanity_check/check.sh:75. Please also update the comment in the line above.

Huh? This completely bypasses the intention of the check...

Copy link
Member

Choose a reason for hiding this comment

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

No, this was added when FEAUTES_OPTIONAL was added to replace the paddern

ifneq (,$(filter foo,$(FEAUTRES_PROVIDES)))
  USEMODULE += optional_submodule
endif

The intention was to enforce the use of FEATURES_OPTIONAL instead. But this here is unrelated.

Copy link
Contributor

Choose a reason for hiding this comment

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

No, this was added when FEAUTES_OPTIONAL was added to replace the paddern

ifneq (,$(filter foo,$(FEAUTRES_PROVIDES)))
  USEMODULE += optional_submodule
endif

The intention was to enforce the use of FEATURES_OPTIONAL instead. But this here is unrelated.

I'm not sure I understand, FEATURES_OPTIONAL should not be checked either, only FEATURES_USED. The buildsystem check is there so that there are no conditionals against FEATURES_OPTIONAL, FEATURES_PROVIDED, FETURES_REQUIRED, see original or #10179 and

# Modules should not check the content of FEATURES_PROVIDED/_REQUIRED/OPTIONAL
# Handling specific behaviors/dependencies should by checking the content of:
# * `USEMODULE`
# * maybe `FEATURES_USED` if it is not a module (== not a periph_)
check_not_parsing_features() {
local patterns=()
local pathspec=()
patterns+=(-e 'if.*filter.*FEATURES_PROVIDED')
patterns+=(-e 'if.*filter.*FEATURES_REQUIRED')
patterns+=(-e 'if.*filter.*FEATURES_OPTIONAL')
# Pathspec with exclude should start by an inclusive pathspec in git 2.7.4
pathspec+=('*')
# Ignore this file when matching as it self matches
pathspec+=(":!${SCRIPT_PATH}")
# These two files contain sanity checks using FEATURES_ so are allowed
pathspec+=(':!Makefile.include' ':!makefiles/info-global.inc.mk')
, am I looking at the wrong line?

@maribu maribu added Area: build system Area: Build system Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation labels Feb 12, 2021
ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_PROVIDED := $(filter-out picolibc,$(FEATURES_PROVIDED))
Copy link
Member

Choose a reason for hiding this comment

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

Maybe just use FEATURES_BLACKLIST? That way it would be more obvious that the feature is not provided due to the setup, rather than due to missing upstream support.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

seem reasonable i test if it keeps working and change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BLACKLISTING does not work as intended

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed that

Copy link
Contributor Author

@kfessel kfessel Feb 12, 2021

Choose a reason for hiding this comment

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

as i just saw you also fixed the Blacklist problem i had in #15973

Copy link
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.

NACK, didn't look at the other changes yet, but I'm against moving the include order.

Comment on lines +370 to +435
# Include Board and CPU configuration
INCLUDES += $(addprefix -I,$(wildcard $(BOARDDIR)/include))
include $(BOARDDIR)/Makefile.include
INCLUDES += -I$(RIOTCPU)/$(CPU)/include
include $(RIOTCPU)/$(CPU)/Makefile.include

# Import all toolchain settings
include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk
Copy link
Contributor

Choose a reason for hiding this comment

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

This is reverting a long effort of changing the order of inclusion: #9913

Copy link
Contributor Author

@kfessel kfessel Feb 12, 2021

Choose a reason for hiding this comment

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

we can also have a error message telling the user that he has to blacklist the provided but not exiting toolchain that the dependency solver prefered for a reason unknown to the user (maybe it was listed first somewhere, or it is alphanumerical first)

ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_PROVIDED := $(filter-out picolibc,$(FEATURES_PROVIDED))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not declarative, FEATURES so far are declarative.

Copy link
Contributor Author

@kfessel kfessel Feb 12, 2021

Choose a reason for hiding this comment

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

I think: I fixed that with blacklisting as @maribu suggested

@fjmolinas
Copy link
Contributor

NACK, didn't look at the other changes yet, but I'm against moving the include order.

@kfessel can you explain the reasoning for this change better?

@@ -413,8 +421,6 @@ endif
# Assume GCC/GNU as supported toolchain if CPU's Makefile.include doesn't
# provide this macro
TOOLCHAINS_SUPPORTED ?= gnu
# Import all toolchain settings
include $(RIOTMAKE)/toolchain/$(TOOLCHAIN).inc.mk
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this is the only thing that needs to be moved?

Copy link
Contributor Author

@kfessel kfessel Feb 12, 2021

Choose a reason for hiding this comment

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

No, we need access to the specific toolchain therefore the cpu prefix definition has to move up
(can't ask x86 gcc if picolibc for arm is available)

Comment on lines +3 to +8
ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_BLACKLIST += picolibc
endif
endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is there a need to check if the FEATURE is provided? Can't you simply blacklist if not present?

Copy link
Contributor Author

@kfessel kfessel Feb 12, 2021

Choose a reason for hiding this comment

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

as you guessed it is to avoid the shell call, if not need, and why should we auto blacklist something no one is talking about.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is what I mean BTW:

RIOT/Makefile.include

Lines 176 to 179 in a5b9136

# UNAME is always needed so use simple variable expansion so only evaluated once
UNAME := $(shell uname -m -s)
OS = $(word 1, $(UNAME))
OS_ARCH = $(word 2, $(UNAME))
, just assign it once, if we want to move towards enabling picolibc most of the time anyway, we will want to call this at least once.

Comment on lines +3 to +8
ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_BLACKLIST += picolibc
endif
endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
ifneq (,$(filter picolibc,$(FEATURES_PROVIDED)))
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_BLACKLIST += picolibc
endif
endif
# Test if picolibc.specs is available
ifneq ($(shell $(LINK) -specs=picolibc.specs -E - 2>/dev/null >/dev/null </dev/null ; echo $$?),0)
FEATURES_BLACKLIST += picolibc
endif

Is it as it is now to avoid the shell call? In that case, I would assign it to a variable once and the check that variable, similar to what is done with OS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

maybe we should but i do not see a huge performance penalty atm.
I will have a look at OS.

Copy link
Contributor

Choose a reason for hiding this comment

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

So this can be used to opportunistically enable picolibc and fall back to newlib if it's not installed?

Shouldn't the first step be testing it as the default libc in the ci?

@kfessel
Copy link
Contributor Author

kfessel commented Feb 23, 2021

will rebase to solve for conflicting change in master

@MrKevinWeiss MrKevinWeiss added this to the Release 2021.07 milestone Jun 21, 2021
@MrKevinWeiss MrKevinWeiss removed this from the Release 2021.07 milestone Jul 15, 2021
@stale
Copy link

stale bot commented Mar 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Mar 2, 2022
@benpicco
Copy link
Contributor

benpicco commented Mar 2, 2022

So this can be used to opportunistically enable picolibc and fall back to newlib if it's not installed?

@stale stale bot removed the State: stale State: The issue / PR has no activity for >185 days label Mar 2, 2022
@kfessel
Copy link
Contributor Author

kfessel commented Mar 2, 2022

So this can be used to opportunistically enable picolibc and fall back to newlib if it's not installed?

yes this was the intention

the stall:bot is digging deep :nice:

without picolibc-arm... on the system:

examples/gnrc_minimal$ BOARD=nucleo-f767zi make
Building application "gnrc_minimal" for "nucleo-f767zi" with MCU "stm32".

picolibc was selected to be build but no picolibc.spec could be found
you might want to install picolibc for arm-none-eabi
or add FEATURES_BLACKLIST += picolibc to Makefile)
check your installation or build configuration.
make: *** [../RIOT-master/makefiles/libc/picolibc.mk:21: _missing-picolibc] Error 1

since #16008 got merged is at least failing loud providing a kinda fix

with this PR it would just fallback to use newlibc

@benpicco
Copy link
Contributor

benpicco commented Mar 2, 2022

Can you give it a rebase?

@fjmolinas
Copy link
Contributor

My change requests still stand here.

@fjmolinas
Copy link
Contributor

Thinking about this again I'm still against it, if we change to have picolibc enabled by default then picolibc would become a dependency of RIOT, we don't blacklist native because libcan is not there, either install it or don't use it.

If we move to picolibc as default then what we can do is check if it's installed and if not add a warning that it should be installed or FEATURES_REQUIRED += newlib added to their application Makefile or RIOT_MAKEFILES_GLOBAL_PRE. If you don't want to install everything there is always the docker path.

Features so far are all declarative, I do not see the need to change because of picolibc, neither do I think its a good idea.

@stale
Copy link

stale bot commented Sep 21, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Sep 21, 2022
@kfessel kfessel added State: don't stale State: Tell state-bot to ignore this issue and removed State: stale State: The issue / PR has no activity for >185 days labels Sep 23, 2022
@github-actions github-actions bot added the Area: tools Area: Supplementary tools label Sep 23, 2022
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 Area: tools Area: Supplementary tools State: don't stale State: Tell state-bot to ignore this issue Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
5 participants