Skip to content
Open
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/ubxtool.*
104 changes: 104 additions & 0 deletions .github/workflows/ubxtool.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Release static ubxtool binaries

on:
push:
tags:
- 'ubxtool-v*'

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
mach: [i686, x86_64, armv6l, armv7l, aarch64]
steps:
- uses: actions/checkout@v2
- name: submodules
run: git submodule update --init --recursive --depth=1
- name: register qemu-user-static
run: sudo docker run --rm --interactive --privileged multiarch/qemu-user-static:register --reset
- name: build-ubxtool
run: ./build-ubxtool ${{ matrix.mach }} static && rm -f bin/.keep
- name: xz
run: xz -8 bin/ubxtool.${{ matrix.mach }}-static
- uses: actions/upload-artifact@v1
with:
name: ubxtool
path: bin/ubxtool.${{ matrix.mach }}-static.xz
# All binaries are uploaded to the same artifact archive. It may
# eventually change: https://github.com/actions/upload-artifact/issues/24

# release does not need 5 parallel running VMs, so it's a separate job
release:
needs: [build]
runs-on: ubuntu-latest
env:
# All the steps but download-artifact and sha256sum need it.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/download-artifact@v1
with:
name: ubxtool

- name: sha256sum
working-directory: ubxtool
run: sha256sum ubxtool.*.xz >SHA256SUMS

- uses: actions/create-release@v1
id: create_release
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: GitHub-built release
draft: false
prerelease: true

# That's a copy-pasta instead of a matrix job to avoid spawing a VM for each upload.
- name: upload i686
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/ubxtool.i686-static.xz
asset_name: ubxtool.i686-static.xz
asset_content_type: application/x-xz

- name: upload x86_64
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/ubxtool.x86_64-static.xz
asset_name: ubxtool.x86_64-static.xz
asset_content_type: application/x-xz

- name: upload armv6l
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/ubxtool.armv6l-static.xz
asset_name: ubxtool.armv6l-static.xz
asset_content_type: application/x-xz

- name: upload armv7l
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/ubxtool.armv7l-static.xz
asset_name: ubxtool.armv7l-static.xz
asset_content_type: application/x-xz

- name: upload aarch64
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/ubxtool.aarch64-static.xz
asset_name: ubxtool.aarch64-static.xz
asset_content_type: application/x-xz

# The last one.
- name: upload SHA256SUMS
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubxtool/SHA256SUMS
asset_name: SHA256SUMS
asset_content_type: text/plain
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ navrecv
testrunner
tlecatch
ubxtool
ubxtool.nodeps
ubxtool.static
# - created by build-ubxtool
/bin/ubxtool.*
# - created by update-tles
active.txt
beidou.txt
Expand Down
39 changes: 39 additions & 0 deletions Dockerfile.ubxtool.glibc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# See `build-ubxtool` script for cross-compilation options.

# `FROM` needs `ARG`s to be specified before the very first `FROM` instruction.
# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG UBUNTU=ubuntu:
ARG BUSYBOX=busybox:

FROM ${UBUNTU}bionic AS build-env

ENV DEBIAN_FRONTEND noninteractive
ENV LC_ALL C.UTF-8

