Skip to content

Commit 1c65ea2

Browse files
Configure cross-compilation for Apple Silicon (#6360)
Adds support for Apple Silicon binaries for NodeJS bindings.
1 parent 96f5780 commit 1c65ea2

File tree

4 files changed

+113
-39
lines changed

4 files changed

+113
-39
lines changed

.github/workflows/osrm-backend.yml

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ jobs:
234234
CCOMPILER: gcc-7
235235
CXXCOMPILER: g++-7
236236

237-
- name: conan-osx-release-node-12
237+
- name: conan-macos-x64-release-node-12
238238
build_node_package: true
239239
continue-on-error: false
240240
node: 12
@@ -247,7 +247,7 @@ jobs:
247247
ENABLE_ASSERTIONS: ON
248248
ENABLE_CONAN: ON
249249

250-
- name: conan-osx-release-node-14
250+
- name: conan-macos-x64-release-node-14
251251
build_node_package: true
252252
continue-on-error: false
253253
node: 14
@@ -260,7 +260,7 @@ jobs:
260260
ENABLE_ASSERTIONS: ON
261261
ENABLE_CONAN: ON
262262

263-
- name: conan-osx-release-node-16
263+
- name: conan-macos-x64-release-node-16
264264
build_node_package: true
265265
continue-on-error: false
266266
node: 16
@@ -273,6 +273,20 @@ jobs:
273273
ENABLE_ASSERTIONS: ON
274274
ENABLE_CONAN: ON
275275

276+
- name: conan-macos-arm64-release-node-16
277+
build_node_package: true
278+
continue-on-error: false
279+
node: 16
280+
runs-on: macos-11
281+
BUILD_TOOLS: ON
282+
BUILD_TYPE: Release
283+
CCOMPILER: clang
284+
CXXCOMPILER: clang++
285+
CUCUMBER_TIMEOUT: 60000
286+
ENABLE_ASSERTIONS: ON
287+
ENABLE_CONAN: ON
288+
ENABLE_APPLE_SILICON: ON
289+
276290
- name: gcc-7-release-shared
277291
continue-on-error: false
278292
node: 12
@@ -356,7 +370,19 @@ jobs:
356370
ENABLE_CONAN: ON
357371
NODE_PACKAGE_TESTS_ONLY: ON
358372

359-
- name: conan-osx-release-node-latest
373+
- name: conan-macos-x64-release-node-latest
374+
build_node_package: true
375+
continue-on-error: true
376+
node: latest
377+
runs-on: macos-11
378+
BUILD_TYPE: Release
379+
CCOMPILER: clang
380+
CXXCOMPILER: clang++
381+
CUCUMBER_TIMEOUT: 60000
382+
ENABLE_ASSERTIONS: ON
383+
ENABLE_CONAN: ON
384+
385+
- name: conan-macos-arm64-release-node-latest
360386
build_node_package: true
361387
continue-on-error: true
362388
node: latest
@@ -367,6 +393,7 @@ jobs:
367393
CUCUMBER_TIMEOUT: 60000
368394
ENABLE_ASSERTIONS: ON
369395
ENABLE_CONAN: ON
396+
ENABLE_APPLE_SILICON: ON
370397

371398
- name: node-latest-conan-linux-release
372399
build_node_package: true
@@ -392,7 +419,7 @@ jobs:
392419
ENABLE_CONAN: ON
393420
NODE_PACKAGE_TESTS_ONLY: ON
394421

395-
- name: conan-osx-release-node-lts
422+
- name: conan-macos-x64-release-node-lts
396423
build_node_package: true
397424
continue-on-error: true
398425
node: "lts/*"
@@ -403,6 +430,19 @@ jobs:
403430
CUCUMBER_TIMEOUT: 60000
404431
ENABLE_ASSERTIONS: ON
405432
ENABLE_CONAN: ON
433+
434+
- name: conan-macos-arm64-release-node-lts
435+
build_node_package: true
436+
continue-on-error: true
437+
node: "lts/*"
438+
runs-on: macos-11
439+
BUILD_TYPE: Release
440+
CCOMPILER: clang
441+
CXXCOMPILER: clang++
442+
CUCUMBER_TIMEOUT: 60000
443+
ENABLE_ASSERTIONS: ON
444+
ENABLE_CONAN: ON
445+
ENABLE_APPLE_SILICON: ON
406446

407447
- name: node-lts-conan-linux-release
408448
build_node_package: true
@@ -447,6 +487,7 @@ jobs:
447487
ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }}
448488
ENABLE_SANITIZER: ${{ matrix.ENABLE_SANITIZER }}
449489
NODE_PACKAGE_TESTS_ONLY: ${{ matrix.NODE_PACKAGE_TESTS_ONLY }}
490+
ENABLE_APPLE_SILICON: ${{ matrix.ENABLE_APPLE_SILICON }}
450491
TARGET_ARCH: ${{ matrix.TARGET_ARCH }}
451492
OSRM_CONNECTION_RETRIES: ${{ matrix.OSRM_CONNECTION_RETRIES }}
452493
OSRM_CONNECTION_EXP_BACKOFF_COEF: ${{ matrix.OSRM_CONNECTION_EXP_BACKOFF_COEF }}
@@ -475,9 +516,9 @@ jobs:
475516
uses: actions/cache@v2
476517
with:
477518
path: ~/.conan
478-
key: v4-conan-${{ matrix.name }}-${{ github.sha }}
519+
key: v6-conan-${{ matrix.name }}-${{ github.sha }}
479520
restore-keys: |
480-
v4-conan-${{ matrix.name }}-
521+
v6-conan-${{ matrix.name }}-
481522
- name: Enable test cache
482523
uses: actions/cache@v2
483524
with:
@@ -583,6 +624,16 @@ jobs:
583624
echo "Using ${JOBS} jobs"
584625
pushd ${OSRM_BUILD_DIR}
585626
627+
# handle Apple Silicon cross compilation
628+
if [[ "${ENABLE_APPLE_SILICON}" == "ON" ]]; then
629+
ARCH=arm64
630+
TARGET="${ARCH}-apple-darwin"
631+
CFLAGS="$CFLAGS --target=$TARGET"
632+
CXXFLAGS="$CXXFLAGS --target=$TARGET"
633+
APPLE_SILICON_FLAGS=(-DCMAKE_C_COMPILER_TARGET="$TARGET" -DCMAKE_CXX_COMPILER_TARGET="$TARGET" -DCMAKE_SYSTEM_PROCESSOR="${ARCH}" -DCMAKE_SYSTEM_NAME="Darwin" -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS")
634+
else
635+
APPLE_SILICON_FLAGS=()
636+
fi
586637
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
587638
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
588639
-DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \
@@ -594,10 +645,11 @@ jobs:
594645
-DBUILD_TOOLS=${BUILD_TOOLS:-OFF} \
595646
-DENABLE_CCACHE=ON \
596647
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR} \
597-
-DENABLE_GLIBC_WORKAROUND=${ENABLE_GLIBC_WORKAROUND:-OFF}
648+
-DENABLE_GLIBC_WORKAROUND=${ENABLE_GLIBC_WORKAROUND:-OFF} \
649+
"${APPLE_SILICON_FLAGS[@]}"
598650
make --jobs=${JOBS}
599651
600-
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
652+
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" && "${ENABLE_APPLE_SILICON}" != "ON" ]]; then
601653
make tests --jobs=${JOBS}
602654
make benchmarks --jobs=${JOBS}
603655
ccache -s
@@ -609,15 +661,15 @@ jobs:
609661
fi
610662
popd
611663
- name: Build example
612-
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
664+
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
613665
run: |
614666
mkdir example/build && pushd example/build
615667
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
616668
make --jobs=${JOBS}
617669
popd
618670
619671
- name: Run all tests
620-
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
672+
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
621673
run: |
622674
make -C test/data benchmark
623675
@@ -634,7 +686,7 @@ jobs:
634686
popd
635687
npm test
636688
- name: Run Node package tests only
637-
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
689+
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' && matrix.ENABLE_APPLE_SILICON != 'ON' }}
638690
run: |
639691
npm run nodejs-tests
640692
- name: Upload test logs
@@ -659,9 +711,17 @@ jobs:
659711
name: codecov-osrm-backend
660712
fail_ci_if_error: true
661713
verbose: true
662-
714+
- name: Check Apple Silicon binary
715+
if: ${{ matrix.ENABLE_APPLE_SILICON == 'ON' }}
716+
run: |
717+
ARCH=$(file ./lib/binding/node_osrm.node | awk '{printf $NF}')
718+
if [[ "$ARCH" != "arm64" ]]; then
719+
file ./lib/binding/node_osrm.node
720+
>&2 echo "Wrong architecture!"
721+
exit 1
722+
fi
663723
- name: Build Node package
664-
if: ${{ matrix.build_node_package && env.PUBLISH == 'On' }}
724+
if: ${{ matrix.build_node_package }}
665725
run: ./scripts/ci/node_package.sh
666726
- name: Publish Node package
667727
if: ${{ matrix.build_node_package && env.PUBLISH == 'On' }}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
- FIXED: Bug in bicycle profile that caused exceptions if there is a highway=bicycle in the data. [#6296](https://github.com/Project-OSRM/osrm-backend/pull/6296)
2323
- FIXED: Internal refactoring of identifier types used in data facade [#6044](https://github.com/Project-OSRM/osrm-backend/pull/6044)
2424
- Build:
25+
- ADDED: Configure cross-compilation for Apple Silicon. [#6360](https://github.com/Project-OSRM/osrm-backend/pull/6360)
2526
- CHANGED: Use apt-get to install Clang on CI. [#6345](https://github.com/Project-OSRM/osrm-backend/pull/6345)
2627
- CHANGED: Fix TBB in case of Conan + NodeJS build. [#6333](https://github.com/Project-OSRM/osrm-backend/pull/6333)
2728
- CHANGED: Migrate to modern TBB version. [#6300](https://github.com/Project-OSRM/osrm-backend/pull/6300)

CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ if (POLICY CMP0074)
6161
endif()
6262
project(OSRM C CXX)
6363

64+
# add @loader_path/$ORIGIN to rpath to make binaries relocatable
65+
if (APPLE)
66+
set(CMAKE_BUILD_RPATH "@loader_path")
67+
else()
68+
set(CMAKE_BUILD_RPATH "\$ORIGIN")
69+
# https://stackoverflow.com/questions/6324131/rpath-origin-not-having-desired-effect
70+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,origin")
71+
endif()
72+
6473
include(JSONParser)
6574
file(READ "package.json" packagejsonraw)
6675
sbeParseJson(packagejson packagejsonraw)
@@ -185,7 +194,7 @@ if(ENABLE_GOLD_LINKER)
185194
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
186195
if("${LD_VERSION}" MATCHES "GNU gold")
187196
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
188-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
197+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
189198
set(OSRM_LDFLAGS "${OSRM_LDFLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
190199
message(STATUS "Using GNU gold as linker.")
191200

@@ -489,11 +498,15 @@ if(ENABLE_CONAN)
489498
NO_OUTPUT_DIRS
490499
OPTIONS boost:filesystem_version=3 # https://stackoverflow.com/questions/73392648/error-with-boost-filesystem-version-in-cmake
491500
onetbb:shared=${TBB_SHARED}
501+
boost:without_stacktrace=True # Apple Silicon cross-compilation fails without it
492502
BUILD missing
493503
)
494504
# explicitly say Conan to use x86 dependencies if build for x86 platforms (https://github.com/conan-io/cmake-conan/issues/141)
495505
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
496506
conan_cmake_run("${CONAN_ARGS};ARCH;x86")
507+
# cross-compilation for Apple Silicon
508+
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
509+
conan_cmake_run("${CONAN_ARGS};ARCH;armv8")
497510
else()
498511
conan_cmake_run("${CONAN_ARGS}")
499512
endif()

scripts/ci/node_package.sh

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ echo "node version is:"
77
which node
88
node -v
99

10-
if [[ ${PUBLISH} == 'On' ]]; then
11-
echo "PUBLISH is set to '${PUBLISH}', publishing!"
12-
NPM_FLAGS=''
13-
if [[ ${BUILD_TYPE} == "Debug" ]]; then
14-
NPM_FLAGS='--debug'
15-
fi
10+
NPM_FLAGS=''
11+
if [[ ${BUILD_TYPE} == "Debug" ]]; then
12+
NPM_FLAGS='--debug'
13+
fi
14+
15+
# append --target_arch in order to handle cross-compilation for Apple Silicon
16+
if [[ "$ENABLE_APPLE_SILICON" == "ON" ]]; then
17+
NPM_FLAGS="${NPM_FLAGS} --target_arch=arm64"
18+
fi
1619

17-
echo "dumping binary meta..."
18-
./node_modules/.bin/node-pre-gyp reveal $NPM_FLAGS
20+
echo "dumping binary meta..."
21+
./node_modules/.bin/node-pre-gyp reveal $NPM_FLAGS
1922

20-
# enforce that binary has proper ORIGIN flags so that
21-
# it can portably find libtbb.so in the same directory
22-
if [[ $(uname -s) == 'Linux' ]]; then
23-
readelf -d ./lib/binding/node_osrm.node > readelf-output.txt
24-
if grep -q 'Flags: ORIGIN' readelf-output.txt; then
25-
echo "Found ORIGIN flag in readelf output"
26-
cat readelf-output.txt
27-
else
28-
echo "*** Error: Could not found ORIGIN flag in readelf output"
29-
cat readelf-output.txt
30-
exit 1
31-
fi
23+
# enforce that binary has proper ORIGIN flags so that
24+
# it can portably find libtbb.so in the same directory
25+
if [[ $(uname -s) == 'Linux' ]]; then
26+
readelf -d ./lib/binding/node_osrm.node > readelf-output.txt
27+
if grep -q 'Flags: ORIGIN' readelf-output.txt; then
28+
echo "Found ORIGIN flag in readelf output"
29+
cat readelf-output.txt
30+
else
31+
echo "*** Error: Could not found ORIGIN flag in readelf output"
32+
cat readelf-output.txt
33+
exit 1
3234
fi
33-
34-
./node_modules/.bin/node-pre-gyp package testpackage $NPM_FLAGS
35-
else
36-
echo "PUBLISH is set to '${PUBLISH}', skipping."
3735
fi
36+
37+
./node_modules/.bin/node-pre-gyp package testpackage $NPM_FLAGS

0 commit comments

Comments
 (0)