From 42ae7821efe19d8d289104eea120d43f74074e9f Mon Sep 17 00:00:00 2001 From: zeyus Date: Wed, 5 Nov 2025 19:31:35 +0100 Subject: [PATCH] ARM runners, arm packages (rpi, jetson compatible) --- .editorconfig | 5 +- .github/workflows/android.yml | 7 +- .github/workflows/apple.yml | 7 + .github/workflows/cppcmake.yml | 208 +++++++++++++++------ .github/workflows/raspberry_pi_manual.yml | 136 ++++++++++++++ cmake/LSLCMake.cmake | 19 +- cmake/toolchains/README.md | 38 ++++ cmake/toolchains/aarch64-linux-gnu.cmake | 24 +++ cmake/toolchains/arm-linux-gnueabihf.cmake | 24 +++ 9 files changed, 409 insertions(+), 59 deletions(-) create mode 100644 .github/workflows/raspberry_pi_manual.yml create mode 100644 cmake/toolchains/README.md create mode 100644 cmake/toolchains/aarch64-linux-gnu.cmake create mode 100644 cmake/toolchains/arm-linux-gnueabihf.cmake diff --git a/.editorconfig b/.editorconfig index 65377cc44..4cadd5648 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,8 @@ insert_final_newline = true charset = utf-8 indent_style = tab -[*.yaml] +[*.{yaml,yml}] indent_style = space indent_size = 2 - +insert_final_newline = true +end_of_line = lf diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 5ab64200b..41225a76d 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -3,7 +3,11 @@ name: Android on: push: branches: ['androidci'] - paths_ignore: ['docs/**', '.travis.yml'] + paths: + - '**' + - '!docs/**' + - '!.github/**' + - '.github/workflows/android.yml' workflow_dispatch: inputs: cmakeextra: @@ -53,4 +57,3 @@ jobs: with: name: build-android-${{ matrix.config.arch }} path: install - diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml index ae97277fc..3d01253a7 100644 --- a/.github/workflows/apple.yml +++ b/.github/workflows/apple.yml @@ -112,6 +112,13 @@ jobs: install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes timeout-minutes: 10 + - name: unit test (intel) + if: matrix.config.name == 'macOS-15-intel' + run: | + mkdir -p dumps + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes + install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes + timeout-minutes: 10 - name: Package and Notarize macOS Installer if: matrix.config.name == 'macOS-latest' diff --git a/.github/workflows/cppcmake.yml b/.github/workflows/cppcmake.yml index c9013f199..202700b61 100644 --- a/.github/workflows/cppcmake.yml +++ b/.github/workflows/cppcmake.yml @@ -33,72 +33,168 @@ jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} + timeout-minutes: 30 strategy: fail-fast: false matrix: config: - - {name: "ubuntu-22.04", os: "ubuntu-22.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } - - {name: "ubuntu-24.04", os: "ubuntu-24.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } - - {name: "windows-x64", os: "windows-latest", cmake_extra: "-T v142,host=x86"} - - {name: "windows-32", os: "windows-latest", cmake_extra: "-T v142,host=x86 -A Win32"} + # x86_64 Linux builds + - {name: "ubuntu-22.04-x64", os: "ubuntu-22.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + - {name: "ubuntu-24.04-x64", os: "ubuntu-24.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + + # ARM Linux builds - cross-compiled with QEMU testing (Jetson, Raspberry Pi compatible) + # SHLIBDEPS must be disabled for cross-compiled packages as the host system + # does not have the target architecture libraries installed + - {name: "ubuntu-22.04-arm64", os: "ubuntu-22.04", arch: "aarch64", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=ON -DLSL_DISABLE_PACKAGE_SHLIBDEPS=ON" } + - {name: "ubuntu-22.04-armhf", os: "ubuntu-22.04", arch: "armv7", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=ON -DLSL_DISABLE_PACKAGE_SHLIBDEPS=ON" } + + # Native ARM build + # - {name: "ubuntu-24.04-arm64-native", os: "ubuntu-24.04-arm", arch: "aarch64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + + # Windows builds + - {name: "windows-x64", os: "windows-latest", arch: "x86_64", cmake_extra: "-T v142,host=x86"} + - {name: "windows-x86", os: "windows-latest", arch: "x86", cmake_extra: "-T v142,host=x86 -A Win32"} + - {name: "windows-arm64", os: "windows-11-arm", arch: "aarch64", cmake_extra: "-T v143,host=ARM64 -A ARM64"} + + # macOS builds (Apple Silicon + Intel) + # - {name: "macos-latest", os: "macos-latest", arch: "universal"} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + + # Set up cross-compilation toolchain for ARM on Linux + - name: Install cross-compilation toolchain + if: matrix.config.cross_compile && runner.os == 'Linux' + run: | + sudo apt-get update + if [[ "${{ matrix.config.arch }}" == "aarch64" ]]; then + sudo apt-get install -y --no-install-recommends \ + gcc-aarch64-linux-gnu \ + g++-aarch64-linux-gnu + echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/cmake/toolchains/aarch64-linux-gnu.cmake" >> $GITHUB_ENV + elif [[ "${{ matrix.config.arch }}" == "armv7" ]]; then + sudo apt-get install -y --no-install-recommends \ + gcc-arm-linux-gnueabihf \ + g++-arm-linux-gnueabihf + echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/cmake/toolchains/arm-linux-gnueabihf.cmake" >> $GITHUB_ENV + fi + + # Cache dependencies for Linux + - name: Cache APT packages + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: /var/cache/apt/archives + key: ${{ runner.os }}-apt-${{ matrix.config.name }}-${{ hashFiles('.github/workflows/cppcmake.yml') }} + restore-keys: | + ${{ runner.os }}-apt-${{ matrix.config.name }}- + ${{ runner.os }}-apt- + + # Cache build artifacts with ccache + - name: Cache ccache + if: runner.os == 'Linux' || runner.os == 'macOS' + uses: actions/cache@v4 + with: + path: ~/.ccache + key: ${{ runner.os }}-ccache-${{ matrix.config.name }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-ccache-${{ matrix.config.name }}- + ${{ runner.os }}-ccache- + + - name: Install ccache + if: runner.os == 'Linux' || runner.os == 'macOS' + run: | + if [[ "${{ runner.os }}" == "Linux" ]]; then + sudo apt-get install -y ccache + elif [[ "${{ runner.os }}" == "macOS" ]]; then + brew install ccache + fi + ccache --max-size=500M + ccache --set-config=compression=true + + - name: Install dependencies + if: runner.os == 'Linux' + run: | + if [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + sudo apt-get install -y --no-install-recommends libpugixml-dev + fi - name: Configure CMake run: | - if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then - sudo apt-get install -y --no-install-recommends libpugixml-dev - fi - cmake --version - cmake -S . -B build \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=${PWD}/install \ - -DLSL_UNITTESTS=ON \ - -DLSL_BENCHMARKS=ON \ - -DCPACK_PACKAGE_DIRECTORY=${PWD}/package \ - -Dlslgitrevision=${{ github.sha }} \ - -Dlslgitbranch=${{ github.ref }} \ - ${{ matrix.config.cmake_extra }} \ - ${{ github.event.inputs.cmakeextra }} - echo ${PWD} - - - name: make - run: cmake --build build --config Release -j - - - name: make install + # Set up ccache as compiler wrapper (skip for cross-compilation) + if [[ "${{ runner.os }}" == "Linux" || "${{ runner.os }}" == "macOS" ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + export CC="ccache gcc" + export CXX="ccache g++" + fi + + cmake --version + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PWD}/install \ + -DLSL_UNITTESTS=ON \ + -DLSL_BENCHMARKS=ON \ + -DCPACK_PACKAGE_DIRECTORY=${PWD}/package \ + -DCPACK_PACKAGE_FILE_NAME="liblsl-${{ matrix.config.arch }}" \ + -Dlslgitrevision=${{ github.sha }} \ + -Dlslgitbranch=${{ github.ref }} \ + ${CMAKE_TOOLCHAIN} \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + echo "Build directory: ${PWD}" + + - name: Build + run: | + cmake --build build --config Release -j + # Show ccache statistics + if command -v ccache &> /dev/null; then + ccache -s + fi + + - name: Install run: cmake --build build --config Release --target install - - name: test install using examples + - name: Test install using examples run: | - # Test that the in-tree install was successful by building the examples - cmake -S examples -B examples/build \ - -DLSL_INSTALL_ROOT=${PWD}/install \ - -DCMAKE_INSTALL_PREFIX=examples/build/install \ - -DLSL_COMFY_DEFAULTS=ON \ - ${{ matrix.config.cmake_extra }} \ - ${{ github.event.inputs.cmakeextra }} - cmake --build examples/build --target install --config Release -j + # Test that the in-tree install was successful by building the examples + cmake -S examples -B examples/build \ + -DLSL_INSTALL_ROOT=${PWD}/install \ + -DCMAKE_INSTALL_PREFIX=examples/build/install \ + -DLSL_COMFY_DEFAULTS=ON \ + ${CMAKE_TOOLCHAIN} \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + cmake --build examples/build --target install --config Release -j + + # Run example binary (skip for cross-compiled builds - no QEMU) + if [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then ./examples/build/install/bin/HandleMetaData + else + echo "Skipping example execution for cross-compiled build (requires real ARM hardware)" + echo "Build validation successful - binary can be tested on target hardware" + fi - - name: package + - name: Package run: | - echo $GITHUB_REF - cmake --build build --target package --config Release -j - echo $PWD - ls -la - # On Debian / Ubuntu the dependencies can only be resolved for - # already installed packages. Therefore, we have built all - # packages without dependencies in the previous step, - # install them and rebuild them with dependency discovery enabled - if [[ "${{ matrix.config.os }}" == ubuntu-* ]]; then - cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON . - sudo dpkg -i package/*.deb - cmake --build build --target package --config Release -j - dpkg -I package/liblsl*.deb - fi - cmake -E remove_directory package/_CPack_Packages - cp testing/lslcfgs/default.cfg . + echo "Creating package for ${{ matrix.config.arch }}" + cmake --build build --target package --config Release -j + + # On Debian / Ubuntu the dependencies can only be resolved for + # already installed packages (only for native builds, not cross-compiled) + if [[ "${{ matrix.config.os }}" == ubuntu-* ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON build + sudo dpkg -i package/*.deb + cmake --build build --target package --config Release -j + dpkg -I package/liblsl*.deb + fi + + if [[ "${{ matrix.config.cross_compile }}" == "true" ]]; then + echo "Cross-compiled ${{ matrix.config.arch }} package created" + ls -lh package/ + fi + + cmake -E remove_directory package/_CPack_Packages + cp testing/lslcfgs/default.cfg . 2>/dev/null || true - name: upload install dir uses: actions/upload-artifact@master @@ -122,14 +218,18 @@ jobs: ip -6 route fi - # run internal tests - - name: unit tests + # Run tests (native builds only) + - name: Unit tests + if: matrix.config.cross_compile != true run: | - if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then + # Set up core dumps for debugging + if [[ "${{ matrix.config.name }}" == ubuntu-* ]]; then ulimit -c unlimited echo "$PWD/dumps/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern fi mkdir -p dumps + + # Run unit tests install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes timeout-minutes: 10 diff --git a/.github/workflows/raspberry_pi_manual.yml b/.github/workflows/raspberry_pi_manual.yml new file mode 100644 index 000000000..d4d6a9dc2 --- /dev/null +++ b/.github/workflows/raspberry_pi_manual.yml @@ -0,0 +1,136 @@ +name: Raspberry Pi Native Build (Manual trigger) +on: + workflow_dispatch: + inputs: + cmakeextra: + description: 'Extra CMake options' + required: false + default: '' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + build: + name: Raspberry Pi ${{ matrix.config.name }} + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + config: + # cortex-a7 -> RPi 3+, if we need 1,2,zero, needs to use arm1176 + # see: https://github.com/marketplace/actions/arm-runner + # adapted from: https://github.com/castle-engine/castle-engine/blob/master/.github/workflows/test-and-pack-arm-runner.yml + - {name: "rpi-armv7l", os: "raspios_lite:latest", cpu: "cortex-a7", cpu_info: "cpuinfo/raspberrypi_3b", cmake_extra: "-DLSL_UNITTESTS=ON -DLSL_BENCHMARKS=ON" } + - {name: "rpi-aarch64", os: "raspios_lite_arm64:latest", cpu: "cortex-a53", cpu_info: "cpuinfo/raspberrypi_4b", cmake_extra: "-DLSL_UNITTESTS=ON -DLSL_BENCHMARKS=ON" } + steps: + - uses: actions/checkout@v5 + - uses: pguyot/arm-runner-action@v2 + with: + base_image: ${{ matrix.config.os }} + cpu: ${{ matrix.config.cpu }} + cpu_info: ${{ matrix.config.cpu_info }} + shell: /bin/bash -eo pipefail + image_additional_mb: 1024 + bind_mount_repository: true + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential pkg-config + - name: Configure CMake + run: | + cmake --version + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PWD}/install \ + -DLSL_UNITTESTS=ON \ + -DLSL_BENCHMARKS=ON \ + -Dlslgitrevision=${{ github.sha }} \ + -Dlslgitbranch=${{ github.ref }} \ + ${{ matrix.config.cmake_extra }} + + - name: make + run: cmake --build build --config Release -j + + - name: make install + run: cmake --build build --config Release --target install -j + + - name: test install using examples + run: | + # Test that the in-tree install was successful by building the examples + cmake -S examples -B examples/build \ + -DLSL_INSTALL_ROOT=${PWD}/install \ + -DCMAKE_INSTALL_PREFIX=examples/build/install \ + -DLSL_COMFY_DEFAULTS=ON \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + cmake --build examples/build --target install --config Release -j + ./examples/build/install/bin/HandleMetaData + + - name: package + run: | + echo $GITHUB_REF + cmake --build build --target package --config Release -j + echo $PWD + ls -la + cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON . + sudo dpkg -i build/*.deb + cmake --build build --target package --config Release -j + dpkg -I build/liblsl*.deb + cmake -E remove_directory build/_CPack_Packages + cp testing/lslcfgs/default.cfg . + + - name: upload install dir + uses: actions/upload-artifact@master + with: + name: build-${{ matrix.config.name }} + path: install + - name: upload package + uses: actions/upload-artifact@master + with: + name: pkg-${{ matrix.config.name }} + path: package + + # Run tests + - name: unit tests + run: | + if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then + ulimit -c unlimited + echo "$PWD/dumps/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern + fi + mkdir -p dumps + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes + install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes + timeout-minutes: 10 + + - name: upload dump + if: failure() + uses: actions/upload-artifact@master + with: + name: dumps-${{ matrix.config.name }} + path: dumps + + - name: upload to release page + if: github.event_name == 'release' + env: + TOKEN: "token ${{ secrets.GITHUB_TOKEN }}" + TAG: ${{ github.event.release.tag_name }} + UPLOAD_URL: ${{ github.event.release.upload_url }} + run: | + # Do try this at home! The REST API is documented at + # https://docs.github.com/en/free-pro-team@latest/rest and you can get a personal + # access token at https://github.com/settings/tokens + # (set TOKEN to "bearer abcdef1234") + # you can get the UPLOAD_URL with a short bash snippet; make sure to set the env var TAG: + # UPLOAD_URL=$(curl -H 'Accept: application/vnd.github.v3+json' $GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/tags/$TAG | jq -r .upload_url) + UPLOAD_URL=${UPLOAD_URL%\{*} # remove "{name,label}" suffix + for pkg in package/*.*; do + NAME=$(basename $pkg) + MIME=$(file --mime-type $pkg|cut -d ' ' -f2) + curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: $TOKEN" -H "Content-Type: $MIME" --data-binary @$pkg $UPLOAD_URL?name=$NAME + done diff --git a/cmake/LSLCMake.cmake b/cmake/LSLCMake.cmake index f64b001bb..083449403 100644 --- a/cmake/LSLCMake.cmake +++ b/cmake/LSLCMake.cmake @@ -312,9 +312,26 @@ macro(LSLGenerateCPackConfig) set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON) set(CPACK_DEB_COMPONENT_INSTALL ON) set(CPACK_DEBIAN_PACKAGE_PRIORITY optional) - set(CPACK_DEBIAN_LIBLSL_PACKAGE_SHLIBDEPS ON) + # Allow disabling SHLIBDEPS for cross-compilation (dpkg-shlibdeps can't analyze ARM binaries on x86 host) + if(NOT LSL_DISABLE_PACKAGE_SHLIBDEPS) + set(CPACK_DEBIAN_LIBLSL_PACKAGE_SHLIBDEPS ON) + endif() set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) + # determine architecture for cross-compiled packages + if(CMAKE_CROSSCOMPILING) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|arm)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386") + endif() + message(STATUS "Cross-compiling: Setting Debian package architecture to ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} (CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR})") + endif() + # include distribution name (e.g. trusty or xenial) in the file name find_program(LSB_RELEASE lsb_release) execute_process(COMMAND ${LSB_RELEASE} -cs diff --git a/cmake/toolchains/README.md b/cmake/toolchains/README.md new file mode 100644 index 000000000..3d02b54ad --- /dev/null +++ b/cmake/toolchains/README.md @@ -0,0 +1,38 @@ +# CMake toolchains + +To build locally for ARM64: +```bash +cmake -S . -B build-arm64 \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/aarch64-linux-gnu.cmake \ + -DCMAKE_BUILD_TYPE=Release +cmake --build build-arm64 +``` + +To build locally for ARMv7: +```bash +cmake -S . -B build-armv7 \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm-linux-gnueabihf.cmake \ + -DCMAKE_BUILD_TYPE=Release +cmake --build build-armv7 +``` + +It is also possible to cross-compile from other hosts but the toolchain files may need to be adjusted accordingly. + +## Testing Cross-Compiled Binaries + +With QEMU: + +```bash +# Install QEMU +sudo apt-get install qemu-user-static + +# Run ARM64 binary +qemu-aarch64-static -L /usr/aarch64-linux-gnu ./build-arm64/your-binary + +# Run ARMv7 binary +qemu-arm-static -L /usr/arm-linux-gnueabihf ./build-armv7/your-binary +``` + +## NVIDIA Jetson + +The ARM64 build (`aarch64-linux-gnu.cmake`) binaries should be compatible with NVIDIA Jetson. diff --git a/cmake/toolchains/aarch64-linux-gnu.cmake b/cmake/toolchains/aarch64-linux-gnu.cmake new file mode 100644 index 000000000..3583c4e86 --- /dev/null +++ b/cmake/toolchains/aarch64-linux-gnu.cmake @@ -0,0 +1,24 @@ +# CMake toolchain file for cross-compiling to ARM64/aarch64 +# Compatible with NVIDIA Jetson, Raspberry Pi 4/5, and other ARM64 Linux systems + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +# Specify the cross compiler +set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) + +# Where to look for the target environment +set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) + +# Set additional compiler flags for better compatibility +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a" CACHE STRING "C flags") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a" CACHE STRING "C++ flags") diff --git a/cmake/toolchains/arm-linux-gnueabihf.cmake b/cmake/toolchains/arm-linux-gnueabihf.cmake new file mode 100644 index 000000000..59fe073ef --- /dev/null +++ b/cmake/toolchains/arm-linux-gnueabihf.cmake @@ -0,0 +1,24 @@ +# CMake toolchain file for cross-compiling to ARMv7 (32-bit ARM with hard float) +# Compatible with Raspberry Pi 2/3 and other ARMv7 Linux systems + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR armv7l) + +# Specify the cross compiler +set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) +set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) + +# Where to look for the target environment +set(CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) + +# Set additional compiler flags for ARMv7 with NEON support +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C flags") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C++ flags")