update preprocess host API

This commit is contained in:
Luke Boswell 2024-06-13 19:10:32 +10:00
parent f8c6786502
commit ee84b61360
No known key found for this signature in database
GPG Key ID: F6DB3C9DB47377B0
5 changed files with 79 additions and 45 deletions

View File

@ -79,6 +79,9 @@ pub const GLUE_DIR: &str = "GLUE_DIR";
pub const GLUE_SPEC: &str = "GLUE_SPEC";
pub const DIRECTORY_OR_FILES: &str = "DIRECTORY_OR_FILES";
pub const ARGS_FOR_APP: &str = "ARGS_FOR_APP";
pub const FLAG_PP_HOST: &str = "host";
pub const FLAG_PP_PLATFORM: &str = "platform";
pub const FLAG_PP_DYLIB: &str = "lib";
const VERSION: &str = include_str!("../../../version.txt");
const DEFAULT_GENERATED_DOCS_DIR: &str = "generated-docs";
@ -400,18 +403,29 @@ pub fn build_app() -> Command {
.subcommand(Command::new(CMD_PREPROCESS_HOST)
.about("Runs the surgical linker preprocessor to generate `.rh` and `.rm` files.")
.arg(
Arg::new(ROC_FILE)
.help("The .roc file for an app using the platform")
Arg::new(FLAG_PP_HOST)
.help("Path to the host executable where the app was linked dynamically")
.value_parser(value_parser!(PathBuf))
.required(true)
)
.arg(
Arg::new(FLAG_TARGET)
.long(FLAG_TARGET)
.help("Choose a different target")
.default_value(Into::<&'static str>::into(Target::default()))
.value_parser(build_target_values_parser)
.required(false),
Arg::new(FLAG_PP_PLATFORM)
.help("Path to the platform/main.roc file")
.value_parser(value_parser!(PathBuf))
.required(true)
)
.arg(
Arg::new(FLAG_PP_DYLIB)
.help("Path to a stubbed app dynamic library (e.g. roc build --lib app.roc)")
.value_parser(value_parser!(PathBuf))
.required(true)
)
.arg(
Arg::new(FLAG_VERBOSE)
.long(FLAG_VERBOSE)
.help("Print detailed information while pre-processing host")
.action(ArgAction::SetTrue)
.required(false)
)
)
.arg(flag_optimize)

View File

@ -6,8 +6,8 @@ use roc_cli::{
build_app, format_files, format_src, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK,
CMD_DEV, CMD_DOCS, CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_PREPROCESS_HOST, CMD_REPL,
CMD_RUN, CMD_TEST, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_MAIN,
FLAG_NO_LINK, FLAG_OUTPUT, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, GLUE_DIR,
GLUE_SPEC, ROC_FILE,
FLAG_NO_LINK, FLAG_OUTPUT, FLAG_PP_DYLIB, FLAG_PP_HOST, FLAG_PP_PLATFORM, FLAG_STDIN,
FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, GLUE_DIR, GLUE_SPEC, ROC_FILE,
};
use roc_docs::generate_docs_html;
use roc_error_macros::user_error;
@ -136,31 +136,53 @@ fn main() -> io::Result<()> {
Ok(0)
}
Some((CMD_PREPROCESS_HOST, matches)) => {
let input_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
let preprocess_host_err =
{ |msg: String| user_error!("\n\n ERROR PRE-PROCESSING HOST: {}\n\n", msg) };
let host_path = matches.get_one::<PathBuf>(FLAG_PP_HOST).unwrap();
if !host_path.is_file() {
preprocess_host_err(format!(
"Expected to find the host executable file at {}",
&host_path.display()
));
}
let platform_path = matches.get_one::<PathBuf>(FLAG_PP_PLATFORM).unwrap();
if !platform_path.is_file() {
preprocess_host_err(format!(
"Expected to find the platform/main.roc file at {}",
&platform_path.display()
));
}
let dylib_path = matches.get_one::<PathBuf>(FLAG_PP_DYLIB).unwrap();
if !dylib_path.is_file() {
preprocess_host_err(format!(
"Expected to find the app stub dynamic library file at {}",
dylib_path.display()
));
}
let target = matches
.get_one::<String>(FLAG_TARGET)
.and_then(|s| Target::from_str(s).ok())
.unwrap_or_default();
let function_kind = FunctionKind::LambdaSet;
let (platform_path, stub_lib, stub_dll_symbols) = roc_linker::generate_stub_lib(
input_path,
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
target,
function_kind,
);
let verbose_and_time = matches.get_one::<bool>(roc_cli::FLAG_VERBOSE).unwrap();
#[cfg(target_os = "windows")]
{
internal_error!("TODO populate stub_dll_symbols for Windows");
}
// TODO: pipeline the executable location through here.
// Currently it is essentally hardcoded as platform_path/dynhost.
roc_linker::preprocess_host(
target,
&platform_path.with_file_name("main.roc"),
// The target triple string must be derived from the triple to convert from the generic
// `system` target to the exact specific target.
&platform_path.with_file_name(format!("{}.rh", target)),
&stub_lib,
&stub_dll_symbols,
host_path,
platform_path,
dylib_path,
*verbose_and_time,
*verbose_and_time,
);
Ok(0)
}
Some((CMD_BUILD, matches)) => {

View File

@ -1181,10 +1181,11 @@ fn build_and_preprocess_host_lowlevel(
roc_linker::preprocess_host(
target,
platform_main_roc,
preprocessed_host_path,
platform_main_roc,
&stub_lib,
stub_dll_symbols,
false,
false,
)
}

View File

@ -365,27 +365,24 @@ fn stub_lib_is_up_to_date(target: Target, stub_lib_path: &Path, custom_names: &[
pub fn preprocess_host(
target: Target,
platform_main_roc: &Path,
preprocessed_path: &Path,
shared_lib: &Path,
stub_dll_symbols: &[String],
host_path: &Path,
platform_path: &Path,
dylib_path: &Path,
verbose: bool,
time: bool,
) {
let metadata_path = platform_main_roc.with_file_name(metadata_file_name(target));
let host_exe_path = if target.operating_system() == OperatingSystem::Windows {
platform_main_roc.with_file_name("dynhost.exe")
} else {
platform_main_roc.with_file_name("dynhost")
};
let preprocessed_path = platform_path.with_file_name(format!("{}.rh", target));
let metadata_path = platform_path.with_file_name(metadata_file_name(target));
preprocess(
target,
&host_exe_path,
host_path,
&metadata_path,
preprocessed_path,
shared_lib,
stub_dll_symbols,
false,
false,
preprocessed_path.as_path(),
dylib_path,
&[],
verbose,
time,
)
}

View File

@ -1088,7 +1088,7 @@ fn gen_macho_le(
}
}
offset += dbg!(cmd_size);
offset += cmd_size;
}
// cmd_loc should be where the last offset ended