Skip to content

Commit

Permalink
Pin dockcross image version, add armv6-lts (raspberry pi, armhf)
Browse files Browse the repository at this point in the history
  • Loading branch information
reimarstier committed May 22, 2024
1 parent 5ed1984 commit b6c3b51
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 32 deletions.
29 changes: 19 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
ARG ARCHITECTURE=linux-arm64
ARG DOCKCROSS_IMAGE=linux-arm64
ARG DOCKCROSS_VERSION=latest

FROM dockcross/$ARCHITECTURE as cannelloni-builder
FROM dockcross/$DOCKCROSS_IMAGE:$DOCKCROSS_VERSION as cannelloni-builder
ARG VERSION=1.1.0
ARG HASH=0dcb9277b21f916f5646574b9b2229d3b8e97d5e99b935a4d0b7509a5f0ccdcd
ARG ARCHITECTURE=linux-arm64
ARG DOCKCROSS_IMAGE=linux-arm64
ARG DOCKCROSS_VERSION=latest
ARG DEBIAN_ARCHITECTURE=arm64

RUN dpkg --add-architecture $DEBIAN_ARCHITECTURE
Expand All @@ -17,11 +19,18 @@ RUN wget https://github.com/mguentner/cannelloni/archive/refs/tags/v$VERSION.tar
RUN echo "$HASH cannelloni-$VERSION.tar.gz" | sha256sum --check --status
RUN tar --strip-components=1 -xvf cannelloni-$VERSION.tar.gz

# Document build metadata
RUN echo "Built with dockcross/$DOCKCROSS_IMAGE:$DOCKCROSS_VERSION\n" | tee -a /tmp/cannelloni/build-metadata.txt

# copy installed libraries to expected target location for cmake toolchain
COPY copylib.sh /copylib.sh
RUN /copylib.sh

RUN cmake -DCMAKE_BUILD_TYPE=Release && make
RUN cmake -DCMAKE_BUILD_TYPE=Release 2>&1 | tee -a /tmp/cannelloni/build-metadata.txt
RUN make 2>&1 | tee -a /tmp/cannelloni/build-metadata.txt

COPY checklib.sh /checklib.sh
RUN /checklib.sh 2>&1 | tee -a /tmp/cannelloni/build-metadata.txt

WORKDIR /tmp/

