Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 22 additions & 142 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,155 +20,35 @@ on:
# Steps to run for the Workflow
jobs:
build:

# Run these steps on Ubuntu
runs-on: ubuntu-latest

container:
image: infinitime/infinitime-build
steps:

#########################################################################################
# Download and Cache Dependencies

- name: Install cmake
uses: lukka/get-cmake@v3.18.3

- name: Check cache for Embedded Arm Toolchain arm-none-eabi-gcc
id: cache-toolchain
uses: actions/cache@v2
env:
cache-name: cache-toolchain-9-2020-q2
with:
path: ${{ runner.temp }}/arm-none-eabi
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}

- name: Install Embedded Arm Toolchain arm-none-eabi-gcc
if: steps.cache-toolchain.outputs.cache-hit != 'true' # Install toolchain if not found in cache
uses: fiam/arm-none-eabi-gcc@v1.0.4
with:
# GNU Embedded Toolchain for Arm release name, in the V-YYYY-qZ format (e.g. "9-2019-q4")
release: 9-2020-q2
# Directory to unpack GCC to. Defaults to a temporary directory.
directory: ${{ runner.temp }}/arm-none-eabi

- name: Check cache for nRF5 SDK
id: cache-nrf5sdk
uses: actions/cache@v2
env:
cache-name: cache-nrf5sdk
with:
path: ${{ runner.temp }}/nrf5_sdk
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}

- name: Install nRF5 SDK
if: steps.cache-nrf5sdk.outputs.cache-hit != 'true' # Install SDK if not found in cache
run: |
cd ${{ runner.temp }}
curl https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip -o nrf5_sdk.zip
unzip nrf5_sdk.zip
mv nRF5_SDK_15.3.0_59ac345 nrf5_sdk

- name: Check cache for MCUBoot
id: cache-mcuboot
uses: actions/cache@v2
env:
cache-name: cache-mcuboot
with:
path: ${{ runner.temp }}/mcuboot
key: ${{ runner.os }}-build-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}

- name: Install MCUBoot
if: steps.cache-mcuboot.outputs.cache-hit != 'true' # Install MCUBoot if not found in cache
run: |
cd ${{ runner.temp }}
git clone --branch v1.7.2 https://github.com/mcu-tools/mcuboot

- name: Install imgtool dependencies
run: |
pip3 install --user -r ${{ runner.temp }}/mcuboot/scripts/requirements.txt

- name: Install adafruit-nrfutil
run: |
pip3 install --user wheel
pip3 install --user setuptools
pip3 install --user adafruit-nrfutil

- name: Install lv_font_conv
run:
npm i -g lv_font_conv@1.5.2

#########################################################################################
# Checkout

# This workaround fixes the error "unsafe repository (REPO is owned by someone else)".
# See https://github.com/actions/checkout/issues/760 and https://github.com/actions/checkout/issues/766
# The fix in "actions/checkout@v2" was not sufficient as the build process also uses git (to get the current
# commit hash, for example).
- name: Workaround permission issues
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Checkout source files
uses: actions/checkout@v2
with:
submodules: recursive

- name: Show files
run: set ; pwd ; ls -l

#########################################################################################
# CMake

- name: CMake
run: |
mkdir -p build
cd build
cmake -G Ninja -DARM_NONE_EABI_TOOLCHAIN_PATH=${{ runner.temp }}/arm-none-eabi -DNRF5_SDK_PATH=${{ runner.temp }}/nrf5_sdk -DUSE_OPENOCD=1 -DBUILD_DFU=1 ../

#########################################################################################
# Make and Upload DFU Package
# pinetime-mcuboot-app.img must be flashed at address 0x8000 in the internal flash memory with OpenOCD:
# program image.bin 0x8000

# For Debugging Builds: Remove "make" option "-j" for clearer output. Add "--trace" to see details.
# For Faster Builds: Add "make" option "-j"

- name: Make pinetime-mcuboot-app
run: |
cmake --build build --target pinetime-mcuboot-app

- name: Unzip DFU package
run: |
# Unzip the package because Upload Artifact will zip up the files
unzip build/src/pinetime-mcuboot-app-dfu*.zip -d build/src/pinetime-mcuboot-app-dfu

