diff --git a/.github/workflows/build-sapien.yml b/.github/workflows/build-sapien.yml new file mode 100644 index 000000000000..c868adab628c --- /dev/null +++ b/.github/workflows/build-sapien.yml @@ -0,0 +1,242 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +# +# Upstream builds libsapien and the Python bindings as two separate CMake +# stages (setup.py --sapien-only then --pybind-only per interpreter, scripts/ +# build.sh / build_aarch64.sh) rather than via cibuildwheel; this workflow +# follows the same shape, driving the manylinux image directly instead of a +# matrix per interpreter so the expensive C++ world (PhysX, svulkan2 and its +# FetchContent deps) is only built once. PhysX has no riscv64 precompiled +# archive, so it's built from source from sapien-sim/PhysX (the exact fork +# SAPIEN pins, not raw NVIDIA-Omniverse/PhysX) and fed back in via +# SAPIEN_PHYSX5_DIR. GPU PhysX, CUDA and OpenImageDenoise are all off +# (SAPIEN_CUDA defaults OFF without a CUDA_PATH). +name: Build sapien wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/sapien.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-sapien.yml' + - 'docs/packages/sapien.yaml' + - 'patches/sapien/**' + push: + branches: [main] + paths: + - '.github/workflows/build-sapien.yml' + - 'docs/packages/sapien.yaml' + - 'patches/sapien/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +env: + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + PIP_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ + PHYSX_TAG: 105.1-physx-5.3.1.patch0 + AUDITWHEEL_FORK_REF: fe61bcdfb78f3955d9a3b6fbb05e3852c32239b0 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: sapien + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build sapien ${{ matrix.version }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + timeout-minutes: 1440 + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + + env: + SAPIEN_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout haosulab/SAPIEN ${{ env.SAPIEN_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: haosulab/SAPIEN + ref: ${{ env.SAPIEN_VERSION }} + submodules: recursive + path: sapien + persist-credentials: false + + - name: Checkout sapien-sim/PhysX ${{ env.PHYSX_TAG }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: sapien-sim/PhysX + ref: ${{ env.PHYSX_TAG }} + path: physx-src + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Apply riscv64 patches + run: | + set -eux + PATCH_DIR="$PWD/python-wheels/patches/sapien/${SAPIEN_VERSION}" + cd physx-src + git apply -v "$PATCH_DIR"/0001-physx-foundation-add-riscv64-to-PX_P64_FAMILY.patch + git apply -v "$PATCH_DIR"/0002-physx-serialization-add-riscv64-binary-platform-tag.patch + git apply -v "$PATCH_DIR"/0003-physx-cmake-extend-aarch64-warning-relaxation-to-riscv64.patch + cd ../sapien + git apply -v "$PATCH_DIR"/0004-cmake-skip-cuda-language-on-riscv64.patch + git apply -v "$PATCH_DIR"/0005-cmake-physx5-add-riscv64-library-path.patch + git apply -v "$PATCH_DIR"/0006-setup.py-plumb-sapien_physx5_dir.patch + git apply -v "$PATCH_DIR"/0007-svulkan2-openvr-add-riscv64-branch.patch + + - name: Build PhysX, SAPIEN core and the Python wheels + run: | + mkdir -p output "$HOME/.cache/sapien-ccache" + docker run -i --rm \ + -v "$PWD/sapien:/sapien" \ + -v "$PWD/physx-src:/physx-src" \ + -v "$PWD/output:/output" \ + -v "$HOME/.cache/sapien-ccache:/ccache" \ + -e CCACHE_DIR=/ccache \ + -e PIP_EXTRA_INDEX_URL \ + -e AUDITWHEEL_FORK_REF \ + -e CMAKE_BUILD_PARALLEL_LEVEL=4 \ + "$MANYLINUX_RISCV64_IMAGE" bash -s <<'SAPIEN_BUILD_EOF' + #!/usr/bin/env bash + set -euxo pipefail + + dnf install -y --setopt=install_weak_deps=False \ + ninja-build \ + libXinerama-devel libXrandr-devel libXcursor-devel libXi-devel \ + wayland-devel libxkbcommon-devel wayland-protocols-devel + + PYBIN0=/opt/python/cp312-cp312/bin + export PATH="$PYBIN0:$PATH" + "$PYBIN0/pip" install -U "git+https://github.com/fbxiang/auditwheel.git@${AUDITWHEEL_FORK_REF}" + cat > /usr/local/bin/auditwheel </dev/null 2>&1 && \ + PHYSX_CCACHE_ARGS="-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" || \ + PHYSX_CCACHE_ARGS="" + cmake -S /physx-src/physx/compiler/public -B /tmp/physx_build -G Ninja \ + -DTARGET_BUILD_PLATFORM=linux \ + -DPHYSX_ROOT_DIR=/physx-src/physx \ + -DPX_OUTPUT_LIB_DIR=/physx-src/physx \ + -DPX_OUTPUT_BIN_DIR=/physx-src/physx \ + -DPX_GENERATE_STATIC_LIBRARIES=1 \ + -DPX_BUILDSNIPPETS=0 \ + -DPX_BUILDPVDRUNTIME=0 \ + -DCMAKE_BUILD_TYPE=release \ + ${PHYSX_CCACHE_ARGS} + cmake --build /tmp/physx_build + find /physx-src/physx/bin -name 'libPhysX*_static_64.a' \ + -exec cp {} "$PHYSX_INSTALL/bin/linux.riscv64/release/" \; + ls "$PHYSX_INSTALL/bin/linux.riscv64/release" + cp -r /physx-src/physx/include "$PHYSX_INSTALL/include" + + cd /sapien + "$PYBIN0/python3" -m pip install -U setuptools wheel + command -v ccache >/dev/null 2>&1 && \ + export CMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_CXX_COMPILER_LAUNCHER=ccache + "$PYBIN0/python3" setup.py bdist_wheel --sapien-only \ + --build-dir=sapien_build --physx5-dir="$PHYSX_INSTALL" + + for PYTAG in cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t; do + PYBIN=/opt/python/${PYTAG}/bin + "$PYBIN/python3" -m pip install -U setuptools wheel + "$PYBIN/python3" setup.py bdist_wheel --pybind-only \ + --build-dir=sapien_build --physx5-dir="$PHYSX_INSTALL" + done + + PACKAGE_VERSION=$("$PYBIN0/python3" setup.py --get-version) + mkdir -p /output + for whl in dist/sapien-"${PACKAGE_VERSION}"-*.whl; do + /usr/local/bin/auditwheel repair "$whl" \ + --exclude 'libvulkan*' --exclude 'libOpenImageDenoise*' \ + --exclude 'libm.so*' --exclude 'libc.so*' --exclude 'libdl.so*' --exclude 'libpthread.so*' \ + --internal libsapien --internal libsvulkan2 \ + -w /output + done + ls -la /output + SAPIEN_BUILD_EOF + + - name: Test sapien wheel (physics only, no GPU/Vulkan on this runner) + run: | + docker run -i --rm \ + -v "$PWD/output:/output" \ + -e PIP_EXTRA_INDEX_URL \ + "$MANYLINUX_RISCV64_IMAGE" bash -s <<'SAPIEN_TEST_EOF' + #!/usr/bin/env bash + set -euxo pipefail + + for PYTAG in cp312-cp312 cp313-cp313 cp314-cp314 cp314-cp314t; do + PYBIN=/opt/python/${PYTAG}/bin + WHEEL=$(ls /output/sapien-*-"${PYTAG}"-manylinux_*riscv64.whl) + "$PYBIN/pip" install "$WHEEL" + "$PYBIN/python3" -c " + import sapien + + scene = sapien.Scene() + scene.physx_system.timestep = 1 / 100 + scene.create_actor_builder().add_box_collision(half_size=[1, 1, 1]).build_static() + for _ in range(10): + scene.step() + print('sapien physx smoke test OK:', sapien.__version__) + " + done + SAPIEN_TEST_EOF + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: sapien-${{ env.SAPIEN_VERSION }}-manylinux_riscv64 + path: output/*.whl + if-no-files-found: error + + publish: + name: Publish sapien ${{ matrix.version }} + needs: [setup, build_wheels] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: sapien-${{ matrix.version }}-manylinux_riscv64 diff --git a/docs/packages/sapien.yaml b/docs/packages/sapien.yaml new file mode 100644 index 000000000000..4216709c1ba0 --- /dev/null +++ b/docs/packages/sapien.yaml @@ -0,0 +1,5 @@ +package-name: sapien +source-code: https://github.com/haosulab/SAPIEN +license: Apache-2.0 +versions: +- version: 3.0.3 diff --git a/patches/sapien/3.0.3/0001-physx-foundation-add-riscv64-to-PX_P64_FAMILY.patch b/patches/sapien/3.0.3/0001-physx-foundation-add-riscv64-to-PX_P64_FAMILY.patch new file mode 100644 index 000000000000..de618e0e296c --- /dev/null +++ b/patches/sapien/3.0.3/0001-physx-foundation-add-riscv64-to-PX_P64_FAMILY.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] physx/foundation: add riscv64 to PX_P64_FAMILY + +Upstream-Status: To upstream [no riscv64 CI to validate against yet] + +PxPreprocessor.h's architecture block recognizes x86_64, i386, arm64, +arm32 and ppc only; any other __riscv/__riscv_xlen==64 target falls +through to `#error "Unknown architecture"`, which is a real compile +blocker for riscv64 (not an untested-upstream SIMD path: this file +never reaches a SIMD choice at all without first defining an arch). + +Add PX_RISCV64 as its own define, give it the usual `#ifndef ... 0 +#endif` default like every other arch macro, and fold it into +PX_P64_FAMILY only (the 64-bit-pointer shortcut used by serialization +and struct layout code) -- not PX_ARM_FAMILY or PX_INTEL_FAMILY, which +riscv64 is neither. Downstream, COMPILE_VECTOR_INTRINSICS +(PxVecMath.h) is gated on PX_INTEL_FAMILY || PX_SWITCH only, so once +PX_RISCV64 exists, riscv64 automatically lands on PxVecMathAoSScalar.h +-- the same scalar fallback aarch64's own precompiled Linux build +already ships in production, not a new/untested code path. + +Signed-off-by: Ludovic Henry +--- + physx/include/foundation/PxPreprocessor.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/physx/include/foundation/PxPreprocessor.h b/physx/include/foundation/PxPreprocessor.h +index 0000000..0000000 100644 +--- a/physx/include/foundation/PxPreprocessor.h ++++ b/physx/include/foundation/PxPreprocessor.h +@@ -116,6 +116,8 @@ + #define PX_ARM 1 + #elif defined(__ppc__) || defined(_M_PPC) || defined(__CELLOS_LV2__) + #define PX_PPC 1 ++#elif defined(__riscv) && (__riscv_xlen == 64) ++ #define PX_RISCV64 1 + #else + #error "Unknown architecture" + #endif +@@ -177,6 +179,9 @@ + #ifndef PX_PPC + #define PX_PPC 0 + #endif ++#ifndef PX_RISCV64 ++ #define PX_RISCV64 0 ++#endif + #ifndef PX_SSE2 + #define PX_SSE2 0 + #endif +@@ -227,7 +232,7 @@ + // architecture + #define PX_INTEL_FAMILY (PX_X64 || PX_X86) + #define PX_ARM_FAMILY (PX_ARM || PX_A64) +-#define PX_P64_FAMILY (PX_X64 || PX_A64) // shortcut for 64-bit architectures ++#define PX_P64_FAMILY (PX_X64 || PX_A64 || PX_RISCV64) // shortcut for 64-bit architectures + + /** + C++ standard library defines +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0002-physx-serialization-add-riscv64-binary-platform-tag.patch b/patches/sapien/3.0.3/0002-physx-serialization-add-riscv64-binary-platform-tag.patch new file mode 100644 index 000000000000..ee0e1fddaad0 --- /dev/null +++ b/patches/sapien/3.0.3/0002-physx-serialization-add-riscv64-binary-platform-tag.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] physx/serialization: add riscv64 binary platform tag + +Upstream-Status: To upstream [no riscv64 CI to validate against yet] + +getBinaryPlatformTag() in SnSerialUtils.cpp is a real compile blocker +on riscv64 independent of the PxPreprocessor.h arch define: with +PX_RISCV64 now defined (previous patch), none of the existing +PX_WINDOWS/PX_LINUX/PX_OSX/PX_SWITCH x PX_X86/PX_X64/PX_A64 branches +match it, so it falls straight through to `#error Unknown binary +platform`. Add a tenth table entry (FOURCC 'L','R','6','4', name +"linuxriscv64") and the matching `#elif PX_LINUX && PX_RISCV64` branch, +bumping SN_NUM_BINARY_PLATFORMS from 9 to 10 to match. + +Signed-off-by: Ludovic Henry +--- + .../src/serialization/SnSerialUtils.cpp | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/physx/source/physxextensions/src/serialization/SnSerialUtils.cpp b/physx/source/physxextensions/src/serialization/SnSerialUtils.cpp +index 0000000..0000000 100644 +--- a/physx/source/physxextensions/src/serialization/SnSerialUtils.cpp ++++ b/physx/source/physxextensions/src/serialization/SnSerialUtils.cpp +@@ -39,6 +39,6 @@ + { + +-#define SN_NUM_BINARY_PLATFORMS 9 ++#define SN_NUM_BINARY_PLATFORMS 10 + const PxU32 sBinaryPlatformTags[SN_NUM_BINARY_PLATFORMS] = + { + PX_MAKE_FOURCC('W','_','3','2'), +@@ -49,7 +49,8 @@ + PX_MAKE_FOURCC('M','_','6','4'), + PX_MAKE_FOURCC('N','X','3','2'), + PX_MAKE_FOURCC('N','X','6','4'), +- PX_MAKE_FOURCC('L','A','6','4') ++ PX_MAKE_FOURCC('L','A','6','4'), ++ PX_MAKE_FOURCC('L','R','6','4') + }; + + const char* sBinaryPlatformNames[SN_NUM_BINARY_PLATFORMS] = +@@ -62,7 +63,8 @@ + "mac64", + "switch32", + "switch64", +- "linuxaarch64" ++ "linuxaarch64", ++ "linuxriscv64" + }; + + } +@@ -88,7 +90,9 @@ + #elif PX_SWITCH && PX_A64 + return sBinaryPlatformTags[7]; + #elif PX_LINUX && PX_A64 + return sBinaryPlatformTags[8]; ++#elif PX_LINUX && PX_RISCV64 ++ return sBinaryPlatformTags[9]; + #else + #error Unknown binary platform + #endif +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0003-physx-cmake-extend-aarch64-warning-relaxation-to-riscv64.patch b/patches/sapien/3.0.3/0003-physx-cmake-extend-aarch64-warning-relaxation-to-riscv64.patch new file mode 100644 index 000000000000..dd5a6b027174 --- /dev/null +++ b/patches/sapien/3.0.3/0003-physx-cmake-extend-aarch64-warning-relaxation-to-riscv64.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] physx/cmake: extend aarch64 warning relaxation to riscv64 + +Upstream-Status: To upstream [no riscv64 CI to validate against yet] + +source/compiler/cmake/linux/CMakeLists.txt treats aarch64 as the only +non-x86_64 Linux target: every other CMAKE_SYSTEM_PROCESSOR (including +riscv64, once it reaches this file at all via TARGET_BUILD_PLATFORM= +linux) falls into the plain ELSE() branch, which turns on `-Werror` +with an exclude list tuned for x86_64 GCC/Clang. aarch64 instead gets +`-Wno-error` plus `-ffp-contract=off` (floating-point-contraction +differences were already flagged as a real behavioural risk on that +arch). A brand new GCC target is virtually guaranteed to trip at least +one warning this x86_64 exclude list doesn't cover, so extend the +aarch64 branch's condition to riscv64 too rather than exposing a new +arch to -Werror untested. + +Signed-off-by: Ludovic Henry +--- + physx/source/compiler/cmake/linux/CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/physx/source/compiler/cmake/linux/CMakeLists.txt b/physx/source/compiler/cmake/linux/CMakeLists.txt +index 0000000..0000000 100644 +--- a/physx/source/compiler/cmake/linux/CMakeLists.txt ++++ b/physx/source/compiler/cmake/linux/CMakeLists.txt +@@ -76,7 +76,7 @@ SET(CLANG_WARNINGS "-ferror-limit=0 -Wall -Wextra -Werror -Wstrict-aliasing=2 + ") + + +-IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") ++IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + # gwoolery: disable warnings as errors for now on aarch64 linux. Most, but not all warnings, would be caught by: + # -Wno-invalid-offsetof -Wno-unused-result -Wno-unused-variable -Wno-uninitialized -Wno-unused-but-set-variable + # -Wno-unused-function -Wno-conversion-null -Wno-deprecated-declarations +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0004-cmake-skip-cuda-language-on-riscv64.patch b/patches/sapien/3.0.3/0004-cmake-skip-cuda-language-on-riscv64.patch new file mode 100644 index 000000000000..2895a4dba7f9 --- /dev/null +++ b/patches/sapien/3.0.3/0004-cmake-skip-cuda-language-on-riscv64.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] cmake: skip CUDA language on riscv64 + +Upstream-Status: To upstream [no riscv64 CI to validate against yet] + +The top-level project() call enables CMake's CUDA language on every +platform except APPLE, independent of the runtime SAPIEN_CUDA option +(setup.py sets -DSAPIEN_CUDA=OFF when CUDA_PATH is unset, but that +cache variable isn't read until after project() already ran). +Enabling the CUDA language makes CMake require a CUDA compiler at +configure time even when SAPIEN_CUDA will end up OFF, which fails +outright on riscv64 runners with no CUDA toolkit. aarch64 wheels are +built with CUDA on via the sbsa toolkit (Jetson/Grace), so this isn't +an aarch64-style fix -- it needs the same treatment as macOS, which +never had a CUDA story either. + +Signed-off-by: Ludovic Henry +--- + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 0000000..0000000 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,5 +1,5 @@ + cmake_minimum_required(VERSION 3.18 FATAL_ERROR) +-if (APPLE) ++if (APPLE OR CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64") + project(sapien LANGUAGES C CXX) + else() + project(sapien LANGUAGES C CXX CUDA) +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0005-cmake-physx5-add-riscv64-library-path.patch b/patches/sapien/3.0.3/0005-cmake-physx5-add-riscv64-library-path.patch new file mode 100644 index 000000000000..64fe118d83d7 --- /dev/null +++ b/patches/sapien/3.0.3/0005-cmake-physx5-add-riscv64-library-path.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] cmake/physx5: add riscv64 library path + +Upstream-Status: Inappropriate [riseproject.dev builds PhysX from source for riscv64 rather than fetching a precompiled archive] + +cmake/physx5.cmake only fetches a precompiled PhysX archive; there is +no riscv64 archive (sapien-sim/physx-precompiled publishes macOS, +linux-aarch64, linux x86_64 and windows only). We build PhysX from +source instead and point SAPIEN_PHYSX5_DIR at the install tree, which +this file already supports via `IS_DIRECTORY ${SAPIEN_PHYSX5_DIR}` -- +skipping the FetchContent branch entirely. What's missing is the +arch-selection block below it that picks which `bin/linux./...` +subdirectory to link against: riscv64 would silently fall into the +x86_64-labeled `bin/linux.clang/release` bucket (the plain ELSE()). +Give it its own `bin/linux.riscv64/release` bucket instead, and make +our from-source PhysX build (build-sapien.yml) install into that +exact path. + +Signed-off-by: Ludovic Henry +--- + cmake/physx5.cmake | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/cmake/physx5.cmake b/cmake/physx5.cmake +index 0000000..0000000 100644 +--- a/cmake/physx5.cmake ++++ b/cmake/physx5.cmake +@@ -68,6 +68,8 @@ elseif(UNIX) + + if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64") + target_link_directories(physx5 INTERFACE $) ++ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64") ++ target_link_directories(physx5 INTERFACE $) + else() + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_directories(physx5 INTERFACE $) +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0006-setup.py-plumb-sapien_physx5_dir.patch b/patches/sapien/3.0.3/0006-setup.py-plumb-sapien_physx5_dir.patch new file mode 100644 index 000000000000..0b42449acb59 --- /dev/null +++ b/patches/sapien/3.0.3/0006-setup.py-plumb-sapien_physx5_dir.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] setup.py: plumb SAPIEN_PHYSX5_DIR + +Upstream-Status: Inappropriate [riseproject.dev-specific: lets the from-source riscv64 PhysX build feed cmake/physx5.cmake's SAPIEN_PHYSX5_DIR cache variable] + +cmake/physx5.cmake already reads SAPIEN_PHYSX5_DIR as a cache variable +(it's how a prebuilt PhysX install overrides the FetchContent +download), but setup.py never threads anything into it -- there is no +CLI flag and no environment variable read anywhere in the file. Add +--physx5-dir (falling back to the SAPIEN_PHYSX5_DIR environment +variable, so CI can just export it) and pass it through as +-DSAPIEN_PHYSX5_DIR=... on both cmake invocations: build_sapien() +(where physx5 is actually linked) and CMakeBuild.build_pybind() (kept +in sync for consistency, even though the pybind step only needs +sapien_DIR from the already-built install). + +Signed-off-by: Ludovic Henry +--- + setup.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/setup.py b/setup.py +index 0000000..0000000 100644 +--- a/setup.py ++++ b/setup.py +@@ -32,6 +32,12 @@ + help="directory to put build files", + ) + parser.add_argument( ++ "--physx5-dir", ++ type=str, ++ default=os.environ.get("SAPIEN_PHYSX5_DIR", ""), ++ help="directory containing a prebuilt PhysX 5 install (also read from SAPIEN_PHYSX5_DIR)", ++) ++parser.add_argument( + "--get-version", + action="store_true", + help="print version string and exit immediately", +@@ -131,6 +137,8 @@ + cmake_args += ["-DSAPIEN_CUDA=ON"] + else: + cmake_args += ["-DSAPIEN_CUDA=OFF"] ++ if args.physx5_dir: ++ cmake_args += [f"-DSAPIEN_PHYSX5_DIR={args.physx5_dir}"] + + cmake_args += [ + f"-DCMAKE_BUILD_TYPE={cfg}", +@@ -257,6 +265,8 @@ + cmake_args += [ + "-Dsapien_DIR=" + os.path.join(sapien_install_dir, "lib/cmake/sapien") + ] ++ if args.physx5_dir: ++ cmake_args += [f"-DSAPIEN_PHYSX5_DIR={args.physx5_dir}"] + + if platform.system() == "Darwin": + cmake_args += ["-DCMAKE_TOOLCHAIN_FILE=../toolchains/macos.toolchain.cmake"] +-- +2.50.1 diff --git a/patches/sapien/3.0.3/0007-svulkan2-openvr-add-riscv64-branch.patch b/patches/sapien/3.0.3/0007-svulkan2-openvr-add-riscv64-branch.patch new file mode 100644 index 000000000000..6da2c7c36e9f --- /dev/null +++ b/patches/sapien/3.0.3/0007-svulkan2-openvr-add-riscv64-branch.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] svulkan2/openvr: add riscv64 branch + +Upstream-Status: Inappropriate [riscv64 build infra detail, out of scope for the comoco-xiao/openvr fork sapien-vulkan-2 pins] + +openvr's own CMakeLists.txt picks -DLINUXARM64 only for +CMAKE_SYSTEM_PROCESSOR=="aarch64" and otherwise -DLINUX64 for any +other 64-bit unix target, so riscv64 silently takes the x86_64-labeled +branch today. openvr_api is linked into svulkan2 but only exercised +with real VR hardware, which none of our runners have, so this is +unlikely to matter in practice -- added anyway for correctness rather +than leaving riscv64 mislabeled as LINUX64 in a dependency we vendor. + +We don't control the comoco-xiao/openvr fork directly (it's fetched +fresh via FetchContent at configure time, not vendored in this repo), +so patch cmake/openvr.cmake's FetchContent_Declare to add a +PATCH_COMMAND that rewrites the one line in its CMakeLists.txt right +after the source is populated. + +Signed-off-by: Ludovic Henry +--- + 3rd_party/sapien-vulkan-2/cmake/openvr.cmake | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/3rd_party/sapien-vulkan-2/cmake/openvr.cmake b/3rd_party/sapien-vulkan-2/cmake/openvr.cmake +index 0000000..0000000 100644 +--- a/3rd_party/sapien-vulkan-2/cmake/openvr.cmake ++++ b/3rd_party/sapien-vulkan-2/cmake/openvr.cmake +@@ -5,6 +5,15 @@ + GIT_TAG v0.0.1 + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE ++ PATCH_COMMAND python3 -c [[ ++import pathlib ++p = pathlib.Path("CMakeLists.txt") ++s = p.read_text() ++old = 'elseif(PROCESSOR_ARCH MATCHES "64")' ++new = 'elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64")\n add_definitions(-DLINUXRISCV64)\n elseif(PROCESSOR_ARCH MATCHES "64")' ++assert old in s ++p.write_text(s.replace(old, new, 1)) ++]] + ) + + # FetchContent_MakeAvailable(openvr) +-- +2.50.1