Expand All @@ -31,26 +40,26 @@ RUN cp --remove-destination /tmp/cannelloni/libcannelloni-common.so.0.0.1 /tmp/c
# copy libsctp library to target directory
RUN cp --no-dereference --preserve=links /usr/lib/*/libsctp* /tmp/cannelloni
RUN curl https://raw.githubusercontent.com/sctp/lksctp-tools/master/COPYING.lib --output /tmp/cannelloni/libsctp-license.txt

# add note about source
RUN echo "You can find a copy of the cannelloni source code at: https://github.com/mguentner/cannelloni/archive/refs/tags/v$VERSION.tar.gz" > /tmp/cannelloni/SOURCES.md
RUN echo "You can find a copy of the libsctp source and license here: https://github.com/sctp/lksctp-tools" >> /tmp/cannelloni/SOURCES.md

# create tar file as output
RUN tar cf /tmp/cannelloni.tar.gz \
cannelloni/cannelloni cannelloni/libcannelloni-common.so.0 cannelloni/gpl-2.0.txt cannelloni/README.md cannelloni/SOURCES.md \
cannelloni/build-metadata.txt \
cannelloni/libsctp*

# create directory as output
# RUN mkdir -p /cannelloni_${ARCHITECTURE}_${VERSION}/
# RUN cp /tmp/cannelloni/libcannelloni-common.so.0 /tmp/cannelloni/cannelloni /tmp/cannelloni/README.md /tmp/cannelloni/gpl-2.0.txt /cannelloni_${ARCHITECTURE}_${VERSION}/
# RUN mkdir -p /cannelloni_${DOCKCROSS_IMAGE}_${VERSION}/
# RUN cp /tmp/cannelloni/libcannelloni-common.so.0 /tmp/cannelloni/cannelloni /tmp/cannelloni/README.md /tmp/cannelloni/gpl-2.0.txt /cannelloni_${DOCKCROSS_IMAGE}_${VERSION}/

FROM scratch AS export-stage
ARG ARCHITECTURE=linux-arm64
ARG DOCKCROSS_IMAGE=linux-arm64
ARG VERSION=1.1.0

# copy tar file from builder
COPY --from=cannelloni-builder /tmp/cannelloni.tar.gz /cannelloni_${ARCHITECTURE}_${VERSION}.tar.gz
COPY --from=cannelloni-builder /tmp/cannelloni.tar.gz /cannelloni_${DOCKCROSS_IMAGE}_${VERSION}.tar.gz

# copy directory from builder
# COPY --from=cannelloni-builder /cannelloni_${ARCHITECTURE}_${VERSION}/ /cannelloni_${ARCHITECTURE}_${VERSION}/
# COPY --from=cannelloni-builder /cannelloni_${DOCKCROSS_IMAGE}_${VERSION}/ /cannelloni_${DOCKCROSS_IMAGE}_${VERSION}/
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Uses [dockcross](https://github.com/dockcross/dockcross) to compile for the spec
* [linux-arm64](https://hub.docker.com/r/dockcross/linux-arm64), **arm64** for e.g. Yocto Linux
* [linux-x64](https://hub.docker.com/r/dockcross/linux-x64), **x86_64** for regular desktop (does not require cross)
* [linux-armv7](https://hub.docker.com/r/dockcross/linux-armv7), **armv7** for e.g. Raspberry Pi 3
* [linux-armv6-lts](https://hub.docker.com/r/dockcross/linux-armv6-lts), for e.g. Raspberry Pi 3 with good old Raspbian, arm-linux-gnueabihf, armhf, glibc 2.28


## Build for multiple architectures
Expand Down Expand Up @@ -58,3 +59,27 @@ Run `build.sh` to build for all architectures.

* Check for available version at [docker-cross](https://github.com/dockcross/dockcross).
* Update variable `ALL_ARCHITECTURES` in [build script](build.py).


## Check your architecture

* System information on e.g. your Raspberry Pi:
```shell
uname --all # print system information (kernel version, processor type)
uname --machine # print machine hardware information
strings /lib/arm-linux-gnueabihf/libc.so.6 | grep GLIBC_
strings /lib/*/libc.so.6 | grep GLIBC_
ldd --version # GCC version
gcc -v # GCC version
gcc -print-multiarch # print target triple

