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: Introduce a user-local configuration file #9801

Conversation

SebastianBoe
Copy link
Collaborator

Introduce a .cmake file that is included by CMake to support
machine-specific configuration without using environment
variables (except for ZEPHYR_BASE).

User testing is showing that Windows users are running into a myriad
of user errors related to environment variables[0]. This PR intends to
resolve them by limiting the required use of environment variables to
a minimum; just ZEPHYR_BASE.

The user errors that will be resolved include:

Forgetting to run zephyr-env.cmd when opening a new terminal.

Not realizing that the environment variable has not been set on all
alive terminals.

And finally; not cleaning the build directory that contains a
prioritized cached value.

The configuration file needs a location and a format.

CMake was chosen for the format because it allows complex
configuration, such as modal configuration and changing the
configuration based on which ZEPHYR_BASE repo is active.

The file location was chosen to be outside of the Zephyr repository to
avoid accidental git cleaning.

[0] #9578

Signed-off-by: Sebastian Bøe [email protected]

@nashif
Copy link
Member

nashif commented Sep 5, 2018

Forgetting to run zephyr-env.cmd when opening a new terminal.

Not realizing that the environment variable has not been set on all
alive terminals.

those are not specific to windows...

@SebastianBoe SebastianBoe added this to the v1.14.0 milestone Sep 5, 2018
@SebastianBoe SebastianBoe added Feature A planned feature with a milestone area: Build System labels Sep 5, 2018
Copy link
Member

@nashif nashif left a comment

Choose a reason for hiding this comment

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

this remove flexibility we currently have switching between different toolchains and tools and forces us to set those per project to override some defaults maintained in a configuration files.

@@ -382,7 +382,8 @@ again.
.. note:: The ``run`` target will use the QEMU binary available from the Zephyr
SDK by default. To use an alternate version of QEMU, for example the
version installed on your host or a custom version, set the
environment variable ``QEMU_BIN_PATH`` to the alternate path.
Copy link
Member

Choose a reason for hiding this comment

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

thats defeats the purpose, if I have this in a file, then it will always be used. What we want is being able to switch between different versions of Qemu based on the session.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Reverted.

@@ -0,0 +1,4 @@
# set(ZEPHYR_SDK_INSTALL_DIR $ENV{HOME}/zephyr-sdk)
# set(ZEPHYR_TOOLCHAIN_VARIANT zephyr)
Copy link
Member

Choose a reason for hiding this comment

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

and how do you switch between variants, this is something I do on daily basis.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

With bash I have

sebo@mach:~$ ls .zephyr*
.zephyr_clang.sh .zephyr_esp.sh .zephyr_issm.sh .zephyrrc .zephyr_sdk.sh .zephyr_xtools.sh
.zephyr_cross_compile.sh .zephyr_gccarmemb.sh .zephyr_kbuild.sh .zephyr_riscv32.sh .zephyr_xcc.sh

today to switch between variants.

with the new scheme you could switch between variants in a session like this:

local.cmake:

if($ENV{zt} STREQUAL gccarmemb)
  set(GCCARMEMB_TOOLCHAIN_PATH /home/sebo/Downloads/gcc-arm-none-eabi-7-2018-q2-update/)
  set(ZEPHYR_TOOLCHAIN_VARIANT gccarmemb)
else()
  set(ZEPHYR_SDK_INSTALL_DIR $ENV{HOME}/zephyr-sdk)
  set(ZEPHYR_TOOLCHAIN_VARIANT zephyr)
endif()

set_ifndef(BOARD nrf52_pca100401)
sebo@mach:~$ export zt=gccarmemb
sebo@mach:~$ cmake ..

Copy link
Member

Choose a reason for hiding this comment

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

With bash I have

sebo@mach:~$ ls .zephyr*
.zephyr_clang.sh .zephyr_esp.sh .zephyr_issm.sh .zephyrrc .zephyr_sdk.sh .zephyr_xtools.sh
.zephyr_cross_compile.sh .zephyr_gccarmemb.sh .zephyr_kbuild.sh .zephyr_riscv32.sh .zephyr_xcc.sh

and all I have to do is just set the correct variant and maintain all related env variables in ~/.zephyrrc

this will also most likely break how sanitycheck works btw.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

and all I have to do is just set the correct variant and maintain all related env variables in ~/.zephyrrc

This use-case will still be supported, just using CMake code instead of bash.

this will also most likely break how sanitycheck works btw.

I wish to deprecate and discourage the use of zephyr-env.sh, but not remove it (for compatibility reasons), so sanitycheck will not be broken by this change.

Copy link
Member

Choose a reason for hiding this comment

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

I wish to deprecate and discourage the use of zephyr-env.sh

why? All that does is set ZEPHYR_BASE, you will have to export the variable using some other mean and the argument of forgetting to do that will still apply, i.e. someone might forget to set ZEPHYR_BASE in the new terminal.

sanitycheck does not depend on zephyr-env.sh btw, but it does depend on the environment variables.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because there are fewer usability issues[0] when users set ZEPHYR_BASE and maintain a local.cmake file than when they run zephyr-env.cmd and maintain a .zephyrrc file.

[0] The three usability issues are described in the commit message. True, they are not resolved for ZEPHYR_BASE, but fewer env vars means fewer user-error opportunities.

@SebastianBoe SebastianBoe force-pushed the local_configuration_file branch from 57086d3 to 78b6f3f Compare September 5, 2018 13:18
@SebastianBoe
Copy link
Collaborator Author

this remove flexibility we currently have switching between different toolchains and tools and forces us to set those per project to override some defaults maintained in a configuration files.

I might be misunderstanding you, but I believe this does not remove this flexibility, see comment #9801 (comment)

# repo.
set(local_dir ${ZEPHYR_BASE})
endif()
set(local_cmake ${local_dir}/zephyr/local.cmake)
Copy link
Member

Choose a reason for hiding this comment

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

Is that file a user or a system/application file? AFAIK configuration files that are maintained by the user are commonly maintained as .rc files and if there are many, they will be in some .rc/ directory. If this is going to .local/ they might appear as non-user editable and do not belong to the user.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a user file.

I was not aware of the .rc convention, I will look into if it makes sense to use it here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using the term 'rc' would communicate something appropriate about the file, but I don't want to use the suffix .rc as that miscommunicates something about the format of the file. So if we are to use the term 'rc' I would suggest rc.cmake or local.rc.cmake.

AFAIK configuration files that are maintained by the user are commonly maintained as .rc files and if there are many, they will be in some .rc/ directory. If this is going to .local/ they might appear as non-user editable and do not belong to the user.

AFAIK placing configuration files in ~/.config/$VENDOR is an appropriate location and will have the appropriate permissions. (Initially I supported XDG_CONFIG_HOME in addition to HOME/.config, but found that this complicated things for the user as there were two locations to search for the file. I believe it is safe to not support XDG_CONFIG_HOME as there are so many other applications that also do not support it).

@codecov-io
Copy link

codecov-io commented Sep 5, 2018

Codecov Report

Merging #9801 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #9801   +/-   ##
=======================================
  Coverage   52.51%   52.51%           
=======================================
  Files         213      213           
  Lines       26082    26082           
  Branches     5624     5624           
=======================================
  Hits        13696    13696           
  Misses      10135    10135           
  Partials     2251     2251

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0329ec7...ba089f6. Read the comment docs.

nashif pushed a commit that referenced this pull request Sep 5, 2018
If one forgets to source the zephyr-env.sh script before starting a doc
build (using the top-level Makefile), a long screenful of error messages
go by and you can miss what the actual problem is.

Check if ZEPHYR_BASE is not set and give a nice short error message.

(Updated to a more generic error message in anticipation of #9801
deprecating use of zephyr-env.sh)

Signed-off-by: David B. Kinder <[email protected]>
@SebastianBoe
Copy link
Collaborator Author

@nashif : I believe that all review feedback has been addressed, please re-assess when convenient.

@carlescufi
Copy link
Member

@SebastianBoe just got to taking a look at this, but before anything else, how does this relate to the current ~/.zephyrrc (Unix) and %userprofile%\zephyrrc.cmd on Windows? Don't those achieve the same purpose today, albeit with different semantics?

My %userprofile%\zephyrrc.cmd:

set ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
set GNUARMEMB_TOOLCHAIN_PATH=c:\gccarmemb

@SebastianBoe
Copy link
Collaborator Author

SebastianBoe commented Sep 7, 2018

It is nearly the same, except for the syntax and the fact that the user does not have to execute a script to to ensure that the config file is used.

So there are fewer opportunities for user-error.

EDIT: Another difference, is that if the user does not use zephyrrc.cmd / zephyrrc there will be 1 fewer language necessary to learn to use Zephyr. Which makes it easier to use Zephyr.

@carlescufi
Copy link
Member

@SebastianBoe understood.

