Skip to content

Commit e20f7ce

Browse files
committed
Attempt build simplification
1 parent dea9c01 commit e20f7ce

File tree

4 files changed

+268
-57
lines changed

4 files changed

+268
-57
lines changed

.github/toolchains/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# CMake toolchains
2+
3+
To build locally for ARM64:
4+
```bash
5+
cmake -S . -B build-arm64 \
6+
-DCMAKE_TOOLCHAIN_FILE=.github/toolchains/aarch64-linux-gnu.cmake \
7+
-DCMAKE_BUILD_TYPE=Release
8+
cmake --build build-arm64
9+
```
10+
11+
To build locally for ARMv7:
12+
```bash
13+
cmake -S . -B build-armv7 \
14+
-DCMAKE_TOOLCHAIN_FILE=.github/toolchains/arm-linux-gnueabihf.cmake \
15+
-DCMAKE_BUILD_TYPE=Release
16+
cmake --build build-armv7
17+
```
18+
19+
It is also possible to cross-compile from other hosts but the toolchain files may need to be adjusted accordingly.
20+
21+
## Testing Cross-Compiled Binaries
22+
23+
With QEMU:
24+
25+
```bash
26+
# Install QEMU
27+
sudo apt-get install qemu-user-static
28+
29+
# Run ARM64 binary
30+
qemu-aarch64-static -L /usr/aarch64-linux-gnu ./build-arm64/your-binary
31+
32+
# Run ARMv7 binary
33+
qemu-arm-static -L /usr/arm-linux-gnueabihf ./build-armv7/your-binary
34+
```
35+
36+
## NVIDIA Jetson
37+
38+
The ARM64 build (`aarch64-linux-gnu.cmake`) binaries should be compatible with NVIDIA Jetson.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# CMake toolchain file for cross-compiling to ARM64/aarch64
2+
# Compatible with NVIDIA Jetson, Raspberry Pi 4/5, and other ARM64 Linux systems
3+
4+
set(CMAKE_SYSTEM_NAME Linux)
5+
set(CMAKE_SYSTEM_PROCESSOR aarch64)
6+
7+
# Specify the cross compiler
8+
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
9+
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
10+
11+
# Where to look for the target environment
12+
set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
13+
14+
# Search for programs in the build host directories
15+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
16+
17+
# Search for libraries and headers in the target directories
18+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
19+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
20+
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
21+
22+
# Set additional compiler flags for better compatibility
23+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a" CACHE STRING "C flags")
24+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a" CACHE STRING "C++ flags")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# CMake toolchain file for cross-compiling to ARMv7 (32-bit ARM with hard float)
2+
# Compatible with Raspberry Pi 2/3 and other ARMv7 Linux systems
3+
4+
set(CMAKE_SYSTEM_NAME Linux)
5+
set(CMAKE_SYSTEM_PROCESSOR armv7l)
6+
7+
# Specify the cross compiler
8+
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
9+
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
10+
11+
# Where to look for the target environment
12+
set(CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
13+
14+
# Search for programs in the build host directories
15+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
16+
17+
# Search for libraries and headers in the target directories
18+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
19+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
20+
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
21+
22+
# Set additional compiler flags for ARMv7 with NEON support
23+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C flags")
24+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C++ flags")

.github/workflows/cppcmake.yml

Lines changed: 182 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -38,69 +38,175 @@ jobs:
3838
fail-fast: false
3939
matrix:
4040
config:
41-
- {name: "ubuntu-22.04", os: "ubuntu-22.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
42-
- {name: "ubuntu-24.04", os: "ubuntu-24.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
43-
- {name: "ubuntu-24.04-arm", os: "ubuntu-24.04-arm", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
44-
- {name: "windows-x64", os: "windows-latest", cmake_extra: "-T v142,host=x86"}
45-
- {name: "windows-32", os: "windows-latest", cmake_extra: "-T v142,host=x86 -A Win32"}
46-
- {name: "windows-arm", os: "windows-11-arm", cmake_extra: "-T v143,host=ARM64 -A ARM64"}
41+
# x86_64 Linux builds
42+
- {name: "ubuntu-22.04-x64", os: "ubuntu-22.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
43+
- {name: "ubuntu-24.04-x64", os: "ubuntu-24.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
44+
45+
# ARM Linux builds - cross-compiled with QEMU testing (Jetson, Raspberry Pi compatible)
46+
- {name: "ubuntu-22.04-arm64", os: "ubuntu-22.04", arch: "aarch64", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
47+
- {name: "ubuntu-22.04-armhf", os: "ubuntu-22.04", arch: "armv7", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
48+
49+
# Native ARM build (optional - can be enabled for additional validation)
50+
# - {name: "ubuntu-24.04-arm64-native", os: "ubuntu-24.04-arm", arch: "aarch64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
51+
52+
# Windows builds
53+
- {name: "windows-x64", os: "windows-latest", arch: "x86_64", cmake_extra: "-T v142,host=x86"}
54+
- {name: "windows-x86", os: "windows-latest", arch: "x86", cmake_extra: "-T v142,host=x86 -A Win32"}
55+
- {name: "windows-arm64", os: "windows-11-arm", arch: "aarch64", cmake_extra: "-T v143,host=ARM64 -A ARM64"}
56+
57+
# macOS builds (Apple Silicon + Intel)
58+
- {name: "macos-latest", os: "macos-latest", arch: "universal"}
59+
4760
steps:
4861
- uses: actions/checkout@v4
4962

63+
# Set up cross-compilation toolchain for ARM on Linux
64+
- name: Install cross-compilation toolchain
65+
if: matrix.config.cross_compile && runner.os == 'Linux'
66+
run: |
67+
sudo apt-get update
68+
if [[ "${{ matrix.config.arch }}" == "aarch64" ]]; then
69+
sudo apt-get install -y --no-install-recommends \
70+
gcc-aarch64-linux-gnu \
71+
g++-aarch64-linux-gnu \
72+
qemu-user-static
73+
echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/.github/toolchains/aarch64-linux-gnu.cmake" >> $GITHUB_ENV
74+
echo "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu" >> $GITHUB_ENV
75+
elif [[ "${{ matrix.config.arch }}" == "armv7" ]]; then
76+
sudo apt-get install -y --no-install-recommends \
77+
gcc-arm-linux-gnueabihf \
78+
g++-arm-linux-gnueabihf \
79+
qemu-user-static
80+
echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/.github/toolchains/arm-linux-gnueabihf.cmake" >> $GITHUB_ENV
81+
echo "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf" >> $GITHUB_ENV
82+
fi
83+
84+
# Cache dependencies for Linux
85+
- name: Cache APT packages
86+
if: runner.os == 'Linux'
87+
uses: actions/cache@v4
88+
with:
89+
path: /var/cache/apt/archives
90+
key: ${{ runner.os }}-apt-${{ matrix.config.name }}-${{ hashFiles('.github/workflows/cppcmake.yml') }}
91+
restore-keys: |
92+
${{ runner.os }}-apt-${{ matrix.config.name }}-
93+
${{ runner.os }}-apt-
94+
95+
# Cache build artifacts with ccache
96+
- name: Cache ccache
97+
if: runner.os == 'Linux' || runner.os == 'macOS'
98+
uses: actions/cache@v4
99+
with:
100+
path: ~/.ccache
101+
key: ${{ runner.os }}-ccache-${{ matrix.config.name }}-${{ github.sha }}
102+
restore-keys: |
103+
${{ runner.os }}-ccache-${{ matrix.config.name }}-
104+
${{ runner.os }}-ccache-
105+
106+
- name: Install ccache
107+
if: runner.os == 'Linux' || runner.os == 'macOS'
108+
run: |
109+
if [[ "${{ runner.os }}" == "Linux" ]]; then
110+
sudo apt-get install -y ccache
111+
elif [[ "${{ runner.os }}" == "macOS" ]]; then
112+
brew install ccache
113+
fi
114+
ccache --max-size=500M
115+
ccache --set-config=compression=true
116+
117+
- name: Install dependencies
118+
if: runner.os == 'Linux'
119+
run: |
120+
if [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then
121+
sudo apt-get install -y --no-install-recommends libpugixml-dev
122+
fi
123+
50124
- name: Configure CMake
51125
run: |
52-
if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then
53-
sudo apt-get install -y --no-install-recommends libpugixml-dev
54-
fi
55-
cmake --version
56-
cmake -S . -B build \
57-
-DCMAKE_BUILD_TYPE=Release \
58-
-DCMAKE_INSTALL_PREFIX=${PWD}/install \
59-
-DLSL_UNITTESTS=ON \
60-
-DLSL_BENCHMARKS=ON \
61-
-DCPACK_PACKAGE_DIRECTORY=${PWD}/package \
62-
-Dlslgitrevision=${{ github.sha }} \
63-
-Dlslgitbranch=${{ github.ref }} \
64-
${{ matrix.config.cmake_extra }} \
65-
${{ github.event.inputs.cmakeextra }}
66-
echo ${PWD}
67-
68-
- name: make
69-
run: cmake --build build --config Release -j
70-
71-
- name: make install
126+
# Set up ccache as compiler wrapper
127+
if [[ "${{ runner.os }}" == "Linux" ]] || [[ "${{ runner.os }}" == "macOS" ]]; then
128+
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
129+
export CC="ccache gcc"
130+
export CXX="ccache g++"
131+
fi
132+
133+
cmake --version
134+
cmake -S . -B build \
135+
-DCMAKE_BUILD_TYPE=Release \
136+
-DCMAKE_INSTALL_PREFIX=${PWD}/install \
137+
-DLSL_UNITTESTS=ON \
138+
-DLSL_BENCHMARKS=ON \
139+
-DCPACK_PACKAGE_DIRECTORY=${PWD}/package \
140+
-DCPACK_PACKAGE_FILE_NAME="liblsl-${{ matrix.config.arch }}" \
141+
-Dlslgitrevision=${{ github.sha }} \
142+
-Dlslgitbranch=${{ github.ref }} \
143+
${CMAKE_TOOLCHAIN} \
144+
${{ matrix.config.cmake_extra }} \
145+
${{ github.event.inputs.cmakeextra }}
146+
echo "Build directory: ${PWD}"
147+
148+
- name: Build
149+
run: |
150+
cmake --build build --config Release -j
151+
# Show ccache statistics
152+
if command -v ccache &> /dev/null; then
153+
ccache -s
154+
fi
155+
156+
- name: Install
72157
run: cmake --build build --config Release --target install
73158

74-
- name: test install using examples
159+
- name: Test install using examples
75160
run: |
76-
# Test that the in-tree install was successful by building the examples
77-
cmake -S examples -B examples/build \
78-
-DLSL_INSTALL_ROOT=${PWD}/install \
79-
-DCMAKE_INSTALL_PREFIX=examples/build/install \
80-
-DLSL_COMFY_DEFAULTS=ON \
81-
${{ matrix.config.cmake_extra }} \
82-
${{ github.event.inputs.cmakeextra }}
83-
cmake --build examples/build --target install --config Release -j
161+
# Set up QEMU for cross-compiled binaries
162+
QEMU_RUNNER=""
163+
if [[ "${{ matrix.config.cross_compile }}" == "true" ]]; then
164+
if [[ "${{ matrix.config.arch }}" == "aarch64" ]]; then
165+
QEMU_RUNNER="qemu-aarch64-static -L /usr/aarch64-linux-gnu"
166+
elif [[ "${{ matrix.config.arch }}" == "armv7" ]]; then
167+
QEMU_RUNNER="qemu-arm-static -L /usr/arm-linux-gnueabihf"
168+
fi
169+
fi
170+
171+
# Test that the in-tree install was successful by building the examples
172+
cmake -S examples -B examples/build \
173+
-DLSL_INSTALL_ROOT=${PWD}/install \
174+
-DCMAKE_INSTALL_PREFIX=examples/build/install \
175+
-DLSL_COMFY_DEFAULTS=ON \
176+
${CMAKE_TOOLCHAIN} \
177+
${{ matrix.config.cmake_extra }} \
178+
${{ github.event.inputs.cmakeextra }}
179+
cmake --build examples/build --target install --config Release -j
180+
181+
# Run example with QEMU if cross-compiled
182+
if [[ -n "$QEMU_RUNNER" ]]; then
183+
$QEMU_RUNNER ./examples/build/install/bin/HandleMetaData
184+
else
84185
./examples/build/install/bin/HandleMetaData
186+
fi
85187
86-
- name: package
188+
- name: Package
87189
run: |
88-
echo $GITHUB_REF
89-
cmake --build build --target package --config Release -j
90-
echo $PWD
91-
ls -la
92-
# On Debian / Ubuntu the dependencies can only be resolved for
93-
# already installed packages. Therefore, we have built all
94-
# packages without dependencies in the previous step,
95-
# install them and rebuild them with dependency discovery enabled
96-
if [[ "${{ matrix.config.os }}" == ubuntu-* ]]; then
97-
cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON .
98-
sudo dpkg -i package/*.deb
99-
cmake --build build --target package --config Release -j
100-
dpkg -I package/liblsl*.deb
101-
fi
102-
cmake -E remove_directory package/_CPack_Packages
103-
cp testing/lslcfgs/default.cfg .
190+
echo "Creating package for ${{ matrix.config.arch }}"
191+
cmake --build build --target package --config Release -j
192+
193+
# On Debian / Ubuntu the dependencies can only be resolved for
194+
# already installed packages (only for native builds, not cross-compiled)
195+
if [[ "${{ matrix.config.os }}" == ubuntu-* ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then
196+
cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON build
197+
sudo dpkg -i package/*.deb
198+
cmake --build build --target package --config Release -j
199+
dpkg -I package/liblsl*.deb
200+
fi
201+
202+
# For cross-compiled ARM packages, add architecture to package metadata
203+
if [[ "${{ matrix.config.cross_compile }}" == "true" ]]; then
204+
echo "Cross-compiled ${{ matrix.config.arch }} package created"
205+
ls -lh package/
206+
fi
207+
208+
cmake -E remove_directory package/_CPack_Packages
209+
cp testing/lslcfgs/default.cfg . 2>/dev/null || true
104210
105211
- name: upload install dir
106212
uses: actions/upload-artifact@master
@@ -124,16 +230,35 @@ jobs:
124230
ip -6 route
125231
fi
126232
127-
# run internal tests
128-
- name: unit tests
233+
# Run internal tests (with QEMU for cross-compiled binaries)
234+
- name: Unit tests
129235
run: |
130-
if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then
236+
# Set up core dumps for debugging (native builds only)
237+
if [[ "${{ matrix.config.name }}" == ubuntu-* ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then
131238
ulimit -c unlimited
132239
echo "$PWD/dumps/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern
133240
fi
134241
mkdir -p dumps
135-
install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes
136-
install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes
242+
243+
# Set up QEMU for cross-compiled binaries
244+
QEMU_RUNNER=""
245+
if [[ "${{ matrix.config.cross_compile }}" == "true" ]]; then
246+
if [[ "${{ matrix.config.arch }}" == "aarch64" ]]; then
247+
QEMU_RUNNER="qemu-aarch64-static -L /usr/aarch64-linux-gnu"
248+
elif [[ "${{ matrix.config.arch }}" == "armv7" ]]; then
249+
QEMU_RUNNER="qemu-arm-static -L /usr/arm-linux-gnueabihf"
250+
fi
251+
echo "Running tests with QEMU: $QEMU_RUNNER"
252+
fi
253+
254+
# Run unit tests
255+
if [[ -n "$QEMU_RUNNER" ]]; then
256+
$QEMU_RUNNER install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes
257+
$QEMU_RUNNER install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes
258+
else
259+
install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes
260+
install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes
261+
fi
137262
timeout-minutes: 10
138263

139264
- name: upload dump

0 commit comments

Comments
 (0)