Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: prototyping support for CMake presets json file. #3979

Closed
wants to merge 2 commits into from

Conversation

tejlmand
Copy link
Contributor

This commit introduces a CMakePresets.json in asset tracker.

CMake presets allows for additional sample and build description in a
single file.

The CMake presets also allows vendor specific fields, and thus allows
it to contain information that normally lives in sample.yaml or
testcase.yaml.

It is also possible to introduce IDE specific data to improve user
experience.

The sample can still be build with existing commands, but the preset
file also allows for building of the application as:
cmake -DBOARD=nrf9160dk_nrf9160ns --preset=default .
or
cmake -DBOARD=nrf9160dk_nrf9160ns --preset=test.

instead of:
cmake -DBOARD=nrf9160dk_nrf9160ns -GNinja -Bbuild .
or
cmake -DBOARD=nrf9160dk_nrf9160ns -GNinja -Bbuild -DCONF_FILE=prj_test.conf .

Signed-off-by: Torsten Rasmussen Torsten.Rasmussen@nordicsemi.no

@github-actions
Copy link

github-actions bot commented Feb 18, 2021

The following west manifest projects have been modified in this Pull Request:

Name Old Revision New Revision Diff
zephyr nrfconnect/sdk-zephyr@7598e62 nrfconnect/sdk-zephyr#469 nrfconnect/sdk-zephyr#469/files

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@tejlmand
Copy link
Contributor Author

Running twister with sample.yaml:

$ ../zephyr/scripts/twister  -N -T applications/asset_tracker
Renaming output directory to /projects/github/ncs/nrf/twister-out.11
INFO    - Zephyr version: v2.4.99-ncs1-rc1-4-g3237110cb770
INFO    - JOBS: 4
INFO    - Selecting default platforms per test case
INFO    - Building initial testcase list...
INFO    - 1 test suites (327 configurations) selected, 325 configurations discarded due to filters.
INFO    - Adding tasks to the queue...
INFO    - Added initial list of jobs to queue
INFO    - Total complete:    2/   2  100%  skipped:  325, failed:    0
INFO    - 2 of 2 test configurations passed (100.00%), 0 failed, 325 skipped with 0 warnings in 25.57 seconds
INFO    - In total 2 test cases were executed, 325 skipped on 327 out of total 328 platforms (99.70%)
INFO    - 0 test configurations executed on platforms, 2 test configurations were only built.
INFO    - Saving reports...
INFO    - Writing xunit report /projects/github/ncs/nrf/twister-out/twister.xml...
INFO    - Writing xunit report /projects/github/ncs/nrf/twister-out/twister_report.xml...
INFO    - Writing JSON report /projects/github/ncs/nrf/twister-out/twister.json
INFO    - Run completed

Running twister with CMakePresets.json:

$ ../zephyr/scripts/twister  -N -T applications/asset_tracker
Renaming output directory to /projects/github/ncs/nrf/twister-out.10
INFO    - Zephyr version: v2.4.99-ncs1-rc1-4-g3237110cb770
INFO    - JOBS: 4
INFO    - Selecting default platforms per test case
INFO    - Building initial testcase list...
INFO    - 1 test suites (327 configurations) selected, 325 configurations discarded due to filters.
INFO    - Adding tasks to the queue...
INFO    - Added initial list of jobs to queue
INFO    - Total complete:    2/   2  100%  skipped:  325, failed:    0
INFO    - 2 of 2 test configurations passed (100.00%), 0 failed, 325 skipped with 0 warnings in 32.79 seconds
INFO    - In total 2 test cases were executed, 325 skipped on 327 out of total 328 platforms (99.70%)
INFO    - 0 test configurations executed on platforms, 2 test configurations were only built.
INFO    - Saving reports...
INFO    - Writing xunit report /projects/github/ncs/nrf/twister-out/twister.xml...
INFO    - Writing xunit report /projects/github/ncs/nrf/twister-out/twister_report.xml...
INFO    - Writing JSON report /projects/github/ncs/nrf/twister-out/twister.json
INFO    - Run completed

This commit introduces a CMakePresets.json in asset tracker.

CMake presets allows for additional sample and build description in a
single file.

The CMake presets also allows vendor specific fields, and thus allows
it to contain information that normally lives in sample.yaml or
testcase.yaml.

It is also possible to introduce IDE specific data to improve user
experience.

The sample can still be build with existing commands, but the preset
file also allows for building of the application as:
`cmake -DBOARD=nrf9160dk_nrf9160ns --preset=default .`
or
`cmake -DBOARD=nrf9160dk_nrf9160ns --preset=test.`

