diff --git a/doc/develop/languages/cpp/index.rst b/doc/develop/languages/cpp/index.rst index 86b994c06d30..1eb61059822e 100644 --- a/doc/develop/languages/cpp/index.rst +++ b/doc/develop/languages/cpp/index.rst @@ -36,8 +36,17 @@ The C++ standard requires the ``main()`` function to have the return type of has to be selected. Zephyr ignores the return value from main, so applications should not return status information and should, instead, return zero. +If you need to access data from the device tree in C++ files, add the following +argument to the ``west build`` command to prevent compile-time macro expansion +issues: + +.. code-block:: console + + EXTRA_GEN_DEFINES_ARGS=--no-inline-comments + .. note:: - Do not use C++ for kernel, driver, or system initialization code. + + Do not use C++ for kernel, driver, or system initialization code. Language Features ***************** diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py index 99aac7d720ce..ab8e9ea91c11 100755 --- a/scripts/dts/gen_defines.py +++ b/scripts/dts/gen_defines.py @@ -32,8 +32,10 @@ def main(): global header_file global flash_area_num + global no_inline_comments args = parse_args() + no_inline_comments = args.no_inline_comments edtlib_logger.setup_edtlib_logging() @@ -136,6 +138,8 @@ def parse_args() -> argparse.Namespace: help="path to write header to") parser.add_argument("--edt-pickle", help="path to read pickled edtlib.EDT object from") + parser.add_argument("--no-inline-comments", action="store_true", + help="remove comments from #define lines") return parser.parse_args() @@ -1016,6 +1020,9 @@ def out_define( warn = fr' __WARN("{deprecation_msg}")' if deprecation_msg else "" + if no_inline_comments: + val = re.sub("\\s*/\\*.*?\\*/\\s*", "", str(val)) + if width: s = f"#define {macro.ljust(width)}{warn} {val}" else: diff --git a/tests/lib/cpp/cxx/app.overlay b/tests/lib/cpp/cxx/app.overlay index 69b87b4c7ac7..21a83ccf7736 100644 --- a/tests/lib/cpp/cxx/app.overlay +++ b/tests/lib/cpp/cxx/app.overlay @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 * * Application overlay for creating a fake device instance we can use to - * test. Subset of tests/kernel/device/app.overlay and other app.overlay - * files. + * test. Nested devices have been used to avoid cross-platform issues by + * forcing a specific 'reg' property size on child nodes. */ / { @@ -20,4 +20,18 @@ zephyr,deferred-init; }; + + test_ctrl: ctrl { + compatible = "fake-cpp-driver"; + status = "okay"; + + #address-cells = < 1 >; + #size-cells = < 0 >; + + test_dev2_reg_addr: dev2@2 { + reg = < 2 >; + compatible = "fake-cpp-driver"; + status = "okay"; + }; + }; }; diff --git a/tests/lib/cpp/cxx/src/main.cpp b/tests/lib/cpp/cxx/src/main.cpp index d2704e0d992f..8d66166b7159 100644 --- a/tests/lib/cpp/cxx/src/main.cpp +++ b/tests/lib/cpp/cxx/src/main.cpp @@ -153,3 +153,22 @@ PM_DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), fake_pm_action); DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), NULL, PM_DEVICE_DT_GET(DT_NODELABEL(test_dev0_boot)), NULL, NULL, POST_KERNEL, 34, NULL); + +/* + * Test preprocessor comment removal. The reg value is defined as 2 in the + * device tree, but gen_defines.py by default outputs an entry that includes a + * trailing comment, such as: + * + * #define DT_N_S_ctrl_S_dev2_2_REG_IDX_0_VAL_ADDRESS 2 / * 0x2 * / + * + * That comment, when present, confuses the C++ preprocessor and results in + * issues like the following: + * + * error: pasting "/ * 0x2 * /" and "U" does not give a valid preprocessing token + * + * or, in this synthetic test case: + * + * error: unable to find numeric literal operator 'operator""UU' + */ +#define VALUE_FROM_DT DT_REG_ADDR(DT_NODELABEL(test_dev2_reg_addr)) +BUILD_ASSERT(UINT32_C(VALUE_FROM_DT) == 2U); diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index a19802928c81..5c5eedbadf1c 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -4,6 +4,8 @@ common: integration_platforms: - mps2/an385 - qemu_cortex_a53 + extra_args: + - EXTRA_GEN_DEFINES_ARGS=--no-inline-comments tests: cpp.main.minimal: