From 9304d3b227f3ee8666cedc8273a6f338b5a3a048 Mon Sep 17 00:00:00 2001 From: Mg Pig Date: Sun, 24 Aug 2025 00:53:42 +0800 Subject: [PATCH] feat(nix): refactor Flake and Migrate Android Support (#1280) --- .envrc | 3 +- .gitignore | 1 + EasyTier.code-workspace | 3 + android.nix | 116 ++++++++++++++++++++++++++++++ easytier-gui/flake.lock | 116 ------------------------------ easytier-gui/flake.nix | 151 ---------------------------------------- flake.nix | 114 ++++++++++++++++++++++-------- 7 files changed, 206 insertions(+), 298 deletions(-) create mode 100644 android.nix delete mode 100644 easytier-gui/flake.lock delete mode 100644 easytier-gui/flake.nix diff --git a/.envrc b/.envrc index 3550a30..fc98216 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,2 @@ -use flake +PROFILE=$(cat .flake-profile 2>/dev/null) +use flake .#${PROFILE} diff --git a/.gitignore b/.gitignore index 642375d..edebcc4 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ easytier-gui/src-tauri/*.dll /easytier-contrib/easytier-ohrs/dist/ .direnv +.flake-profile diff --git a/EasyTier.code-workspace b/EasyTier.code-workspace index 808d827..ae221d3 100644 --- a/EasyTier.code-workspace +++ b/EasyTier.code-workspace @@ -50,5 +50,8 @@ "editor.formatOnSaveMode": "modifications", "editor.formatOnPaste": false, "editor.formatOnType": true, + "[nix]": { + "editor.formatOnSave": false, + }, } } \ No newline at end of file diff --git a/android.nix b/android.nix new file mode 100644 index 0000000..821bcb4 --- /dev/null +++ b/android.nix @@ -0,0 +1,116 @@ +# Android build environment +{ + pkgs, + nixpkgs, + system, +}: + +let + androidEnv = pkgs.callPackage "${nixpkgs}/pkgs/development/mobile/androidenv" { + inherit pkgs; + licenseAccepted = true; + }; + + includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin; + ndkVersion = "26.1.10909125"; + ndkVersions = [ ndkVersion ]; + + sdkArgs = { + includeNDK = true; + includeSources = true; + includeSystemImages = false; + includeEmulator = false; + inherit ndkVersions; + useGoogleAPIs = true; + useGoogleTVAddOns = true; + buildToolsVersions = [ "34.0.0" ]; + numLatestPlatformVersions = 10; + includeExtras = [ + "extras;google;gcm" + ] + ++ pkgs.lib.optionals includeAuto [ + "extras;google;auto" + ]; + extraLicenses = [ + "android-sdk-preview-license" + "android-googletv-license" + "android-sdk-arm-dbt-license" + "google-gdk-license" + "intel-android-extra-license" + "intel-android-sysimage-license" + "mips-android-sysimage-license" + ]; + }; + + androidComposition = androidEnv.composeAndroidPackages sdkArgs; + androidSdk = androidComposition.androidsdk; + platformTools = androidComposition.platform-tools; + cmake = androidComposition.cmake; + ndkHostTag = + if pkgs.stdenv.isLinux then + "linux-x86_64" + else if pkgs.stdenv.isDarwin then + "darwin-x86_64" + else + ""; + ndkToolchain = "${androidSdk}/libexec/android-sdk/ndk/${ndkVersion}/toolchains/llvm/prebuilt/${ndkHostTag}"; +in +{ + inherit + androidSdk + platformTools + cmake + ndkToolchain + ndkVersion + ; + + # List of packages required for Android development + packages = [ + pkgs.jdk # openjdk 21 + androidSdk + platformTools + cmake + pkgs.glibc_multi.dev + ]; + + # Provide Rust extensions/targets for use by the upper-level flake + rust = { + extensions = [ "rust-std" ]; + targets = [ + "aarch64-linux-android" + "armv7-linux-androideabi" + "i686-linux-android" + "x86_64-linux-android" + ]; + }; + + # Android environment variables and shellHook + envVars = { + LANG = "C.UTF-8"; + LC_ALL = "C.UTF-8"; + JAVA_HOME = "${pkgs.jdk}/lib/openjdk"; + ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; + ANDROID_NDK_ROOT = "\${ANDROID_SDK_ROOT}/ndk-bundle"; + NDK_HOME = "${androidSdk}/libexec/android-sdk/ndk/${ndkVersion}"; + LIBCLANG_PATH = "${ndkToolchain}/lib"; + KCP_SYS_EXTRA_HEADER_PATH = "${ndkToolchain}/lib/clang/19/include:${pkgs.glibc_multi.dev}/include"; + ZSTD_SYS_STATIC = "1"; + BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${ndkToolchain}/sysroot -I${ndkToolchain}/lib/clang/17/include "; + + shellHook = '' + echo "Android environment activated" + export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=$(echo "$ANDROID_SDK_ROOT/build-tools/"*"/aapt2")" + cmake_root="$(echo "$ANDROID_SDK_ROOT/cmake/"*/)" + export PATH="$cmake_root/bin:$PATH" + + unset NIX_CFLAGS_COMPILE + unset NIX_CFLAGS_COMPILE_FOR_BUILD + + cat < easytier-gui/local.properties + sdk.dir=$ANDROID_SDK_ROOT + ndk.dir=$ANDROID_NDK_ROOT + cmake.dir=$cmake_root + EOF + ''; + }; +} diff --git a/easytier-gui/flake.lock b/easytier-gui/flake.lock deleted file mode 100644 index ee46c02..0000000 --- a/easytier-gui/flake.lock +++ /dev/null @@ -1,116 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1754725699, - "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-android": { - "locked": { - "lastModified": 1754725699, - "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", - "type": "github" - } - }, - "nixpkgs-java": { - "locked": { - "lastModified": 1754725699, - "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", - "nixpkgs-android": "nixpkgs-android", - "nixpkgs-java": "nixpkgs-java", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1754966322, - "narHash": "sha256-7f/LH60DnjjQVKbXAsHIniGaU7ixVM7eWU3hyjT24YI=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "7c13cec2e3828d964b9980d0ffd680bd8d4dce90", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/easytier-gui/flake.nix b/easytier-gui/flake.nix deleted file mode 100644 index 93d3757..0000000 --- a/easytier-gui/flake.nix +++ /dev/null @@ -1,151 +0,0 @@ -{ - # usage: - # nix develop .#android --extra-experimental-features "nix-command flakes" - # pnpm tauri android build - description = "Android build environment for EasyTier"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - # java21 - nixpkgs-java.url = "github:NixOS/nixpkgs/85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054"; - #nixpkgs-java.url = "github:NixOS/nixpkgs/nixos-unstable"; - # androidEnv - nixpkgs-android.url = "github:NixOS/nixpkgs/85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054"; - #nixpkgs-android.url = "github:NixOS/nixpkgs/nixos-unstable"; - }; - - outputs = { self, nixpkgs, nixpkgs-java, nixpkgs-android, flake-utils, rust-overlay, ... }: - flake-utils.lib.eachDefaultSystem (system: - let - overlays = [ (import rust-overlay) ]; - pkgs = import nixpkgs { - inherit system overlays; - config = { licenseAccepted = true; allowUnfree = true; }; - }; - - rustVersion = "1.89.0"; - rustWithAndroid = pkgs.rust-bin.stable.${rustVersion}.default.override { - extensions = [ "rust-src" "rust-std" ]; - targets = [ - "aarch64-linux-android" - "armv7-linux-androideabi" - "i686-linux-android" - "x86_64-linux-android" - ]; - }; - includeAuto = pkgs.stdenv.hostPlatform.isx86_64 || pkgs.stdenv.hostPlatform.isDarwin; - # ndkVersion = "28.1.13356709"; - ndkVersion = "26.1.10909125"; - ndkVersions = [ - ndkVersion - ]; - - # Android 环境配置 - sdkArgs = { - includeNDK = true; - includeSources = true; - includeSystemImages = false; - includeEmulator = false; - inherit ndkVersions; - useGoogleAPIs = true; - useGoogleTVAddOns = true; - buildToolsVersions = [ "34.0.0" ]; - - # Make sure everything from the last decade works since we are not using system images. - numLatestPlatformVersions = 10; - includeExtras = [ - "extras;google;gcm" - ] - ++ pkgs.lib.optionals includeAuto [ - "extras;google;auto" - ]; - # Accepting more licenses declaratively: - extraLicenses = [ - # Already accepted for you with the global accept_license = true or - # licenseAccepted = true on androidenv. - # "android-sdk-license" - - # These aren't, but are useful for more uncommon setups. - "android-sdk-preview-license" - "android-googletv-license" - "android-sdk-arm-dbt-license" - "google-gdk-license" - "intel-android-extra-license" - "intel-android-sysimage-license" - "mips-android-sysimage-license" - ]; - }; - javaPkgs = import nixpkgs-java { inherit system; }; - androidEnv = pkgs.callPackage "${nixpkgs-android}/pkgs/development/mobile/androidenv" { - inherit pkgs; - licenseAccepted = true; - }; - androidComposition = androidEnv.composeAndroidPackages sdkArgs; - androidSdk = androidComposition.androidsdk; - platformTools = androidComposition.platform-tools; - cmake = androidComposition.cmake; - # NDK uses a specific host tag directory name which we can determine from the host platform - ndkHostTag = if pkgs.stdenv.isLinux then "linux-x86_64" else if pkgs.stdenv.isDarwin then "darwin-x86_64" else ""; - ndkToolchain = "${androidSdk}/libexec/android-sdk/ndk/${ndkVersion}/toolchains/llvm/prebuilt/${ndkHostTag}"; - in - - { - # android entry - devShells.android = pkgs.mkShell rec { - nativeBuildInputs = [ - rustWithAndroid - javaPkgs.jdk - androidSdk - platformTools - cmake - pkgs.glibc_multi.dev - # pkgs.clang - pkgs.pkg-config - pkgs.protobuf - - pkgs.nodejs_22 - pkgs.pnpm - ]; - buildInputs = []; - - LANG = "C.UTF-8"; - LC_ALL = "C.UTF-8"; - JAVA_HOME = "${javaPkgs.jdk}/lib/openjdk"; - - ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; - ANDROID_NDK_ROOT = "${ANDROID_SDK_ROOT}/ndk-bundle"; - NDK_HOME = "${androidSdk}/libexec/android-sdk/ndk/${ndkVersion}"; - - LIBCLANG_PATH = "${ndkToolchain}/lib"; - KCP_SYS_EXTRA_HEADER_PATH = "${ndkToolchain}/lib/clang/19/include:${pkgs.glibc_multi.dev}/include"; - ZSTD_SYS_STATIC = "1"; - - BINDGEN_EXTRA_CLANG_ARGS = "--sysroot=${ndkToolchain}/sysroot -I${ndkToolchain}/lib/clang/17/include "; - - # 设置编译器标志 - shellHook = '' - echo "Android environment activated" - export GRADLE_OPTS="-Dorg.gradle.project.android.aapt2FromMavenOverride=$(echo "$ANDROID_SDK_ROOT/build-tools/"*"/aapt2")" - cmake_root="$(echo "$ANDROID_SDK_ROOT/cmake/"*/)" - export PATH="$cmake_root/bin:$PATH" - - unset NIX_CFLAGS_COMPILE - unset NIX_CFLAGS_COMPILE_FOR_BUILD - - cat < local.properties - sdk.dir=$ANDROID_SDK_ROOT - ndk.dir=$ANDROID_NDK_ROOT - cmake.dir=$cmake_root - EOF - ''; - }; - - #devShells.default = pkgs.mkShell {}; - } - ); -} diff --git a/flake.nix b/flake.nix index b4e2009..0f5f49c 100644 --- a/flake.nix +++ b/flake.nix @@ -10,47 +10,101 @@ }; }; - outputs = { self, nixpkgs, flake-utils, rust-overlay, ... }: - flake-utils.lib.eachDefaultSystem (system: + outputs = + { + self, + nixpkgs, + flake-utils, + rust-overlay, + ... + }: + flake-utils.lib.eachDefaultSystem ( + system: let overlays = [ (import rust-overlay) ]; pkgs = import nixpkgs { inherit system overlays; + config = { + licenseAccepted = true; + allowUnfree = true; + }; }; rustVersion = "1.89.0"; - rust = pkgs.rust-bin.stable.${rustVersion}.default.override{ - extensions = [ "rust-src" "rust-analyzer" ]; + makeRust = + features: + pkgs.rust-bin.stable.${rustVersion}.default.override { + extensions = [ + "rust-src" + "rust-analyzer" + ] + ++ (if builtins.elem "android" features then android.rust.extensions else [ ]); + + targets = if builtins.elem "android" features then android.rust.targets else [ ]; + }; + + android = import ./android.nix { + inherit pkgs system nixpkgs; }; + + makeShell = + features: + let + hasFeature = feature: builtins.elem feature features; + withFeature = feature: pkgList: if hasFeature feature then pkgList else [ ]; + flattenPaths = xs: builtins.concatLists (map (p: if builtins.isList p then p else [ p ]) xs); + rust = makeRust features; + in + pkgs.mkShell (rec { + nativeBuildInputs = + with pkgs; + ( + [ + rust + protobuf + clang + pkg-config + bridge-utils # for three node test + ] + ++ (withFeature "web" [ + nodejs_22 + pnpm + ]) + ++ (withFeature "android" android.packages) + ); + + buildInputs = with pkgs; ([ + zstd + openssl + libclang + llvmPackages.libclang + libsoup_3 + webkitgtk_4_1 + ]); + + RUST_SRC_PATH = "${rust}/lib/rustlib/src/rust/library"; + LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + BINDGEN_EXTRA_CLANG_ARGS = "-I${pkgs.clang}/resource-root/include"; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (flattenPaths (buildInputs ++ nativeBuildInputs)); + ZSTD_SYS_USE_PKG_CONFIG = true; + KCP_SYS_EXTRA_HEADER_PATH = "${pkgs.libclang.lib}/lib/clang/19/include:${pkgs.glibc.dev}/include"; + } + // (if hasFeature "android" then android.envVars else { })); in { - devShells.default = pkgs.mkShell rec { - nativeBuildInputs = with pkgs; [ - rust - protobuf - clang - pkg-config - - # web - nodejs_22 - pnpm + devShells = { + default = makeShell [ ]; + core = makeShell [ ]; + web = makeShell [ "web" ]; + gui = makeShell [ "gui" ]; + android = makeShell [ + "android" + "web" ]; - buildInputs = with pkgs; [ - zstd - openssl - libclang - llvmPackages.libclang - - # gui - webkitgtk_4_1 - libsoup_3 + full = makeShell [ + "web" + "gui" + "android" ]; - - RUST_SRC_PATH = "${rust}/lib/rustlib/src/rust/library"; - LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; - BINDGEN_EXTRA_CLANG_ARGS = "-I${pkgs.clang}/resource-root/include"; - LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (buildInputs ++ nativeBuildInputs); - ZSTD_SYS_USE_PKG_CONFIG = true; - KCP_SYS_EXTRA_HEADER_PATH = "${pkgs.libclang.lib}/lib/clang/19/include:${pkgs.glibc.dev}/include"; }; } );