mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 15:03:46 +00:00
split up bitcode building to reduce dependency chains
This commit is contained in:
parent
24c7bded35
commit
d5e191d083
18 changed files with 418 additions and 140 deletions
|
@ -16,11 +16,3 @@ roc_utils = { path = "../../utils" }
|
|||
|
||||
tempfile.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
roc_utils = { path = "../../utils" }
|
||||
|
||||
# dunce can be removed once ziglang/zig#5109 is fixed
|
||||
dunce = "1.0.3"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.build-dependencies]
|
||||
tempfile.workspace = true
|
||||
|
|
18
crates/compiler/builtins/bitcode/Cargo.toml
Normal file
18
crates/compiler/builtins/bitcode/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "roc_bitcode"
|
||||
description = "Compiles the zig bitcode to `.o` for builtins"
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tempfile.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
# dunce can be removed once ziglang/zig#5109 is fixed
|
||||
dunce = "1.0.3"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.build-dependencies]
|
||||
tempfile.workspace = true
|
15
crates/compiler/builtins/bitcode/bc/Cargo.toml
Normal file
15
crates/compiler/builtins/bitcode/bc/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "roc_bitcode_bc"
|
||||
description = "Compiles the zig bitcode to `.bc` for llvm"
|
||||
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
# dunce can be removed once ziglang/zig#5109 is fixed
|
||||
dunce = "1.0.3"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.build-dependencies]
|
||||
tempfile.workspace = true
|
217
crates/compiler/builtins/bitcode/bc/build.rs
Normal file
217
crates/compiler/builtins/bitcode/bc/build.rs
Normal file
|
@ -0,0 +1,217 @@
|
|||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
use std::{
|
||||
env::{self, VarError},
|
||||
path::PathBuf,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use tempfile::tempdir;
|
||||
|
||||
/// To debug the zig code with debug prints, we need to disable the wasm code gen
|
||||
const DEBUG: bool = false;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
// "." is relative to where "build.rs" is
|
||||
// dunce can be removed once ziglang/zig#5109 is fixed
|
||||
let bitcode_path = dunce::canonicalize(Path::new(".")).unwrap().join("..");
|
||||
|
||||
// workaround for github.com/ziglang/zig/issues/9711
|
||||
#[cfg(target_os = "macos")]
|
||||
let zig_cache_dir = tempdir().expect("Failed to create temp directory for zig cache");
|
||||
#[cfg(target_os = "macos")]
|
||||
std::env::set_var("ZIG_GLOBAL_CACHE_DIR", zig_cache_dir.path().as_os_str());
|
||||
|
||||
// LLVM .bc FILES
|
||||
|
||||
generate_bc_file(&bitcode_path, "ir", "builtins-host");
|
||||
|
||||
if !DEBUG {
|
||||
generate_bc_file(&bitcode_path, "ir-wasm32", "builtins-wasm32");
|
||||
}
|
||||
|
||||
generate_bc_file(&bitcode_path, "ir-i386", "builtins-i386");
|
||||
generate_bc_file(&bitcode_path, "ir-x86_64", "builtins-x86_64");
|
||||
generate_bc_file(
|
||||
&bitcode_path,
|
||||
"ir-windows-x86_64",
|
||||
"builtins-windows-x86_64",
|
||||
);
|
||||
|
||||
get_zig_files(bitcode_path.as_path(), &|path| {
|
||||
let path: &Path = path;
|
||||
println!(
|
||||
"cargo:rerun-if-changed={}",
|
||||
path.to_str().expect("Failed to convert path to str")
|
||||
);
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
zig_cache_dir
|
||||
.close()
|
||||
.expect("Failed to delete temp dir zig_cache_dir.");
|
||||
}
|
||||
|
||||
fn generate_bc_file(bitcode_path: &Path, zig_object: &str, file_name: &str) {
|
||||
let mut ll_path = bitcode_path.join(file_name);
|
||||
ll_path.set_extension("ll");
|
||||
let dest_ir_host = ll_path.to_str().expect("Invalid dest ir path");
|
||||
|
||||
println!("Compiling host ir to: {}", dest_ir_host);
|
||||
|
||||
let mut bc_path = bitcode_path.join(file_name);
|
||||
bc_path.set_extension("bc");
|
||||
let dest_bc_64bit = bc_path.to_str().expect("Invalid dest bc path");
|
||||
println!("Compiling 64-bit bitcode to: {}", dest_bc_64bit);
|
||||
|
||||
// workaround for github.com/ziglang/zig/issues/9711
|
||||
#[cfg(target_os = "macos")]
|
||||
let _ = fs::remove_dir_all("./zig-cache");
|
||||
|
||||
let mut zig_cmd = zig();
|
||||
|
||||
zig_cmd
|
||||
.current_dir(bitcode_path)
|
||||
.args(["build", zig_object, "-Drelease=true"]);
|
||||
|
||||
run_command(zig_cmd, 0);
|
||||
}
|
||||
|
||||
pub fn get_lib_dir() -> PathBuf {
|
||||
// Currently we have the OUT_DIR variable which points to `/target/debug/build/roc_builtins-*/out/`.
|
||||
// So we just need to add "/bitcode" to that.
|
||||
let dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
|
||||
// create dir if it does not exist
|
||||
fs::create_dir_all(&dir).expect("Failed to make $OUT_DIR/ dir.");
|
||||
|
||||
dir
|
||||
}
|
||||
|
||||
fn run_command(mut command: Command, flaky_fail_counter: usize) {
|
||||
let command_str = pretty_command_string(&command);
|
||||
let command_str = command_str.to_string_lossy();
|
||||
|
||||
let output_result = command.output();
|
||||
|
||||
match output_result {
|
||||
Ok(output) => match output.status.success() {
|
||||
true => (),
|
||||
false => {
|
||||
let error_str = match str::from_utf8(&output.stderr) {
|
||||
Ok(stderr) => stderr.to_string(),
|
||||
Err(_) => format!("Failed to run \"{}\"", command_str),
|
||||
};
|
||||
|
||||
// Flaky test errors that only occur sometimes on MacOS ci server.
|
||||
if error_str.contains("FileNotFound")
|
||||
|| error_str.contains("unable to save cached ZIR code")
|
||||
|| error_str.contains("LLVM failed to emit asm")
|
||||
{
|
||||
if flaky_fail_counter == 10 {
|
||||
panic!("{} failed 10 times in a row. The following error is unlikely to be a flaky error: {}", command_str, error_str);
|
||||
} else {
|
||||
run_command(command, flaky_fail_counter + 1)
|
||||
}
|
||||
} else if error_str
|
||||
.contains("lld-link: error: failed to write the output file: Permission denied")
|
||||
{
|
||||
panic!("{} failed with:\n\n {}\n\nWorkaround:\n\n Re-run the cargo command that triggered this build.\n\n", command_str, error_str);
|
||||
} else {
|
||||
panic!("{} failed with:\n\n {}\n", command_str, error_str);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(reason) => panic!("{} failed: {}", command_str, reason),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_zig_files(dir: &Path, cb: &dyn Fn(&Path)) -> io::Result<()> {
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path_buf = entry.path();
|
||||
if path_buf.is_dir() {
|
||||
if !path_buf.ends_with("zig-cache") {
|
||||
get_zig_files(&path_buf, cb).unwrap();
|
||||
}
|
||||
} else {
|
||||
let path = path_buf.as_path();
|
||||
|
||||
match path.extension() {
|
||||
Some(osstr) if osstr == "zig" => {
|
||||
cb(path);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gives a friendly error if zig is not installed.
|
||||
/// Also makes it easy to track where we use zig in the codebase.
|
||||
pub fn zig() -> Command {
|
||||
let command_str = match std::env::var("ROC_ZIG") {
|
||||
Ok(path) => path,
|
||||
Err(_) => "zig".into(),
|
||||
};
|
||||
|
||||
if check_command_available(&command_str) {
|
||||
Command::new(command_str)
|
||||
} else {
|
||||
panic!("I could not find the zig command.\nPlease install zig, see instructions at https://ziglang.org/learn/getting-started/.",)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_command_available(command_name: &str) -> bool {
|
||||
if cfg!(target_family = "unix") {
|
||||
let unparsed_path = match std::env::var("PATH") {
|
||||
Ok(var) => var,
|
||||
Err(VarError::NotPresent) => return false,
|
||||
Err(VarError::NotUnicode(_)) => {
|
||||
panic!("found PATH, but it included invalid unicode data!")
|
||||
}
|
||||
};
|
||||
|
||||
std::env::split_paths(&unparsed_path).any(|dir| dir.join(command_name).exists())
|
||||
} else if cfg!(target = "windows") {
|
||||
let mut cmd = Command::new("Get-Command");
|
||||
|
||||
cmd.args([command_name]);
|
||||
|
||||
let cmd_str = format!("{:?}", cmd);
|
||||
|
||||
let cmd_out = cmd.output().unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Failed to execute `{}` to check if {} is available:\n {}",
|
||||
cmd_str, command_name, err
|
||||
)
|
||||
});
|
||||
|
||||
cmd_out.status.success()
|
||||
} else {
|
||||
// We're in uncharted waters, best not to panic if
|
||||
// things may end up working out down the line.
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pretty_command_string(command: &Command) -> std::ffi::OsString {
|
||||
let mut command_string = std::ffi::OsString::new();
|
||||
command_string.push(command.get_program());
|
||||
|
||||
for arg in command.get_args() {
|
||||
command_string.push(" ");
|
||||
command_string.push(arg);
|
||||
}
|
||||
|
||||
command_string
|
||||
}
|
0
crates/compiler/builtins/bitcode/bc/src/lib.rs
Normal file
0
crates/compiler/builtins/bitcode/bc/src/lib.rs
Normal file
|
@ -1,11 +1,12 @@
|
|||
use roc_utils::zig;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
use std::{
|
||||
env::{self, VarError},
|
||||
path::PathBuf,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use tempfile::tempdir;
|
||||
|
@ -18,8 +19,7 @@ fn main() {
|
|||
|
||||
// "." is relative to where "build.rs" is
|
||||
// dunce can be removed once ziglang/zig#5109 is fixed
|
||||
let build_script_dir_path = dunce::canonicalize(Path::new(".")).unwrap();
|
||||
let bitcode_path = build_script_dir_path.join("bitcode");
|
||||
let bitcode_path = dunce::canonicalize(Path::new(".")).unwrap();
|
||||
|
||||
// workaround for github.com/ziglang/zig/issues/9711
|
||||
#[cfg(target_os = "macos")]
|
||||
|
@ -27,22 +27,6 @@ fn main() {
|
|||
#[cfg(target_os = "macos")]
|
||||
std::env::set_var("ZIG_GLOBAL_CACHE_DIR", zig_cache_dir.path().as_os_str());
|
||||
|
||||
// LLVM .bc FILES
|
||||
|
||||
generate_bc_file(&bitcode_path, "ir", "builtins-host");
|
||||
|
||||
if !DEBUG {
|
||||
generate_bc_file(&bitcode_path, "ir-wasm32", "builtins-wasm32");
|
||||
}
|
||||
|
||||
generate_bc_file(&bitcode_path, "ir-i386", "builtins-i386");
|
||||
generate_bc_file(&bitcode_path, "ir-x86_64", "builtins-x86_64");
|
||||
generate_bc_file(
|
||||
&bitcode_path,
|
||||
"ir-windows-x86_64",
|
||||
"builtins-windows-x86_64",
|
||||
);
|
||||
|
||||
// OBJECT FILES
|
||||
#[cfg(windows)]
|
||||
const BUILTINS_HOST_FILE: &str = "builtins-host.obj";
|
||||
|
@ -107,38 +91,13 @@ fn generate_object_file(bitcode_path: &Path, zig_object: &str, object_file_name:
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_bc_file(bitcode_path: &Path, zig_object: &str, file_name: &str) {
|
||||
let mut ll_path = bitcode_path.join(file_name);
|
||||
ll_path.set_extension("ll");
|
||||
let dest_ir_host = ll_path.to_str().expect("Invalid dest ir path");
|
||||
|
||||
println!("Compiling host ir to: {}", dest_ir_host);
|
||||
|
||||
let mut bc_path = bitcode_path.join(file_name);
|
||||
bc_path.set_extension("bc");
|
||||
let dest_bc_64bit = bc_path.to_str().expect("Invalid dest bc path");
|
||||
println!("Compiling 64-bit bitcode to: {}", dest_bc_64bit);
|
||||
|
||||
// workaround for github.com/ziglang/zig/issues/9711
|
||||
#[cfg(target_os = "macos")]
|
||||
let _ = fs::remove_dir_all("./bitcode/zig-cache");
|
||||
|
||||
let mut zig_cmd = zig();
|
||||
|
||||
zig_cmd
|
||||
.current_dir(bitcode_path)
|
||||
.args(["build", zig_object, "-Drelease=true"]);
|
||||
|
||||
run_command(zig_cmd, 0);
|
||||
}
|
||||
|
||||
pub fn get_lib_dir() -> PathBuf {
|
||||
// Currently we have the OUT_DIR variable which points to `/target/debug/build/roc_builtins-*/out/`.
|
||||
// So we just need to add "/bitcode" to that.
|
||||
let dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("bitcode");
|
||||
let dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
|
||||
// create dir if it does not exist
|
||||
fs::create_dir_all(&dir).expect("Failed to make $OUT_DIR/bitcode dir.");
|
||||
fs::create_dir_all(&dir).expect("Failed to make $OUT_DIR/ dir.");
|
||||
|
||||
dir
|
||||
}
|
||||
|
@ -192,7 +151,7 @@ fn cp_unless_zig_cache(src_dir: &Path, target_dir: &Path) -> io::Result<()> {
|
|||
}
|
||||
|
||||
fn run_command(mut command: Command, flaky_fail_counter: usize) {
|
||||
let command_str = roc_utils::pretty_command_string(&command);
|
||||
let command_str = pretty_command_string(&command);
|
||||
let command_str = command_str.to_string_lossy();
|
||||
|
||||
let output_result = command.output();
|
||||
|
@ -252,3 +211,63 @@ fn get_zig_files(dir: &Path, cb: &dyn Fn(&Path)) -> io::Result<()> {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Gives a friendly error if zig is not installed.
|
||||
/// Also makes it easy to track where we use zig in the codebase.
|
||||
pub fn zig() -> Command {
|
||||
let command_str = match std::env::var("ROC_ZIG") {
|
||||
Ok(path) => path,
|
||||
Err(_) => "zig".into(),
|
||||
};
|
||||
|
||||
if check_command_available(&command_str) {
|
||||
Command::new(command_str)
|
||||
} else {
|
||||
panic!("I could not find the zig command.\nPlease install zig, see instructions at https://ziglang.org/learn/getting-started/.",)
|
||||
}
|
||||
}
|
||||
|
||||
fn check_command_available(command_name: &str) -> bool {
|
||||
if cfg!(target_family = "unix") {
|
||||
let unparsed_path = match std::env::var("PATH") {
|
||||
Ok(var) => var,
|
||||
Err(VarError::NotPresent) => return false,
|
||||
Err(VarError::NotUnicode(_)) => {
|
||||
panic!("found PATH, but it included invalid unicode data!")
|
||||
}
|
||||
};
|
||||
|
||||
std::env::split_paths(&unparsed_path).any(|dir| dir.join(command_name).exists())
|
||||
} else if cfg!(target = "windows") {
|
||||
let mut cmd = Command::new("Get-Command");
|
||||
|
||||
cmd.args([command_name]);
|
||||
|
||||
let cmd_str = format!("{:?}", cmd);
|
||||
|
||||
let cmd_out = cmd.output().unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Failed to execute `{}` to check if {} is available:\n {}",
|
||||
cmd_str, command_name, err
|
||||
)
|
||||
});
|
||||
|
||||
cmd_out.status.success()
|
||||
} else {
|
||||
// We're in uncharted waters, best not to panic if
|
||||
// things may end up working out down the line.
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pretty_command_string(command: &Command) -> std::ffi::OsString {
|
||||
let mut command_string = std::ffi::OsString::new();
|
||||
command_string.push(command.get_program());
|
||||
|
||||
for arg in command.get_args() {
|
||||
command_string.push(" ");
|
||||
command_string.push(arg);
|
||||
}
|
||||
|
||||
command_string
|
||||
}
|
65
crates/compiler/builtins/bitcode/src/lib.rs
Normal file
65
crates/compiler/builtins/bitcode/src/lib.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use tempfile::NamedTempFile;
|
||||
|
||||
const HOST_WASM: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/builtins-wasm32.o"));
|
||||
// TODO: in the future, we should use Zig's cross-compilation to generate and store these
|
||||
// for all targets, so that we can do cross-compilation!
|
||||
#[cfg(unix)]
|
||||
const HOST_UNIX: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/builtins-host.o"));
|
||||
#[cfg(windows)]
|
||||
const HOST_WINDOWS: &[u8] =
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/builtins-windows-x86_64.obj"));
|
||||
|
||||
pub fn host_wasm_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".wasm")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_WASM)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn host_unix_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".o")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_UNIX)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn host_windows_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".obj")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_WINDOWS)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
pub fn host_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
host_unix_tempfile()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
host_windows_tempfile()
|
||||
}
|
||||
|
||||
#[cfg(not(any(windows, unix)))]
|
||||
{
|
||||
unreachable!()
|
||||
}
|
||||
}
|
|
@ -1,73 +1,6 @@
|
|||
use roc_module::symbol::Symbol;
|
||||
use roc_target::TargetInfo;
|
||||
use std::ops::Index;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
pub const HOST_WASM: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/bitcode/builtins-wasm32.o"));
|
||||
// TODO: in the future, we should use Zig's cross-compilation to generate and store these
|
||||
// for all targets, so that we can do cross-compilation!
|
||||
#[cfg(unix)]
|
||||
pub const HOST_UNIX: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/bitcode/builtins-host.o"));
|
||||
#[cfg(windows)]
|
||||
pub const HOST_WINDOWS: &[u8] = include_bytes!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
"/bitcode/builtins-windows-x86_64.obj"
|
||||
));
|
||||
|
||||
pub fn host_wasm_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".wasm")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_WASM)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn host_unix_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".o")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_UNIX)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn host_windows_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
let tempfile = tempfile::Builder::new()
|
||||
.prefix("host_bitcode")
|
||||
.suffix(".obj")
|
||||
.rand_bytes(8)
|
||||
.tempfile()?;
|
||||
|
||||
std::fs::write(tempfile.path(), HOST_WINDOWS)?;
|
||||
|
||||
Ok(tempfile)
|
||||
}
|
||||
|
||||
pub fn host_tempfile() -> std::io::Result<NamedTempFile> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
host_unix_tempfile()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
host_windows_tempfile()
|
||||
}
|
||||
|
||||
#[cfg(not(any(windows, unix)))]
|
||||
{
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Copy, Clone)]
|
||||
pub struct IntrinsicName {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue