diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9336526..ca609d76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,6 +71,19 @@ jobs: uses: mymindstorm/setup-emsdk@v14 with: actions-cache-folder: 'emsdk-cache' + + - name: Setup Android NDK + if: matrix.os == 'macos-13' + uses: nttld/setup-ndk@v1 + with: + ndk-version: r25c + link-to-sdk: true + + - name: Set Android NDK variables + if: matrix.os == 'macos-13' + shell: bash + run: | + echo "ANDROID_NDK_HOME=$ANDROID_NDK_HOME" >> $GITHUB_ENV - name: Restore Dependencies shell: bash @@ -101,6 +114,8 @@ jobs: dotnet build -c Debug -r iossimulator-x64 dotnet build -c Debug -r iossimulator-arm64 dotnet build -c Debug -r ios-arm64 + dotnet build -c Debug -r android-arm64 + dotnet build -c Debug -r android-x64 dotnet build -c Release -r linux-x64 dotnet build -c Release -r linux-arm64 @@ -112,6 +127,8 @@ jobs: dotnet build -c Release -r iossimulator-x64 dotnet build -c Release -r iossimulator-arm64 dotnet build -c Release -r ios-arm64 + dotnet build -c Release -r android-arm64 + dotnet build -c Release -r android-x64 - name: Run Tests shell: bash diff --git a/src/Flecs.NET.Native/Flecs.NET.Native.csproj b/src/Flecs.NET.Native/Flecs.NET.Native.csproj index a9ac30cf..fc932260 100644 --- a/src/Flecs.NET.Native/Flecs.NET.Native.csproj +++ b/src/Flecs.NET.Native/Flecs.NET.Native.csproj @@ -45,9 +45,9 @@ - + - + PreserveNewest runtimes/ @@ -104,7 +104,7 @@ aarch64-macos - + x86_64-ios-simulator @@ -129,6 +129,18 @@ --sysroot "$(EMSDK)/upstream/emscripten" + + + aarch64-linux-android + --sysroot $(ANDROID_NDK_HOME) + + + + + x86_64-linux-android + --sysroot $(ANDROID_NDK_HOME) + + $(RuntimeIdentifier) diff --git a/src/Flecs.NET.Native/build.zig b/src/Flecs.NET.Native/build.zig index 407801fb..adf6abca 100644 --- a/src/Flecs.NET.Native/build.zig +++ b/src/Flecs.NET.Native/build.zig @@ -1,8 +1,16 @@ const std = @import("std"); +const builtin = @import("builtin"); const Build = std.Build; pub const LibraryType = enum { Shared, Static }; +const BuildOptions = struct { + optimize: std.builtin.OptimizeMode, + target: Build.ResolvedTarget, + library_type: LibraryType, + compiler_rt_path: ?[]const u8, +}; + const src_flags = [_][]const u8{ "-std=c99", "-fno-sanitize=undefined", @@ -134,7 +142,7 @@ const src_files = [_][]const u8{ "../../native/flecs/src/storage/table.c", }; -pub fn compileFlecs(b: *Build, options: anytype) void { +pub fn compileFlecs(b: *Build, options: BuildOptions) void { const lib = switch (options.library_type) { .Shared => b.addSharedLibrary(.{ .name = "flecs", @@ -190,6 +198,50 @@ pub fn compileFlecs(b: *Build, options: anytype) void { dir.close(); lib.addIncludePath(.{ .cwd_relative = cache_include }); }, + .linux => { + if (options.target.result.abi == .android) { + if (b.sysroot == null) { + @panic("A --sysroot path to an Android NDK needs to be provided when compiling for Android."); + } + + const host_tuple = switch (builtin.target.os.tag) { + .linux => "linux-x86_64", + .windows => "windows-x86_64", + .macos => "darwin-x86_64", + else => @panic("unsupported host OS"), + }; + + const triple = switch (options.target.result.cpu.arch) { + .aarch64 => "aarch64-linux-android", + .x86_64 => "x86_64-linux-android", + else => @panic("Unsupported Android architecture"), + }; + const android_api_level: []const u8 = "21"; + + const android_sysroot = b.pathJoin(&.{ b.sysroot.?, "/toolchains/llvm/prebuilt/", host_tuple, "/sysroot" }); + const android_lib_path = b.pathJoin(&.{ android_sysroot, "/usr/lib/", triple, android_api_level }); + const android_include_path = b.pathJoin(&.{ android_sysroot, "/usr/include" }); + const android_system_include_path = b.pathJoin(&.{ android_sysroot, "/usr/include/", triple }); + + lib.addLibraryPath(.{ .cwd_relative = android_lib_path }); + + const libc_file_name = "android-libc.conf"; + var libc_content = std.ArrayList(u8).init(b.allocator); + errdefer libc_content.deinit(); + + const writer = libc_content.writer(); + const libc_installation = std.zig.LibCInstallation{ + .include_dir = android_include_path, + .sys_include_dir = android_system_include_path, + .crt_dir = android_lib_path, + }; + libc_installation.render(writer) catch @panic("Failed to render libc"); + const libc_path = b.addWriteFiles().add(libc_file_name, libc_content.items); + + lib.setLibCFile(libc_path); + lib.libc_file.?.addStepDependencies(&lib.step); + } + }, else => {}, }