2018-09-26 17:10:12 +02:00
#!/usr/bin/env bash
#
# Copyright (C) 2018 Gaëtan Harter <gaetan.harter@fu-berlin.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
#
# Central test script to have sanity checks for the build system
# It is run unconditionally on all files.
#
#
: " ${ RIOTBASE : = " $( cd " $( dirname " $0 " ) /../../../ " || exit; pwd ) " } "
2021-01-12 16:31:08 +01:00
: " ${ RIOTTOOLS : = ${ RIOTBASE } /dist/tools } "
. " ${ RIOTTOOLS } " /ci/github_annotate.sh
2018-09-26 17:10:12 +02:00
SCRIPT_PATH = dist/tools/buildsystem_sanity_check/check.sh
2019-06-13 15:53:58 +02:00
tab_indent( ) {
# Ident using 'bashism' to to the tab compatible with 'bsd-sed'
sed 's/^/\' $'\t/'
}
prepend( ) {
# 'i' needs 'i\{newline}' and a newline after for 'bsd-sed'
sed ' 1i\
'"$1"'
'
}
error_with_message( ) {
2021-01-12 16:31:08 +01:00
while read INPUT; do
if github_annotate_is_on; then
MESSAGE = " ${ 1 } "
FILE = $( echo " ${ INPUT } " | cut -d: -f1)
LINE = $( echo " ${ INPUT } " | cut -d: -f2)
MATCH = $( echo " ${ INPUT } " | cut -d: -f3)
if [ [ $var = ~ ^[ 0-9] +$ ] ] || [ -z " $MATCH " ] ; then
# line is not provided in grep pattern
LINE = 0
fi
github_annotate_error " $FILE " " $LINE " " $MESSAGE "
fi
# We need to generate non GitHub annotations for this script to fail.
# Also, the pure annotate output is not very helpful on its own ;-)
echo " ${ INPUT } " | tab_indent | prepend " ${ 1 } : "
done
2019-06-13 15:53:58 +02:00
}
2018-09-26 17:10:12 +02:00
# 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' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2021-01-12 16:29:46 +01:00
| error_with_message 'Modules should not check the content of FEATURES_PROVIDED/REQUIRED/OPTIONAL'
2018-09-26 17:10:12 +02:00
}
2020-05-29 09:23:59 +02:00
# Providing features for boards and CPUs should only be done in
# Makefile.features
check_providing_features_only_makefile_features( ) {
local patterns = ( )
local pathspec = ( )
2020-07-14 16:22:55 +02:00
patterns += ( -e '^[ ]*FEATURES_PROVIDED *+= *' )
2020-05-29 09:23:59 +02:00
2020-07-14 16:22:55 +02:00
pathspec += ( "*Makefile\.*" )
2020-05-29 09:23:59 +02:00
pathspec += ( ":!*Makefile.features" )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2020-07-14 16:22:55 +02:00
| error_with_message 'Features should only be provided in Makefile.features files'
2020-05-29 09:23:59 +02:00
}
2019-05-03 12:11:12 +02:00
# Some variables do not need to be exported and even cause issues when being
# exported because they are evaluated even when not needed.
#
# Currently this blacklists exported variables instead of whitelisting or
# providing a mechanism for handling it.
# It just keep things not exported anymore in the future.
UNEXPORTED_VARIABLES = ( )
UNEXPORTED_VARIABLES += ( 'FLASHFILE' )
UNEXPORTED_VARIABLES += ( 'TERMPROG' 'TERMFLAGS' )
2019-05-17 13:56:49 +02:00
UNEXPORTED_VARIABLES += ( 'FLASHER' 'FFLAGS' )
2019-05-17 13:56:49 +02:00
UNEXPORTED_VARIABLES += ( 'RESET' 'RESETFLAGS' )
2019-05-17 13:56:49 +02:00
UNEXPORTED_VARIABLES += ( 'DEBUGGER' 'DEBUGGER_FLAGS' )
UNEXPORTED_VARIABLES += ( 'DEBUGSERVER' 'DEBUGSERVER_FLAGS' )
2019-05-17 13:56:49 +02:00
UNEXPORTED_VARIABLES += ( 'PREFLASHER' 'PREFFLAGS' 'FLASHDEPS' )
2021-02-18 17:15:55 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_DEBUG_ADAPTER' 'DEBUG_ADAPTER_ID' )
2019-06-03 10:26:18 +02:00
UNEXPORTED_VARIABLES += ( 'PROGRAMMER_SERIAL' )
2019-06-03 10:22:39 +02:00
UNEXPORTED_VARIABLES += ( 'STLINK_VERSION' )
2019-06-03 16:24:48 +02:00
UNEXPORTED_VARIABLES += ( 'PORT_LINUX' 'PORT_DARWIN' )
2019-05-17 13:56:49 +02:00
UNEXPORTED_VARIABLES += ( 'PORT[ ?=:]' 'PORT$' )
2020-01-02 20:42:55 +01:00
UNEXPORTED_VARIABLES += ( 'LINKFLAGS' 'LINKER_SCRIPT' )
2020-01-10 14:09:26 +01:00
UNEXPORTED_VARIABLES += ( 'USEMODULE_INCLUDES' )
2020-02-24 11:36:20 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_ADAPTER_INIT' )
2020-02-24 09:11:19 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_CONFIG' )
2020-02-24 11:26:24 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_RESET_USE_CONNECT_ASSERT_SRST' )
2020-03-26 10:00:37 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_CMD_RESET_RUN' )
2020-03-26 09:30:50 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_PRE_FLASH_CMDS' 'OPENOCD_PRE_VERIFY_CMDS' )
2021-02-18 18:18:54 +01:00
UNEXPORTED_VARIABLES += ( 'OPENOCD_PRE_FLASH_CHECK_SCRIPT' )
2021-02-18 17:16:20 +01:00
UNEXPORTED_VARIABLES += ( 'PYOCD_FLASH_TARGET_TYPE' )
2020-03-08 15:11:06 +01:00
UNEXPORTED_VARIABLES += ( 'PYOCD_ADAPTER_INIT' )
2020-03-03 16:44:45 +01:00
UNEXPORTED_VARIABLES += ( 'JLINK_DEVICE' 'JLINK_IF' )
UNEXPORTED_VARIABLES += ( 'JLINK_PRE_FLASH' 'JLINK_RESET_FILE' )
2020-06-10 18:49:04 +02:00
UNEXPORTED_VARIABLES += ( 'GIT_CACHE' 'GIT_CACHE_DIR' )
2020-06-10 18:54:46 +02:00
UNEXPORTED_VARIABLES += ( 'LINKXX' )
2020-06-28 12:15:18 +02:00
UNEXPORTED_VARIABLES += ( 'APPDEPS' 'BUILDDEPS' 'DEBUGDEPS' )
2020-11-20 12:31:15 +01:00
UNEXPORTED_VARIABLES += ( 'EMULATOR' 'EMULATOR_FLAGS' )
2019-05-20 19:49:12 +02:00
EXPORTED_VARIABLES_ONLY_IN_VARS = ( )
2019-10-08 15:04:10 +02:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'CPU_ARCH' )
2020-06-10 13:11:32 +02:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'CPU_CORE' )
2019-10-08 15:04:10 +02:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'CPU_FAM' )
2020-03-26 10:26:14 +01:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'NATIVEINCLUDES' )
2020-01-10 14:47:09 +01:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'UNDEF' )
2020-01-10 14:02:51 +01:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'USEMODULE' )
2020-01-10 15:02:33 +01:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'TARGET_ARCH' )
2019-12-12 20:40:54 +01:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'TOOLCHAIN' )
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'WERROR' )
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'WPEDANTIC' )
2020-06-10 18:54:46 +02:00
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'CC[ =]' 'CXX' 'CCAS' )
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'AR[ =]' 'RANLIB' )
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'AS' 'NM' 'SIZE' 'LINK' )
EXPORTED_VARIABLES_ONLY_IN_VARS += ( 'OBJDUMP' 'OBJCOPY' )
2019-12-12 20:40:54 +01:00
2019-05-03 12:11:12 +02:00
check_not_exporting_variables( ) {
local patterns = ( )
local pathspec = ( )
for variable in " ${ UNEXPORTED_VARIABLES [@] } " ; do
patterns += ( -e " export[[:blank:]]\+ ${ variable } " )
done
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " \
2021-01-12 16:28:36 +01:00
| error_with_message 'Variables must not be exported'
2019-05-03 12:11:12 +02:00
2019-05-20 19:49:12 +02:00
# Some variables may still be exported in 'makefiles/vars.inc.mk' as the
2019-10-23 21:15:42 +02:00
# only place that should export common variables
2019-05-20 19:49:12 +02:00
pathspec += ( '*' )
2019-05-03 12:11:12 +02:00
pathspec += ( ':!makefiles/vars.inc.mk' )
2020-08-25 16:00:11 +02:00
pathspec += ( ':!**/Vagrantfile' )
2019-05-03 12:11:12 +02:00
2019-05-20 19:49:12 +02:00
patterns = ( )
for variable in " ${ EXPORTED_VARIABLES_ONLY_IN_VARS [@] } " ; do
patterns += ( -e " export[[:blank:]]\+ ${ variable } " )
done
# Only run if there are patterns, otherwise it matches everything
if [ ${# patterns [@] } -ne 0 ] ; then
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2021-01-12 16:28:36 +01:00
| error_with_message 'Variables must only be exported in `makefiles/vars.inc.mk`'
2019-05-20 19:49:12 +02:00
fi
2019-05-03 12:11:12 +02:00
}
2019-06-11 11:59:26 +02:00
# Deprecated variables or patterns
# Prevent deprecated variables or patterns to re-appear after cleanup
check_deprecated_vars_patterns( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e 'FEATURES_MCU_GROUP' )
2019-09-16 19:02:54 +02:00
patterns += ( -e 'TEST_ON_CI_WHITELIST += all' )
2019-06-11 11:59:26 +02:00
# 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 } " )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2021-01-12 16:28:36 +01:00
| error_with_message 'Deprecated variables or patterns'
2019-06-11 11:59:26 +02:00
}
2018-09-26 17:10:12 +02:00
2019-05-02 13:26:30 +02:00
# Makefile files cpu must not be included by the board anymore
# They are included by the main Makefile.include/Makefile.features/Makefile.dep
check_board_do_not_include_cpu_features_dep( ) {
local patterns = ( )
local pathspec = ( )
# shellcheck disable=SC2016
# Single quotes are used to not expand expressions
patterns += ( -e 'include $(RIOTCPU)/.*/Makefile\..*' )
pathspec += ( 'boards/' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-05-02 13:26:30 +02:00
| error_with_message 'Makefiles files from cpu must not be included by the board anymore'
}
2019-05-02 13:26:30 +02:00
# CPU and CPU_MODEL definition have been moved to 'BOARD|CPU/Makefile.features'
check_cpu_cpu_model_defined_in_makefile_features( ) {
local patterns = ( )
local pathspec = ( )
# With our without space and with or without ?=
patterns += ( -e '^ *\(export\)\? *CPU \??\?=' )
patterns += ( -e '^ *\(export\)\? *CPU_MODEL \??\?=' )
2020-02-05 14:22:38 +01:00
pathspec += ( ':!**.md' )
2019-05-02 13:26:30 +02:00
pathspec += ( ':!boards/**/Makefile.features' )
pathspec += ( ':!cpu/**/Makefile.features' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-05-02 13:26:30 +02:00
| error_with_message 'CPU and CPU_MODEL definition must be done by board/BOARD/Makefile.features, board/common/**/Makefile.features or cpu/CPU/Makefile.features'
}
2019-08-14 17:13:22 +02:00
# Applications Makefile must not set 'BOARD =' unconditionally
check_not_setting_board_equal( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e '^[[:space:]]*BOARD[[:space:]]*=' )
pathspec += ( '**/Makefile' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-08-14 17:13:22 +02:00
| error_with_message 'Applications Makefile should use "BOARD ?="'
}
2019-10-11 16:37:11 +02:00
# Examples must not provide BOARD_INSUFFICIENT_MEMORY in Makefile, but in
# Makefile.ci
check_board_insufficient_memory_not_in_makefile( ) {
local patterns = ( )
local pathspec = ( )
2019-10-17 11:30:58 +02:00
patterns += ( -e '^[[:space:]]*BOARD_INSUFFICIENT_MEMORY[[:space:]:+]*=' )
2019-10-11 16:37:11 +02:00
2019-10-17 11:30:58 +02:00
pathspec += ( '**/Makefile' )
2019-10-11 16:37:11 +02:00
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-10-11 16:37:11 +02:00
| error_with_message 'Move BOARD_INSUFFICIENT_MEMORY to Makefile.ci'
}
2019-11-01 14:10:01 +01:00
# Test applications must not define the APPLICATION variable
checks_tests_application_not_defined_in_makefile( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e '^[[:space:]]*APPLICATION[[:space:]:+]=' )
pathspec += ( 'tests/**/Makefile' )
2019-12-16 15:35:00 +01:00
pathspec += ( ':!tests/external_board_native/Makefile' )
2019-11-01 14:10:01 +01:00
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-11-01 14:10:01 +01:00
| error_with_message "Don't define APPLICATION in test Makefile"
}
2019-11-01 13:54:32 +01:00
# Develhelp should not be set via CFLAGS
checks_develhelp_not_defined_via_cflags( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e '^[[:space:]]*CFLAGS[[:space:]:+]+=[[:space:]:+]-DDEVELHELP' )
pathspec += ( '**/Makefile' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2019-11-01 13:54:32 +01:00
| error_with_message "Use DEVELHELP ?= 1 instead of using CFLAGS directly"
}
2020-01-13 11:52:41 +01:00
# Common code in boards should not use $(BOARD) to reference files
check_files_in_boards_not_reference_board_var( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e '/$(BOARD)/' )
pathspec += ( 'boards/' )
# boards/common/nrf52 uses a hack to resolve dependencies early
pathspec += ( ':!boards/common/nrf52/Makefile.include' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2020-01-13 11:52:41 +01:00
| error_with_message 'Code in boards/ should not use $(BOARDS) to reference files since this breaks external BOARDS changing BOARDSDIR"'
}
2020-06-25 10:15:23 +02:00
check_no_pseudomodules_in_makefile_dep( ) {
2020-05-23 16:35:05 +02:00
local patterns = ( )
local pathspec = ( )
patterns += ( -e 'PSEUDOMODULES[\t ]*[+:]*=' )
pathspec += ( '**/Makefile.dep' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2020-05-23 16:35:05 +02:00
| error_with_message "Don't define PSEUDOMODULES in Makefile.dep"
}
2020-06-25 09:55:37 +02:00
check_no_usemodules_in_makefile_include( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e 'USEMODULE[\t ]*[+:]*=' )
pathspec += ( '**/Makefile.include' )
pathspec += ( ':!Makefile.include' )
pathspec += ( ':!tests/**/Makefile.include' )
pathspec += ( ':!examples/**/Makefile.include' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2020-06-25 09:55:37 +02:00
| error_with_message "Don't include USEMODULE in Makefile.include"
}
2021-01-08 15:04:28 +01:00
check_no_pkg_source_local( ) {
local patterns = ( )
local pathspec = ( )
patterns += ( -e 'PKG_SOURCE_LOCAL' )
pathspec += ( 'pkg/*/Makefile' )
2021-01-12 16:30:22 +01:00
git -C " ${ RIOTBASE } " grep -n " ${ patterns [@] } " -- " ${ pathspec [@] } " \
2021-01-08 15:04:28 +01:00
| error_with_message "Don't push PKG_SOURCE_LOCAL definitions upstream"
}
2019-06-13 15:53:58 +02:00
error_on_input( ) {
2019-06-14 12:24:31 +02:00
! grep ''
2019-06-13 15:53:58 +02:00
}
2019-06-13 15:55:15 +02:00
all_checks( ) {
check_not_parsing_features
2020-05-29 09:23:59 +02:00
check_providing_features_only_makefile_features
2019-06-13 15:55:15 +02:00
check_not_exporting_variables
2019-06-11 11:59:26 +02:00
check_deprecated_vars_patterns
2019-05-02 13:26:30 +02:00
check_board_do_not_include_cpu_features_dep
2019-05-02 13:26:30 +02:00
check_cpu_cpu_model_defined_in_makefile_features
2019-08-14 17:13:22 +02:00
check_not_setting_board_equal
2019-10-11 16:37:11 +02:00
check_board_insufficient_memory_not_in_makefile
2019-11-01 14:10:01 +01:00
checks_tests_application_not_defined_in_makefile
2019-11-01 13:54:32 +01:00
checks_develhelp_not_defined_via_cflags
2020-01-13 11:52:41 +01:00
check_files_in_boards_not_reference_board_var
2020-06-25 10:15:23 +02:00
check_no_pseudomodules_in_makefile_dep
2020-06-25 09:55:37 +02:00
check_no_usemodules_in_makefile_include
2021-01-08 15:04:28 +01:00
check_no_pkg_source_local
2019-06-13 15:55:15 +02:00
}
2018-09-26 17:10:12 +02:00
2019-06-13 15:55:15 +02:00
main( ) {
2019-06-14 10:57:52 +02:00
all_checks | prepend 'Invalid build system patterns found by ' " ${ 0 } : " | error_on_input >& 2
2019-06-13 15:55:15 +02:00
exit $?
2018-09-26 17:10:12 +02:00
}
if [ [ " ${ BASH_SOURCE [0] } " = = " ${ 0 } " ] ] ; then
2021-01-12 16:31:08 +01:00
github_annotate_setup
2018-09-26 17:10:12 +02:00
main
2021-01-12 16:31:08 +01:00
github_annotate_teardown
github_annotate_report_last_run
2018-09-26 17:10:12 +02:00
fi