From b598a1b2ca4f3fda0382b997cb26a04c31f3ed68 Mon Sep 17 00:00:00 2001 From: Chiichen Date: Fri, 6 Sep 2024 23:16:50 +0800 Subject: [PATCH] build: fix build failure on windows --- .github/workflows/CI.yml | 40 +++++------ examples/image_capture/Cargo.toml | 8 +-- libvnc-sys/Cargo.toml | 3 +- libvnc-sys/build.rs | 114 +++++++++++++++++++++++++----- 4 files changed, 123 insertions(+), 42 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 28661e9..d216109 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ "master" ] + branches: ["master"] pull_request: - branches: [ "master" ] + branches: ["master"] env: CARGO_TERM_COLOR: always @@ -13,36 +13,36 @@ jobs: ci: strategy: matrix: - os: [ubuntu-latest,macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - name: Install Rust nightly - run : rustup update nightly - - name: Build - run: cargo build --verbose - - name: Test - run: cargo test --verbose - - name: Clippy - run: cargo clippy -- -D warnings - - name: Cargo Fmt Check - run : cargo fmt --all -- --check + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install Rust nightly + run: rustup update nightly + - name: Build + run: cargo build --verbose + - name: Test + run: cargo test --verbose + - name: Clippy + run: cargo clippy -- -D warnings + - name: Cargo Fmt Check + run: cargo fmt --all -- --check build-from-package: strategy: matrix: - os: [ubuntu-latest,macos-latest] + os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Install Rust nightly - run : rustup update nightly + run: rustup update nightly - name: Install libvncserver (Ubuntu) if: matrix.os == 'ubuntu-latest' run: | sudo apt-get update && - sudo apt-get install libvncserver-dev + sudo apt-get install libvncserver-dev - name: Install libvncserver (Macos) if: matrix.os == 'macos-latest' run: brew install libvncserver @@ -51,4 +51,4 @@ jobs: - name: Test run: | cargo test -p libvnc --features pkg --verbose & - cargo test -p libvnc-sys --features pkg --verbose \ No newline at end of file + cargo test -p libvnc-sys --features pkg --verbose diff --git a/examples/image_capture/Cargo.toml b/examples/image_capture/Cargo.toml index 6366a72..8281d3e 100644 --- a/examples/image_capture/Cargo.toml +++ b/examples/image_capture/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "image_capture" +name = "image_capture" version = "0.1.0" edition = "2021" [dependencies] env_logger = "0.11.3" -image = "0.25.1" -libvnc = "0.1.1" -log = "0.4.21" +image = "0.25.1" +libvnc = "*" +log = "0.4.21" [dev-dependencies] diff --git a/libvnc-sys/Cargo.toml b/libvnc-sys/Cargo.toml index d6a654f..e29ccbd 100644 --- a/libvnc-sys/Cargo.toml +++ b/libvnc-sys/Cargo.toml @@ -17,7 +17,8 @@ exclude = ["compile_commands.json"] bindgen = "0.70.0" cc = "1.0.95" pkg-config = "0.3.30" -cmake = "0.1.50" +# cmake = "0.1.50" +# which = "6.0.3" [features] default = [] diff --git a/libvnc-sys/build.rs b/libvnc-sys/build.rs index 278d2d2..1171766 100644 --- a/libvnc-sys/build.rs +++ b/libvnc-sys/build.rs @@ -42,10 +42,60 @@ fn bindgen_vncserver() { } #[cfg(not(feature = "pkg"))] fn bindgen_vncserver() { + use std::{ + env::current_dir, + fs::{self, create_dir_all}, + process::Command, + vec, + }; + #[cfg(target_os = "android")] compile_error!("Unsupported Target Android"); - let mut config = cmake::Config::new("libvncserver"); + // https://github.com/LibVNC/libvncserver/issues/628 use cmake in plain command line to avoid compile error on windows + // let mut config = cmake::Config::new("libvncserver"); + // let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + // let target_triple = env::var("TARGET").unwrap(); + // if target_triple != env::var("HOST").unwrap() { + // if !cfg!(target_os = "linux") { + // //cfg!(target_os) in build.rs means the host os that build script is running + // panic!("Cross-compilation on platforms other than linux is not supported") + // } + // if target_os == "windows" { + // config.define( + // "CMAKE_TOOLCHAIN_FILE", + // "../cmake/Toolchain-cross-mingw32-linux.cmake", + // ); + // } + // } else if target_os == "windows" { + // config.define( + // "CMAKE_TOOLCHAIN_FILE", + // which::which("vcpkg") + // .expect("Install vcpkg and make sure it can be found in current environment") + // .parent() + // .unwrap() + // .join("scripts/buildsystems/vcpkg.cmake"), //TODO BETTER toolchain path + // ); + // config.define("WITH_OPENSSL", "OFF"); + // config.define("WITH_GNUTLS", "OFF"); + // config.define("WITH_GCRYPT", "OFF"); + // } else if target_os == "android" { + // panic!("unsupported build target {}", target_os) + // } + // //TODO In WSL, if QT is installed in Windows system, then the build process might fail on Qt example. + // let dst = config.build(); + // >>> Manually build libvncserver with cmake + let mut dst = PathBuf::from(env::var("OUT_DIR").unwrap()); + dst.push("build"); + let libvncserver_path = current_dir() + .unwrap() + .join("libvncserver") + .display() + .to_string(); + let mut cmake_args = vec![]; + cmake_args.push(libvncserver_path.as_str()); + // let cmake_install_prefix_arg = format!(r#"-DCMAKE_INSTALL_PREFIX="{}""#, dst.display()); + // cmake_args.push(&cmake_install_prefix_arg); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_triple = env::var("TARGET").unwrap(); if target_triple != env::var("HOST").unwrap() { @@ -54,35 +104,66 @@ fn bindgen_vncserver() { panic!("Cross-compilation on platforms other than linux is not supported") } if target_os == "windows" { - config.define( - "CMAKE_TOOLCHAIN_FILE", - "../cmake/Toolchain-cross-mingw32-linux.cmake", - ); + cmake_args + .push(r#"-DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-cross-mingw32-linux.cmake""#); } } else if target_os == "windows" { - config.define( - "CMAKE_TOOLCHAIN_FILE", - "C:/vcpkg/scripts/buildsystems/vcpkg.cmake", //TODO BETTER toolchain path - ); - config.define("WITH_OPENSSL", "OFF"); - config.define("WITH_GNUTLS", "OFF"); - config.define("WITH_GCRYPT", "OFF"); + // config.define( + // "CMAKE_TOOLCHAIN_FILE", + // which::which("vcpkg") + // .expect("Install vcpkg and make sure it can be found in current environment") + // .parent() + // .unwrap() + // .join("scripts/buildsystems/vcpkg.cmake"), + // ); + cmake_args.push("-DWITH_OPENSSL=OFF"); + cmake_args.push("-DWITH_GNUTLS=OFF"); + cmake_args.push("-DWITH_GCRYPT=OFF"); } else if target_os == "android" { panic!("unsupported build target {}", target_os) } + //Make sure dst is cleaned up + if !dst.is_dir() { + let _ = fs::remove_dir_all(dst.as_path()); + let _ = create_dir_all(dst.as_path()); + } + let mut command = Command::new("cmake"); + command + .current_dir(dst.as_path()) + .args(cmake_args) + .env("CMAKE_INSTALL_PREFIX", dst.display().to_string()); + let status = command.status().unwrap(); + if !status.success() { + panic!("Failed to run {:?}", command) + } - //TODO In WSL, if QT is installed in Windows system, then the build process might fail on Qt example. - let dst = config.build(); + let mut command = Command::new("cmake"); + command + .current_dir(dst.as_path()) + .arg("--build") + .arg(".") + .arg("--target") + .arg("install"); + let status = command.status().unwrap(); + println!("command : {:?} status:{:?}", command, status); + if !status.success() { + panic!("Failed to run {:?}", command) + } + // << Manually build libvncserver done println!("cargo:rustc-link-lib=dylib=vncserver"); println!("cargo:rustc-link-lib=dylib=vncclient"); //There's no libvncclient , so we need to specify the vncclient manually - println!("cargo:rustc-link-search={}/build", dst.display(),); + println!("cargo:rustc-link-search={}", dst.display()); let rfb_header = format!("{}/{}", dst.display(), "include/rfb/rfb.h"); let rfbclient_header = format!("{}/{}", dst.display(), "include/rfb/rfbclient.h"); let bindings = bindgen::Builder::default() .header(rfb_header) .header(rfbclient_header) .use_core() - .clang_arg(format!("-I{}/{}", dst.display(), "include")) + .clang_args([ + format!("-I{}/{}", dst.display(), "include"), + #[cfg(target_os = "windows")] + format!("-DWIN32"), + ]) .generate() .expect("unable to generate rfb bindings"); @@ -91,7 +172,6 @@ fn bindgen_vncserver() { .write_to_file(out_path.join("rfb.rs")) .expect("couldn't write bindings!"); } - fn main() { bindgen_vncserver(); }