Skip to content

Commit 1198087

Browse files
tejlmandcfriedt
authored andcommitted
cmake: APPLICATION_CONFIG_DIR support implemented
With this commit a dedicated APPLICATION_CONFIG_DIR is added to the Zephyr build system. Currently, the APPLICATION_SOURCE_DIR is identical also the base location of configuration files. This is very practical for simple samples, but also has it limitations for more complex setups. Introducing a dedicated APPLICATION_CONFIG_DIR allows users more customization options in Zephyr build system. Especially in terms of custom build configuration files unknown to Zephyr itself. For example, instead of all configuration files being located directly in the application source folder, a project might prefer to organize their configuration files on a per board basis, for example: <app>/boards/custom_board_A/prj.conf <app>/boards/custom_board_A/app.overlay <app>/boards/custom_board_A/custom_file.mine <app>/boards/custom_board_B/prj.conf <app>/boards/custom_board_B/app.overlay <app>/boards/custom_board_B/custom_file.mine ... instead of n-files located in the root of the sample. If the user / sample specifies APPLICATION_CONFIG_DIR, then this folder will always be used instead of the default configuration folder. As part of this extension the behaviour of `-DCONF_FILE=<relative-path>/prj_<build>.conf` and additional Kconfig fragments automatic sourcing has been aligned with the default behavior of `prj.conf`. Signed-off-by: Torsten Rasmussen <[email protected]>
1 parent 2eb1315 commit 1198087

File tree

9 files changed

+116
-23
lines changed

9 files changed

+116
-23
lines changed

cmake/app/boilerplate.cmake

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,17 @@ please check your installation. ARCH roots searched: \n\
424424
${ARCH_ROOT}")
425425
endif()
426426

427+
if(DEFINED APPLICATION_CONFIG_DIR)
428+
string(CONFIGURE ${APPLICATION_CONFIG_DIR} APPLICATION_CONFIG_DIR)
429+
if(NOT IS_ABSOLUTE ${APPLICATION_CONFIG_DIR})
430+
get_filename_component(APPLICATION_CONFIG_DIR ${APPLICATION_CONFIG_DIR} ABSOLUTE)
431+
endif()
432+
else()
433+
# Application config dir is not set, so we default to the application
434+
# source directory as configuration directory.
435+
set(APPLICATION_CONFIG_DIR ${APPLICATION_SOURCE_DIR})
436+
endif()
437+
427438
if(DEFINED CONF_FILE)
428439
# This ensures that CACHE{CONF_FILE} will be set correctly to current scope
429440
# variable CONF_FILE. An already current scope variable will stay the same.
@@ -441,14 +452,9 @@ if(DEFINED CONF_FILE)
441452
# Need the file name to look for match.
442453
# Need path in order to check if it is absolute.
443454
get_filename_component(CONF_FILE_NAME ${CONF_FILE} NAME)
444-
get_filename_component(CONF_FILE_DIR ${CONF_FILE} DIRECTORY)
445455
if(${CONF_FILE_NAME} MATCHES "prj_(.*).conf")
446456
set(CONF_FILE_BUILD_TYPE ${CMAKE_MATCH_1})
447457
set(CONF_FILE_INCLUDE_FRAGMENTS true)
448-
449-
if(NOT IS_ABSOLUTE ${CONF_FILE_DIR})
450-
set(CONF_FILE_DIR ${APPLICATION_SOURCE_DIR}/${CONF_FILE_DIR})
451-
endif()
452458
endif()
453459
endif()
454460
elseif(CACHED_CONF_FILE)
@@ -459,21 +465,19 @@ elseif(CACHED_CONF_FILE)
459465
elseif(DEFINED ENV{CONF_FILE})
460466
set(CONF_FILE $ENV{CONF_FILE})
461467

462-
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf)
463-
set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf)
468+
elseif(EXISTS ${APPLICATION_CONFIG_DIR}/prj_${BOARD}.conf)
469+
set(CONF_FILE ${APPLICATION_CONFIG_DIR}/prj_${BOARD}.conf)
464470

