Merge pull request #2780 from rtfeldman/no-link

Add --no-link flag for more complex linking cases
This commit is contained in:
Richard Feldman 2022-04-08 23:49:48 -04:00 committed by GitHub
commit babe281b5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 6 deletions

1
Cargo.lock generated
View File

@ -3370,6 +3370,7 @@ dependencies = [
"roc_can",
"roc_collections",
"roc_constrain",
"roc_error_macros",
"roc_gen_dev",
"roc_gen_llvm",
"roc_gen_wasm",

View File

@ -246,6 +246,11 @@ pub fn build_file<'a>(
todo!("gracefully handle failing to surgically link");
})?;
BuildOutcome::NoProblems
} else if matches!(link_type, LinkType::None) {
// Just copy the object file to the output folder.
binary_path.set_extension(app_extension);
std::fs::copy(app_o_file, &binary_path).unwrap();
BuildOutcome::NoProblems
} else {
let mut inputs = vec![
host_input_path.as_path().to_str().unwrap(),

View File

@ -34,6 +34,7 @@ pub const FLAG_DEV: &str = "dev";
pub const FLAG_OPTIMIZE: &str = "optimize";
pub const FLAG_OPT_SIZE: &str = "opt-size";
pub const FLAG_LIB: &str = "lib";
pub const FLAG_NO_LINK: &str = "no-link";
pub const FLAG_TARGET: &str = "target";
pub const FLAG_TIME: &str = "time";
pub const FLAG_LINK: &str = "roc-linker";
@ -88,6 +89,12 @@ pub fn build_app<'a>() -> App<'a> {
.about("Build a C library instead of an executable.")
.required(false),
)
.arg(
Arg::new(FLAG_NO_LINK)
.long(FLAG_NO_LINK)
.about("Does not link. Instead just outputs the `.o` file")
.required(false),
)
.arg(
Arg::new(FLAG_DEBUG)
.long(FLAG_DEBUG)
@ -291,10 +298,14 @@ pub fn build(matches: &ArgMatches, config: BuildConfig) -> io::Result<i32> {
let emit_debug_info = matches.is_present(FLAG_DEBUG);
let emit_timings = matches.is_present(FLAG_TIME);
let link_type = if matches.is_present(FLAG_LIB) {
LinkType::Dylib
} else {
LinkType::Executable
let link_type = match (
matches.is_present(FLAG_LIB),
matches.is_present(FLAG_NO_LINK),
) {
(true, false) => LinkType::Dylib,
(true, true) => user_error!("build can only be one of `--lib` or `--no-link`"),
(false, true) => LinkType::None,
(false, false) => LinkType::Executable,
};
let surgically_link = matches.is_present(FLAG_LINK);
let precompiled = matches.is_present(FLAG_PRECOMPILED);

View File

@ -24,6 +24,7 @@ roc_gen_llvm = { path = "../gen_llvm", optional = true }
roc_gen_wasm = { path = "../gen_wasm", optional = true }
roc_gen_dev = { path = "../gen_dev", default-features = false }
roc_reporting = { path = "../../reporting" }
roc_error_macros = { path = "../../error_macros" }
roc_std = { path = "../../roc_std", default-features = false }
bumpalo = { version = "3.8.0", features = ["collections"] }
libloading = "0.7.1"

View File

@ -2,6 +2,7 @@ use crate::target::{arch_str, target_zig_str};
#[cfg(feature = "llvm")]
use libloading::{Error, Library};
use roc_builtins::bitcode;
use roc_error_macros::internal_error;
// #[cfg(feature = "llvm")]
use roc_mono::ir::OptLevel;
use std::collections::HashMap;
@ -20,10 +21,10 @@ fn zig_executable() -> String {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum LinkType {
// These numbers correspond to the --lib flag; if it's present
// (e.g. is_present returns `1 as bool`), this will be 1 as well.
// These numbers correspond to the --lib and --no-link flags
Executable = 0,
Dylib = 1,
None = 2,
}
/// input_paths can include the host as well as the app. e.g. &["host.o", "roc_app.o"]
@ -835,6 +836,7 @@ fn link_linux(
output_path,
)
}
LinkType::None => internal_error!("link_linux should not be called with link type of none"),
};
let env_path = env::var("PATH").unwrap_or_else(|_| "".to_string());
@ -904,6 +906,7 @@ fn link_macos(
("-dylib", output_path)
}
LinkType::None => internal_error!("link_macos should not be called with link type of none"),
};
let arch = match target.architecture {