From 437b2e2df5f2fbcef540b1b3b4a6f5df7264d9a2 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 13:58:01 -0800 Subject: [PATCH 01/20] Robustify R setting detection --- CHANGELOG.md | 4 + Cargo.toml | 2 +- README.md | 8 +- build.rs | 243 ++++++++++++++++++--------------------------------- 4 files changed, 96 insertions(+), 161 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fa291c..97da24a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [0.2.2] - 2025-02-19 +### Fixed +- Rely on `R_HOME` env var first, then try `R RHOME`; panic if both fail. + ## [0.2.1] - 2025-02-02 ### Fixed - Reformatted code to conform to Rust formatting standards (no functional changes). diff --git a/Cargo.toml b/Cargo.toml index 07f52d3..770e09f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "r-src" -version = "0.2.1" +version = "0.2.2" edition = "2021" license = "MIT" authors = ["Balasubramanian Narasimhan "] diff --git a/README.md b/README.md index 28cb4ad..5834eda 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,11 @@ but has extra platform-specific dependencies for `Windows` such as Two components are required to build the library: -1. [`R`](https://cran.r-project.org/): It needs to be installed and - available in the search path. On `Windows`, the `Rtools` binaries - are also expected to be on the search path. +1. [`R`](https://cran.r-project.org/): An environment variable + `R_HOME` indicating the value of `R_HOME` is first looked for and, + if not found, the command `R RHOME` is tried, so `R` must be on the + path for the latter. On `Windows`, the `Rtools` binaries are also + expected to be on the search path. 2. [`Rust`](https://www.rust-lang.org/learn/get-started): It is recommended to install `Rust` using `rustup`; search path should include `Rust` binaries. diff --git a/build.rs b/build.rs index a805636..fa425be 100644 --- a/build.rs +++ b/build.rs @@ -1,17 +1,11 @@ use std::{ collections::HashMap, - ffi::{OsStr, OsString}, - io, - path::Path, + io, env, + path::{Path, PathBuf}, process::Command, }; -#[cfg(target_family = "unix")] -use std::os::unix::ffi::OsStrExt; - -#[cfg(target_family = "windows")] -use std::os::windows::ffi::OsStringExt; - +/// Holds key/value pairs parsed from "R CMD config --all". #[derive(Debug)] struct ConfigVariables { map: HashMap, @@ -19,160 +13,98 @@ struct ConfigVariables { impl ConfigVariables { fn get_r_cmd_config(&self, key: &str) -> String { - match self.map.get(key) { - Some(value) => value.to_string(), - None => String::from(""), - } - } -} - -// frustratingly, something like the following does not exist in an -// OS-independent way in Rust -#[cfg(target_family = "unix")] -fn byte_array_to_os_string(bytes: &[u8]) -> OsString { - let os_str = OsStr::from_bytes(bytes); - os_str.to_os_string() -} - -#[link(name = "kernel32")] -#[cfg(target_family = "windows")] -extern "system" { - #[link_name = "GetConsoleCP"] - fn get_console_code_page() -> u32; - #[link_name = "MultiByteToWideChar"] - fn multi_byte_to_wide_char( - CodePage: u32, - dwFlags: u32, - lpMultiByteStr: *const u8, - cbMultiByte: i32, - lpWideCharStr: *mut u16, - cchWideChar: i32, - ) -> i32; -} - -// convert bytes to wide-encoded characters on Windows -// from: https://stackoverflow.com/a/40456495/4975218 -#[cfg(target_family = "windows")] -fn wide_from_console_string(bytes: &[u8]) -> Vec { - assert!(bytes.len() < std::i32::MAX as usize); - let mut wide; - let mut len; - unsafe { - let cp = get_console_code_page(); - len = multi_byte_to_wide_char( - cp, - 0, - bytes.as_ptr() as *const u8, - bytes.len() as i32, - std::ptr::null_mut(), - 0, - ); - wide = Vec::with_capacity(len as usize); - len = multi_byte_to_wide_char( - cp, - 0, - bytes.as_ptr() as *const u8, - bytes.len() as i32, - wide.as_mut_ptr(), - len, - ); - wide.set_len(len as usize); + self.map.get(key).cloned().unwrap_or_default() } - wide -} - -#[cfg(target_family = "windows")] -fn byte_array_to_os_string(bytes: &[u8]) -> OsString { - // first, use Windows API to convert to wide encoded - let wide = wide_from_console_string(bytes); - // then, use `std::os::windows::ffi::OsStringExt::from_wide()` - OsString::from_wide(&wide) } -/// Runs the command `R RHOME` and returns the trimmed output if successful. -/// Panics with a meaningful error message if the command fails. fn get_r_home() -> String { - // Attempt to run the command `R RHOME` - let output = Command::new("R").arg("RHOME").output(); // Capture the command's output - - match output { - Ok(output) if output.status.success() => { - // Convert stdout to a String and trim it - String::from_utf8(output.stdout) - .expect("Invalid UTF-8 in RHOME output") - .trim() - .to_string() - } - Ok(output) => { - eprintln!( - "Error: Command `R RHOME` failed with status: {}\nStderr: {}", - output.status, - String::from_utf8_lossy(&output.stderr) - ); - panic!("Failed to detect RHOME using `R RHOME`. Is R installed and in your PATH?"); - } - Err(err) => { - panic!( - "Failed to execute `R RHOME`: {}. Is R installed and in your PATH?", - err - ); + // Indicate that we're trying to find R_HOME from the environment. + print!("Trying to find R_HOME in environment..."); + if let Ok(r_home) = env::var("R_HOME") { + println!("{}", r_home); + return r_home; + } else { + println!("unsuccessful!"); + } + + // Inform that R_HOME was not found in the environment and we're trying `R RHOME`. + print!("R_HOME not found in environment, trying `R RHOME` command..."); + + let output = Command::new("R") + .arg("RHOME") + .output() + .expect("Failed to execute `R RHOME` command"); + + if output.status.success() { + let r_home = String::from_utf8_lossy(&output.stdout) + .trim() + .to_string(); + + if !r_home.is_empty() { + println!("success: {}", r_home); + return r_home; } } + + // If both methods fail, panic with an error message. + panic!("Could not determine R_HOME: it is not set in the environment and `R RHOME` did not return a valid value."); } -// Execute an R CMD config and return the captured output -fn r_cmd_config>(r_binary: S) -> io::Result { - let out = Command::new(r_binary) +/// Run `R CMD config --all` using the provided R executable path and return its stdout as a String. +fn r_cmd_config(r_binary: &Path) -> io::Result { + let output = Command::new(r_binary) .args(&["CMD", "config", "--all"]) .output()?; - - // if there are any errors we print them out, helps with debugging - if !out.stderr.is_empty() { - println!( - "> {}", - byte_array_to_os_string(&out.stderr) - .as_os_str() - .to_string_lossy() - ); + if !output.stderr.is_empty() { + println!("> {}", String::from_utf8_lossy(&output.stderr)); } - - Ok(byte_array_to_os_string(&out.stdout)) + Ok(String::from_utf8_lossy(&output.stdout).into_owned()) } +/// Build the configuration map by invoking R commands. fn build_r_cmd_configs() -> ConfigVariables { - let r_binary = format!(r"{}/bin/R", get_r_home()); - let r_configs = r_cmd_config(r_binary); + let r_home = get_r_home(); + + // Determine the R executable path. + let r_binary: PathBuf = if cfg!(target_os = "windows") { + // On Windows R is typically installed in a subdirectory. + // Try the "x64" folder first (for 64-bit installations), then fall back. + let candidate = Path::new(&r_home).join("bin").join("x64").join("R.exe"); + if candidate.exists() { + candidate + } else { + Path::new(&r_home).join("bin").join("R.exe") + } + } else { + Path::new(&r_home).join("bin").join("R") + }; + let configs = r_cmd_config(&r_binary).unwrap_or_default(); let mut rcmd_config_map = HashMap::new(); - match r_configs { - Ok(configs) => { - let input = configs.as_os_str().to_string_lossy(); - for line in input.lines() { - // Ignore lines beyond comment marker - if line.starts_with("##") { - break; - } - let parts: Vec<_> = line.split('=').map(str::trim).collect(); - if let [name, value] = parts.as_slice() { - rcmd_config_map.insert(name.to_string(), value.to_string()); - } - } + + // Parse the output, expecting lines of the form KEY=VALUE. + for line in configs.lines() { + // Stop if we reach comments (the R output sometimes appends comments). + if line.starts_with("##") { + break; + } + let parts: Vec<&str> = line.split('=').map(str::trim).collect(); + if parts.len() == 2 { + rcmd_config_map.insert(parts[0].to_string(), parts[1].to_string()); } - _ => (), } - // Return the struct ConfigVariables { map: rcmd_config_map, } } -fn get_libs_and_paths(strings: Vec) -> (Vec, Vec) { - let mut paths: Vec = Vec::new(); - let mut libs: Vec = Vec::new(); - - for s in &strings { - let parts: Vec<&str> = s.split_whitespace().collect(); - for part in parts { +/// Given a list of strings (such as BLAS, LAPACK, etc. flags), +/// extract library paths (starting with "-L") and libraries (starting with "-l"). +fn get_libs_and_paths(strings: &[String]) -> (Vec, Vec) { + let mut paths = Vec::new(); + let mut libs = Vec::new(); + for s in strings { + for part in s.split_whitespace() { if part.starts_with("-L") { paths.push(part[2..].to_string()); } else if part.starts_with("-l") { @@ -185,27 +117,24 @@ fn get_libs_and_paths(strings: Vec) -> (Vec, Vec) { fn main() { let r_configs = build_r_cmd_configs(); - let (lib_paths, libs) = get_libs_and_paths( - [ - r_configs.get_r_cmd_config("BLAS_LIBS"), - r_configs.get_r_cmd_config("LAPACK_LIBS"), - r_configs.get_r_cmd_config("FLIBS"), - ] - .to_vec(), - ); - - for path in lib_paths.iter() { - // Some R builds (e.g. homebrew) contain hardwired gfortran12 - // paths, which may or may not exist if one has upgraded - // gfortran. So filter out non-existent ones, so that cargo - // doesn't complain. - if Path::new(path).exists() { + let config_strings = [ + r_configs.get_r_cmd_config("BLAS_LIBS"), + r_configs.get_r_cmd_config("LAPACK_LIBS"), + r_configs.get_r_cmd_config("FLIBS"), + ]; + let (lib_paths, libs) = get_libs_and_paths(&config_strings); + + // Emit link search paths. Only output those that exist. + for path in lib_paths { + if Path::new(&path).exists() { println!("cargo:rustc-link-search={}", path); + eprintln!("cargo:rustc-link-search={}", path); } } - - for lib in libs.iter() { + // Emit libraries for the linker. + for lib in libs { println!("cargo:rustc-link-lib=dylib={}", lib); + eprintln!("cargo:rustc-link-lib=dylib={}", lib); } println!("cargo:rerun-if-changed=build.rs"); } From b040f7fbb59f867486e3627599e9ea6354c93566 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 14:03:35 -0800 Subject: [PATCH 02/20] Update build.rs --- build.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/build.rs b/build.rs index fa425be..30fba52 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,6 @@ use std::{ collections::HashMap, - io, env, + env, io, path::{Path, PathBuf}, process::Command, }; @@ -21,11 +21,11 @@ fn get_r_home() -> String { // Indicate that we're trying to find R_HOME from the environment. print!("Trying to find R_HOME in environment..."); if let Ok(r_home) = env::var("R_HOME") { - println!("{}", r_home); + println!("{}", r_home); return r_home; } else { - println!("unsuccessful!"); - } + println!("unsuccessful!"); + } // Inform that R_HOME was not found in the environment and we're trying `R RHOME`. print!("R_HOME not found in environment, trying `R RHOME` command..."); @@ -36,12 +36,10 @@ fn get_r_home() -> String { .expect("Failed to execute `R RHOME` command"); if output.status.success() { - let r_home = String::from_utf8_lossy(&output.stdout) - .trim() - .to_string(); + let r_home = String::from_utf8_lossy(&output.stdout).trim().to_string(); if !r_home.is_empty() { - println!("success: {}", r_home); + println!("success: {}", r_home); return r_home; } } @@ -128,13 +126,13 @@ fn main() { for path in lib_paths { if Path::new(&path).exists() { println!("cargo:rustc-link-search={}", path); - eprintln!("cargo:rustc-link-search={}", path); + eprintln!("cargo:rustc-link-search={}", path); } } // Emit libraries for the linker. for lib in libs { println!("cargo:rustc-link-lib=dylib={}", lib); - eprintln!("cargo:rustc-link-lib=dylib={}", lib); + eprintln!("cargo:rustc-link-lib=dylib={}", lib); } println!("cargo:rerun-if-changed=build.rs"); } From 0e1daf8b1b1a0529c59229c39ffec92a601323d3 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 17:19:55 -0800 Subject: [PATCH 03/20] Update test.yml --- .github/workflows/test.yml | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0a28d96..d08c9a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,57 @@ name: Tests +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: "${{ matrix.config.os }} (R: ${{ matrix.config.r }}, Rust: ${{ matrix.config.rust }})" + + strategy: + fail-fast: false + matrix: + config: + - {os: windows-latest, r: 'release', rust: 'stable-msvc' } + - {os: windows-latest, r: 'devel', rust: 'stable-msvc' } + - {os: macOS-latest, r: 'release', rust: 'stable' } + - {os: ubuntu-latest, r: 'release', rust: 'stable' } + - {os: ubuntu-latest, r: 'devel', rust: 'stable' } + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up R + uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + rtools-version: ${{ matrix.config.rtools-version }} + # TODO: enable RSPM when all the packages are available + use-public-rspm: false + + - name: Rust toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: Test crate + run: | + cargo test --vv + + + + + + + + + + on: push: branches: From 7701cf30652cde4f282aa57be3d82ef9b233592a Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 17:21:11 -0800 Subject: [PATCH 04/20] Update test.yml --- .github/workflows/test.yml | 237 ------------------------------------- 1 file changed, 237 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d08c9a1..541581b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,240 +43,3 @@ jobs: run: | cargo test --vv - - - - - - - - - -on: - push: - branches: - - main - - master - pull_request: - branches: - - main - - master - -# cargo error handling is wrapped by ci-cargo, for simplicity and better logging. -# To use ci-cargo in a step, source ci-cargo.ps1 (using `. ./ci-cargo.ps`, note the extra dot in front). -# ci-cargo does not handle correctly -- separator, so wrap it in quotes ('--') -# A special named parameter called `ActionName` can be used to set the name of current ci-cargo action, -# used as `ci-cargo .... -ActionName "Called for documentation purposes"`. -jobs: - # All tests - tests: - runs-on: ${{ matrix.config.os }} - - name: ${{ matrix.config.os }} (R-${{ matrix.config.r }} rust-${{ matrix.config.rust-version }}) - - strategy: - fail-fast: false - matrix: - config: - - { - os: windows-latest, - r: "release", - rust-version: "stable-msvc", - rtools-version: "44", - features: "full-functionality", - } - - { - os: windows-latest, - r: "devel", - rust-version: "stable-msvc", - rtools-version: "44", - features: "default", - } - - { - os: windows-latest, - r: "oldrel", - rust-version: "stable-msvc", - rtools-version: "43", - features: "default", - } - - - { - os: macOS-latest, - r: "release", - rust-version: "stable", - features: "full-functionality", - } - - { - os: ubuntu-latest, - r: "release", - rust-version: "stable", - features: "full-functionality", - check_fmt: true, - } - - { - os: ubuntu-latest, - r: "release", - rust-version: "nightly", - features: "full-functionality", - extra-args: ["-Zdoctest-xcompile"], - } - # R-devel requires LD_LIBRARY_PATH - - { - os: ubuntu-latest, - r: "devel", - rust-version: "stable", - features: "default", - } - - { - os: ubuntu-latest, - r: "oldrel", - rust-version: "stable", - features: "default", - } - - env: - R_REMOTES_NO_ERRORS_FROM_WARNINGS: true - - # This environment variable enables support for pseudo multi-target cargo builds. - # Current stable Rust does not support multi-targeting, - # see https://github.com/rust-lang/cargo/issues/8176 - # The variable is treated as a comma-separated list of valid Rust targets. - # 'default' value emits no '--target' flag. - # E.g.: BUILD_TARGETS=i686-pc-windows-gnu,x86_64-pc-windows-gnu builds two times, - # each time providing '--target=*-pc-windows-gnu' flag to cargo. - BUILD_TARGETS: default - - # PowerShell core is available on all platforms and can be used to unify scripts - defaults: - run: - shell: pwsh - - steps: - - uses: actions/checkout@v3 - - - name: Set up Rust - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.config.rust-version }} - components: rustfmt, clippy - - - name: Set up R - uses: r-lib/actions/setup-r@v2 - with: - r-version: ${{ matrix.config.r }} - rtools-version: ${{ matrix.config.rtools-version }} - # TODO: enable RSPM when all the packages are available - use-public-rspm: false - - - name: Set up Pandoc - uses: r-lib/actions/setup-pandoc@v2 - - - name: Configure Windows (R >= 4.2) - if: startsWith(runner.os, 'Windows') && matrix.config.r != '4.1' - run: | - if ("${{ matrix.config.rtools-version }}" -eq "42") { - $rtools_home = "C:\rtools42" # for R 4.2 - } else { - $rtools_home = "C:\rtools43" # for R >= 4.3 - } - - # c.f. https://github.com/wch/r-source/blob/f1501504df8df1668a57d3a1b6f80167f24441d3/src/library/profile/Rprofile.windows#L70-L71 - echo "${rtools_home}\x86_64-w64-mingw32.static.posix\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "${rtools_home}\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - - # Add target - rustup target add x86_64-pc-windows-gnu - echo "BUILD_TARGETS=x86_64-pc-windows-gnu" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append ; - - # The following lines add two tweaks: - # - # 1. Change the linker name to "x86_64-w64-mingw32.static.posix-gcc.exe". - # 2. Add empty libgcc_s.a and libgcc_eh.a, and add them to the compiler's - # library search paths via `LIBRARY_PATH` envvar. - # - # The first tweak is needed because Rtools42 doesn't contain - # "x86_64-w64-mingw32-gcc," which `rustc` uses as the default linker - # for the `x86_64-pc-windows-gnu` target. - # - # If we use the Rtools' toolchain, the second tweak is also required. - # `rustc` adds `-lgcc_eh` and `-lgcc_s` flags to the compiler, but - # Rtools' GCC doesn't have `libgcc_eh` or `libgcc_s` due to the - # compilation settings. So, in order to please the compiler, we need - # to add empty `libgcc_eh` or `libgcc_s` to the library search paths. - # - # For more details, please refer to https://github.com/r-windows/rtools-packages/blob/2407b23f1e0925bbb20a4162c963600105236318/mingw-w64-gcc/PKGBUILD#L313-L316 - - New-Item -Path libgcc_mock -Type Directory - New-Item -Path libgcc_mock\libgcc_eh.a -Type File - New-Item -Path libgcc_mock\libgcc_s.a -Type File - - New-Item -Path .cargo -ItemType Directory -Force - $pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} - @" - [target.x86_64-pc-windows-gnu] - linker = "x86_64-w64-mingw32.static.posix-gcc.exe" - - [env] - LIBRARY_PATH = "${pwd_slash}/libgcc_mock" - "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; - env: - RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} - - # TODO: Remove this runner when we drop the support for R < 4.2 - - name: Configure Windows (R < 4.2) - if: startsWith(runner.os, 'Windows') && matrix.config.r == '4.1' - # 1. Add rust target - # 2. Add target name to the $targets variable - # 3. Add mingw32/mingw64 bin folders to PATH - # 4. Add R x64/i386 folders to PATH - run: | - $targets=@() - if ($env:RUST_TOOLCHAIN -notlike "*x86_64*") { - rustup target add i686-pc-windows-gnu ; - $targets+="i686-pc-windows-gnu" - echo "${env:RTOOLS40_HOME}\mingw32\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\i386" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - } - if ($env:RUST_TOOLCHAIN -notlike "*i686*") { - rustup target add x86_64-pc-windows-gnu ; - $targets+="x86_64-pc-windows-gnu" - echo "${env:RTOOLS40_HOME}\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - } - echo "BUILD_TARGETS=$($targets -join ',')" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append ; - env: - RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} - - # This is required for ubuntu r-devel - # 'Del alias:R' removes 'R' alias which prevents running R - - name: Configure Linux - if: startsWith(runner.os, 'linux') - run: | - Del alias:R - echo "LD_LIBRARY_PATH=$(R -s -e 'cat(normalizePath(R.home()))')/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - # Check code formatting. As this doesn't depend on the platform, do this only on one platform. - - name: Check code formatting - if: matrix.config.check_fmt - run: cargo fmt -- --check - - # For each target in the BUILD_TARGETS comma-separated list, run cargo build with appropriate target - # Required by Windows builds, does not affect other platforms - - name: Build - run: | - . ./ci-cargo.ps1 - foreach($target in ($env:BUILD_TARGETS).Split(',')) { - ci-cargo build $(if($target -ne 'default') {"--target=$target"} ) -ActionName "Building for $target target" - } - # For each target in the BUILD_TARGETS comma-separated list, run cargo test with appropriate target - # Required by Windows builds, does not affect other platforms - # ! ci-cargo requires '--' to be wrapped in quotes (passed as an explicit string) - - name: Run tests - run: | - . ./ci-cargo.ps1 - foreach($target in ($env:BUILD_TARGETS).Split(',')) { - # Note: no feature is specified, which means such features like graphics, serde, ndarray, and num-complex are not tested here. - ci-cargo test $(if($target -ne 'default') {"--target=$target"} ) '--' --nocapture -ActionName "Testing for $target target" - } - From fdf3e7bfaf938527467bde3130e65148f42ad244 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 17:23:18 -0800 Subject: [PATCH 05/20] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 541581b..c75b244 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,5 +41,5 @@ jobs: - name: Test crate run: | - cargo test --vv + cargo test -vv From cc1dd30f548bf620e8410f8a0dae0f9968903617 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 17:29:23 -0800 Subject: [PATCH 06/20] Update test.yml --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c75b244..78ed812 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,8 +7,11 @@ on: branches: [main, master] jobs: - R-CMD-check: + Crate-check: runs-on: ${{ matrix.config.os }} + defaults: + run: + shell: bash name: "${{ matrix.config.os }} (R: ${{ matrix.config.r }}, Rust: ${{ matrix.config.rust }})" From 71472df7f05dbe9d1982e9862c1c5e97bfecb69d Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Wed, 19 Feb 2025 17:35:48 -0800 Subject: [PATCH 07/20] Update test.yml --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 78ed812..04f114f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust: 'stable-msvc' } - - {os: windows-latest, r: 'devel', rust: 'stable-msvc' } + - {os: windows-latest, r: 'release', rust: 'stable' } + - {os: windows-latest, r: 'devel', rust: 'stable' } - {os: macOS-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'devel', rust: 'stable' } From ae0ebae6c46d79cede8307c6baf7882ef5df298b Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:03:17 -0800 Subject: [PATCH 08/20] Update test.yml --- .github/workflows/test.yml | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 04f114f..0ad568b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,6 +42,54 @@ jobs: - name: Rust toolchain uses: dtolnay/rust-toolchain@nightly + - name: Configure Windows + if: startsWith(runner.os, 'Windows') + run: | + $rtools_home = "C:\rtools${{ matrix.config.rtools-version }}" + + # c.f. https://github.com/wch/r-source/blob/f1501504df8df1668a57d3a1b6f80167f24441d3/src/library/profile/Rprofile.windows#L70-L71 + echo "${rtools_home}\x86_64-w64-mingw32.static.posix\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; + echo "${rtools_home}\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; + echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; + + # Add target + rustup target add x86_64-pc-windows-gnu + echo "BUILD_TARGETS=x86_64-pc-windows-gnu" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append ; + + # The following lines add two tweaks: + # + # 1. Change the linker name to "x86_64-w64-mingw32.static.posix-gcc.exe". + # 2. Add empty libgcc_s.a and libgcc_eh.a, and add them to the compiler's + # library search paths via `LIBRARY_PATH` envvar. + # + # The first tweak is needed because Rtools42 doesn't contain + # "x86_64-w64-mingw32-gcc," which `rustc` uses as the default linker + # for the `x86_64-pc-windows-gnu` target. + # + # If we use the Rtools' toolchain, the second tweak is also required. + # `rustc` adds `-lgcc_eh` and `-lgcc_s` flags to the compiler, but + # Rtools' GCC doesn't have `libgcc_eh` or `libgcc_s` due to the + # compilation settings. So, in order to please the compiler, we need + # to add empty `libgcc_eh` or `libgcc_s` to the library search paths. + # + # For more details, please refer to https://github.com/r-windows/rtools-packages/blob/2407b23f1e0925bbb20a4162c963600105236318/mingw-w64-gcc/PKGBUILD#L313-L316 + + New-Item -Path libgcc_mock -Type Directory + New-Item -Path libgcc_mock\libgcc_eh.a -Type File + New-Item -Path libgcc_mock\libgcc_s.a -Type File + + New-Item -Path .cargo -ItemType Directory -Force + $pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} + @" + [target.x86_64-pc-windows-gnu] + linker = "x86_64-w64-mingw32.static.posix-gcc.exe" + + [env] + LIBRARY_PATH = "${pwd_slash}/libgcc_mock" + "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; + env: + RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} + - name: Test crate run: | cargo test -vv From 595f66b7e84fe46c250f5bf0e90b6be295fe6db2 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:08:12 -0800 Subject: [PATCH 09/20] Update test.yml --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0ad568b..95a1c72 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust: 'stable' } - - {os: windows-latest, r: 'devel', rust: 'stable' } + - {os: windows-latest, r: 'release', rust: 'stable', rtools-version: "44"} + - {os: windows-latest, r: 'devel', rust: 'stable', rtools-version: "43"} - {os: macOS-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'devel', rust: 'stable' } @@ -88,7 +88,7 @@ jobs: LIBRARY_PATH = "${pwd_slash}/libgcc_mock" "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; env: - RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} + RUST_TOOLCHAIN: ${{ matrix.config.rust}} - name: Test crate run: | From 48b2c003d8770f953ef45ac55e5f9d74ab955100 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:12:50 -0800 Subject: [PATCH 10/20] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 95a1c72..f918450 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,7 +88,7 @@ jobs: LIBRARY_PATH = "${pwd_slash}/libgcc_mock" "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; env: - RUST_TOOLCHAIN: ${{ matrix.config.rust}} + RUST_TOOLCHAIN: ${{ matrix.config.rust }} - name: Test crate run: | From 26a75ce34f3d09306cfa6f3d33fa34fac243e9f1 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:21:30 -0800 Subject: [PATCH 11/20] Update test.yml --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f918450..5166104 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,8 +19,8 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust: 'stable', rtools-version: "44"} - - {os: windows-latest, r: 'devel', rust: 'stable', rtools-version: "43"} + - {os: windows-latest, r: 'release', rust: 'stable-msvc', rtools-version: "44"} + - {os: windows-latest, r: 'devel', rust: 'stable-msvc', rtools-version: "43"} - {os: macOS-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'release', rust: 'stable' } - {os: ubuntu-latest, r: 'devel', rust: 'stable' } @@ -88,7 +88,7 @@ jobs: LIBRARY_PATH = "${pwd_slash}/libgcc_mock" "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; env: - RUST_TOOLCHAIN: ${{ matrix.config.rust }} + RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} - name: Test crate run: | From 34bbb1e071d8defd5b0d3bc9ef5516f1a97b1937 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:23:21 -0800 Subject: [PATCH 12/20] Update test.yml --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5166104..d9461a8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -88,8 +88,8 @@ jobs: LIBRARY_PATH = "${pwd_slash}/libgcc_mock" "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; env: - RUST_TOOLCHAIN: ${{ matrix.config.rust-version }} - + RUST_TOOLCHAIN: ${{ matrix.config.rust }} + - name: Test crate run: | cargo test -vv From eccb0b0f18522d1c0888141cce7d13fa3591c669 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Thu, 20 Feb 2025 13:32:33 -0800 Subject: [PATCH 13/20] Update test.yml --- .github/workflows/test.yml | 75 +++++++------------------------------- 1 file changed, 13 insertions(+), 62 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d9461a8..bab798a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,76 +19,27 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust: 'stable-msvc', rtools-version: "44"} - - {os: windows-latest, r: 'devel', rust: 'stable-msvc', rtools-version: "43"} - - {os: macOS-latest, r: 'release', rust: 'stable' } - - {os: ubuntu-latest, r: 'release', rust: 'stable' } - - {os: ubuntu-latest, r: 'devel', rust: 'stable' } + - {os: 'macos-latest', r: 'release', rust: 'stable'} + - {os: 'windows-latest', r: 'release', rust: 'stable'} + - {os: 'ubuntu-latest', r: 'release', rust: 'stable'} + - {os: 'ubuntu-latest', r: 'devel', rust: 'stable', http-user-agent: 'release'} + - {os: 'ubuntu-latest', r: 'release', rust: 'nightly'} + - {os: 'ubuntu-24.04-arm', r: 'release', rust: 'stable', rspm: 'false'} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v4 - - - name: Set up R - uses: r-lib/actions/setup-r@v2 - with: - r-version: ${{ matrix.config.r }} - rtools-version: ${{ matrix.config.rtools-version }} - # TODO: enable RSPM when all the packages are available - use-public-rspm: false - - - name: Rust toolchain - uses: dtolnay/rust-toolchain@nightly - - - name: Configure Windows - if: startsWith(runner.os, 'Windows') - run: | - $rtools_home = "C:\rtools${{ matrix.config.rtools-version }}" - - # c.f. https://github.com/wch/r-source/blob/f1501504df8df1668a57d3a1b6f80167f24441d3/src/library/profile/Rprofile.windows#L70-L71 - echo "${rtools_home}\x86_64-w64-mingw32.static.posix\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "${rtools_home}\usr\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; - # Add target - rustup target add x86_64-pc-windows-gnu - echo "BUILD_TARGETS=x86_64-pc-windows-gnu" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append ; + - uses: dtolnay/rust-toolchain@nightly + if: matrix.config.rust == 'nightly' - # The following lines add two tweaks: - # - # 1. Change the linker name to "x86_64-w64-mingw32.static.posix-gcc.exe". - # 2. Add empty libgcc_s.a and libgcc_eh.a, and add them to the compiler's - # library search paths via `LIBRARY_PATH` envvar. - # - # The first tweak is needed because Rtools42 doesn't contain - # "x86_64-w64-mingw32-gcc," which `rustc` uses as the default linker - # for the `x86_64-pc-windows-gnu` target. - # - # If we use the Rtools' toolchain, the second tweak is also required. - # `rustc` adds `-lgcc_eh` and `-lgcc_s` flags to the compiler, but - # Rtools' GCC doesn't have `libgcc_eh` or `libgcc_s` due to the - # compilation settings. So, in order to please the compiler, we need - # to add empty `libgcc_eh` or `libgcc_s` to the library search paths. - # - # For more details, please refer to https://github.com/r-windows/rtools-packages/blob/2407b23f1e0925bbb20a4162c963600105236318/mingw-w64-gcc/PKGBUILD#L313-L316 - - New-Item -Path libgcc_mock -Type Directory - New-Item -Path libgcc_mock\libgcc_eh.a -Type File - New-Item -Path libgcc_mock\libgcc_s.a -Type File - - New-Item -Path .cargo -ItemType Directory -Force - $pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} - @" - [target.x86_64-pc-windows-gnu] - linker = "x86_64-w64-mingw32.static.posix-gcc.exe" - - [env] - LIBRARY_PATH = "${pwd_slash}/libgcc_mock" - "@ | Out-File -FilePath .cargo/config.toml -Encoding utf8 -Append ; - env: - RUST_TOOLCHAIN: ${{ matrix.config.rust }} + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: ${{ matrix.config.rspm || 'true' }} - name: Test crate run: | From eebc441f5ca2c49bc2676cb1e489e26f22fd200b Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Mon, 24 Feb 2025 12:03:52 -0800 Subject: [PATCH 14/20] Update test.yml --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bab798a..b75662c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,6 +41,13 @@ jobs: http-user-agent: ${{ matrix.config.http-user-agent }} use-public-rspm: ${{ matrix.config.rspm || 'true' }} + - name: Set R_HOME on Windows + if: matrix.config.os == 'windows-latest' + shell: pwsh + run: | + $rHome = & Rscript -e "cat(R.home())" + echo "R_HOME=$rHome" | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Test crate run: | cargo test -vv From a2772a302fe1fdf3aac410686b4c66325cf6d371 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 16:13:23 -0800 Subject: [PATCH 15/20] Update test.yml --- .github/workflows/test.yml | 49 ++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b75662c..ae2ec49 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,47 +6,44 @@ on: pull_request: branches: [main, master] +name: Cargo-test + jobs: - Crate-check: + Cargo-test: runs-on: ${{ matrix.config.os }} - defaults: - run: - shell: bash - - name: "${{ matrix.config.os }} (R: ${{ matrix.config.r }}, Rust: ${{ matrix.config.rust }})" - + name: Cargo-test ${{ matrix.config.os }} (${{ matrix.config.r }} - ${{ matrix.config.rust-version }}) + strategy: fail-fast: false matrix: config: - - {os: 'macos-latest', r: 'release', rust: 'stable'} - - {os: 'windows-latest', r: 'release', rust: 'stable'} - - {os: 'ubuntu-latest', r: 'release', rust: 'stable'} - - {os: 'ubuntu-latest', r: 'devel', rust: 'stable', http-user-agent: 'release'} - - {os: 'ubuntu-latest', r: 'release', rust: 'nightly'} - - {os: 'ubuntu-24.04-arm', r: 'release', rust: 'stable', rspm: 'false'} - + - {os: windows-latest, r: 'release', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu' } + - {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu' } + - {os: macOS-latest, r: 'release', rust-version: 'stable' } + - {os: ubuntu-latest, r: 'release', rust-version: 'stable' } + - {os: ubuntu-latest, r: 'devel', rust-version: 'stable' } + env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - + steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - if: matrix.config.rust == 'nightly' + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.config.rust-version }} + targets: ${{ matrix.config.rust-target }} + + - uses: baptiste0928/cargo-install@v3 + if: matrix.config.r == 'release' + with: + crate: cargo-license - uses: r-lib/actions/setup-r@v2 with: r-version: ${{ matrix.config.r }} - http-user-agent: ${{ matrix.config.http-user-agent }} - use-public-rspm: ${{ matrix.config.rspm || 'true' }} - - - name: Set R_HOME on Windows - if: matrix.config.os == 'windows-latest' - shell: pwsh - run: | - $rHome = & Rscript -e "cat(R.home())" - echo "R_HOME=$rHome" | Out-File -FilePath $env:GITHUB_ENV -Append + rtools-version: ${{ matrix.config.rtools-version }} + use-public-rspm: true - name: Test crate run: | From 1d7a5c8a7e50345ca27e69cd27b1ff48b20f024f Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 16:20:53 -0800 Subject: [PATCH 16/20] Update test.yml --- .github/workflows/test.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae2ec49..22dd5d1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,12 +6,10 @@ on: pull_request: branches: [main, master] -name: Cargo-test - jobs: - Cargo-test: + Crate-check: runs-on: ${{ matrix.config.os }} - name: Cargo-test ${{ matrix.config.os }} (${{ matrix.config.r }} - ${{ matrix.config.rust-version }}) + name: Crate-check ${{ matrix.config.os }} (${{ matrix.config.r }} - ${{ matrix.config.rust-version }}) strategy: fail-fast: false From 95ca555208786b929408ed35573fd4a59bdf3509 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 16:22:54 -0800 Subject: [PATCH 17/20] Update test.yml --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22dd5d1..6247f6e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,10 +20,10 @@ jobs: - {os: macOS-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'devel', rust-version: 'stable' } - + env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - + steps: - uses: actions/checkout@v4 From bff715c793115b996f04350ae4bb79518f0320ac Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 18:14:34 -0800 Subject: [PATCH 18/20] Update test.yml --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6247f6e..a1a89c8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,15 +15,15 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu' } - - {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu' } + - {os: windows-latest, r: 'release', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu', rtools-version: '44'} + - {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu', rtools-version: '44'} - {os: macOS-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'devel', rust-version: 'stable' } - + env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - + steps: - uses: actions/checkout@v4 From 78482a86c820feaa33fbdda6df849506f005face Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 18:15:52 -0800 Subject: [PATCH 19/20] Update test.yml --- .github/workflows/test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1a89c8..166b4b4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,10 +20,10 @@ jobs: - {os: macOS-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'devel', rust-version: 'stable' } - + env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - + steps: - uses: actions/checkout@v4 @@ -46,4 +46,3 @@ jobs: - name: Test crate run: | cargo test -vv - From 79a0a9fc65b1d8d0212a528dda2bcbc2a19f4804 Mon Sep 17 00:00:00 2001 From: Balasubramanian Narasimhan Date: Tue, 4 Mar 2025 18:41:22 -0800 Subject: [PATCH 20/20] Switched back to ci-cargo for workflow --- .github/workflows/test.yml | 115 +++++++++++++++++++++++++++++++------ ci-cargo.ps1 | 17 +++--- 2 files changed, 107 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 166b4b4..5555ac9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,34 +15,117 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: 'release', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu', rtools-version: '44'} - - {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', rust-target: 'x86_64-pc-windows-gnu', rtools-version: '44'} + - {os: windows-latest, r: 'release', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', rtools-version: '44'} + - {os: windows-latest, r: 'devel', rust-version: 'stable-msvc', target: 'x86_64-pc-windows-gnu', rtools-version: '44'} - {os: macOS-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'release', rust-version: 'stable' } - {os: ubuntu-latest, r: 'devel', rust-version: 'stable' } env: + RSPM: ${{ matrix.config.rspm }} GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - + + # PowerShell core is available on all platforms and can be used to unify scripts + defaults: + run: + shell: pwsh + steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master + - name: Set up R + uses: r-lib/actions/setup-r@v2 with: - toolchain: ${{ matrix.config.rust-version }} - targets: ${{ matrix.config.rust-target }} + r-version: ${{ matrix.config.r }} + use-public-rspm: true + rtools-version: ${{ matrix.config.rtools-version }} - - uses: baptiste0928/cargo-install@v3 - if: matrix.config.r == 'release' + - name: Set up Rust + uses: dtolnay/rust-toolchain@master with: - crate: cargo-license + toolchain: ${{ matrix.config.rust-version }} + components: rustfmt, clippy + targets: ${{ matrix.config.target }} - - uses: r-lib/actions/setup-r@v2 - with: - r-version: ${{ matrix.config.r }} - rtools-version: ${{ matrix.config.rtools-version }} - use-public-rspm: true + # Stuff here lifted from libR-sys workflows with thanks to authors. + # All configurations for Windows go here + # 1. Configure linker + # 2. Create libgcc_eh mock + # 3. Add R bin path to PATH + # 4. Add Rtools' GCC to PATH (required to find linker) + # 5. Add include path (required to resolve standard headers like stdio.h) + - name: Configure Windows + if: runner.os == 'Windows' + run: | + # Configure linker + echo "RUSTFLAGS=-C linker=x86_64-w64-mingw32.static.posix-gcc.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + # Create libgcc_eh mock + New-Item -Path libgcc_mock -Type Directory + New-Item -Path libgcc_mock\libgcc_eh.a -Type File + New-Item -Path libgcc_mock\libgcc_s.a -Type File + $pwd_slash = echo "${PWD}" | % {$_ -replace '\\','/'} + echo "LIBRARY_PATH=${pwd_slash}/libgcc_mock" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + # Add R bin path to PATH + echo "$(Rscript.exe -e 'cat(normalizePath(R.home()))')\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ; + + # Add Rtools' GCC to PATH + if ($env:RTOOLS_VERSION -eq '44') { + $mingw_root = "C:\rtools44\x86_64-w64-mingw32.static.posix" + } elseif ($env:RTOOLS_VERSION -eq '43') { + $mingw_root = "C:\rtools43\x86_64-w64-mingw32.static.posix" + } elseif ($env:RTOOLS_VERSION -eq '42') { + $mingw_root = "C:\rtools42\x86_64-w64-mingw32.static.posix" + } + echo "$mingw_root\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + # Add include path + echo "LIBRSYS_LIBCLANG_INCLUDE_PATH=$mingw_root\include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + env: + RUST_TARGET: ${{ matrix.config.target }} + RTOOLS_VERSION: ${{ matrix.config.rtools-version }} + + + # macOS configurations, mainly llvm and path to libclang + # Because of this R installation issue on macOS-11.0 + # https://github.com/r-lib/actions/issues/200 + # Symlinks to R/Rscript are not properly set up, so we do it by hand, using this trick + # https://github.com/r-lib/ps/commit/a24f2c4d1bdba63be14e7729b9ab81d0ed9f719e + # Environment variables are required fir Mac-OS-11.0, see + # https://github.com/extendr/libR-sys/issues/35 + - name: Configure macOS + if: runner.os == 'macOS' + run: | + brew install llvm + echo "LIBCLANG_PATH=$(brew --prefix llvm)/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + $env:LLVM_CONFIG_PATH = "$(brew --prefix llvm)/bin/llvm-config" + echo "LLVM_CONFIG_PATH=$env:LLVM_CONFIG_PATH" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "LIBRSYS_LIBCLANG_INCLUDE_PATH=$(. $env:LLVM_CONFIG_PATH --libdir)/clang/$(. $env:LLVM_CONFIG_PATH --version)/include" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + if ((Get-ChildItem -Path /usr/local/bin -Filter R | Measure-Object).Count -eq 0) { + echo "::warning:: Found no R symlink in /usr/local/bin, setting up manually..." + ln -s /Library/Frameworks/R.framework/Versions/Current/Resources/bin/R /usr/local/bin/ + } + if ((Get-ChildItem -Path /usr/local/bin -Filter Rscript | Measure-Object).Count -eq 0) { + echo "::warning:: Found no Rscript symlink in /usr/local/bin, setting up manually..." + ln -s /Library/Frameworks/R.framework/Versions/Current/Resources/bin/Rscript /usr/local/bin/ + } + + # This is required for ubuntu r-devel + # 'Del alias:R' removes R alias which prevents running R + - name: Configure Linux + if: runner.os == 'linux' + run: | + Del alias:R + echo "LD_LIBRARY_PATH=$(R -s -e 'cat(normalizePath(R.home()))')/lib" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + env: + RUST_TARGET: ${{ matrix.config.target }} - - name: Test crate + - name: Run test run: | - cargo test -vv + . ./ci-cargo.ps1 + ci-cargo test -vv + env: + RUST_TARGET: ${{ matrix.config.target }} diff --git a/ci-cargo.ps1 b/ci-cargo.ps1 index 71cc007..0e5adfd 100644 --- a/ci-cargo.ps1 +++ b/ci-cargo.ps1 @@ -9,12 +9,11 @@ function ci-cargo { ) - try { - Write-Output "::group::$ActionName" - $CargoArgs = $CargoArgs | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } - Write-Output "Running cargo $CargoArgs" + try { + echo "::group::$ActionName" + echo "Running cargo $CargoArgs" cargo $CargoArgs - if ($LASTEXITCODE -ne 0) { + if($LASTEXITCODE -ne 0) { throw $LASTEXITCODE } } @@ -22,12 +21,12 @@ function ci-cargo { if ($ActionName -ne $null -and $ActionName -ne "") { $ActionName = "'$ActionName': " } - $errMsg = "$($ActionName)cargo failed with code $LASTEXITCODE (args: $CargoArgs)" - Write-Output "::error::$errMsg" - Write-Error -Message "$errMsg" -ErrorAction Stop + $err_msg = "$($ActionName)cargo failed with code $LASTEXITCODE (args: $CargoArgs)" + echo "::error::$err_msg" + Write-Error -Message "$err_msg" -ErrorAction Stop } finally { - Write-Output "::endgroup::" + echo "::endgroup::" } <#