mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Use roc_target over target_lexicon
Tailors a target class for our needs. Replaces tons of uses across the entire compiler. This is a base for later adding new targets like thumb.
This commit is contained in:
parent
185262510c
commit
6dc5bfb1b7
72 changed files with 1008 additions and 1371 deletions
|
@ -17,7 +17,7 @@ use roc_reporting::{
|
|||
cli::{report_problems, Problems},
|
||||
report::{RenderTarget, DEFAULT_PALETTE},
|
||||
};
|
||||
use roc_target::{OperatingSystem, TargetInfo};
|
||||
use roc_target::{Architecture, Target};
|
||||
use std::ffi::OsStr;
|
||||
use std::ops::Deref;
|
||||
use std::{
|
||||
|
@ -25,7 +25,6 @@ use std::{
|
|||
thread::JoinHandle,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
#[cfg(feature = "target-wasm32")]
|
||||
use roc_collections::all::MutSet;
|
||||
|
@ -96,7 +95,7 @@ pub fn gen_from_mono_module<'a>(
|
|||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
code_gen_options: CodeGenOptions,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
|
@ -146,7 +145,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
opt_level: OptLevel,
|
||||
backend_mode: LlvmBackendMode,
|
||||
emit_debug_info: bool,
|
||||
|
@ -162,7 +161,6 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
let all_code_gen_start = Instant::now();
|
||||
|
||||
// Generate the binary
|
||||
let target_info = roc_target::TargetInfo::from(target);
|
||||
let context = Context::create();
|
||||
let module = arena.alloc(module_from_builtins(target, &context, "app"));
|
||||
|
||||
|
@ -210,7 +208,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
context: &context,
|
||||
interns: loaded.interns,
|
||||
module,
|
||||
target_info,
|
||||
target,
|
||||
mode: backend_mode,
|
||||
|
||||
exposed_to_host: loaded
|
||||
|
@ -387,9 +385,8 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
}
|
||||
|
||||
// Emit the .o file
|
||||
use target_lexicon::Architecture;
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::X86_32(_) | Architecture::Aarch64(_) => {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::X86_32 | Architecture::Aarch64 => {
|
||||
let reloc = RelocMode::PIC;
|
||||
let target_machine =
|
||||
target::target_machine(target, convert_opt_level(opt_level), reloc).unwrap();
|
||||
|
@ -405,7 +402,7 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
}
|
||||
_ => internal_error!(
|
||||
"TODO gracefully handle unsupported architecture: {:?}",
|
||||
target.architecture
|
||||
target.architecture()
|
||||
),
|
||||
}
|
||||
};
|
||||
|
@ -432,21 +429,19 @@ fn gen_from_mono_module_llvm<'a>(
|
|||
fn gen_from_mono_module_dev<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
match target.architecture() {
|
||||
Architecture::Wasm32 => gen_from_mono_module_dev_wasm32(
|
||||
arena,
|
||||
loaded,
|
||||
preprocessed_host_path,
|
||||
wasm_dev_stack_bytes,
|
||||
),
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
Architecture::X86_64 | Architecture::Aarch64 => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, backend_mode)
|
||||
}
|
||||
_ => todo!(),
|
||||
|
@ -457,15 +452,13 @@ fn gen_from_mono_module_dev<'a>(
|
|||
pub fn gen_from_mono_module_dev<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
_host_input_path: &Path,
|
||||
_wasm_dev_stack_bytes: Option<u32>,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
match target.architecture() {
|
||||
Architecture::X86_64 | Architecture::Aarch64 => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, backend_mode)
|
||||
}
|
||||
_ => todo!(),
|
||||
|
@ -549,7 +542,7 @@ fn gen_from_mono_module_dev_wasm32<'a>(
|
|||
fn gen_from_mono_module_dev_assembly<'a>(
|
||||
arena: &'a bumpalo::Bump,
|
||||
loaded: MonomorphizedModule<'a>,
|
||||
target: &target_lexicon::Triple,
|
||||
target: Target,
|
||||
backend_mode: AssemblyBackendMode,
|
||||
) -> GenFromMono<'a> {
|
||||
let all_code_gen_start = Instant::now();
|
||||
|
@ -694,12 +687,10 @@ pub fn handle_loading_problem(problem: LoadingProblem) -> std::io::Result<i32> {
|
|||
}
|
||||
|
||||
pub fn standard_load_config(
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
order: BuildOrdering,
|
||||
threading: Threading,
|
||||
) -> LoadConfig {
|
||||
let target_info = TargetInfo::from(target);
|
||||
|
||||
let exec_mode = match order {
|
||||
BuildOrdering::BuildIfChecks => ExecutionMode::ExecutableIfCheck,
|
||||
BuildOrdering::AlwaysBuild => ExecutionMode::Executable,
|
||||
|
@ -717,7 +708,7 @@ pub fn standard_load_config(
|
|||
};
|
||||
|
||||
LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
function_kind,
|
||||
render: RenderTarget::ColorTerminal,
|
||||
palette: DEFAULT_PALETTE,
|
||||
|
@ -729,7 +720,7 @@ pub fn standard_load_config(
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn build_file<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
app_module_path: PathBuf,
|
||||
code_gen_options: CodeGenOptions,
|
||||
emit_timings: bool,
|
||||
|
@ -767,7 +758,7 @@ pub fn build_file<'a>(
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn build_loaded_file<'a>(
|
||||
arena: &'a Bump,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
app_module_path: PathBuf,
|
||||
code_gen_options: CodeGenOptions,
|
||||
emit_timings: bool,
|
||||
|
@ -779,8 +770,6 @@ fn build_loaded_file<'a>(
|
|||
compilation_start: Instant,
|
||||
out_path: Option<&Path>,
|
||||
) -> Result<BuiltFile<'a>, BuildFileError<'a>> {
|
||||
let operating_system = roc_target::OperatingSystem::from(target.operating_system);
|
||||
|
||||
let platform_main_roc = match &loaded.entry_point {
|
||||
EntryPoint::Executable { platform_path, .. } => platform_path.to_path_buf(),
|
||||
_ => unreachable!(),
|
||||
|
@ -792,9 +781,9 @@ fn build_loaded_file<'a>(
|
|||
|
||||
if is_platform_prebuilt && linking_strategy == LinkingStrategy::Surgical {
|
||||
// Fallback to legacy linking if the preprocessed host file does not exist, but a legacy host does exist.
|
||||
let preprocessed_host_path = platform_main_roc
|
||||
.with_file_name(roc_linker::preprocessed_host_filename(target).unwrap());
|
||||
let legacy_host_path = legacy_host_file(target, &platform_main_roc).unwrap();
|
||||
let preprocessed_host_path =
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target));
|
||||
let legacy_host_path = legacy_host_file(target, &platform_main_roc);
|
||||
if !preprocessed_host_path.exists() && legacy_host_path.exists() {
|
||||
linking_strategy = LinkingStrategy::Legacy;
|
||||
}
|
||||
|
@ -802,15 +791,15 @@ fn build_loaded_file<'a>(
|
|||
|
||||
// the preprocessed host is stored beside the platform's main.roc
|
||||
let preprocessed_host_path = if linking_strategy == LinkingStrategy::Legacy {
|
||||
if let roc_target::OperatingSystem::Wasi = operating_system {
|
||||
if target == Target::Wasm32 {
|
||||
// when compiling a wasm application, we implicitly assume here that the host is in zig
|
||||
// and has a file called "host.zig"
|
||||
platform_main_roc.with_file_name("host.zig")
|
||||
} else {
|
||||
legacy_host_file(target, &platform_main_roc).unwrap()
|
||||
legacy_host_file(target, &platform_main_roc)
|
||||
}
|
||||
} else {
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target).unwrap())
|
||||
platform_main_roc.with_file_name(roc_linker::preprocessed_host_filename(target))
|
||||
};
|
||||
|
||||
let output_exe_path = match out_path {
|
||||
|
@ -841,22 +830,12 @@ fn build_loaded_file<'a>(
|
|||
if ends_with_sep {
|
||||
let filename = app_module_path.file_name().unwrap_or_default();
|
||||
|
||||
with_output_extension(
|
||||
&path.join(filename),
|
||||
operating_system,
|
||||
linking_strategy,
|
||||
link_type,
|
||||
)
|
||||
with_output_extension(&path.join(filename), target, linking_strategy, link_type)
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
}
|
||||
}
|
||||
None => with_output_extension(
|
||||
&app_module_path,
|
||||
operating_system,
|
||||
linking_strategy,
|
||||
link_type,
|
||||
),
|
||||
None => with_output_extension(&app_module_path, target, linking_strategy, link_type),
|
||||
};
|
||||
|
||||
// We don't need to spawn a rebuild thread when using a prebuilt host.
|
||||
|
@ -1018,13 +997,13 @@ fn build_loaded_file<'a>(
|
|||
std::fs::write(&output_exe_path, &*roc_app_bytes).unwrap();
|
||||
}
|
||||
(LinkingStrategy::Legacy, _) => {
|
||||
let extension = if matches!(operating_system, roc_target::OperatingSystem::Wasi) {
|
||||
let extension = if target == Target::Wasm32 {
|
||||
// Legacy linker is only by used llvm wasm backend, not dev.
|
||||
// llvm wasm backend directly emits a bitcode file when targeting wasi, not a `.o` or `.wasm` file.
|
||||
// If we set the extension wrong, zig will print a ton of warnings when linking.
|
||||
"bc"
|
||||
} else {
|
||||
operating_system.object_file_ext()
|
||||
target.object_file_ext()
|
||||
};
|
||||
let app_o_file = tempfile::Builder::new()
|
||||
.prefix("roc_app")
|
||||
|
@ -1124,10 +1103,9 @@ fn spawn_rebuild_thread(
|
|||
platform_main_roc: PathBuf,
|
||||
preprocessed_host_path: PathBuf,
|
||||
output_exe_path: PathBuf,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
dll_stub_symbols: Vec<String>,
|
||||
) -> std::thread::JoinHandle<u128> {
|
||||
let thread_local_target = target.clone();
|
||||
std::thread::spawn(move || {
|
||||
// Printing to stderr because we want stdout to contain only the output of the roc program.
|
||||
// We are aware of the trade-offs.
|
||||
|
@ -1138,19 +1116,14 @@ fn spawn_rebuild_thread(
|
|||
|
||||
match linking_strategy {
|
||||
LinkingStrategy::Additive => {
|
||||
let host_dest = rebuild_host(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
platform_main_roc.as_path(),
|
||||
None,
|
||||
);
|
||||
let host_dest = rebuild_host(opt_level, target, platform_main_roc.as_path(), None);
|
||||
|
||||
preprocess_host_wasm32(host_dest.as_path(), &preprocessed_host_path);
|
||||
}
|
||||
LinkingStrategy::Surgical => {
|
||||
build_and_preprocess_host_lowlevel(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
target,
|
||||
platform_main_roc.as_path(),
|
||||
preprocessed_host_path.as_path(),
|
||||
&dll_stub_symbols,
|
||||
|
@ -1161,12 +1134,7 @@ fn spawn_rebuild_thread(
|
|||
std::fs::copy(&preprocessed_host_path, output_exe_path.as_path()).unwrap();
|
||||
}
|
||||
LinkingStrategy::Legacy => {
|
||||
rebuild_host(
|
||||
opt_level,
|
||||
&thread_local_target,
|
||||
platform_main_roc.as_path(),
|
||||
None,
|
||||
);
|
||||
rebuild_host(opt_level, target, platform_main_roc.as_path(), None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1144,7 @@ fn spawn_rebuild_thread(
|
|||
|
||||
pub fn build_and_preprocess_host(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
exposed_symbols: roc_linker::ExposedSymbols,
|
||||
|
@ -1194,7 +1162,7 @@ pub fn build_and_preprocess_host(
|
|||
|
||||
fn build_and_preprocess_host_lowlevel(
|
||||
opt_level: OptLevel,
|
||||
target: &Triple,
|
||||
target: Target,
|
||||
platform_main_roc: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
stub_dll_symbols: &[String],
|
||||
|
@ -1227,12 +1195,12 @@ pub fn check_file<'a>(
|
|||
|
||||
// only used for generating errors. We don't do code generation, so hardcoding should be fine
|
||||
// we need monomorphization for when exhaustiveness checking
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
let target = Target::LinuxX64;
|
||||
|
||||
// Step 1: compile the app and generate the .o file
|
||||
|
||||
let load_config = LoadConfig {
|
||||
target_info,
|
||||
target,
|
||||
// TODO: we may not want this for just checking.
|
||||
function_kind: FunctionKind::LambdaSet,
|
||||
// TODO: expose this from CLI?
|
||||
|
@ -1295,7 +1263,7 @@ pub fn build_str_test<'a>(
|
|||
app_module_source: &'a str,
|
||||
assume_prebuild: bool,
|
||||
) -> Result<BuiltFile<'a>, BuildFileError<'a>> {
|
||||
let triple = target_lexicon::Triple::host();
|
||||
let target = target_lexicon::Triple::host().into();
|
||||
|
||||
let code_gen_options = CodeGenOptions {
|
||||
backend: CodeGenBackend::Llvm(LlvmBackendMode::Binary),
|
||||
|
@ -1314,7 +1282,7 @@ pub fn build_str_test<'a>(
|
|||
let build_ordering = BuildOrdering::AlwaysBuild;
|
||||
let threading = Threading::AtMost(2);
|
||||
|
||||
let load_config = standard_load_config(&triple, build_ordering, threading);
|
||||
let load_config = standard_load_config(target, build_ordering, threading);
|
||||
|
||||
let compilation_start = std::time::Instant::now();
|
||||
|
||||
|
@ -1331,7 +1299,7 @@ pub fn build_str_test<'a>(
|
|||
|
||||
build_loaded_file(
|
||||
arena,
|
||||
&triple,
|
||||
target,
|
||||
app_module_path.to_path_buf(),
|
||||
code_gen_options,
|
||||
emit_timings,
|
||||
|
@ -1347,15 +1315,15 @@ pub fn build_str_test<'a>(
|
|||
|
||||
fn with_output_extension(
|
||||
path: &Path,
|
||||
os: OperatingSystem,
|
||||
target: Target,
|
||||
linking_strategy: LinkingStrategy,
|
||||
link_type: LinkType,
|
||||
) -> PathBuf {
|
||||
match (linking_strategy, link_type) {
|
||||
(LinkingStrategy::Additive, _) | (LinkingStrategy::Legacy, LinkType::None) => {
|
||||
// Additive linking and no linking both output the object file type.
|
||||
path.with_extension(os.object_file_ext())
|
||||
path.with_extension(target.object_file_ext())
|
||||
}
|
||||
_ => path.with_extension(os.executable_file_ext().unwrap_or_default()),
|
||||
_ => path.with_extension(target.executable_file_ext().unwrap_or_default()),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue