Skip to content

Commit

Permalink
cmake: Introduce a user-local configuration file
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
SebastianBoe committed Sep 12, 2018
1 parent 13a2103 commit ba089f6
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 116 deletions.
27 changes: 27 additions & 0 deletions cmake/app/boilerplate.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,35 @@ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${AUTOCONF_H})

include(${ZEPHYR_BASE}/cmake/extensions.cmake)

# Python must be detected before extensions.cmake is used
find_package(PythonInterp 3.4)

find_system_configuration_directory(dir)
check_if_directory_is_writeable(${dir} ok)
if(${ok})
set(local_dir ${dir})
else()
# It is not expected that the system configuration directory will
# not be writeable, but just in case, we fall back to using the
# repo.
set(local_dir ${ZEPHYR_BASE})
endif()
set(local_cmake ${local_dir}/zephyr/local.cmake)

if(NOT (EXISTS ${local_cmake}))
file(
COPY ${ZEPHYR_BASE}/cmake/local_template.cmake
DESTINATION ${local_dir}/zephyr
)
file(RENAME
${local_dir}/zephyr/local_template.cmake
${local_cmake}
)
endif()

message("Using system configuration from: ${local_cmake}")
include(${local_cmake} OPTIONAL)

include(${ZEPHYR_BASE}/cmake/ccache.cmake)

if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
Expand Down
13 changes: 13 additions & 0 deletions cmake/extensions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1174,3 +1174,16 @@ function(find_appropriate_cache_directory dir)

set(${dir} ${local_dir} PARENT_SCOPE)
endfunction()

# Find a directory where it is appropriate to have configuration that
# is local to this machine. e.g. installation paths.
function(find_system_configuration_directory dir)
if(CMAKE_HOST_APPLE)
set(${dir} $ENV{HOME}/Library/Preferences PARENT_SCOPE)
elseif(CMAKE_HOST_WIN32)
set(${dir} $ENV{LOCALAPPDATA} PARENT_SCOPE)
else()
# Assume Linux when we did not detect 'mac' or 'win'
set(${dir} $ENV{HOME}/.config PARENT_SCOPE)
endif()
endfunction()
4 changes: 4 additions & 0 deletions cmake/local_template.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# set(ZEPHYR_SDK_INSTALL_DIR $ENV{HOME}/zephyr-sdk)
# set(ZEPHYR_TOOLCHAIN_VARIANT zephyr)

# set_ifndef(BOARD nrf52_pca10040)
116 changes: 67 additions & 49 deletions doc/getting_started/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Getting Started Guide
Use this guide to get started with your :ref:`Zephyr <introducing_zephyr>`
development.

.. _getting_started_git_clone:

Checking Out the Source Code Anonymously
****************************************

Expand All @@ -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.

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:

.. code-block:: console
# With Linux/macOS (bash)
export ZEPHYR_BASE=$HOME/zephyr
echo "export ZEPHYR_BASE=$HOME/zephyr" >> $HOME/.bashrc
# On Windows
set ZEPHYR_BASE=%USERPROFILE%\zephyr
setx ZEPHYR_BASE %USERPROFILE%\zephyr
.. _getting_started_cmake:

A brief note on the Zephyr build system
Expand All @@ -46,6 +62,24 @@ by Zephyr:
Most of the examples in the Zephyr documentation use ``ninja`` as a build tool,
but you should be able to use any generator on any of the examples listed.

.. _getting_started_local_cmake:

Development Environment Configuration File
******************************************

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:

======= ============================================
macOS $HOME/Library/Preferences/zephyr/local.cmake
Windows %LOCALAPPDATA%/zephyr/local.cmake
Linux $HOME/.config/zephyr/local.cmake
======= ============================================

Set Up the Development Environment
**********************************

Expand Down Expand Up @@ -79,25 +113,7 @@ consult its documentation for flashing and running instructions.
Building a Sample Application
=============================

Follow these steps to build the :ref:`hello_world` sample application
provided with Zephyr.

#. Navigate to the main project directory:

.. code-block:: console
cd zephyr
#. Set up your build environment:

.. code-block:: console
# On Linux/macOS
source zephyr-env.sh
# On Windows
zephyr-env.cmd
#. Build the :ref:`hello_world` example for the `arduino_101` board, enter:
To build the :ref:`hello_world` example for the `arduino_101` board, enter:

