From 3d3f1761ad871b23c8c896d292d1cfbae0d8ea59 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 11 Dec 2023 12:14:49 +0800 Subject: [PATCH] feat: support build tabby on windows (#948) * feat: update config to support build on windows * resolve comment * update release.yml * resolve comment --- .github/workflows/release.yml | 29 ++++++++++++++---- Cargo.lock | 1 + ci/prepare_build_environment.ps1 | 1 + crates/llama-cpp-bindings/build.rs | 39 +++++++++++++++++++++---- crates/llama-cpp-bindings/src/engine.cc | 3 +- crates/tabby-common/Cargo.toml | 1 + crates/tabby-common/src/path.rs | 2 +- 7 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 ci/prepare_build_environment.ps1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b22676562baf..39dd5328618f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,7 @@ jobs: container: ${{ matrix.container }} strategy: matrix: - binary: [aarch64-apple-darwin, x86_64-manylinux2014, x86_64-manylinux2014-cuda117] + binary: [aarch64-apple-darwin, x86_64-manylinux2014, x86_64-manylinux2014-cuda117, x86_64-pc-windows-msvc] include: - os: macos-latest target: aarch64-apple-darwin @@ -40,6 +40,11 @@ jobs: binary: x86_64-manylinux2014-cuda117 container: sameli/manylinux2014_x86_64_cuda_11.7 build_args: --features cuda + - os: windows-latest + target: x86_64-pc-windows-msvc + binary: x86_64-pc-windows-msvc + ext: .exe + build_args: --features cuda env: SCCACHE_GHA_ENABLED: true @@ -77,20 +82,34 @@ jobs: ~/.cargo/registry ~/.cargo/git - - run: bash ./ci/prepare_build_environment.sh + - name: Prepare build environment for macOS & Linux + run: bash ./ci/prepare_build_environment.sh + if: runner.os != 'Windows' + + - name: Prepare build environment for Windows + run: ./ci/prepare_build_environment.ps1 + if: runner.os == 'Windows' + + - name: Install CUDA toolkit for Windows + uses: Jimver/cuda-toolkit@v0.2.11 + with: + cuda: '11.7.1' + method: 'network' + sub-packages: '["nvcc", "cudart", "cublas", "cublas_dev", "thrust", "visual_studio_integration"]' + if: runner.os == 'Windows' - name: Bulid release binary run: cargo build ${{ matrix.build_args }} --release --target ${{ matrix.target }} --package tabby - name: Rename release binary - run: mv target/${{ matrix.target }}/release/tabby tabby_${{ matrix.binary }} + run: mv target/${{ matrix.target }}/release/tabby${{ matrix.ext }} tabby_${{ matrix.binary }}${{ matrix.ext }} - name: Upload artifacts uses: actions/upload-artifact@v3 with: retention-days: 3 - name: tabby_${{ matrix.binary }} - path: tabby_${{ matrix.binary }} + name: tabby_${{ matrix.binary }}${{ matrix.ext }} + path: tabby_${{ matrix.binary }}${{ matrix.ext }} pre-release: if: github.event_name == 'push' diff --git a/Cargo.lock b/Cargo.lock index 9a467d01029f..18f71f43a5ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3641,6 +3641,7 @@ dependencies = [ "async-trait", "filenamify", "glob", + "home", "lazy_static", "reqwest", "serde", diff --git a/ci/prepare_build_environment.ps1 b/ci/prepare_build_environment.ps1 new file mode 100644 index 000000000000..7235782df0a4 --- /dev/null +++ b/ci/prepare_build_environment.ps1 @@ -0,0 +1 @@ +choco install --yes protoc diff --git a/crates/llama-cpp-bindings/build.rs b/crates/llama-cpp-bindings/build.rs index b4e09f6c8506..a768e361faf2 100644 --- a/crates/llama-cpp-bindings/build.rs +++ b/crates/llama-cpp-bindings/build.rs @@ -10,11 +10,16 @@ fn main() { "Please init submodules with `git submodule update --init --recursive` and try again" ); - println!("cargo:rerun-if-changed=cc/*.h"); - println!("cargo:rerun-if-changed=cc/*.cc"); + println!("cargo:rerun-if-changed=include/engine.h"); + println!("cargo:rerun-if-changed=src/engine.cc"); println!("cargo:rustc-link-lib=llama"); println!("cargo:rustc-link-lib=ggml_static"); + build_llama_cpp(); + build_cxx_binding(); +} + +fn build_llama_cpp() { let mut config = Config::new("llama.cpp"); if cfg!(target_os = "macos") { config.define("LLAMA_METAL", "ON"); @@ -26,9 +31,16 @@ fn main() { if cfg!(feature = "cuda") { config.define("LLAMA_CUBLAS", "ON"); config.define("CMAKE_POSITION_INDEPENDENT_CODE", "ON"); - println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64"); + if cfg!(target_os = "windows") { + let Ok(cuda_path) = env::var("CUDA_PATH") else { + panic!("CUDA_PATH is not set"); + }; + println!(r"cargo:rustc-link-search=native={}\lib\x64", cuda_path); + } else { + println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64"); + println!("cargo:rustc-link-lib=culibos"); + } println!("cargo:rustc-link-lib=cudart"); - println!("cargo:rustc-link-lib=culibos"); println!("cargo:rustc-link-lib=cublas"); println!("cargo:rustc-link-lib=cublasLt"); } @@ -69,9 +81,26 @@ fn main() { println!("cargo:rustc-link-lib=hipblas"); } + // By default, this value is automatically inferred from Rust’s compilation profile. + // For Windows platform, we always build llama.cpp in release mode. + // See https://github.com/TabbyML/tabby/pull/948 for more details. + if cfg!(target_os = "windows") { + config.profile("Release"); + } + let dst = config.build(); - println!("cargo:rustc-link-search=native={}/build", dst.display()); + if cfg!(target_os = "windows") { + println!( + r"cargo:rustc-link-search=native={}\build\{}", + dst.display(), + config.get_profile() + ); + } else { + println!("cargo:rustc-link-search=native={}/build", dst.display()); + } +} +fn build_cxx_binding() { cxx_build::bridge("src/lib.rs") .file("src/engine.cc") .flag_if_supported("-Iinclude") diff --git a/crates/llama-cpp-bindings/src/engine.cc b/crates/llama-cpp-bindings/src/engine.cc index 468584b73dad..8178dc101e95 100644 --- a/crates/llama-cpp-bindings/src/engine.cc +++ b/crates/llama-cpp-bindings/src/engine.cc @@ -1,5 +1,3 @@ -#include "engine.h" - #include #include #include @@ -9,6 +7,7 @@ #include #include +#include "llama-cpp-bindings/include/engine.h" #include "llama-cpp-bindings/src/lib.rs.h" namespace llama { diff --git a/crates/tabby-common/Cargo.toml b/crates/tabby-common/Cargo.toml index 667f1afa8f23..acbbe2323a03 100644 --- a/crates/tabby-common/Cargo.toml +++ b/crates/tabby-common/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] filenamify = "0.1.0" +home = "0.5.5" lazy_static = { workspace = true } serde = { workspace = true } serdeconv = { workspace = true } diff --git a/crates/tabby-common/src/path.rs b/crates/tabby-common/src/path.rs index 44a1cab80f79..2dc5305fe542 100644 --- a/crates/tabby-common/src/path.rs +++ b/crates/tabby-common/src/path.rs @@ -6,7 +6,7 @@ lazy_static! { static ref TABBY_ROOT: Mutex> = { Mutex::new(Cell::new(match env::var("TABBY_ROOT") { Ok(x) => PathBuf::from(x), - Err(_) => PathBuf::from(env::var("HOME").unwrap()).join(".tabby"), + Err(_) => home::home_dir().unwrap().join(".tabby"), })) }; }