cmake: zephyr modules: sanitize all module name when used as variable
The introduction of Zephyr module glue code in the Zephyr repository introduces a Kconfig variable in the form of: `config ZEPHYR_<MODULE_NAME>_MODULE`. All Kconfig variables go into `autoconf.h`, therefore it is necessary to sanitize the Kconfig variable, so that it does not contain special characters. To ensure consistent variable name, then the module name will be sanitized in all variable use in both Kconfig and CMake. The sanitization is done be replacing all special characters with an underscore, `_`. Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
0ce0f63036
commit
3d88083bf1
|
@ -454,7 +454,7 @@ foreach(module_name ${ZEPHYR_MODULE_NAMES})
|
||||||
# this binary_dir is created but stays empty. Object files land in
|
# this binary_dir is created but stays empty. Object files land in
|
||||||
# the main binary dir instead.
|
# the main binary dir instead.
|
||||||
# https://cmake.org/pipermail/cmake/2019-June/069547.html
|
# https://cmake.org/pipermail/cmake/2019-June/069547.html
|
||||||
string(TOUPPER ${module_name} MODULE_NAME_UPPER)
|
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
|
||||||
if(NOT ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "")
|
if(NOT ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR} STREQUAL "")
|
||||||
set(ZEPHYR_CURRENT_MODULE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR})
|
set(ZEPHYR_CURRENT_MODULE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR})
|
||||||
set(ZEPHYR_CURRENT_CMAKE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR})
|
set(ZEPHYR_CURRENT_CMAKE_DIR ${ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR})
|
||||||
|
|
|
@ -1960,6 +1960,47 @@ Relative paths are only allowed with `-D${ARGV1}=<path>`")
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# zephyr_string(<mode> <out-var> <input> ...)
|
||||||
|
#
|
||||||
|
# Zephyr string function extension.
|
||||||
|
# This function extends the CMake string function by providing additional
|
||||||
|
# manipulation arguments to CMake string.
|
||||||
|
#
|
||||||
|
# SANITIZE: Ensure that the output string does not contain any special
|
||||||
|
# characters. Special characters, such as -, +, =, $, etc. are
|
||||||
|
# converted to underscores '_'.
|
||||||
|
#
|
||||||
|
# SANITIZE TOUPPER: Ensure that the output string does not contain any special
|
||||||
|
# characters. Special characters, such as -, +, =, $, etc. are
|
||||||
|
# converted to underscores '_'.
|
||||||
|
# The sanitized string will be returned in UPPER case.
|
||||||
|
#
|
||||||
|
# returns the updated string
|
||||||
|
function(zephyr_string)
|
||||||
|
set(options SANITIZE TOUPPER)
|
||||||
|
cmake_parse_arguments(ZEPHYR_STRING "${options}" "" "" ${ARGN})
|
||||||
|
|
||||||
|
if (NOT ZEPHYR_STRING_UNPARSED_ARGUMENTS)
|
||||||
|
message(FATAL_ERROR "Function zephyr_string() called without a return variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(GET ZEPHYR_STRING_UNPARSED_ARGUMENTS 0 return_arg)
|
||||||
|
list(REMOVE_AT ZEPHYR_STRING_UNPARSED_ARGUMENTS 0)
|
||||||
|
|
||||||
|
list(JOIN ZEPHYR_STRING_UNPARSED_ARGUMENTS "" work_string)
|
||||||
|
|
||||||
|
if(ZEPHYR_STRING_SANITIZE)
|
||||||
|
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" work_string ${work_string})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ZEPHYR_STRING_TOUPPER)
|
||||||
|
string(TOUPPER ${work_string} work_string)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${return_arg} ${work_string} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
# zephyr_check_cache(<variable> [REQUIRED])
|
# zephyr_check_cache(<variable> [REQUIRED])
|
||||||
#
|
#
|
||||||
|
|
|
@ -69,7 +69,7 @@ string(REPLACE ";" "?" DTS_ROOT_BINDINGS "${DTS_ROOT_BINDINGS}")
|
||||||
# This allows Kconfig files to refer relative from a modules root as:
|
# This allows Kconfig files to refer relative from a modules root as:
|
||||||
# source "$(ZEPHYR_FOO_MODULE_DIR)/Kconfig"
|
# source "$(ZEPHYR_FOO_MODULE_DIR)/Kconfig"
|
||||||
foreach(module_name ${ZEPHYR_MODULE_NAMES})
|
foreach(module_name ${ZEPHYR_MODULE_NAMES})
|
||||||
string(TOUPPER ${module_name} MODULE_NAME_UPPER)
|
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
|
||||||
list(APPEND
|
list(APPEND
|
||||||
ZEPHYR_KCONFIG_MODULES_DIR
|
ZEPHYR_KCONFIG_MODULES_DIR
|
||||||
"ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR=${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}"
|
"ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR=${ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR}"
|
||||||
|
|
|
@ -104,7 +104,7 @@ if(WEST OR ZEPHYR_MODULES)
|
||||||
|
|
||||||
list(APPEND ZEPHYR_MODULE_NAMES ${module_name})
|
list(APPEND ZEPHYR_MODULE_NAMES ${module_name})
|
||||||
|
|
||||||
string(TOUPPER ${module_name} MODULE_NAME_UPPER)
|
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
|
||||||
if(NOT ${MODULE_NAME_UPPER} STREQUAL CURRENT)
|
if(NOT ${MODULE_NAME_UPPER} STREQUAL CURRENT)
|
||||||
set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path})
|
set(ZEPHYR_${MODULE_NAME_UPPER}_MODULE_DIR ${module_path})
|
||||||
set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${cmake_path})
|
set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${cmake_path})
|
||||||
|
|
|
@ -421,6 +421,13 @@ CMake variable ``ZEPHYR_<MODULE_NAME>_MODULE_DIR`` and the variable
|
||||||
``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` holds the location of the directory
|
``ZEPHYR_<MODULE_NAME>_CMAKE_DIR`` holds the location of the directory
|
||||||
containing the module's :file:`CMakeLists.txt` file.
|
containing the module's :file:`CMakeLists.txt` file.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
When used for CMake and Kconfig variables, all letters in module names are
|
||||||
|
converted to uppercase and all non-alphanumeric characters are converted
|
||||||
|
to underscores (_).
|
||||||
|
As example, the module ``foo-bar`` must be referred to as
|
||||||
|
``ZEPHYR_FOO_BAR_MODULE_DIR`` in CMake and Kconfig.
|
||||||
|
|
||||||
Here is an example for the Zephyr module ``foo``:
|
Here is an example for the Zephyr module ``foo``:
|
||||||
|
|
||||||
.. code-block:: yaml
|
.. code-block:: yaml
|
||||||
|
|
|
@ -5,7 +5,8 @@ file(GLOB cmake_modules "${CMAKE_CURRENT_LIST_DIR}/*/CMakeLists.txt")
|
||||||
foreach(module ${cmake_modules})
|
foreach(module ${cmake_modules})
|
||||||
get_filename_component(module_dir ${module} DIRECTORY)
|
get_filename_component(module_dir ${module} DIRECTORY)
|
||||||
get_filename_component(module_name ${module_dir} NAME)
|
get_filename_component(module_name ${module_dir} NAME)
|
||||||
string(TOUPPER ${module_name} MODULE_NAME_UPPER)
|
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
|
||||||
|
|
||||||
set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${module_dir})
|
set(ZEPHYR_${MODULE_NAME_UPPER}_CMAKE_DIR ${module_dir})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ file(GLOB kconfig_modules "${CMAKE_CURRENT_LIST_DIR}/*/Kconfig")
|
||||||
foreach(module ${kconfig_modules})
|
foreach(module ${kconfig_modules})
|
||||||
get_filename_component(module_dir ${module} DIRECTORY)
|
get_filename_component(module_dir ${module} DIRECTORY)
|
||||||
get_filename_component(module_name ${module_dir} NAME)
|
get_filename_component(module_name ${module_dir} NAME)
|
||||||
string(TOUPPER ${module_name} MODULE_NAME_UPPER)
|
zephyr_string(SANITIZE TOUPPER MODULE_NAME_UPPER ${module_name})
|
||||||
|
|
||||||
set(ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG ${module_dir}/Kconfig)
|
set(ZEPHYR_${MODULE_NAME_UPPER}_KCONFIG ${module_dir}/Kconfig)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
|
@ -262,7 +262,7 @@ class KconfigCheck(ComplianceTest):
|
||||||
with open(modules_file, 'w') as fp_module_file:
|
with open(modules_file, 'w') as fp_module_file:
|
||||||
for module in modules:
|
for module in modules:
|
||||||
fp_module_file.write("ZEPHYR_{}_KCONFIG = {}\n".format(
|
fp_module_file.write("ZEPHYR_{}_KCONFIG = {}\n".format(
|
||||||
module.upper(),
|
re.sub('[^a-zA-Z0-9]', '_', module).upper(),
|
||||||
modules_dir + '/' + module + '/Kconfig'
|
modules_dir + '/' + module + '/Kconfig'
|
||||||
))
|
))
|
||||||
fp_module_file.write(content)
|
fp_module_file.write(content)
|
||||||
|
|
|
@ -19,6 +19,7 @@ maintained in modules in addition to what is available in the main Zephyr tree.
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
import pykwalify.core
|
import pykwalify.core
|
||||||
|
@ -128,11 +129,13 @@ def process_module(module):
|
||||||
.format(module_yml.as_posix(), e))
|
.format(module_yml.as_posix(), e))
|
||||||
|
|
||||||
meta['name'] = meta.get('name', module_path.name)
|
meta['name'] = meta.get('name', module_path.name)
|
||||||
|
meta['name-sanitized'] = re.sub('[^a-zA-Z0-9]', '_', meta['name'])
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
if Path(module_path.joinpath('zephyr/CMakeLists.txt')).is_file() and \
|
if Path(module_path.joinpath('zephyr/CMakeLists.txt')).is_file() and \
|
||||||
Path(module_path.joinpath('zephyr/Kconfig')).is_file():
|
Path(module_path.joinpath('zephyr/Kconfig')).is_file():
|
||||||
return {'name': module_path.name,
|
return {'name': module_path.name,
|
||||||
|
'name-sanitized': re.sub('[^a-zA-Z0-9]', '_', module_path.name),
|
||||||
'build': {'cmake': 'zephyr', 'kconfig': 'zephyr/Kconfig'}}
|
'build': {'cmake': 'zephyr', 'kconfig': 'zephyr/Kconfig'}}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -148,7 +151,7 @@ def process_cmake(module, meta):
|
||||||
return('\"{}\":\"{}\":\"{}\"\n'
|
return('\"{}\":\"{}\":\"{}\"\n'
|
||||||
.format(meta['name'],
|
.format(meta['name'],
|
||||||
module_path.as_posix(),
|
module_path.as_posix(),
|
||||||
"${ZEPHYR_" + meta['name'].upper() + "_CMAKE_DIR}"))
|
"${ZEPHYR_" + meta['name-sanitized'].upper() + "_CMAKE_DIR}"))
|
||||||
|
|
||||||
cmake_setting = section.get('cmake', None)
|
cmake_setting = section.get('cmake', None)
|
||||||
if not validate_setting(cmake_setting, module, 'CMakeLists.txt'):
|
if not validate_setting(cmake_setting, module, 'CMakeLists.txt'):
|
||||||
|
@ -185,11 +188,14 @@ def process_settings(module, meta):
|
||||||
return out_text
|
return out_text
|
||||||
|
|
||||||
|
|
||||||
def kconfig_snippet(name, path, kconfig_file=None):
|
def kconfig_snippet(meta, path, kconfig_file=None):
|
||||||
|
name = meta['name']
|
||||||
|
name_sanitized = meta['name-sanitized']
|
||||||
|
|
||||||
snippet = (f'menu "{name} ({path})"',
|
snippet = (f'menu "{name} ({path})"',
|
||||||
f'osource "{kconfig_file.resolve().as_posix()}"' if kconfig_file
|
f'osource "{kconfig_file.resolve().as_posix()}"' if kconfig_file
|
||||||
else f'osource "$(ZEPHYR_{name.upper()}_KCONFIG)"',
|
else f'osource "$(ZEPHYR_{name_sanitized.upper()}_KCONFIG)"',
|
||||||
f'config ZEPHYR_{name.upper()}_MODULE',
|
f'config ZEPHYR_{name_sanitized.upper()}_MODULE',
|
||||||
' bool',
|
' bool',
|
||||||
' default y',
|
' default y',
|
||||||
'endmenu\n')
|
'endmenu\n')
|
||||||
|
@ -202,7 +208,7 @@ def process_kconfig(module, meta):
|
||||||
module_yml = module_path.joinpath('zephyr/module.yml')
|
module_yml = module_path.joinpath('zephyr/module.yml')
|
||||||
kconfig_extern = section.get('kconfig-ext', False)
|
kconfig_extern = section.get('kconfig-ext', False)
|
||||||
if kconfig_extern:
|
if kconfig_extern:
|
||||||
return kconfig_snippet(meta['name'], module_path)
|
return kconfig_snippet(meta, module_path)
|
||||||
|
|
||||||
kconfig_setting = section.get('kconfig', None)
|
kconfig_setting = section.get('kconfig', None)
|
||||||
if not validate_setting(kconfig_setting, module):
|
if not validate_setting(kconfig_setting, module):
|
||||||
|
@ -212,7 +218,7 @@ def process_kconfig(module, meta):
|
||||||
|
|
||||||
kconfig_file = os.path.join(module, kconfig_setting or 'zephyr/Kconfig')
|
kconfig_file = os.path.join(module, kconfig_setting or 'zephyr/Kconfig')
|
||||||
if os.path.isfile(kconfig_file):
|
if os.path.isfile(kconfig_file):
|
||||||
return kconfig_snippet(meta['name'], module_path, Path(kconfig_file))
|
return kconfig_snippet(meta, module_path, Path(kconfig_file))
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue