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

kconfig/cmake: Improve reconfiguration behavior #22043

Merged
merged 1 commit into from
Jan 22, 2020

Conversation

ulfalizer
Copy link
Collaborator

@ulfalizer ulfalizer commented Jan 20, 2020

There are some issues with the behavior when rerunning CMake in an
already initialized build directory:

  1. The check for assignments to promptless symbols in configuration
    fragments isn't run when reconfiguring, because it only runs if
    zephyr/.config doesn't exist

  2. As outlined in
    The contents of .config should not be able to prevent users from running menuconfig. #9573, you can
    get into situations where zephyr/.config is invalid (e.g. due to
    being outdated), but menuconfig/guiconfig can't be run to fix it

  3. If kconfig.py fails while merging fragments during reconfiguration,
    it will ignore the fragments during the next reconfiguration and use
    the existing zephyr/.config instead, because the fragment checksum
    is calculated and saved before running kconfig.py

(Footnote: The input configuration file(s) to kconfig.py can be either a
list of configuration fragments, when merging fragments, or just
zephyr/.config, if the merged configuration is up-to-date. The output
configuration file is always zephyr/.config.)

To fix the first two issues, explicitly tell kconfig.py when it's
dealing with handwritten configuration input (fragments), via a new
--handwritten-input-configs flag. This is more robust than checking
whether zephyr/.config exists, which was the old logic.

When dealing with handwritten input, there should be no assignments to
promptless symbols. Assignments to promptless symbols is expected in
zephyr/.config however, because it doubles as configuration output.

When running menuconfig/guiconfig, the input configuration is
zephyr/.config rather than configuration fragments, so this change also
makes sure that menuconfig can always be run as long as zephyr/.config
exists and is up-to-date.

To fix the last issue, only write the checksum for the configuration
fragments if kconfig.py succeeds (which means it wrote a
zephyr/.config).

Also improve naming a bit, add help texts for the command-line
parameters to kconfig.py, and simplify write_kconfig_filenames() by
moving logic into it.

Partial fix for
#9573, without the
part in #issuecomment-469701831. Can still run into issues when e.g.
when CMake files can't make sense of settings.

@carlescufi
Copy link
Member

@SebastianBoe can you review this PR?

@ulfalizer ulfalizer force-pushed the reconf-improvements branch from 0887f29 to 47a9e4a Compare January 20, 2020 18:37
@SebastianBoe
Copy link
Collaborator

Will review soon.

@SebastianBoe
Copy link
Collaborator

SebastianBoe commented Jan 21, 2020

This solves part of #9573, but not all of it (as I read 9573).

So we need to remove the "fixes #9573" from the description.

Steps to reproduce:

Build hello world with qemu_cortex_m3.

Run menuconfig and enable ADC.

Run menuconfig again to try to change another configuration, but see it fail because .config is corrupt.

sebo@sebo-nix:~/ncs/zephyr/samples/hello_world/outdir$ ninja menuconfig
ninja menuconfig
[0/1] Re-running CMake...
-- Zephyr version: 2.1.99
-- Selected BOARD qemu_cortex_m3
-- Found west: /home/sebo/.local/bin/west (found suitable version "0.6.99", minimum required is "0.6.0")
-- Loading /home/sebo/ncs/zephyr/boards/arm/qemu_cortex_m3/qemu_cortex_m3.dts as base
Devicetree configuration written to /home/sebo/ncs/zephyr/samples/hello_world/outdir/zephyr/include/generated/devicetree.conf
Parsing /home/sebo/ncs/zephyr/Kconfig
Loaded configuration '/home/sebo/ncs/zephyr/samples/hello_world/outdir/zephyr/.config'
No change to '/home/sebo/ncs/zephyr/samples/hello_world/outdir/zephyr/.config'
-- Cache files will be written to: /home/sebo/.cache/zephyr
-- Configuring done
CMake Error at ../../cmake/extensions.cmake:372 (add_library):
  No SOURCES given to target: drivers__adc