# This allows you to use a local Ubuntu mirror
ARG APT_URL=
ENV APT_URL ${APT_URL:-mirror://mirrors.ubuntu.com/mirrors.txt}
RUN set -ex && \
sed -i "s%http://archive.ubuntu.com/ubuntu/%${APT_URL}%" /etc/apt/sources.list && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
build-essential \
g++ \
git \
libprotobuf-dev \
libzstd-dev \
make \
protobuf-compiler \
&& \
apt-get -y clean && \
:

ARG NCPU=1
ADD . /galmon/
WORKDIR /galmon
RUN make -j$NCPU ubxtool.nodeps

FROM ${BUSYBOX}glibc
COPY --from=build-env /galmon/ubxtool.nodeps /opt/ubxtool
ENTRYPOINT ["/opt/ubxtool"]
38 changes: 38 additions & 0 deletions Dockerfile.ubxtool.static
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See `build-ubxtool` script for cross-compilation options.

ARG ALPINE=alpine:

# 1. GCC has issues with exception unwinding with static build of libmusl.
# The bug is fixed for gcc-10, but alpine:3.11 has 9.2.0-r3 and alpine:3.10 has 8.3.0-r0.
# Both are affected per test and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91737
#
# 2. clang-9.0.0-r1 from alpine:3.11 generates wrong FPU instructions for Raspberry Pi 1 B+ and Zero.
# It uses d{16..31} registers for a VFPv2 FPU and that leads to SIGILL.
# The bug is described at https://reviews.llvm.org/D67375
# The bug is fixed in clang-10: https://reviews.llvm.org/rGddf5e86c222c6b5226be53e1250421fe608bb4d0
#
# 3. clang-8.0.0-r0 from alpine:3.10 is not affected by the bug, so we use it.
FROM ${ALPINE}3.10 AS build-env

# g++ is still installed to bring C++ headers like <string>, <map>, etc.
# See https://pkgs.alpinelinux.org/contents?file=iostream&branch=v3.10&arch=armhf
RUN set -ex && \
apk add --no-cache \
clang \
g++ \
git \
make \
protobuf-dev \
zstd-dev \
zstd-static \
&& \
:

ARG NCPU=1
ADD . /galmon/
WORKDIR /galmon/
RUN CXX=clang make -j$NCPU ubxtool.static

FROM scratch
COPY --from=build-env /galmon/ubxtool.static /opt/ubxtool
ENTRYPOINT ["/opt/ubxtool"]
14 changes: 12 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ CHEAT_ARG := $(shell ./update-git-hash-if-necessary)
PROGRAMS = navparse ubxtool navnexus navcat navrecv navdump testrunner navdisplay tlecatch reporter sp3feed \
galmonmon rinreport rtcmtool

EXTRA_PROGRAMS = ubxtool.static ubxtool.nodeps

all: navmon.pb.cc $(PROGRAMS)

-include Makefile.local
Expand All @@ -44,7 +46,7 @@ H2OPP=ext/powerblog/h2o-pp.o
SIMPLESOCKETS=ext/powerblog/ext/simplesocket/swrappers.o ext/powerblog/ext/simplesocket/sclasses.o ext/powerblog/ext/simplesocket/comboaddress.o

clean:
rm -f *~ *.o *.d ext/*/*.o ext/*/*.d $(PROGRAMS) navmon.pb.h navmon.pb.cc $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) $(H2OPP) $(SIMPLESOCKETS)
rm -f *~ *.o *.d ext/*/*.o ext/*/*.d $(PROGRAMS) $(EXTRA_PROGRAMS) navmon.pb.h navmon.pb.cc $(patsubst %.cc,%.o,$(wildcard ext/sgp4/libsgp4/*.cc)) $(H2OPP) $(SIMPLESOCKETS)
rm -f ext/fmt-6.1.2/src/format.[do] ext/sgp4/libsgp4/*.d ext/powerblog/ext/simplesocket/*.d

help2man:
Expand Down Expand Up @@ -121,8 +123,16 @@ rtcmtool: rtcmtool.o navmon.pb.o githash.o ext/fmt-6.1.2/src/format.o bits.o nm
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lz -pthread -lprotobuf -lzstd


ubxtool: navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-6.1.2/src/format.o galileo.o gps.o beidou.o navmon.o ephemeris.o $(SIMPLESOCKETS) osen.o githash.o nmmsender.o zstdwrap.o
UBXTOOL_DEPS = navmon.pb.o ubxtool.o ubx.o bits.o ext/fmt-6.1.2/src/format.o galileo.o gps.o beidou.o navmon.o ephemeris.o $(SIMPLESOCKETS) osen.o githash.o nmmsender.o zstdwrap.o

ubxtool: $(UBXTOOL_DEPS)
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -pthread -lzstd
# Static build with musl on alpine and clang
ubxtool.static: $(UBXTOOL_DEPS)
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -pthread -lzstd -lstdc++ -static
# Static linking of `glibc` is non-trivial, so glibc is kept dynamically linked
ubxtool.nodeps: $(UBXTOOL_DEPS)
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib /usr/lib/*-linux-*/libprotobuf.a -pthread /usr/lib/*-linux-*/libzstd.a -static-libgcc -static-libstdc++

testrunner: navmon.pb.o testrunner.o ubx.o bits.o ext/fmt-6.1.2/src/format.o galileo.o gps.o beidou.o ephemeris.o sp3.o osen.o navmon.o rinex.o githash.o
$(CXX) -std=gnu++17 $^ -o $@ -L/usr/local/lib -lprotobuf -lz
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ docker run -d --restart=always --device=/dev/ttyACM0 --name=galmon galmon/galmon
To make your docker container update automatically you could use a tool such as
[watchtower](https://containrrr.github.io/watchtower/).

Build `ubxtool` in Docker
-------------------------

To build a minimal `ubxtool` docker image:

```
git clone https://github.com/ahupowerdns/galmon.git --recursive
./build-ubxtool
```

It may also cross-compile a binary and an image for a Raspberry Pi:

```
git clone https://github.com/ahupowerdns/galmon.git --recursive
docker run -it --rm --privileged multiarch/qemu-user-static:register --reset
./build-ubxtool armv6l
```

Running
-------

Expand Down
Empty file added bin/.keep
Empty file.
95 changes: 95 additions & 0 deletions build-ubxtool
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/bin/bash
#
# The script relies on the following project:
# - https://github.com/multiarch/qemu-user-static
# - https://github.com/multiarch/ubuntu-core
# - https://github.com/multiarch/alpine
#
# It's also probably possible to use more official {i386,amd64,arm32v6,arm32v7,arm64v8}/alpine
# images adding qemu binary from multiarch/qemu-user-static:{arm,arm64} to them.
#
# Register qemu-user-static before building
# $ docker run --rm --privileged multiarch/qemu-user-static:register --reset

set -e

this_mach=$(uname --machine)
ncpu=$(grep -c ^processor /proc/cpuinfo)

if [ "$this_mach" != "x86_64" ]; then
echo "$0: build was tested on x86_64, not on this <$this_mach>" 1>&2
fi

mach=${1:-${this_mach}}
libc=${2:-static}

case "$mach" in
i686)
alpine=x86 # official: i386/alpine
ubuntu=x86
busybox=i386
;;
x86_64)
alpine=x86_64 # official: amd64/alpine
ubuntu=x86_64
busybox=amd64
;;
armv6l)
# For Raspberry 1 and Zero.
# Tested on Raspberry 1 B+ (BCM2835 rev. 0010).
alpine=armhf # official: arm32v6/alpine
ubuntu=*
busybox=arm32v6
;;
armv7l)
# For Raspberry 2 and 3.
# Tested on Raspberry 3 Model B (BCM2835 revision a02082).
# Tested on Raspberry 3 Model B+ (BCM2835 revision a020d3).
alpine=armv7 # official: arm32v7/alpine
ubuntu=armhf
busybox=arm32v7
;;
aarch64)
# For Raspberry 4?
alpine=arm64 # official: arm64v8/alpine
ubuntu=arm64 # or aarch64? See https://wiki.ubuntu.com/ARM/RaspberryPi#Ubuntu_arm64.2FAArch64
busybox=arm64v8
;;
*)
echo "$0: unknown machine hardware name <$mach>, known are: {i686,x86_64,armv6l,armv7l,aarch64}" 1>&2
exit 1
esac

