If you want to build and test barcode QR code scanner applications for embedded and IoT devices, such as Raspberry Pi, Arduino, Jetson Nano and so on, a physical device is not must-have for development. This article shows how to use Dynamsoft Barcode SDK to build barcode QR code reading applications for Linux ARM32 and Aarch64 (also called ARM64) in Docker container. The sample code is written in C++ and Python.
Docker Images for Running Linux ARM32 and Aarch64
Since there are many existing Docker images for Linux ARM32 and Aarch64, we do not need to build them from scratch. The arm32v7/gcc and arm64v8/gcc have provided a full GCC environment. We can use them as the base images.
docker pull arm32v7/gcc
docker pull arm64v8/gcc
multiarch/qemu-user-static is required for emulating ARM32 and Aarch64 instructions on x86_64 Linux.
docker run --rm --privileged multiarch/qemu-user-static:register --reset
C++ Barcode QR Code Scanner for Linux ARM32 and Aarch64
Get the C++ sample code developed with Dynamsoft Barcode SDK that supports Windows (x86_64)
, macOS(x86_64)
, and Linux(x86_64, ARM32, and ARM64)
.
git clone https://github.com/yushulx/cmake-cpp-barcode-qrcode.git
We mount the project folder to the Docker container rather than copy it to the container. It is convenient for later distribution.
docker run --platform linux/arm/v7 -it --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp arm32v7/gcc
docker run --platform linux/arm64/v8 -it --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp arm64v8/gcc
Then install cmake
and build the project:
apt install -y cmake
mkdir build
cmake -B build
cmake --build build --config release
cmake --install build
The executable file and the shared libraries will be copied to the dist
folder after running the --install
command. We can run the application by:
./dist/BarcodeReader ./images/AllSupportedBarcodeTypes.png ./license-key.txt
Get the 30-day trial license key and save it to the license-key.txt
file.
Python Barcode QR Code Scanner for Linux ARM32 and Aarch64
Get the source code of the Python barcode QR code sample.
git clone https://github.com/yushulx/python-barcode-qrcode-sdk.git
The GCC Docker images have contained Python environment without pip
.
We install pip
firstly, and then install other required Python packages for building the wheel file inside the Docker container.
apt install python3-pip -y
pip3 install auditwheel patchelf-wrapper
Build the Python wheel file and repair it with auditwheel
. Only the manylinux-supported wheel file can be uploaded to PyPI.
python3 setup_setuptools.py bdist_wheel
auditwheel repair wheelhouse/{*.whl} --plat manylinux2014_$(uname -m)
We can install and test the Python barcode QR code scanner SDK as follows:
pip3 install wheelhouse/{*.whl}
python3 test.py
GitHub Actions for Building Linux ARM32 and Aarch64 Barcode QR Code Scanner
GitHub Actions is a tool for automating the build and release of software. We can configure action workflow to build, test and distribute our Linux ARM32 and Aarch64 barcode QR code scanner applications.
GitHub Actions for Building CMake Project
We create two jobs: one for arm32 and one for arm64. The basic steps include:
- Clone the project from GitHub repository.
- Set up the QEMU user-static image.
- Run Docker container to build and test the project.
- Use zip tool to compress the dist folder.
-
Make the package downloadable as an artifact file.
name: CMake
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
arm32_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: CMake build and run
run: |
docker run --platform linux/arm/v7 --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp arm32v7/gcc bash -c "apt update && apt install -y cmake; mkdir build && cmake -B build && cmake --build build --config ${{env.BUILD_TYPE}} && cmake --install build; ./dist/BarcodeReader ./images/AllSupportedBarcodeTypes.png ./license-key.txt"
- name: Archive Release
uses: thedoctor0/zip-release@main
with:
type: 'zip'
filename: arm32.zip
exclusions: '*.git* /*node_modules/* .editorconfig'
path: ${{github.workspace}}/dist
- uses: actions/upload-artifact@v2
with:
path: ./*.zip
arm64_build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: CMake build and run
run: |
docker run --platform linux/arm64/v8 --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp arm64v8/gcc bash -c "apt update && apt install -y cmake; mkdir build && cmake -B build && cmake --build build --config ${{env.BUILD_TYPE}} && cmake --install build; ./dist/BarcodeReader ./images/AllSupportedBarcodeTypes.png ./license-key.txt"
- name: Archive Release
uses: thedoctor0/zip-release@main
with:
type: 'zip'
filename: arm64.zip
exclusions: '*.git* /*node_modules/* .editorconfig'
path: ${{github.workspace}}/dist
- uses: actions/upload-artifact@v2
with:
path: ./*.zip
GitHub Actions for Building Python Wheel
The cibuildwheel is the official tool to build Python wheel file. It supports manylinux2014 aarch64 Docker image.
Here we only build the aarch64 wheel file with cibuildwheel.
- Clone the project from GitHub repository.
- Set up the Python environment.
- Set up the QEMU user-static image.
- Build the Python wheel file with cibuildwheel in Docker container.
- Test the Python barcode QR code scanner SDK.
- Package all Python wheel files to artifact.
-
Upload all Python wheel files to PyPI.
name: Build and upload to PyPI
on: [push, pull_request]
jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v2
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.6.1
env:
CIBW_ARCHS_LINUX: aarch64
- name: Run test.py in develop mode
run: |
python setup_setuptools.py develop
python -m pip install opencv-python
python --version
python test.py
- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build sdist
run: pipx run build --sdist
- uses: actions/upload-artifact@v2
with:
path: dist/*.tar.gz
upload_pypi:
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
# upload to PyPI on every tag starting with 'v'
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
# alternatively, to publish when a GitHub Release is created, use the following rule:
# if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v2
with:
name: artifact
path: dist
- uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
password: ${{ secrets.pypi_password }}
skip_existing: true