Call Stack (most recent call first):
  ../../cmake/extensions.cmake:349 (zephyr_library_named)
  ../../drivers/adc/CMakeLists.txt:3 (zephyr_library)


-- Build files have been written to: /home/sebo/ncs/zephyr/samples/hello_world/outdir
FAILED: build.ninja 
/home/sebo/bin/cmake/cmake-3.13.1-Linux-x86_64/bin/cmake -S/home/sebo/ncs/zephyr/samples/hello_world -B/home/sebo/ncs/zephyr/samples/hello_world/outdir
ninja: error: rebuilding 'build.ninja': subcommand failed

@SebastianBoe
Copy link
Collaborator

SebastianBoe commented Jan 21, 2020

I'd like to test this. Could you give steps to reproduce:

kconfig.py fails while merging fragments during reconfiguration

@ulfalizer
Copy link
Collaborator Author

Run menuconfig again to try to change another configuration, but see it fail because .config is corrupt.

That one shouldn't be a problem on the kconfig.py end at least. Any idea what causes it?

The description for #9573 is about int/hex symbols without defaults, which is more of a Kconfig issue. That's fixed at least.

I'd like to test this. Could you give steps to reproduce:

kconfig.py fails while merging fragments during reconfiguration

  1. cd samples/hello_world; mkdir b; cd b; cmake -GNinja -DBOARD=frdm_kw41z .. (any board will do)

  2. Put some nonsense into samples/hello_world/prj.conf, like fsdifhsdiufh

  3. Reconfigure with cmake -GNinja -DBOARD=frdm_kw41z ... Fails, but still saves checksum.

  4. Reconfigure with cmake -GNinja -DBOARD=frdm_kw41z .. again. Now succeeds, because checksum is up-to-date.

The fix here is to prevent the checksum from being saved in step 3.

@SebastianBoe
Copy link
Collaborator

That one shouldn't be a problem on the kconfig.py end at least. Any idea what causes it?

When the .config is corrupt (by corrupt I mean that when CMake runs with it it does not complete, but instead crashes at some point. This could either be because the Kconfig sources are incorrect and generating invalid configurations, or because the build scripts are incorrect and making wrong assumptions about what kind of Kconfig it could be receiving) it will not be possible to run ninja menuconfig because the build fails before the new ninja build system is generated.

The description for #9573 is about int/hex symbols without defaults, which is more of a Kconfig issue. That's fixed at least.

I interpret 9573 about being about the title, and the description just being one example of how 9573 can occur. With this interpretation we can't close it. See also

#9573 (comment)

@ulfalizer ulfalizer force-pushed the reconf-improvements branch from 47a9e4a to 02c1cd4 Compare January 21, 2020 15:57
@ulfalizer
Copy link
Collaborator Author

Hadn't noticed the amendment. Updates the commit description now.

Rest fine?

@ulfalizer ulfalizer force-pushed the reconf-improvements branch from 02c1cd4 to 3868a96 Compare January 21, 2020 17:04
for path in paths}):
with open(kconfig_list_path, 'w') as out:
for path in sorted({os.path.realpath(os.path.join(kconf.srctree, path))
for path in kconf.kconfig_filenames}):
Copy link
Collaborator

@SebastianBoe SebastianBoe Jan 22, 2020

Choose a reason for hiding this comment

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

For future reference, the review goes faster when changes are separated from refactorings in different commits.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Because then when looking at refactoring patches I can trivially verify that the changes have no semantic effects.

And when looking at actual changes I won't have to sift through the noise of unrelated refactoring.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, did some drive-by-ing and got lazy. Will split better next time.

"on them, like no promptless symbols being "
"assigned")
parser.add_argument("kconfig",
help="Top-level Kconfig file")
Copy link
Collaborator

Choose a reason for hiding this comment

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

When kconfig_root is used, the variable name is self-explanatory and no help text is needed.