.. zephyr-app-commands::
:zephyr-app: samples/hello_world
Expand Down Expand Up @@ -164,24 +180,22 @@ packaged, the one you compiled on your own, or the one you downloaded from the
net. The Zephyr build system doesn't know about them and doesn't officially
support them.

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 environment variable set to the Zephyr SDK
installation directory. To build without the Zephyr SDK's prebuilt host tools,
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
Zephyr SDK installation directory. To build without the Zephyr SDK's
prebuilt host tools, the ``ZEPHYR_SDK_INSTALL_DIR`` variable must be
unset. Check the :ref:`local.cmake <getting_started_local_cmake>` file
and the environment to make sure it is not being set.

Follow the steps below to build without the Zephyr SDK:
To unset an environment variable do:

.. code-block:: console
# On Linux/macOS
unset ZEPHYR_SDK_INSTALL_DIR
cd <zephyr git clone location>
source zephyr-env.sh
# On Windows
set ZEPHYR_SDK_INSTALL_DIR=
cd <zephyr git clone location>
zephyr-env.cmd
.. _third_party_x_compilers:

Expand All @@ -196,30 +210,32 @@ SDK, follow the steps below.
and extract it on your file system. This example assumes the compiler was
extracted to: :file:`<user folder>/gcc-arm-none-eabi-7-2018-q2-update/`.

#. Build the example :ref:`hello_world` project, enter:
#. Enable the compiler by creating or modifying the file
:ref:`local.cmake <getting_started_local_cmake>` with:

.. code-block:: console
.. code-block:: CMake
# On Linux/macOS
export GNUARMEMB_TOOLCHAIN_PATH="~/gcc-arm-none-eabi-7-2018-q2-update/"
export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
set(GNUARMEMB_TOOLCHAIN_PATH $ENV{HOME}/gcc-arm-none-eabi-7-2018-q2-update/)
# On Windows
set GNUARMEMB_TOOLCHAIN_PATH="%userprofile%\gcc-arm-none-eabi-7-2018-q2-update\"
set ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb
set(ZEPHYR_TOOLCHAIN_VARIANT gnuarmemb)
set(GNUARMEMB_TOOLCHAIN_PATH $ENV{userprofile}\gcc-arm-none-eabi-7-2018-q2-update\)
#. Build the example :ref:`hello_world` project, enter:

.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: arduino_due
:goals: build

Make sure to unset the ZEPHYR_SDK_INSTALL_DIR if you don't use the
Make sure to unset the ``ZEPHYR_SDK_INSTALL_DIR`` if you don't use the
SDK's host tools. See `Building without the Zephyr SDK`_ for details.

It is possible to use the Zephyr SDK's host tools along with a 3rd
party cross compiler. To do that, keep the 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
the Zephyr SDK installation directory. See `Set Up the Development
Environment`_ for more details on ``ZEPHYR_SDK_INSTALL_DIR``.

Using Custom Cross Compilers
============================
Expand All @@ -236,14 +252,16 @@ To use a custom cross compiler, follow the steps below.
# On Fedora or Red hat
sudo dnf install arm-none-eabi-newlib
#. Build the example :ref:`hello_world` project, enter:
#. Enable the compiler by creating or modifying the file
:ref:`local.cmake <getting_started_local_cmake>` with:

.. code-block:: console
.. code-block:: CMake
# On Linux/macOS
set(ZEPHYR_TOOLCHAIN_VARIANT cross-compile)
set(CROSS_COMPILE /usr/bin/arm-none-eabi-)
# On Linux
unset GNUARMEMB_TOOLCHAIN_PATH
export ZEPHYR_TOOLCHAIN_VARIANT=cross-compile
export CROSS_COMPILE=/usr/bin/arm-none-eabi-
#. Build the example :ref:`hello_world` project, enter:

.. zephyr-app-commands::
:zephyr-app: samples/hello_world
Expand All @@ -252,14 +270,14 @@ To use a custom cross compiler, follow the steps below.

Note that the Zephyr build system assumes that all the tools within your
toolchain used to compile and link your code, reside in the same directory and
have a common prefix. Set the ``CROSS_COMPILE`` environment variable to the
have a common prefix. Set the ``CROSS_COMPILE`` variable to the
path of your toolchain's location and that common prefix. In the example above,
gcc-arm-none-eabi is installed in ``/usr/bin/`` with the common prefix of
``arm-none-eabi-``. If your toolchain is at ``/opt/mytoolchain/bin`` with the
prefix of ``myarch-none-elf-``, it would be
``CROSS_COMPILE=/opt/mytoolchain/bin/arch-none-elf-``.
``set(CROSS_COMPILE /opt/mytoolchain/bin/arch-none-elf-)``.

Make sure to unset the ZEPHYR_SDK_INSTALL_DIR if you don't use the SDK's host
Make sure to unset the ``ZEPHYR_SDK_INSTALL_DIR`` if you don't use the SDK's host
tools. See `Building without the Zephyr SDK`_ and `Set Up the Development
Environment`_ for more details.

Expand Down
23 changes: 8 additions & 15 deletions doc/getting_started/installation_linux.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ On Clear Linux host system:
Install additional packages required for development with Zephyr::

cd ~/zephyr # or to your directory where zephyr is cloned
pip3 install --user -r scripts/requirements.txt
pip3 install --user -r $ZEPHYR_BASE/scripts/requirements.txt

CMake version 3.8.2 or higher is required. Check what version you have using
``cmake --version``; if you have an older version, check the backports or
Expand All @@ -98,8 +97,8 @@ install a more recent version manually. For example, to install version
mkdir $HOME/cmake && cd $HOME/cmake
wget https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.sh
yes | sh cmake-3.8.2-Linux-x86_64.sh | cat
echo "export PATH=$PWD/cmake-3.8.2-Linux-x86_64/bin:\$PATH" >> $HOME/.zephyrrc
source <zephyr git clone location>/zephyr-env.sh
echo "export PATH=$PWD/cmake-3.8.2-Linux-x86_64/bin:\$PATH" >> $HOME/.bashrc
bash
cmake --version

.. _zephyr_sdk:
Expand Down Expand Up @@ -156,13 +155,9 @@ Follow these steps to install the SDK on your Linux host system.
To install the SDK in the default location, you need to run the
installation binary as root.

#. To use the Zephyr SDK, export the following environment variables and
use the target location where SDK was installed:
#. To use the Zephyr SDK create or modify the file :ref:`local.cmake <getting_started_local_cmake>`
with the following:

.. code-block:: console
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=<sdk installation directory>

.. note::
Some Linux distributions have default CFLAGS and CXXFLAGS
Expand All @@ -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
cat <<EOF > ~/.zephyrrc
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk
EOF
set(ZEPHYR_TOOLCHAIN_VARIANT zephyr)
set(ZEPHYR_SDK_INSTALL_DIR /opt/zephyr-sdk/)
.. note::
Use ``<sdk installation directory>`` in place of ``/opt/zephyr-sdk/`` in the
Expand Down
33 changes: 7 additions & 26 deletions doc/getting_started/installation_mac.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,12 @@ Install tools to build Zephyr binaries:
.. code-block:: console
brew install cmake ninja dfu-util doxygen qemu dtc python3 gperf
cd ~/zephyr # or to the folder where you cloned the zephyr repo
pip3 install --user -r scripts/requirements.txt
pip3 install --user -r $ZEPHYR_BASE/scripts/requirements.txt
.. note::
If ``pip3`` does not seem to have been installed correctly use
``brew reinstall python3`` in order to reinstall it.

Source :file:`zephyr-env.sh` wherever you have cloned the Zephyr Git repository:

.. code-block:: console
unset ZEPHYR_SDK_INSTALL_DIR
cd <zephyr git clone location>
source zephyr-env.sh
Finally, assuming you are using a 3rd-party toolchain you can try building the :ref:`hello_world` sample to check things out.

To build for the ARM-based Nordic nRF52 Development Kit:
Expand Down Expand Up @@ -119,24 +110,14 @@ repo and run the following command::

Repeat the step for all architectures you want to support in your environment.

To use the toolchain with Zephyr, export the following environment variables
and use the target location where the toolchain was installed, type:

.. code-block:: console
export ZEPHYR_TOOLCHAIN_VARIANT=xtools
export XTOOLS_TOOLCHAIN_PATH=/Volumes/CrossToolNGNew/build/output/
To use the toolchain with Zephyr create or modify :ref:`local.cmake
<getting_started_local_cmake>` with the location where the toolchain
was installed:

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
cat <<EOF > ~/.zephyrrc
export XTOOLS_TOOLCHAIN_PATH=/Volumes/CrossToolNGNew/build/output/
export ZEPHYR_TOOLCHAIN_VARIANT=xtools
EOF
set(ZEPHYR_TOOLCHAIN_VARIANT xtools)
set(XTOOLS_TOOLCHAIN_PATH /Volumes/CrossToolNGNew/build/output/)
.. note:: In previous releases of Zephyr, the ``ZEPHYR_TOOLCHAIN_VARIANT``
variable was called ``ZEPHYR_GCC_VARIANT``.
Expand Down
Loading

0 comments on commit ba089f6

Please sign in to comment.