465-
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj.conf)
466-
set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf)
471+
elseif(EXISTS ${APPLICATION_CONFIG_DIR}/prj.conf)
472+
set(CONF_FILE ${APPLICATION_CONFIG_DIR}/prj.conf)
467473
set(CONF_FILE_INCLUDE_FRAGMENTS true)
468474
endif()
469475

470476
if(CONF_FILE_INCLUDE_FRAGMENTS)
471-
if(NOT CONF_FILE_DIR)
472-
set(CONF_FILE_DIR ${APPLICATION_SOURCE_DIR})
473-
endif()
474-
zephyr_file(CONF_FILES ${CONF_FILE_DIR}/boards KCONF CONF_FILE BUILD ${CONF_FILE_BUILD_TYPE})
477+
zephyr_file(CONF_FILES ${APPLICATION_CONFIG_DIR}/boards KCONF CONF_FILE BUILD ${CONF_FILE_BUILD_TYPE})
475478
endif()
476479

480+
set(APPLICATION_CONFIG_DIR ${APPLICATION_CONFIG_DIR} CACHE INTERNAL "The application configuration folder")
477481
set(CACHED_CONF_FILE ${CONF_FILE} CACHE STRING "If desired, you can build the application using\
478482
the configuration settings specified in an alternate .conf file using this parameter. \
479483
These settings will override the settings in the application’s .config file or its default .conf file.\
@@ -482,7 +486,7 @@ The CACHED_CONF_FILE is internal Zephyr variable used between CMake runs. \
482486
To change CONF_FILE, use the CONF_FILE variable.")
483487
unset(CONF_FILE CACHE)
484488

485-
zephyr_file(CONF_FILES ${APPLICATION_SOURCE_DIR}/boards DTS APP_BOARD_DTS)
489+
zephyr_file(CONF_FILES ${APPLICATION_CONFIG_DIR}/boards DTS APP_BOARD_DTS)
486490

487491
# The CONF_FILE variable is now set to its final value.
488492
zephyr_boilerplate_watch(CONF_FILE)
@@ -492,10 +496,10 @@ if(DTC_OVERLAY_FILE)
492496
# in the CMakeCache.txt.
493497
elseif(APP_BOARD_DTS)
494498
set(DTC_OVERLAY_FILE ${APP_BOARD_DTS})
495-
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay)
496-
set(DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay)
497-
elseif(EXISTS ${APPLICATION_SOURCE_DIR}/app.overlay)
498-
set(DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/app.overlay)
499+
elseif(EXISTS ${APPLICATION_CONFIG_DIR}/${BOARD}.overlay)
500+
set(DTC_OVERLAY_FILE ${APPLICATION_CONFIG_DIR}/${BOARD}.overlay)
501+
elseif(EXISTS ${APPLICATION_CONFIG_DIR}/app.overlay)
502+
set(DTC_OVERLAY_FILE ${APPLICATION_CONFIG_DIR}/app.overlay)
499503
endif()
500504

501505
set(DTC_OVERLAY_FILE ${DTC_OVERLAY_FILE} CACHE STRING "If desired, you can \

cmake/kconfig.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ foreach(f ${merge_config_files})
199199
if(IS_ABSOLUTE ${f})
200200
set(path ${f})
201201
else()
202-
set(path ${APPLICATION_SOURCE_DIR}/${f})
202+
set(path ${APPLICATION_CONFIG_DIR}/${f})
203203
endif()
204204

205205
list(APPEND merge_config_files_with_absolute_paths ${path})

doc/application/index.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,29 @@ documentation `runningcmake`_ .
587587
Application Configuration
588588
*************************
589589

590+
.. _application-configuration-directory:
591+
592+
Application Configuration Directory
593+
===================================
594+
595+
Zephyr will use configuration files from the application's configuration
596+
directory except for files with an absolute path provided by the arguments
597+
described earlier, for example ``CONF_FILE``, ``OVERLAY_CONFIG``, and
598+
``DTC_OVERLAY_FILE``.
599+
600+
The application configuration directory is defined by the
601+
``APPLICATION_CONFIG_DIR`` variable.
602+
603+
``APPLICATION_CONFIG_DIR`` will be set by one of the sources below with the
604+
highest priority listed first.
605+
606+
1. If ``APPLICATION_CONFIG_DIR`` is specified by the user with
607+
``-DAPPLICATION_CONFIG_DIR=<path>`` or in a CMake file before
608+
``find_package(Zephyr)`` then this folder is used a the application's
609+
configuration directory.
610+
611+
2. The application's source directory.
612+
590613
.. _application-kconfig:
591614

592615
Kconfig Configuration

doc/guides/build/kconfig/setting.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,26 @@ The application configuration can come from the sources below. By default,
154154
:file:`boards/<BOARD>_<build>.conf` is used.
155155

156156
3. Otherwise, :file:`prj_<BOARD>.conf` is used if it exists in the application
157-
directory.
157+
configuration directory.
158158

159159
4. Otherwise, if :file:`boards/<BOARD>.conf` exists in the application
160-
directory, the result of merging it with :file:`prj.conf` is used.
160+
configuration directory, the result of merging it with :file:`prj.conf` is
161+
used.
161162

162163
5. Otherwise, if board revisions are used and
163164
:file:`boards/<BOARD>_<revision>.conf` exists in the application
164-
directory, the result of merging it with :file:`prj.conf` and
165+
configuration directory, the result of merging it with :file:`prj.conf` and
165166
:file:`boards/<BOARD>.conf` is used.
166167

167168
6. Otherwise, :file:`prj.conf` is used if it exists in the application
168-
directory
169+
configuration directory
170+
171+
All configuration files will be taken from the application's configuration
172+
directory except for files with an absolute path that are given with the
173+
``CONF_FILE`` argument.
174+
175+
See :ref:`Application Configuration Directory <application-configuration-directory>`
176+
on how the application configuration directory is defined.
169177

170178
If a symbol is assigned both in :file:`<BOARD>_defconfig` and in the
171179
application configuration, the value set in the application configuration takes
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
if(DEFINED APPLICATION_CONFIG_DIR)
6+
# Has been specified as relative on CMake invocation, convert to absolute
7+
# and keep reference to see it's identical when Zephyr boilerplate returns.
8+
get_filename_component(EXPECTED_APPLICATION_CONFIG_DIR ${APPLICATION_CONFIG_DIR} ABSOLUTE)
9+
else()
10+
# We expect a board config setup
11+
set(EXPECTED_APPLICATION_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD})
12+
endif()
13+
14+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
15+
16+
project(app_config_dir_test)
17+
18+
if(CONFIG_FAIL_TEST)
19+
message(FATAL_ERROR "Test failed, "
20+
"actual CONFIG_FAIL_TEST=${CONFIG_FAIL_TEST}, "
21+
"expected CONFIG_FAIL_TEST=n"
22+
)
23+
endif()
24+
25+
if(NOT "${APPLICATION_CONFIG_DIR}" STREQUAL "${EXPECTED_APPLICATION_CONFIG_DIR}")
26+
message(FATAL_ERROR "Test failed, "
27+
"actual APPLICATION_CONFIG_DIR=${APPLICATION_CONFIG_DIR}, "
28+
"expected APPLICATION_CONFIG_DIR=${EXPECTED_APPLICATION_CONFIG_DIR}"
29+
)
30+
endif()
31+
32+
target_sources(app PRIVATE src/main.c)

tests/cmake/config_dir/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2021 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config FAIL_TEST
5+
bool "Fail the test"
6+
default y
7+
8+
source "Kconfig.zephyr"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# If this config is loaded, then the test will pass and specifying a custom
2+
# configuration dir worked correctly.
3+
CONFIG_FAIL_TEST=n

tests/cmake/config_dir/src/main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* Copyright (c) 2021 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
void test_main(void)
8+
{
9+
/* Intentionally left empty, we are testing CMake. */
10+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
tests:
2+
config_dir.user_defined:
3+
platform_allow: native_posix
4+
build_only: true
5+
extra_args: APPLICATION_CONFIG_DIR:PATH=foo

0 commit comments

Comments
 (0)