- name: Upload DFU package
- name: Build
shell: bash
env:
SOURCES_DIR: .
run: |
/opt/build.sh all
- name: Upload DFU artifacts
uses: actions/upload-artifact@v2
with:
name: pinetime-mcuboot-app-dfu
path: build/src/pinetime-mcuboot-app-dfu/*

#########################################################################################
# Make and Upload Standalone Firmware

- name: Make pinetime-app
run: |
cmake --build build --target pinetime-app

- name: Upload standalone firmware
name: InfiniTime DFU file
path: |
./build/output/pinetime-mcuboot-app-dfu-*.zip
- name: Upload MCUBoot image artifacts
uses: actions/upload-artifact@v2
with:
name: pinetime-app.out
path: build/src/pinetime-app*.out

#########################################################################################
# Make but don't Upload the Recovery Firmware to be sure it builds correctly

- name: Make pinetime-recovery
run: |
cmake --build build --target pinetime-recovery

#########################################################################################
# Finish

- name: Find output
run: |
find . -name "pinetime-app.*" -ls
find . -name "pinetime-mcuboot-app.*" -ls

# Embedded Arm Toolchain and nRF5 SDK will only be cached if the build succeeds.
# So make sure that the first build always succeeds, e.g. comment out the "Make" step.
name: InfiniTime MCUBoot image file
path: |
./build/output/pinetime-mcuboot-app-image-*.bin
56 changes: 23 additions & 33 deletions doc/buildWithDocker.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,58 @@
# Build the project using Docker

A [Docker image (Dockerfile)](../docker) containing all the build environment is available for X86_64 and AMD64 architectures. These images make the build of the firmware and the generation of the DFU file for OTA quite easy, as well as preventing clashes with any other toolchains or development environments you may have installed.
A [Docker image (Dockerfile)](../docker) containing all the build environment is available for X86_64 and AMD64 architectures.
These images make the build of the firmware and the generation of the DFU file for OTA quite easy, as well as preventing clashes with any other toolchains or development environments you may have installed.

Based on Ubuntu 18.04 with the following build dependencies:
Based on Ubuntu 22.04 with the following build dependencies:

* ARM GCC Toolchain
* nRF SDK
* MCUBoot
* adafruit-nrfutil
* lv_font_conv

## Run a container to build the project

The `infinitime-build` image contains all the dependencies you need. The default `CMD` will compile sources found in `/sources`, so you need only mount your code.
The `infinitime-build` image contains all the dependencies you need.
The default `CMD` will compile sources found in `/sources`, so you need only mount your code.

Before continuing, make sure you first build the image as indicated in the [Build the image](#build-the-image) section, or check the [Using the image from Docker Hub](#using-the-image-from-docker-hub) section if you prefer to use a pre-made image.

This example will build the firmware, generate the MCUBoot image and generate the DFU file. For cloning the repo, see [these instructions](../doc/buildAndProgram.md#clone-the-repo). Outputs will be written to **<project_root>/build/output**:
This example will build the firmware, generate the MCUBoot image and generate the DFU file.
For cloning the repo, see [these instructions](../doc/buildAndProgram.md#clone-the-repo). Outputs will be written to **<project_root>/build/output**:

```bash
cd <project_root> # e.g. cd ./work/Pinetime
docker run --rm -it -v $(pwd):/sources infinitime-build
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime-build
```

If you only want to build a single CMake target, you can pass it in as the first parameter to the build script. This means calling the script explicitly as it will override the `CMD`. Here's an example For `pinetime-app`:
By default, the container runs as `root`, which is not convenient as all the files generated by the build will also belong to `root`.
The parameter `--user` overrides that default behavior.
The command above will run as your current user.

```bash
docker run --rm -it -v $(pwd):/sources infinitime-build /opt/build.sh pinetime-app
```

The image is built using 1000:1000 for the user id and group id. If this is different to your user or group ids (run `id -u` and `id -g` to find out what your id values are if you are unsure), you will need to override them via the `--user` parameter in order to prevent permission errors with the output files (and the cmake build cache).

Running with this image is the same as above, you just specify the ids to `docker run`:
If you only want to build a single CMake target, you can pass it in as the first parameter to the build script.
This means calling the script explicitly as it will override the `CMD`.
Here's an example for `pinetime-app`:

```bash
docker run --rm -it -v $(pwd):/sources --user $(id -u):$(id -g) infinitime-build
```

Or you can specify your user id and group id (by number, not by name) directly:

```bash
docker run --rm -it -v $(pwd):/sources --user 1234:1234 infinitime-build
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime-build /opt/build.sh pinetime-app
```

## Using the image from Docker Hub

The image is available via Docker Hub for both the amd64 and arm64v8 architectures at [pfeerick/infinitime-build](https://hub.docker.com/r/pfeerick/infinitime-build).
The image is available via Docker Hub for both the amd64 and arm64v8 architectures at [infinitime/infinitime-build](https://hub.docker.com/repository/docker/infinitime/infinitime-build).

It can be pulled (downloaded) using the following command:
You can run it using the following command:

```bash
docker pull pfeerick/infinitime-build
docker run --rm -it -v ${PWD}:/sources --user $(id -u):$(id -g) infinitime/infinitime-build
```

The default `latest` tag *should* automatically identify the correct image architecture, but if for some reason Docker does not, you can specify it manually:

* For AMD64 (x86_64) systems: `docker pull pfeerick/infinitime-build:amd64`
* For AMD64 (x86_64) systems: `docker pull --platform linux/amd64 infinitime/infinitime-build`

* For ARM64v8 (ARM64/aarch64) systems: `docker pull pfeerick/infinitime-build:arm64v8`
* For ARM64v8 (ARM64/aarch64) systems: `docker pull --platform linux/arm64 infinitime/infinitime-build`

## Build the image

Expand All @@ -65,11 +61,5 @@ You can build the image yourself if you like!
The following commands must be run from the root of the project. This operation will take some time but, when done, a new image named *infinitime-build* is available.

```bash
docker image build -t infinitime-build ./docker
```

The `PUID` and `PGID` build arguments are used to set the user and group ids used in the container, meaning you will not need to specify it later unless they change for some reason. Specifying them is not mandatory, as this can be over-ridden at build time via the `--user` flag, but doing so will make the command you need to run later a bit shorter. In the below examples, they are set to your current user id and group id automatically. You can specify them manually, but they must be specified by number, not by name.

```bash
docker image build -t infinitime-build --build-arg PUID=$(id -u) --build-arg PGID=$(id -g) ./docker
```
docker build -t infinitime-build ./docker
```
5 changes: 0 additions & 5 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,5 @@ RUN bash -c "source /opt/build.sh; GetNrfSdk;"
# McuBoot
RUN bash -c "source /opt/build.sh; GetMcuBoot;"

ARG PUID=1000
ARG PGID=1000
RUN groupadd --system --gid $PGID infinitime && useradd --system --uid $PUID --gid $PGID infinitime

USER infinitime:infinitime
ENV SOURCES_DIR /sources
CMD ["/opt/build.sh"]
16 changes: 6 additions & 10 deletions docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set -e
export TOOLS_DIR="${TOOLS_DIR:=/opt}"
export SOURCES_DIR="${SOURCES_DIR:=/sources}"
export BUILD_DIR="${BUILD_DIR:=$SOURCES_DIR/build}"
export OUTPUT_DIR="${OUTPUT_DIR:=$BUILD_DIR/output}"
export OUTPUT_DIR="${OUTPUT_DIR:=$SOURCES_DIR/build/output}"

export BUILD_TYPE=${BUILD_TYPE:=Release}
export GCC_ARM_VER=${GCC_ARM_VER:="gcc-arm-none-eabi-9-2020-q2-update"}
Expand All @@ -22,7 +22,7 @@ main() {
local target="$1"

mkdir -p "$TOOLS_DIR"

[[ ! -d "$TOOLS_DIR/$GCC_ARM_VER" ]] && GetGcc
[[ ! -d "$TOOLS_DIR/$NRF_SDK_VER" ]] && GetNrfSdk
[[ ! -d "$TOOLS_DIR/mcuboot" ]] && GetMcuBoot
Expand All @@ -31,7 +31,7 @@ main() {

CmakeGenerate
CmakeBuild $target
BUILD_RESULT=$?
BUILD_RESULT=$?
if [ "$DISABLE_POSTBUILD" != "true" -a "$BUILD_RESULT" == 0 ]; then
source "$BUILD_DIR/post_build.sh"
fi
Expand All @@ -54,18 +54,14 @@ GetNrfSdk() {
}

CmakeGenerate() {
# We can swap the CD and trailing SOURCES_DIR for -B and -S respectively
# once we go to newer CMake (Ubuntu 18.10 gives us CMake 3.10)
cd "$BUILD_DIR"

cmake -G "Unix Makefiles" \
-S "$SOURCES_DIR" \
-B "$BUILD_DIR" \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DUSE_OPENOCD=1 \
-DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_VER" \
-DNRF5_SDK_PATH="$TOOLS_DIR/$NRF_SDK_VER" \
-DBUILD_DFU=1 \
"$SOURCES_DIR"
cmake -L -N .
-DBUILD_DFU=1
}

CmakeBuild() {
Expand Down
10 changes: 4 additions & 6 deletions docker/post_build.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ cp "$BUILD_DIR/src/pinetime-mcuboot-app-dfu-$PROJECT_VERSION.zip" "$OUTPUT_DIR/p
cp "$BUILD_DIR/src/pinetime-mcuboot-recovery-loader-image-$PROJECT_VERSION.bin" "$OUTPUT_DIR/pinetime-mcuboot-recovery-loader-image-$PROJECT_VERSION.bin"
cp "$BUILD_DIR/src/pinetime-mcuboot-recovery-loader-dfu-$PROJECT_VERSION.zip" "$OUTPUT_DIR/pinetime-mcuboot-recovery-loader-dfu-$PROJECT_VERSION.zip"


mkdir -p "$OUTPUT_DIR/src"
cd "$BUILD_DIR"
cp src/*.bin "$OUTPUT_DIR/src"
cp src/*.hex "$OUTPUT_DIR/src"
cp src/*.out "$OUTPUT_DIR/src"
cp src/*.map "$OUTPUT_DIR/src"
cp $BUILD_DIR/src/*.bin "$OUTPUT_DIR/src/"
cp $BUILD_DIR/src/*.hex "$OUTPUT_DIR/src/"
cp $BUILD_DIR/src/*.out "$OUTPUT_DIR/src/"
cp $BUILD_DIR/src/*.map "$OUTPUT_DIR/src/"

ls -RUv1 "$OUTPUT_DIR" | sed 's;^\([^/]\); \1;g'