That said users still need to know how to export ZEPHYR_BASE, so the point about one less language is a bit moot.

That said I am in favor of this change. I am going to add a couple more people to this review to get more feedback.

@carlescufi
Copy link
Member

@mbolivar @MaureenHelm would like to hear your opinion on this proposal.

@MaureenHelm
Copy link
Member

Forgetting to run zephyr-env.cmd when opening a new terminal.

It's a common mistake and I like that you're fixing it.

My %userprofile%\zephyrrc.cmd:

set ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
set GNUARMEMB_TOOLCHAIN_PATH=c:\gccarmemb

I also have:

set PATH=%PATH%;C:\Program Files (x86)\SEGGER\JLink_V631d

I think this change means I'll have to set the JLink path elsewhere, right?

@nashif
Copy link
Member

nashif commented Sep 7, 2018

Forgetting to run zephyr-env.cmd when opening a new terminal.

I not sure I understand what we are fixing here, you still have to set ZEPHYR_BASE somehow, whether you do that manually, using a script, you might forget it, and this is not specific to windows at all.

I do not think this is a reason enough to change the behaviour and move this to cmake, environment variables provide lots of flexibility that many will not want to give away. So I am still a -1 on this.

Josh0027 pushed a commit to Josh0027/zephyr that referenced this pull request Sep 10, 2018
If one forgets to source the zephyr-env.sh script before starting a doc
build (using the top-level Makefile), a long screenful of error messages
go by and you can miss what the actual problem is.

Check if ZEPHYR_BASE is not set and give a nice short error message.

(Updated to a more generic error message in anticipation of zephyrproject-rtos#9801
deprecating use of zephyr-env.sh)

Signed-off-by: David B. Kinder <[email protected]>
@SebastianBoe
Copy link
Collaborator Author

SebastianBoe commented Sep 10, 2018

I not sure I understand what we are fixing here,

Which of the three listed user-errors are unclear? Perhaps I can
improve the explanation.

you still have to set ZEPHYR_BASE somehow, whether you do that
manually, using a script, you might forget it, and this is not
specific to windows at all.

Correct. This PR does not address any user-errors related to
ZEPHYR_BASE, it concerns only the configuration that
traditionally goes into zephyr-env.cmd.

I do not think this is a reason enough to change the behaviour
and move this to cmake, environment variables provide lots of
flexibility that many will not want to give away. So I am still a
-1 on this.

We are not removing the ability to use environment variables. We
are removing some of the environment variable documentation
though, if this approach is accepted I could try to find some way
to explain that configuration can be maintained in env vars as
well.

EDIT: To make this less theoretical, and more concrete, have a look
at the user errors discovered in a recent workshop. Interestingly, this PR
resolves all three of them. Meaning, if this PR were merged, those users
would have been able to get started without issues.
#9578

@@ -30,6 +32,20 @@ using Git to clone the repository anonymously. Enter:
You have successfully checked out a copy of the source code to your local
machine in a ``zephyr`` folder in your home directory.

The environment variable ``ZEPHYR_BASE`` must be set to the repository
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's simplify this to:

Zephyr development tools assume the environment variable
``ZEPHYR_BASE`` is set to the repository path.  Here are examples
for setting this variable on our supported development platforms:

should be created to manage user-specific configurations such as
install paths.

It is a CMake build script that is executed early in the configuration
Copy link
Contributor

Choose a reason for hiding this comment

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

Change to:

A CMake build script is used early in the configuration process
to replace all uses of environment variables, except for ``ZEPHYR_BASE``.
The following sections define where this :file:`local.cmake` file lives
and what to put in it.

The :file:`local.cmake` file location depends on the platform:

the ZEPHYR_SDK_INSTALL_DIR environment variable must be unset
As already noted above, the SDK also includes prebuilt host tools. To
use the SDK's prebuilt host tools alongside a 3rd party or custom
cross-compiler, keep the ZEPHYR_SDK_INSTALL_DIR variable set to the
Copy link
Contributor

Choose a reason for hiding this comment

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

Add the double back-ticks on the environment variable name:

``ZEPHYR_SDK_INSTALL_DIR``

environment variable set to the Zephyr SDK installation directory.
See `Set Up the Development Environment`_ for more details on the
ZEPHYR_SDK_INSTALL_DIR environment variable.
party cross compiler. To do that, keep ZEPHYR_SDK_INSTALL_DIR set to
Copy link
Contributor

Choose a reason for hiding this comment

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