```

* Check binary and shared object files
```shell
# ldd - print shared object dependencies
ldd ./cannelloni
ldd ./libcannelloni-common.so.0
# readelf - display information about ELF files
readelf -h libcannelloni-common.so.0
```
61 changes: 40 additions & 21 deletions build.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
#!/usr/bin/env python3

import argparse
import dataclasses
import os
import subprocess


@dataclasses.dataclass
class BuildMetadata:
debian_architecture: str
dockcross_image: str
dockcross_version: str


DEFAULT_VERSION = "1.1.0"
DEFAULT_HASH = "0dcb9277b21f916f5646574b9b2229d3b8e97d5e99b935a4d0b7509a5f0ccdcd"
ALL_ARCHITECTURES = ["linux-arm64", "linux-x64", "linux-armv7"]

DEBIAN_ARCHITECTURES = {
"linux-arm64": "arm64",
"linux-x64": "amd64",
"linux-armv7": "armhf",
# Dockcross image names: https://github.com/dockcross/dockcross?tab=readme-ov-file#summary-cross-compilers
# Debian architectures: https://wiki.debian.org/SupportedArchitectures
BUILD_TARGETS = {
"linux-arm64": BuildMetadata(debian_architecture="arm64", dockcross_image="linux-arm64", dockcross_version="20240418-88c04a4"),
"linux-x64": BuildMetadata(debian_architecture="amd64", dockcross_image="linux-x64", dockcross_version="20240418-88c04a4"),
"linux-armv7": BuildMetadata(debian_architecture="armhf", dockcross_image="linux-armv7", dockcross_version="20240418-88c04a4"),
"linux-armv7-lts": BuildMetadata(debian_architecture="armhf", dockcross_image="linux-armv7-lts", dockcross_version="20240418-88c04a4"),
"linux-armv6": BuildMetadata(debian_architecture="armhf", dockcross_image="linux-armv6", dockcross_version="20240418-88c04a4"),
"linux-armv6-lts": BuildMetadata(debian_architecture="armhf", dockcross_image="linux-armv6-lts", dockcross_version="20240418-88c04a4"),
}


def build_cannelloni(architecture: str, build_version: str, build_hash: str):
debian_architecture = DEBIAN_ARCHITECTURES[architecture]

def build_cannelloni(target: BuildMetadata, build_version: str, build_hash: str):
cmd = f"""docker build
--build-arg VERSION={build_version}
--build-arg HASH={build_hash}
--build-arg ARCHITECTURE={architecture}
--build-arg DEBIAN_ARCHITECTURE={debian_architecture}
--build-arg DOCKCROSS_IMAGE={target.dockcross_image}
--build-arg DOCKCROSS_VERSION={target.dockcross_version}
--build-arg DEBIAN_ARCHITECTURE={target.debian_architecture}
--output type=local,dest=out ."""

result = subprocess.run(cmd.split())
my_env = os.environ.copy()
my_env["BUILDKIT_PROGRESS"] = "plain" # show progress output when building with docker
result = subprocess.run(cmd.split(), env=my_env)
if result.returncode != 0:
raise RuntimeError("Failed to build docker image for architecture={}".format(architecture))
raise RuntimeError("Failed to build docker image for architecture={}".format(target.debian_architecture))


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Build cannelloni for your architecture')
parser.add_argument('--architecture', help='Architecture to build.', choices=ALL_ARCHITECTURES, required=False)
parser.add_argument('--architecture', help='Architecture to build.', choices=BUILD_TARGETS.keys(), required=False)
parser.add_argument('--version', help='Cannelloni release version to build.')
parser.add_argument('--hash', help='Cannelloni release hash to do integrity check.')
args = parser.parse_args()
Expand All @@ -41,12 +55,17 @@ def build_cannelloni(architecture: str, build_version: str, build_hash: str):
build_hash = args.hash or DEFAULT_HASH

if given_architecture is None:
build_architectures = ALL_ARCHITECTURES
target_list = list(BUILD_TARGETS.keys())
else:
build_architectures = [given_architecture]
print(build_architectures)
print(build_version)
print(build_hash)
target_list = [given_architecture]

for architecture in target_list:
metadata = BUILD_TARGETS[architecture]

for architecture in build_architectures:
build_cannelloni(architecture, build_version, build_hash)
print(f"""
Build cannelloni for your architecture.
Dockcross image: dockcross/{metadata.dockcross_image}:{metadata.dockcross_version}
Debian architecture: {metadata.debian_architecture}
""")
build_cannelloni(metadata, build_version, build_hash)
16 changes: 16 additions & 0 deletions checklib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -x

# for other architectures than x86_64, copy libraries to this location for cmake toolchain
TARGET_XCC_DIR="$(ls -d /usr/xcc/*/*/sysroot/)"

if [ -n "$TARGET_XCC_DIR" ]; then
echo "Built with crosstool-ng"
"$TARGET_XCC_DIR"/usr/bin/ldd --version
echo -e "\nPrint shared object information on cannelloni library:"
readelf -h /tmp/cannelloni/cannelloni
else
echo "Not a cross build."
ldd --version
ldd /tmp/cannelloni/cannelloni
fi
2 changes: 1 addition & 1 deletion copylib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ if [ -n "$TARGET_XCC_DIR" ]; then
cp /usr/include/netinet/sctp.h "$TARGET_XCC_DIR"/usr/include/netinet/
cp /usr/lib/*/libsctp.* "$TARGET_XCC_DIR"/usr/lib/
else
echo "Nothing to do for current architecture: $ARCHITECTURE"
echo "Not a cross build. Nothing to do for current architecture: $ARCHITECTURE"
fi

0 comments on commit b6c3b51

Please sign in to comment.