From f92cc6ae91bec1754064b311f9f1d0aa2ce08268 Mon Sep 17 00:00:00 2001 From: Dexoron Date: Thu, 23 Jul 2026 19:59:16 +0800 Subject: [PATCH] fix(ci): fix tests --- .github/workflows/ci.yml | 47 ++++++++++++++++++++++++++++-- src/core/build/builder/artifact.rs | 30 +++++++++++++++---- src/core/build/builder/msvc/mod.rs | 9 ++++-- tests/cli_deps.rs | 19 ++++++++---- 4 files changed, 89 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 570ca30..1f7bcea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,8 @@ on: env: CARGO_TERM_COLOR: always RUSTFLAGS: -Dwarnings + CARGO_INCREMENTAL: "0" + SCCACHE_GHA_ENABLED: "true" jobs: checks: @@ -24,7 +26,13 @@ jobs: with: components: rustfmt, clippy + - name: sccache + uses: mozilla-actions/sccache-action@v0.0.9 + - uses: Swatinem/rust-cache@v2 + with: + shared-key: dcr-ci + cache-all-crates: true - name: Format run: cargo fmt --all --check @@ -52,7 +60,22 @@ jobs: - name: Setup Rust uses: dtolnay/rust-toolchain@stable + - name: sccache + uses: mozilla-actions/sccache-action@v0.0.9 + - uses: Swatinem/rust-cache@v2 + with: + shared-key: dcr-ci + cache-all-crates: true + cache-on-failure: true + + - name: Cache apt packages + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: /var/cache/apt/archives + key: apt-${{ runner.os }}-${{ hashFiles('.github/workflows/ci.yml') }} + restore-keys: apt-${{ runner.os }}- - name: Install Linux tools if: runner.os == 'Linux' @@ -64,7 +87,8 @@ jobs: nasm \ clang-format \ clang-tidy \ - git + git \ + llvm - name: Install macOS tools if: runner.os == 'macOS' @@ -76,8 +100,11 @@ jobs: if: runner.os == 'Windows' shell: pwsh run: | - choco install nasm -y + choco install nasm llvm -y echo "C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + if (Test-Path "C:\Program Files\LLVM\bin") { + echo "C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + } - name: Unit tests (binary crate) run: cargo test --bins -- --nocapture @@ -89,6 +116,10 @@ jobs: if: runner.os != 'Windows' run: cargo test --tests --features archive -- --nocapture + - name: sccache stats + if: always() + run: sccache --show-stats || true + test-archive-linux: name: archive feature smoke needs: checks @@ -99,15 +130,25 @@ jobs: - name: Setup Rust uses: dtolnay/rust-toolchain@stable + - name: sccache + uses: mozilla-actions/sccache-action@v0.0.9 + - uses: Swatinem/rust-cache@v2 + with: + shared-key: dcr-ci + cache-all-crates: true - name: Install tools run: | sudo apt-get update - sudo apt-get install -y build-essential clang nasm + sudo apt-get install -y build-essential clang nasm llvm - name: Build with archive run: cargo build --features archive - name: Flat-bin + unit suite with archive run: cargo test --features archive --test cli_build --test cli_workspace --test cli_errors -- --nocapture + + - name: sccache stats + if: always() + run: sccache --show-stats || true diff --git a/src/core/build/builder/artifact.rs b/src/core/build/builder/artifact.rs index 1a1c22a..03ce351 100644 --- a/src/core/build/builder/artifact.rs +++ b/src/core/build/builder/artifact.rs @@ -160,14 +160,12 @@ pub(crate) fn archive_static( return Ok(common::elapsed_secs(start_time)); } - let archiver = ctx.archiver.unwrap_or(if cfg!(target_os = "windows") { - "lib" - } else { - "ar" - }); + let archiver = ctx + .archiver + .unwrap_or_else(|| default_archiver(ctx.compiler)); let mut cmd = Command::new(archiver); - if cfg!(target_os = "windows") && archiver == "lib" { + if cfg!(target_os = "windows") && is_msvc_lib(archiver) { cmd.arg("/nologo").arg(format!("/OUT:{lib_path}")); } else { cmd.arg("rcs").arg(&lib_path); @@ -243,6 +241,26 @@ pub(crate) fn link_binary( run(ctx, cmd, start_time) } +fn default_archiver(compiler: &str) -> &'static str { + let c = compiler.to_lowercase(); + if cfg!(target_os = "windows") { + if c.contains("cl") && !c.contains("clang") { + "lib" + } else if c.contains("clang") { + "llvm-ar" + } else { + "ar" + } + } else { + "ar" + } +} + +fn is_msvc_lib(archiver: &str) -> bool { + let a = archiver.to_lowercase(); + a == "lib" || a == "lib.exe" || a.ends_with("\\lib.exe") || a.ends_with("/lib.exe") +} + fn run(ctx: &BuildContext, mut cmd: Command, start_time: Instant) -> Result { if ctx.verbose || std::env::var("DCR_DEBUG").is_ok() { eprintln!("[dcr] {:?}", cmd); diff --git a/src/core/build/builder/msvc/mod.rs b/src/core/build/builder/msvc/mod.rs index dfcf69b..d6f8cb9 100644 --- a/src/core/build/builder/msvc/mod.rs +++ b/src/core/build/builder/msvc/mod.rs @@ -60,8 +60,13 @@ pub fn build(ctx: &BuildContext) -> Result { let elapsed = common::elapsed_secs(start_time); return Ok(elapsed); } - let mut cmd = Command::new(ctx.archiver.unwrap_or("lib")); - cmd.arg("/nologo").arg(format!("/OUT:{lib_path}")); + let archiver = ctx.archiver.unwrap_or("lib"); + let mut cmd = Command::new(archiver); + if archiver == "lib" || archiver.eq_ignore_ascii_case("lib.exe") { + cmd.arg("/nologo").arg(format!("/OUT:{lib_path}")); + } else { + cmd.arg("rcs").arg(&lib_path); + } for obj in &objects { cmd.arg(obj); } diff --git a/tests/cli_deps.rs b/tests/cli_deps.rs index 5acb361..29687a1 100644 --- a/tests/cli_deps.rs +++ b/tests/cli_deps.rs @@ -117,11 +117,15 @@ fn registry_dependency_is_built_from_cache() { "[registry.local]\nurl = \"file://local\"\npriority = 1\n", ) .expect("failed to write registry config"); + let dep_path = dep + .canonicalize() + .unwrap_or(dep.clone()) + .to_string_lossy() + .replace('\\', "/"); std::fs::write( dcr_home.join("index.json"), format!( - "{{\"packages\":[{{\"name\":\"mylib\",\"latest_version\":\"0.1.0\",\"path\":\"{}\"}}]}}", - dep.display() + "{{\"packages\":[{{\"name\":\"mylib\",\"latest_version\":\"0.1.0\",\"path\":\"{dep_path}\"}}]}}" ), ) .expect("failed to write registry index"); @@ -151,11 +155,16 @@ fn registry_dependency_is_built_from_cache() { .expect("failed to write app source"); let index_path = dcr_home.join("index.json"); - let envs = [ + let home_s = home.to_string_lossy().to_string(); + let index_s = index_path.to_string_lossy().to_string(); + let mut envs = vec![ ("DCR_COMPILER", compiler), - ("HOME", home.to_str().unwrap()), - ("DCR_INDEX_PATH", index_path.to_str().unwrap()), + ("HOME", home_s.as_str()), + ("DCR_INDEX_PATH", index_s.as_str()), ]; + if cfg!(windows) { + envs.push(("USERPROFILE", home_s.as_str())); + } let out = run_dcr_env(&["build"], &app, &envs); if !out.status.success() { eprintln!("stdout: {}", String::from_utf8_lossy(&out.stdout));