Description
Description
Many variables are exported using export VARIABLE
without even knowing why, the impact, or even be needed. In the same time, many variables are evaluated using :=
instead of using deferred
variables.
Guess why calling make clean
is slow ? All these variables/shell call must be evaluated for each target called even if the targett is not using it at all.
I tried preventing changing these without reasons, but keeping them in this wrong state by default, is causing me issues in several places. I want to start getting rid of them on a methodical way instead of currently working it around.
Listing them all
git grep -a -n 'export ' '*' ':!doc/**' ':!**/*.c' ':!**/*.h' ':!**/*.py' ':!makefiles/utils/**' ':!*.murdock' ':!dist/tools/buildsystem_sanity_check/**' ':!*release-notes.txt' ':!dist/tools/**' | tee output
wc -l output; date
1105
Fri May 17 13:37:10 CEST 2019
wc -l output ; date
938 output
Tue May 28 18:23:42 CEST 2019
wc -l output ; date # Pre rule update
940 output
Mon Jun 3 10:01:49 CEST 2019
wc -l output ; date # Grep rule updated
892 output
Mon Jun 3 10:04:58 CEST 2019
wc -l output; date
854 output
Mon Jun 3 10:46:56 CEST 2019
wc -l output; date
830 output
Tue Jun 4 16:04:14 CEST 2019
wc -l output; date
822 output
Tue Jun 11 13:31:51 CEST 2019
wc -l output; date
619 output
Wed Aug 21 20:17:48 CEST 2019
wc -l output; date # rule update to see in patches and match 'export '
618 output
Thu Aug 29 11:51:28 CEST 2019
wc -l output; date
498 output
Thu Aug 29 14:39:32 CEST 2019
wc -l output ; date
503 output
Thu Sep 12 14:47:10 CEST 2019
wc -l output; date
280 output
Wed Jun 24 08:32:23 CEST 2020
I am personally tracking them in https://ci-ilab.imp.fu-berlin.de/job/RIOT%20cleanup%20warnings/
Steps
-
List variables where export or direct evaluation can directly be removed here == only used inside
Makefile.include
and remove them- LINKFLAGS
- global export vars.inc.mk
makefiles/vars.inc.mk: do not export LINKFLAGS #10853 - atmega_common
cpu/atmega_common: do not export LINKFLAGS #10854 - Other platforms:
git grep 'export LINKFLAGS' | wc -l 37
- global export vars.inc.mk
- LINK
- need to export it for
generate-xcompile-toolchain.sh
so for building packages in general, it is also usingLFLAGS
which is not mapped toLINKFLAGS
.
- need to export it for
- CFLAGS/INCLUDES/variables used by
Makefile.base
make: do not locally export compilation variables #12098- Static instead of dynamic checking for supported variables makefiles/cflags.inc.mk: handle optional cflags #12123 (not set for
--std=c99
yet)
- Static instead of dynamic checking for supported variables makefiles/cflags.inc.mk: handle optional cflags #12123 (not set for
- PORT/FFLAGS/TERMPROG/TERMFLAGS/FLASHER/...
-
TERMPROG
TERMFLAGS
:- unexport TERM* variables unexport TERM* variables #11064
-
boards/nz32-sc151/Makefile.include:export TERMFLAGS = -p $(PORT)
boards/nz32-sc151: do not blindly set TERMFLAGS #11065
-
FLASHER/FFLAGS/DEBUGGER/DEBUGGER_FLAGS/DEBUGSERVER/DEBUGSERVER_FLAGS/RESET/RESET_FLAGS
make: remove exports for flash debug reset #11554 -
PORT
makefiles: remove exports so that PORT is not evaluated if it's not needed. #10440- dist/tools/buildsystem_sanity_check: check no PORT exports dist/tools/buildsystem_sanity_check: check no PORT exports #12209
- PORT_LINUX|PORT_DARWIN board: remove exporting PORT_LINUX|PORT_DARWIN #11619
-
- DEBUG_* and STLINK variables make: boards: remove use of export with debug adapter related variables #11614
- RIOT_VERSION Running the git command on my machine takes currently
0.1
seconds. Everytimemake
is run.- Remove exporting and immediate evaluation of
CFLAGS_WITH_MACROS
and only evaluategit describe
command when needeed makefiles: Introduce GIT_VERSION and use it for RIOT_VERSION #11881- Follow-up: Makefile.include: remove RIOT_VERSION_OVERRIDE Makefile.include: remove RIOT_VERSION_OVERRIDE #11771
- Remove exporting and immediate evaluation of
- Unexporting CPU/CPU_MODEL from the board files is done together in Tracking: move CPU/CPU_MODEL to Makefile.features #11477 (still exported in vars.inc.mk)
- LINKFLAGS
-
Only export in
makefiles/vars.inc.mk
for variables that currently really need to be exported -
Variables that need to be exported to sub-builds need a mechanism to say who gets it
-
makefiles/utils/variables: add functions to help managing variables makefiles/utils/variables: add functions to help managing variables #11664
-
Variables that are transparently given to scripts even if only one needs it
- GIT_CACHE_DIR (make: pkg: don't export globally GITCACHE and GIT_CACHE_DIR vars #14263)
- flashing tools specific variables which are exported in
board
instead of in theflasher
Cleaning up
- Check usage of a variable with
git grep -e '$(VARIABLE)' -e '${VARIABLE}'
and verify uses are indeed only in directly included makefiles - Add the variable in the
check_not_exporting_variables()
checked variables to prevent re-adding the export https://github.com/RIOT-OS/RIOT/blob/master/dist/tools/buildsystem_sanity_check/check.sh - Lines that where only
export VARIABLE
must be removed and not justexport
removed
This has different consequences:
Evaluation when not needed
-
Using an
export
on a variable means the value will be evaluated even for rules that do not use the variable.
This causes issues for example with listingtty
devices, evaluatingINCLUDES
and gettingGCC_INCLUDES_DIRS
-
It also causes evaluation on the host machine when only the docker container should be doing it. It happened with
avr-ld
for example, somechecks
being performed on the host machine, sayingobjcopy not found
.
Sub builds
When trying to call make
inside of make
many variables from the first build are sent to the second one.
Variables that can change a build
As everything is exported, it is hard to know what can have an impact on a build result.
Having it in control would simplify documenting what should and what should not be available.
The default behavior has become harmful
The default case has been to always use :=
or export
even when it does not make sense, and it gets merged without even reviewing why there is an export
there.
export PRIVATE_VAR_FOR_SCRIPT = foo_bar
OTHER_VAR_ONLY_USE_OF_PRIVATE_VAR_FOR_SCRIPT = $(PRIVATE_VAR_FOR_SCRIPT)
Examples
GLOBAL_GOALS
has it should not evaluate the rest of the build system because it isslow
or causes isssues- make: test SERIAL for sam0 boards only if required #10840
- makefiles: Provide USB UART device serial number matching #7695 (comment)
Related issues
I am starting to build on a machine that has nothing but docker and the build system complains about these things.