instead of:
`cmake -DBOARD=nrf9160dk_nrf9160ns -GNinja -Bbuild .`
or
`cmake -DBOARD=nrf9160dk_nrf9160ns -GNinja -Bbuild
       -DCONF_FILE=prj_test.conf .`

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
@tejlmand tejlmand force-pushed the prototyping/cmake_presets branch from 3ff7090 to 546462a Compare February 18, 2021 13:37
@NordicBuilder
Copy link
Contributor

You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds.

Note: This comment is automatically posted by the Documentation Publishing GitHub Action.

@trond-snekvik
Copy link
Contributor

Can these presets also be used with west build?
Like this, perhaps?

west build --cmake-only -p -- --preset=default

or does west break the preset mechanism?

@mbolivar-nordic
Copy link
Contributor

or does west break the preset mechanism?

West is just a wrapper; you should be able to pass any CMake arguments you like, including --preset.

@trond-snekvik
Copy link
Contributor

West is just a wrapper; you should be able to pass any CMake arguments you like, including --preset.

West adds generator and directory flags unconditionally, so it's not a pure wrap. I suppose what I'm really asking is, does the preset override this, and should it?

@tejlmand
Copy link
Contributor Author

tejlmand commented Mar 5, 2021

West adds generator and directory flags unconditionally

Not true:

$ west build -b nrf52840dk_nrf52840 --cmake-only 
-- west build: generating a build system
....
$ cat build/CMakeCache.txt |grep CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM:FILEPATH=/home/tora/.local/bin/ninja

as expected, Ninja is used.

Now, let's tell CMake (and west) to use make instead

$ west build -b nrf52840dk_nrf52840 --cmake-only -- -G'Unix Makefiles'
-- west build: generating a build system
...
$ cat build/CMakeCache.txt |grep CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make

and because west invokes cmake --build then make will be the build command invoked through west.

So user can still overrule what west uses per default.

Specifying NCS Toolchain, v1.5.0 in preset.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
@github-actions github-actions bot added the CI-all-test Run All integration tests label Apr 14, 2021
@DatGizmo
Copy link
Contributor

With the new Integration Test Specification process we don't need the github labels.
I will remove them.

Right now this PR runs all Integration tests because it changes sdk-zephyr in west.yml and there is no test-spec.yml in that repo yet.
You can add changes to this PR nrfconnect/sdk-zephyr#767 to make the test spec here more targeted.

To get the test spec feature working correctly on this PR, you need to rebase it to the latest main to get the .github/test-spec.yml file

Then run CI here to update the test spec.

Information about the test spec feature
CI-Help for issues

@DatGizmo DatGizmo removed the CI-all-test Run All integration tests label Mar 16, 2022
@wbober wbober removed their request for review September 7, 2022 08:04
@marc-hb
Copy link

marc-hb commented Jan 3, 2023

West adds generator and directory flags unconditionally, so it's not a pure wrap

Do you have some specific examples or were you just guessing?

cc: @aborisovich

@trond-snekvik
Copy link
Contributor

Do you have some specific examples or were you just guessing?

Source directory, build directory, generator, -DBOARD and -DWEST_PYTHON, although some of these aren't completely unconditional, to be fair:
https://github.com/zephyrproject-rtos/zephyr/blob/dd468fc2618d55af2302abaf4cfcfbdd652a31a4/scripts/west_commands/build.py#L457-L485

The issue is that the preset doesn't stay a fully reproducible recipe for the build when you pass it to west:

  • If BOARD is set in the environment, it'll override the preset. If it's not, west build errors out.

  • The preset's values for generator and binary dir are always overridden, so use cases where you'd like to save what the name of the build directory should be are blocked. For instance, Bluetooth Audio projects need to set up one build for each earbud, and for their flash scripts to work, they have to use specific build names. This cannot be achieved by passing -- --preset <preset> to west, as this information is lost.

If we want preset support for west build, it has to become a proper flag for that west command, so these overrides can be stripped from the cmake invocation. This isn't some massive blocker, but I'm still of the opinion that west build doesn't cleanly wrap cmake in a way that's compatible with cmake presets and its primary use case (shareable and reproducible builds).

@tejlmand
Copy link
Contributor Author

tejlmand commented Jan 5, 2023

The issue is that the preset doesn't stay a fully reproducible recipe for the build when you pass it to west:

Presets main goal is not to ensure reproducible builds but easier sharing of settings.
From where do you get the impression that one of its main goal are reproducible builds ?

CMake supports two main files, CMakePresets.json and CMakeUserPresets.json, that allow users to specify common configure options and share them with others. CMake also supports files included with the include field.

Ref: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html

Even when using presets then user can still pass whatever setting they want in addition the the preset file by hand.
Hence the preset will never be trustworthy for reproducibility.
Also notice users can create user specific CMakeUserPresets.json for user specific adjustment, but note the following:

