Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
431b3c3
transpile: store `const GENERATED_RUST_TOOLCHAIN_TOML: &str` from `ge…
kkysen Nov 3, 2025
b60012a
transpile: parse `const GENERATED_RUST_TOOLCHAIN: &str` from `GENERAT…
kkysen Nov 3, 2025
b57f81f
transpile: tests: use `-fsyntax-only` instead of `-c -o /dev/null`
kkysen Nov 2, 2025
a67bffd
ci: install `zig` for `zig cc` for cross compilation
kkysen Nov 3, 2025
31309e8
transpile: tests: use `zig cc -###` to look up cross-compilation args
kkysen Nov 3, 2025
38616fd
transpile: tests: find `TargetArgs` for all `Target`s
kkysen Nov 3, 2025
e39fef8
transpile: tests: make `fn transpile` a method on `struct TargetArgs`
kkysen Nov 3, 2025
e76b287
transpile: tests: transpile snapshots on all targets
kkysen Nov 3, 2025
82a1c88
transpile: tests: first check if all `rustup target`s are installed
kkysen Nov 3, 2025
30365e6
transpile: tests: print which file we're transpiling to which target
kkysen Nov 3, 2025
88ac507
transpile: tests: switch from zig target to rust target for clang target
kkysen Nov 3, 2025
94ea66d
transpile: tests: make `AllTargetsArgs` take an explicit list of targ…
kkysen Nov 3, 2025
ac4c362
transpile: tests: rename `AllTargetArgs` to `Targets` since it's no l…
kkysen Nov 3, 2025
ab1e005
transpile: tests: add `x86` and `arm` `linux` targets, but don't test…
kkysen Nov 3, 2025
b030af3
transpile: tests: add `riscv64` target, but don't test it yet (riscv …
kkysen Nov 3, 2025
a16922c
transpile: tests: use `""` instead of `None` for `platform`
kkysen Nov 3, 2025
76dc388
transpile: tests: change `fn Targets::transpile`'s `platform` to `Int…
kkysen Nov 3, 2025
03948fc
transpile: tests: enable `x86` and `arm` snapshots
kkysen Nov 3, 2025
b2ff814
transpile: tests: combine all the `insta::glob!`s so that we can remo…
kkysen Nov 3, 2025
8d4c925
ci: remove extra newline
kkysen Nov 3, 2025
559f83a
ci: make sure `python 3.14` is used to ensure a stable version
kkysen Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,17 @@ jobs:

- name: Install Python Packages
run: |
uv python install 3.14
uv run python -V

uv venv
uv pip install -r ./scripts/requirements.txt

# `zig cc` needed for cross-compilation
uv tool install ziglang
ln -s $(which python-zig) $(dirname $(which python-zig))/zig
zig version

# rust-cache very carefully caches toolchains and target directories,
# based on the job and toolchain and other factors. See
# https://github.com/Swatinem/rust-cache#cache-details for what gets
Expand All @@ -47,6 +55,17 @@ jobs:
# Run after `rust-cache` so that this is cached.
- run: rustup component add rustfmt rustc-dev

- name: Install generated Rust targets
run: |
rustup +nightly-2023-04-15 target add \
x86_64-unknown-linux-gnu \
x86_64-apple-darwin \
aarch64-unknown-linux-gnu \
aarch64-apple-darwin \
i686-unknown-linux-gnu \
armv7-unknown-linux-gnueabihf \
riscv64gc-unknown-linux-gnu

- name: cargo fmt --check
run: |
export RUSTFLAGS="$RUSTFLAGS -D warnings"
Expand Down Expand Up @@ -98,7 +117,6 @@ jobs:
# It's important that we keep `RUSTFLAGS` consistent between different steps
# so that we don't have to rebuild everything.
echo "RUSTFLAGS=-Clink-arg=-L/opt/homebrew/lib -Clink-arg=-Wl,-rpath,/opt/homebrew/lib" >> $GITHUB_ENV


- name: cargo build --release
run: |
Expand Down
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions c2rust-transpile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ llvm-static = ["c2rust-ast-exporter/llvm-static"]

[dev-dependencies]
insta = { version = "1.43.2", features = ["glob"] }
shell-words = "1.1.0"
68 changes: 61 additions & 7 deletions c2rust-transpile/src/build_files/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::collections::BTreeMap;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::slice;
use std::str::{from_utf8, FromStr};

use handlebars::Handlebars;
use pathdiff::diff_paths;
Expand Down Expand Up @@ -225,7 +226,7 @@ fn emit_build_rs(
});
let output = reg.render("build.rs", &json).unwrap();
let output_path = build_dir.join("build.rs");
maybe_write_to_file(&output_path, output, tcfg.overwrite_existing)
maybe_write_to_file(&output_path, &output, tcfg.overwrite_existing)
}

/// Emit lib.rs (main.rs) for a library (binary). Returns `Some(path)`
Expand Down Expand Up @@ -253,15 +254,68 @@ fn emit_lib_rs(
let output_path = build_dir.join(file_name);
let output = reg.render("lib.rs", &json).unwrap();

maybe_write_to_file(&output_path, output, tcfg.overwrite_existing)
maybe_write_to_file(&output_path, &output, tcfg.overwrite_existing)
}

pub const GENERATED_RUST_TOOLCHAIN_TOML: &str = include_str!("generated-rust-toolchain.toml");
pub const GENERATED_RUST_TOOLCHAIN: &str = {
const fn find_substring(s: &str, sub: &str, start: usize) -> usize {
let s = s.as_bytes();
let sub = sub.as_bytes();
assert!(sub.len() + start <= s.len());
let n = s.len() - sub.len();
let mut i = start;
while i < n {
let mut j = 0;
let mut eq = true;
while j < sub.len() {
if s[i + j] != sub[j] {
eq = false;
break;
}
j += 1;
}
if eq {
return i;
}
i += 1;
}
assert!(false);
return 0;
}

let toml = GENERATED_RUST_TOOLCHAIN_TOML;
let prefix = "\nchannel = \"";
let suffix = "\"";
let prefix_start = find_substring(toml, prefix, 0);
let start = prefix_start + prefix.len();
let end = find_substring(toml, suffix, start);

let toml = toml.as_bytes();
let len = end - start;
assert!(start + len <= toml.len());
// `const` slicing.
// SAFETY: Above `assert!`.
let toolchain = unsafe {
let ptr = toml.as_ptr().add(start);
slice::from_raw_parts(ptr, len)
};
let toolchain = match from_utf8(toolchain) {
Ok(toolchain) => toolchain,
Err(_) => panic!(),
};
toolchain
};

/// If we translate variadic functions, the output will only compile
/// on a nightly toolchain until the `c_variadics` feature is stable.
fn emit_rust_toolchain(tcfg: &TranspilerConfig, build_dir: &Path) {
let output_path = build_dir.join("rust-toolchain.toml");
let output = include_str!("generated-rust-toolchain.toml").to_string();
maybe_write_to_file(&output_path, output, tcfg.overwrite_existing);
maybe_write_to_file(
&output_path,
GENERATED_RUST_TOOLCHAIN_TOML,
tcfg.overwrite_existing,
);
}

fn emit_cargo_toml<'lcmd>(
Expand Down Expand Up @@ -306,10 +360,10 @@ fn emit_cargo_toml<'lcmd>(
let file_name = "Cargo.toml";
let output_path = build_dir.join(file_name);
let output = reg.render(file_name, &json).unwrap();
maybe_write_to_file(&output_path, output, tcfg.overwrite_existing);
maybe_write_to_file(&output_path, &output, tcfg.overwrite_existing);
}

fn maybe_write_to_file(output_path: &Path, output: String, overwrite: bool) -> Option<PathBuf> {
fn maybe_write_to_file(output_path: &Path, output: &str, overwrite: bool) -> Option<PathBuf> {
if output_path.exists() && !overwrite {
eprintln!("Skipping existing file {}", output_path.display());
return None;
Expand Down
8 changes: 4 additions & 4 deletions c2rust-transpile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ use regex::Regex;
use serde_derive::Serialize;
pub use tempfile::TempDir;

use crate::build_files::{emit_build_files, get_build_dir, CrateConfig};
pub use crate::build_files::{GENERATED_RUST_TOOLCHAIN, GENERATED_RUST_TOOLCHAIN_TOML};
use crate::c_ast::Printer;
use crate::c_ast::*;
pub use crate::diagnostics::Diagnostic;
use c2rust_ast_exporter as ast_exporter;

use crate::build_files::{emit_build_files, get_build_dir, CrateConfig};
use crate::compile_cmds::get_compile_commands;
use crate::convert_type::RESERVED_NAMES;
pub use crate::diagnostics::Diagnostic;
pub use crate::translator::ReplaceMode;
use c2rust_ast_exporter as ast_exporter;
use std::prelude::v1::Vec;

type PragmaVec = Vec<(&'static str, Vec<&'static str>)>;
Expand Down
Loading
Loading