case "$libc" in
static)
img="--build-arg ALPINE=multiarch/alpine:${alpine}-v"
;;
glibc)
if [ "$ubuntu" = "*" ]; then
echo "$0: unsupported combination of machine <$mach> and libc <$libc>" 1>&2
exit 1
fi
img="--build-arg UBUNTU=multiarch/ubuntu-core:${ubuntu}- --build-arg BUSYBOX=${busybox}/busybox:"
;;
*)
echo "$0: unknown libc <$libc>, known are: {static,glibc}" 1>&2
exit 1
esac

# Base image is set with `ARG` and not with `sed Dockerfile | docker build -f -`
# as streaming Dockerfile to stdin actually saves it to a file and adds a line
# like ".dockerfile.8a2b17b1408769bf5047" to .dockerignore. And .dockerignore
# should not be touched to make reasonable `githash.h`.

tag="${mach}-${libc}"

docker build \
--build-arg NCPU=${ncpu} \
${img} \
-f Dockerfile.ubxtool.${libc} \
--tag ubxtool:${tag} \
.

cntr=$(docker create ubxtool:${tag})
docker cp ${cntr}:/opt/ubxtool bin/ubxtool.${tag}
docker rm ${cntr}
1 change: 1 addition & 0 deletions ubxtool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <iostream>
#include <fstream>
#include <string.h>
#include <signal.h>
#include "fmt/format.h"
#include "fmt/printf.h"
#include "bits.hh"
Expand Down