CMakeUserPresets.json should NOT be checked in. For example, if a project is using Git, CMakePresets.json may be tracked, and CMakeUserPresets.json should be added to the .gitignore.


so use cases where you'd like to save what the name of the build directory should be are blocked. For instance, Bluetooth Audio projects need to set up one build for each earbud, and for their flash scripts to work, they have to use specific build names.

Presets doesn't give you that, even if you specify this in a preset file then user can overrule while invoking CMake directly

Ref:

The options specified by the preset (variables, generator, etc.) can all be overridden by manually specifying them on the command line. For example, if the preset sets a variable called MYVAR to 1, but the user sets it to 2 with a -D argument, the value 2 is preferred.

What you can say is that west itself should not default to something else unless user explicitly states it.
If a preset is given, then defaults in there should be preferred over defaults in west, but even such would not guarantee you a specific build folder name if the user manually specifies the build dir.


but I'm still of the opinion that west build doesn't cleanly wrap cmake in a way that's compatible with cmake presets and its primary use case (shareable and reproducible builds)

Just because you have a very special use-case with Bluetooth Audio projects that doesn't mean west and CMake presets would not meet the primary use-case in the 99% of other samples i NCS / Zephyr.

What you describe are not my main concerns with presets.
I see other dangers with the presets.

@marc-hb
Copy link

marc-hb commented Jan 6, 2023

From where do you get the impression that one of its main goal are reproducible builds ?

While I never tried to read the mind of the CMake designers, I can see how having fewer settings on the command line and in environment variables and more settings in git instead can HELP achieving reproducibility.

Hence the preset will never be trustworthy for reproducibility.

Totally agreed except I would replace "trustworthy" with "silver bullet". I do not expect CMake presets (or anything else) to provide any reproducibility "silver bullet". However it looks like CMake presets can HELP.

Achieving build reproducibility is exactly like fixing other bugs: there are plenty of tools to help but the moment you stop trying then the game is over. Using different command line options or environment variables and expecting build reproducibility is like ignoring all compiler warnings and expecting bug-free software. No CMake preset or any other "silver bullet" will ever fix that but there are tools and practices that help a lot

@marc-hb
Copy link

marc-hb commented Jan 6, 2023

If BOARD is set in the environment, it'll override the preset. If it's not, west build errors out.

Dunno about this specific parameter but generally speaking precedence should always be intuitive and more importantly well documented.

The preset's values for generator and binary dir are always overridden

This looks like a (future) bug. User input should never be silently ignored - except of course by other user input with a higher precedence. If these specific values cannot be defined in presets then attempting to define them in presets should simply fail the build until they are removed from presets.

Copy link

@aborisovich aborisovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my impression, Cmake presents are competitive to west build command.
I mean west was created to be a command line wrapper to build a concrete thing ("board" - which is a set of configurations) conveniently.
CMake presets provide similar functionality. So here we are in the awkward situation where the West tool loses some of its usability (this is my personal subjective opinion). I think it is always better to use tools more native to the build system.
So I am all for this change @tejlmand . I think it might need changes to west just to make sure we do not scrumble the settings.
I mean some addition to west that would just purely pass by everything what a preset does. In other words, I agree with @trond-snekvik said:

If we want preset support for west build, it has to become a proper flag for that west command, so these overrides can be stripped from the cmake invocation. This isn't some massive blocker, but I'm still of the opinion that west build doesn't cleanly wrap cmake in a way that's compatible with cmake presets and its primary use case (shareable and reproducible builds).

We certainly should add this as a separate west flag and make sure nothing is broken in the process (as @tejlmand mentioned):

If a preset is given, then defaults in there should be preferred over defaults in west, but even such would not guarantee you a specific build folder name if the user manually specifies the build dir.

To sum up: in my opinion, we should add a new flag west --preset, and validate in the process that all preset defaults are not overridden by west python code.

Comment on lines +2 to +6
"version": 1,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I can advise from my experience with presets is to use possibly the newest Preset manifest version.
Looks like presets for CMake configure, build and test steps were added as separate steps in CMake v3.20.0 (manifest ver 2.0). Features grow very dynamically and we will need them to group configurations using inheritance successfully. Zephyr minimal Cmake is 3.20.0 as far as I remember?

@tejlmand
Copy link
Contributor Author

However it looks like CMake presets can HELP.

Completely agree, I was not in anyway trying to give impression that it cannot help.
My fear was more that if you want to force a specific presets behavior in order to guarantee reproducibility then there's a risk you try to enforce use of presets to ignore user overrides, hence the reason I wanted to raise awareness.

Achieving build reproducibility is exactly like fixing other bugs: there are plenty of tools to help but the moment you stop trying then the game is over.

Completely agree.
And we can definitely improve on this.

Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Oct 19, 2024
@github-actions github-actions bot closed this Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants