summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build-arm64-layer.yml72
-rw-r--r--package.json4
-rw-r--r--py_modules/lsfg_vk/installation.py36
3 files changed, 106 insertions, 6 deletions
diff --git a/.github/workflows/build-arm64-layer.yml b/.github/workflows/build-arm64-layer.yml
new file mode 100644
index 0000000..973a548
--- /dev/null
+++ b/.github/workflows/build-arm64-layer.yml
@@ -0,0 +1,72 @@
+name: Build ARM64 lsfg-vk layer
+
+on:
+ workflow_dispatch:
+ pull_request:
+ paths:
+ - .github/workflows/build-arm64-layer.yml
+
+permissions:
+ contents: read
+
+env:
+ SOURCE_REPOSITORY: https://github.com/FrankBarretta/lsfg-vk-android.git
+ SOURCE_COMMIT: 3e89e5439a98f55d5acb003d20039426ab24e69c
+
+jobs:
+ build:
+ name: Native AArch64 release build
+ runs-on: ubuntu-24.04-arm
+
+ steps:
+ - name: Install build dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install --yes --no-install-recommends \
+ clang cmake g++ git libvulkan-dev ninja-build
+
+ - name: Check out the pinned layer source
+ run: |
+ git init lsfg-vk-android
+ cd lsfg-vk-android
+ git remote add origin "${SOURCE_REPOSITORY}"
+ git fetch --depth=1 origin "${SOURCE_COMMIT}"
+ git checkout --detach FETCH_HEAD
+ git submodule update --init --recursive --depth=1
+ test "$(git rev-parse HEAD)" = "${SOURCE_COMMIT}"
+
+ - name: Build with static C++ runtimes
+ run: |
+ cmake -S lsfg-vk-android -B build -G Ninja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_C_COMPILER=clang \
+ -DCMAKE_CXX_COMPILER=clang++ \
+ -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
+ -DCMAKE_SHARED_LINKER_FLAGS="-static-libstdc++ -static-libgcc -Wl,--exclude-libs,ALL"
+ cmake --build build --parallel 4
+ strip --strip-unneeded build/liblsfg-vk.so
+
+ - name: Verify and document the artifact
+ run: |
+ mkdir -p artifact
+ install -m 0755 build/liblsfg-vk.so artifact/liblsfg-vk-arm64.so
+ readelf -h artifact/liblsfg-vk-arm64.so | grep -q 'Machine:.*AArch64'
+ readelf -d artifact/liblsfg-vk-arm64.so | tee artifact/ELF-DYNAMIC.txt
+ ! grep -Eq 'libstdc\+\+\.so|libgcc_s\.so' artifact/ELF-DYNAMIC.txt
+ sha256sum artifact/liblsfg-vk-arm64.so | tee artifact/SHA256SUMS
+ {
+ echo "Source repository: ${SOURCE_REPOSITORY}"
+ echo "Source commit: ${SOURCE_COMMIT}"
+ echo "Runner: ubuntu-24.04-arm"
+ echo "Compiler: $(clang++ --version | head -n1)"
+ echo "CMake: $(cmake --version | head -n1)"
+ echo "Static runtimes: libstdc++ and libgcc"
+ } > artifact/SOURCE.txt
+
+ - name: Upload ARM64 layer
+ uses: actions/upload-artifact@v4
+ with:
+ name: lsfg-vk-arm64-${{ env.SOURCE_COMMIT }}
+ path: artifact/
+ if-no-files-found: error
+ retention-days: 90
diff --git a/package.json b/package.json
index a71b9cc..347820b 100644
--- a/package.json
+++ b/package.json
@@ -66,8 +66,8 @@
},
{
"name": "liblsfg-vk-arm64.so",
- "url": "https://github.com/xXJSONDeruloXx/lsfg-vk/releases/download/arm-test/liblsfg-vk.so",
- "sha256hash": "c745893b3798eb1acb422775a43107fc3f2efb2ae2711090b90b04941d8de309"
+ "url": "https://github.com/Janleyx/decky-lsfg-vk-for-Ayn-Odin-2/releases/download/arm64-layer-3e89e54/liblsfg-vk-arm64.so",
+ "sha256hash": "2e84f8d1a1dd0344474846f6252d6f948f72caaaeab3cd316c04254be05a9949"
}
],
"pnpm": {
diff --git a/py_modules/lsfg_vk/installation.py b/py_modules/lsfg_vk/installation.py
index 4f01be1..29259f7 100644
--- a/py_modules/lsfg_vk/installation.py
+++ b/py_modules/lsfg_vk/installation.py
@@ -53,7 +53,7 @@ class InstallationService(BaseService):
if self._is_arm_architecture():
self.log.info("Detected ARM architecture, using ARM binary")
arm_so_path = plugin_dir / BIN_DIR / ARM_LIB_FILENAME
- shutil.copy2(arm_so_path, self.lib_file)
+ self._copy_plugin_file(arm_so_path, self.lib_file)
self.log.info(f"Overwrote with ARM binary: {self.lib_file}")
self._create_config_file()
@@ -78,7 +78,35 @@ class InstallationService(BaseService):
Returns:
True if running on ARM (aarch64), False otherwise
"""
- return platform.machine().lower() == 'aarch64'
+ if platform.machine().lower() in ('aarch64', 'arm64'):
+ return True
+
+ # Decky runs through FEX on Armada, so Python reports x86_64 even
+ # though the host is AArch64. Armada exposes this native helper only
+ # on its ARM image, including inside Decky's FEX rootfs.
+ if Path('/usr/libexec/armada/device-env').is_file():
+ self.log.info("Detected native AArch64 Armada host through device-env")
+ return True
+
+ # Fall back to the native PID 1 ELF header. e_machine 183 is AArch64.
+ try:
+ with Path('/proc/1/exe').open('rb') as host_executable:
+ elf_header = host_executable.read(20)
+ if elf_header[:4] == b'\x7fELF' and elf_header[5] in (1, 2):
+ byte_order = 'little' if elf_header[5] == 1 else 'big'
+ if int.from_bytes(elf_header[18:20], byte_order) == 183:
+ self.log.info("Detected native AArch64 host through PID 1")
+ return True
+ except OSError as e:
+ self.log.debug(f"Could not inspect native host architecture: {e}")
+
+ return False
+
+ @staticmethod
+ def _copy_plugin_file(src_file: Path, dst_file: Path) -> None:
+ """Copy plugin content without preserving FEX-incompatible metadata."""
+ shutil.copyfile(src_file, dst_file)
+ dst_file.chmod(0o644)
def _extract_and_install_files(self, zip_path: Path) -> None:
"""Extract zip file and install files to appropriate locations
@@ -117,7 +145,7 @@ class InstallationService(BaseService):
if file_path.suffix == JSON_EXT and file == JSON_FILENAME:
self._copy_and_fix_json_file(src_file, dst_file)
else:
- shutil.copy2(src_file, dst_file)
+ self._copy_plugin_file(src_file, dst_file)
self.log.info(f"Copied {file} to {dst_file}")
@@ -147,7 +175,7 @@ class InstallationService(BaseService):
except (json.JSONDecodeError, KeyError, OSError) as e:
self.log.error(f"Error fixing JSON file {src_file}: {e}")
# Fallback to simple copy if JSON modification fails
- shutil.copy2(src_file, dst_file)
+ self._copy_plugin_file(src_file, dst_file)
def _create_config_file(self) -> None:
"""Create or update the TOML config file in ~/.config/lsfg-vk with default configuration and detected DLL path