I prefer this name over kconfig, which could be referring to anything.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

kconfig_root to me sounds like it refers to $srctree (the root directory that source works relative to).

I could call it kconfig_file though. Should be clear enough. Looks like the C tools do:

$ scripts/kconfig/conf --help
Usage: scripts/kconfig/conf [-s] [option] <kconfig-file>
...

Copy link
Collaborator

Choose a reason for hiding this comment

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

I forgot about srctree, yes, kconfig_file will have to do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed

parser.add_argument("kconfig",
help="Top-level Kconfig file")
parser.add_argument("config_out",
help="Output configuration file")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Configuration file is too ambiguous, let's either use the term "Kconfig fragment" or "fragment" to clarify.

Using _out and _in suffixes makes sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The output configuration file is a not a fragment, so probably shouldn't have "fragment" in it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah, right, I consider the

A=B syntax to be

of the filetype "Kconfig fragment",

but I guess technically fragment also implies that it's just a subset of options.

Then I don't know how to make this clearer, so this will have to do.

help="Output file for list of parsed Kconfig files")
parser.add_argument("configs_in",
nargs="+",
help="Input configuration files")
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to use the term fragment to be less ambiguous.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated the help text.

parser.add_argument("conf_fragments", nargs='+')
parser.add_argument("--handwritten-input-configs",
action="store_true",
help="Assume the input configuration files are "
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/configuration files/input fragments/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated the help text.

Copy link
Collaborator

@SebastianBoe SebastianBoe left a comment

Choose a reason for hiding this comment

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

Minor changes requested.

The improvement itself is sane.

There are some issues with the behavior when rerunning CMake in an
already initialized build directory:

 1. The check for assignments to promptless symbols in configuration
    fragments isn't run when reconfiguring, because it only runs if
    zephyr/.config doesn't exist

 2. As outlined in
    zephyrproject-rtos#9573, you can
    get into situations where zephyr/.config is invalid (e.g. due to
    being outdated), but menuconfig/guiconfig can't be run to fix it

 3. If kconfig.py fails while merging fragments during reconfiguration,
    it will ignore the fragments during the next reconfiguration and use
    the existing zephyr/.config instead, because the fragment checksum
    is calculated and saved before running kconfig.py

(Footnote: The input configuration file(s) to kconfig.py can be either a
list of configuration fragments, when merging fragments, or just
zephyr/.config, if the merged configuration is up-to-date. The output
configuration file is always zephyr/.config.)

To fix the first two issues, explicitly tell kconfig.py when it's
dealing with handwritten configuration input (fragments), via a new
--handwritten-input-configs flag. This is more robust than checking
whether zephyr/.config exists, which was the old logic.

When dealing with handwritten input, there should be no assignments to
promptless symbols. Assignments to promptless symbols is expected in
zephyr/.config however, because it doubles as configuration output.

When running menuconfig/guiconfig, the input configuration is
zephyr/.config rather than configuration fragments, so this change also
makes sure that menuconfig can always be run as long as zephyr/.config
exists and is up-to-date.

To fix the last issue, only write the checksum for the configuration
fragments if kconfig.py succeeds (which means it wrote a
zephyr/.config).

Also improve naming a bit, add help texts for the command-line
parameters to kconfig.py, and simplify write_kconfig_filenames() by
moving logic into it.

Partial fix for
zephyrproject-rtos#9573, without the
part in #issuecomment-469701831. Can still run into issues when e.g.
when CMake files can't make sense of settings.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
@ulfalizer ulfalizer force-pushed the reconf-improvements branch from 3868a96 to 1209796 Compare January 22, 2020 14:04
@ulfalizer
Copy link
Collaborator Author

Nits fixed.

@carlescufi carlescufi merged commit 45050dd into zephyrproject-rtos:master Jan 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Build System area: Kconfig bug The issue is a bug, or the PR is fixing a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants