Skip to content

Commit 6cf5fa6

Browse files
committed
[nrf fromtree] cmake: introduce build_info function
The build_info function provides a generic and stable way of dumping build information to the <build>/build_info.yml file. The build info file is in YAML format and the keys in the file are intended to be stable, as to allow external tools to retrieve information regarding the build. The main differences to the CMakeCache.txt are: - Settings in the CMakeCache.txt are user controlled, whereas the information in the build info file is intended to be those values which are used by the build system regardless if those are specified by the developer or picked up automatically. - Internal build system variables are not present in the CMake cache and should not be, because their values are calculated when CMake runs. This also has the benefits of decoupling CMake variable names from build info keys. Several CMake variables has internal build system names, and the build system is free to rename those at its own discretion. Having dedicated key names ensures a stable API that external tools can rely upon. Signed-off-by: Torsten Rasmussen <[email protected]> (cherry picked from commit 5d5c2d4)
1 parent 26a9604 commit 6cf5fa6

File tree

3 files changed

+177
-0
lines changed

3 files changed

+177
-0
lines changed

cmake/modules/extensions.cmake

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3595,6 +3595,67 @@ function(topological_sort)
35953595
set(${TS_RESULT} "${sorted_targets}" PARENT_SCOPE)
35963596
endfunction()
35973597

3598+
# Usage:
3599+
# build_info(<tag>... VALUE <value>...)
3600+
#
3601+
# This function populates updates the build_info.yml info file with exchangable build information
3602+
# related to the current build.
3603+
#
3604+
# Example:
3605+
# build_info(devicetree files VALUE file1.dts file2.dts file3.dts)
3606+
# Will update the 'devicetree files' key in the build info yaml with the list
3607+
# of files, file1.dts file2.dts file3.dts.
3608+
#
3609+
# build_info(vendor-specific foo VALUE bar)
3610+
# Will place the vendor specific key 'foo' with value 'bar' in the vendor specific section
3611+
# of the build info file.
3612+
#
3613+
# <tag>...: One of the pre-defined valid CMake keys supported by build info or vendor-specific.
3614+
# See 'scripts/schemas/build-schema.yml' CMake section for valid tags.
3615+
# VALUE <value>... : value(s) to place in the build_info.yml file.
3616+
function(build_info)
3617+
set(arg_list ${ARGV})
3618+
list(FIND arg_list VALUE index)
3619+
if(index EQUAL -1)
3620+
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}(...) missing a required argument: VALUE")
3621+
endif()
3622+
3623+
yaml_context(EXISTS NAME build_info result)
3624+
if(NOT result)
3625+
yaml_load(FILE ${ZEPHYR_BASE}/scripts/schemas/build-schema.yml NAME build_info_schema)
3626+
if(EXISTS ${CMAKE_BINARY_DIR}/build_info.yml)
3627+
yaml_load(FILE ${CMAKE_BINARY_DIR}/build_info.yml NAME build_info)
3628+
else()
3629+
yaml_create(FILE ${CMAKE_BINARY_DIR}/build_info.yml NAME build_info)
3630+
endif()
3631+
yaml_set(NAME build_info KEY version VALUE "0.1.0")
3632+
endif()
3633+
3634+
list(SUBLIST arg_list 0 ${index} keys)
3635+
list(SUBLIST arg_list ${index} -1 values)
3636+
list(POP_FRONT values)
3637+
3638+
if(ARGV0 STREQUAL "vendor-specific")
3639+
set(type VALUE)
3640+
else()
3641+
set(schema_check ${keys})
3642+
list(TRANSFORM schema_check PREPEND "mapping;")
3643+
yaml_get(check NAME build_info_schema KEY mapping cmake ${schema_check})
3644+
if(check MATCHES ".*-NOTFOUND")
3645+
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}(...) called with invalid tag: ${keys}")
3646+
endif()
3647+
3648+
yaml_get(type NAME build_info_schema KEY mapping cmake ${schema_check} type)
3649+
if(type MATCHES "seq|sequence")
3650+
set(type LIST)
3651+
else()
3652+
set(type VALUE)
3653+
endif()
3654+
endif()
3655+
3656+
yaml_set(NAME build_info KEY cmake ${keys} ${type} "${values}")
3657+
endfunction()
3658+
35983659
########################################################
35993660
# 4. Devicetree extensions
36003661
########################################################
@@ -5779,4 +5840,13 @@ if(CMAKE_SCRIPT_MODE_FILE)
57795840
function(zephyr_set variable)
57805841
# This silence the error: zephyr_set(... SCOPE <scope>) doesn't exists.
57815842
endfunction()
5843+
5844+
# Build info creates a custom target for handling of build info.
5845+
# build_info is not needed in script mode but still called by Zephyr CMake
5846+
# modules. Therefore disable build_info(...) in when including
5847+
# extensions.cmake in script mode.
5848+
function(build_info)
5849+
# This silence the error: 'YAML context 'build_info' does not exist.'
5850+
# 'Remember to create a YAML context'
5851+
endfunction()
57825852
endif()

cmake/modules/unittest.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ cmake_minimum_required(VERSION 3.20.0)
44

55
include(extensions)
66
include(west)
7+
include(yaml)
78
include(root)
89
include(zephyr_module)
910
include(boards)

scripts/schemas/build-schema.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2024, Nordic Semiconductor ASA
4+
5+
# A pykwalify schema for basic validation of the Zephyr build info YAML file.
6+
7+
type: map
8+
mapping:
9+
version:
10+
required: true
11+
type: str
12+
cmake:
13+
type: map
14+
mapping:
15+
application:
16+
type: map
17+
mapping:
18+
source-dir:
19+
type: str
20+
configuration-dir:
21+
type: str
22+
board:
23+
type: map
24+
mapping:
25+
name:
26+
required: true
27+
type: str
28+
qualifiers:
29+
type: str
30+
revision:
31+
type: str
32+
path:
33+
type: seq
34+
sequence:
35+
- type: str
36+
devicetree:
37+
type: map
38+
mapping:
39+
files:
40+
type: seq
41+
sequence:
42+
- type: str
43+
user-files:
44+
type: seq
45+
sequence:
46+
- type: str
47+
extra-user-files:
48+
type: seq
49+
sequence:
50+
- type: str
51+
include-dirs:
52+
type: seq
53+
sequence:
54+
- type: str
55+
bindings-dirs:
56+
type: seq
57+
sequence:
58+
- type: str
59+
kconfig:
60+
type: map
61+
mapping:
62+
files:
63+
type: seq
64+
sequence:
65+
- type: str
66+
user-files:
67+
type: seq
68+
sequence:
69+
- type: str
70+
extra-user-files:
71+
type: seq
72+
sequence:
73+
- type: str
74+
sysbuild:
75+
type: bool
76+
toolchain:
77+
type: map
78+
mapping:
79+
name:
80+
type: str
81+
version:
82+
type: str
83+
path:
84+
type: str
85+
zephyr:
86+
type: map
87+
mapping:
88+
zephyr-base:
89+
type: str
90+
version:
91+
type: str
92+
vendor-specific:
93+
type: map
94+
mapping:
95+
regex;(.*):
96+
type: map
97+
mapping:
98+
regex;(.*):
99+
type: str
100+
west:
101+
type: map
102+
mapping:
103+
command:
104+
type: str
105+
topdir:
106+
type: str

0 commit comments

Comments
 (0)