Add the double back-ticks on the environment variable name:

``ZEPHYR_SDK_INSTALL_DIR``

@@ -176,12 +171,10 @@ Follow these steps to install the SDK on your Linux host system.
To use the same toolchain in new sessions in the future, you can set the
variables in the file :file:`${HOME}/.zephyrrc`, for example:

.. code-block:: console
.. code-block:: CMake
Copy link
Contributor

Choose a reason for hiding this comment

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

don't indent the code-block directive


cd %userprofile%\zephyr
pip3 install -r scripts/requirements.txt
pip3 install -r %ZEPHYR_BASE%/scripts/requirements.txt
Copy link
Contributor

Choose a reason for hiding this comment

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

we lost the code-block directive in your edit.

Introduce a .cmake file that is included by CMake to support
machine-specific configuration without using environment
variables (except for ZEPHYR_BASE).

User testing is showing that Windows users are running into a myriad
of user errors related to environment variables[0]. This PR intends to
resolve them by limiting the required use of environment variables to
a minimum; just ZEPHYR_BASE.

The user errors that will be resolved include:

Forgetting to run zephyr-env.cmd when opening a new terminal.

Not realizing that the environment variable has not been set on all
alive terminals.

And finally; not cleaning the build directory that contains a
prioritized cached value.

The configuration file needs a location and a format.

CMake was chosen for the format because it allows complex
configuration, such as modal configuration and changing the
configuration based on which ZEPHYR_BASE repo is active.

The file location was chosen to be outside of the Zephyr repository to
avoid accidental git cleaning.

[0] zephyrproject-rtos#9578

Signed-off-by: Sebastian Bøe <[email protected]>
@SebastianBoe SebastianBoe force-pushed the local_configuration_file branch from 78b6f3f to ba089f6 Compare September 12, 2018 06:59
@SebastianBoe
Copy link
Collaborator Author

@dbkinder : Thank you for the feedback, all points are now addressed.

Copy link
Member

@aescolar aescolar left a comment

Choose a reason for hiding this comment

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

I agree with @nashif points
+
You comment that:

EDIT: Another difference, is that if the user does not use zephyrrc.cmd / zephyrrc there will be 1 fewer language necessary to learn to use Zephyr. Which makes it easier to use Zephyr.

I think it is more reasonable to assume a user knows how to set an environment variable in his shell of choice, than to know about cmake's scripts.
If anything, you are adding another language. And not one many know. I think the assumption should be that typical users do not need to mess with any build scripts, but just call them.
+

The file location was chosen to be outside of the Zephyr repository to avoid accidental git cleaning.

Why not add a line in .gitignore for it? I really dislike having Zephyr "install" itself around. Soon Zephyr will need to come with an uninstall program..

@SebastianBoe
Copy link
Collaborator Author

I think it is more reasonable to assume a user knows how to set an environment variable in his shell of choice, than to know about cmake's scripts.

That is not a reasonable assumption. Most embedded windows developers do not know how to write bat files.

I am not adding a language. CMake is already required knowledge in Zephyr. Typical users must write application build scripts, not only read them.

Why not add a line in .gitignore for it? I really dislike having Zephyr "install" itself around. Soon Zephyr will need to come with an uninstall program..

gitignored files can be accidentally deleted by git clean.

@aescolar
Copy link
Member

Typical users must write application build scripts, not only read them.

I would expect typical users to work in a team of several developers, where only 1 of them messes with the build scripts, and the rest at best add the odd source file to the library (if the library wasn't set to just pick *.c like many of our samples do)

@SebastianBoe
Copy link
Collaborator Author

I am sure that users familiar or not with CMake syntax will be able to follow the documentation. An excerpt of the documentation:

#. Enable the compiler by creating or modifying the file
   :ref:`local.cmake <getting_started_local_cmake>` with:

   .. code-block:: CMake

       # On Linux/macOS	      

set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
set(GNUARMEMB_TOOLCHAIN_PATH $ENV{HOME}/gcc-arm-none-eabi-7-2018-q2-update/)

	      # On Windows

set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
set(GNUARMEMB_TOOLCHAIN_PATH $ENV{userprofile}\gcc-arm-none-eabi-7-2018-q2-update\)

Copy link
Contributor

@dbkinder dbkinder left a comment

Choose a reason for hiding this comment

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

+1 for doc changes, thanks.

@SebastianBoe
Copy link
Collaborator Author

Closing as this was not able to get through review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Build System Feature A planned feature with a milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants