mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
commit
d94b3f521c
10 changed files with 603 additions and 547 deletions
880
Cargo.lock
generated
880
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -82,7 +82,7 @@ bumpalo = { version = "3.12.0", features = ["collections"] }
|
||||||
bytemuck = { version = "1.13.1", features = ["derive"] }
|
bytemuck = { version = "1.13.1", features = ["derive"] }
|
||||||
capstone = { version = "0.11.0", default-features = false }
|
capstone = { version = "0.11.0", default-features = false }
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
clap = { version = "3.2.23", default-features = false, features = ["std", "color", "suggestions"] }
|
clap = { version = "4.2.7", default-features = false, features = ["std", "color", "suggestions"] }
|
||||||
colored = "2.0.0"
|
colored = "2.0.0"
|
||||||
confy = { git = 'https://github.com/rust-cli/confy', features = ["yaml_conf"], default-features = false }
|
confy = { git = 'https://github.com/rust-cli/confy', features = ["yaml_conf"], default-features = false }
|
||||||
console_error_panic_hook = "0.1.7"
|
console_error_panic_hook = "0.1.7"
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
extern crate const_format;
|
extern crate const_format;
|
||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use clap::{Arg, ArgMatches, Command, ValueSource};
|
use clap::{
|
||||||
|
builder::PossibleValuesParser, parser::ValueSource, value_parser, Arg, ArgAction, ArgMatches,
|
||||||
|
Command,
|
||||||
|
};
|
||||||
use roc_build::link::{LinkType, LinkingStrategy};
|
use roc_build::link::{LinkType, LinkingStrategy};
|
||||||
use roc_build::program::{
|
use roc_build::program::{
|
||||||
handle_error_module, handle_loading_problem, standard_load_config, BuildFileError,
|
handle_error_module, handle_loading_problem, standard_load_config, BuildFileError,
|
||||||
|
@ -18,7 +21,7 @@ use roc_mono::ir::OptLevel;
|
||||||
use roc_packaging::cache::RocCacheDir;
|
use roc_packaging::cache::RocCacheDir;
|
||||||
use roc_packaging::tarball::Compression;
|
use roc_packaging::tarball::Compression;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::{CString, OsStr};
|
use std::ffi::{CString, OsStr, OsString};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
@ -72,72 +75,76 @@ pub const ARGS_FOR_APP: &str = "ARGS_FOR_APP";
|
||||||
|
|
||||||
const VERSION: &str = include_str!("../../../version.txt");
|
const VERSION: &str = include_str!("../../../version.txt");
|
||||||
|
|
||||||
pub fn build_app<'a>() -> Command<'a> {
|
pub fn build_app() -> Command {
|
||||||
let flag_optimize = Arg::new(FLAG_OPTIMIZE)
|
let flag_optimize = Arg::new(FLAG_OPTIMIZE)
|
||||||
.long(FLAG_OPTIMIZE)
|
.long(FLAG_OPTIMIZE)
|
||||||
.help("Optimize the compiled program to run faster\n(Optimization takes time to complete.)")
|
.help("Optimize the compiled program to run faster\n(Optimization takes time to complete.)")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_max_threads = Arg::new(FLAG_MAX_THREADS)
|
let flag_max_threads = Arg::new(FLAG_MAX_THREADS)
|
||||||
.long(FLAG_MAX_THREADS)
|
.long(FLAG_MAX_THREADS)
|
||||||
.help("Limit the number of threads (and hence cores) used during compilation")
|
.help("Limit the number of threads (and hence cores) used during compilation")
|
||||||
.takes_value(true)
|
.value_parser(value_parser!(usize))
|
||||||
.validator(|s| s.parse::<usize>())
|
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_opt_size = Arg::new(FLAG_OPT_SIZE)
|
let flag_opt_size = Arg::new(FLAG_OPT_SIZE)
|
||||||
.long(FLAG_OPT_SIZE)
|
.long(FLAG_OPT_SIZE)
|
||||||
.help("Optimize the compiled program to have a small binary size\n(Optimization takes time to complete.)")
|
.help("Optimize the compiled program to have a small binary size\n(Optimization takes time to complete.)")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_dev = Arg::new(FLAG_DEV)
|
let flag_dev = Arg::new(FLAG_DEV)
|
||||||
.long(FLAG_DEV)
|
.long(FLAG_DEV)
|
||||||
.help("Make compilation finish as soon as possible, at the expense of runtime performance")
|
.help("Make compilation finish as soon as possible, at the expense of runtime performance")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_debug = Arg::new(FLAG_DEBUG)
|
let flag_debug = Arg::new(FLAG_DEBUG)
|
||||||
.long(FLAG_DEBUG)
|
.long(FLAG_DEBUG)
|
||||||
.help("Store LLVM debug information in the generated program")
|
.help("Store LLVM debug information in the generated program")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_time = Arg::new(FLAG_TIME)
|
let flag_time = Arg::new(FLAG_TIME)
|
||||||
.long(FLAG_TIME)
|
.long(FLAG_TIME)
|
||||||
.help("Print detailed compilation time information")
|
.help("Print detailed compilation time information")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_linker = Arg::new(FLAG_LINKER)
|
let flag_linker = Arg::new(FLAG_LINKER)
|
||||||
.long(FLAG_LINKER)
|
.long(FLAG_LINKER)
|
||||||
.help("Set which linker to use\n(The surgical linker is enabled by default only when building for wasm32 or x86_64 Linux, because those are the only targets it currently supports. Otherwise the legacy linker is used by default.)")
|
.help("Set which linker to use\n(The surgical linker is enabled by default only when building for wasm32 or x86_64 Linux, because those are the only targets it currently supports. Otherwise the legacy linker is used by default.)")
|
||||||
.possible_values(["surgical", "legacy"])
|
.value_parser(["surgical", "legacy"])
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_prebuilt = Arg::new(FLAG_PREBUILT)
|
let flag_prebuilt = Arg::new(FLAG_PREBUILT)
|
||||||
.long(FLAG_PREBUILT)
|
.long(FLAG_PREBUILT)
|
||||||
.help("Assume the platform has been prebuilt and skip rebuilding the platform\n(This is enabled by default when using `roc build` with a --target other than `--target <current machine>`.)")
|
.help("Assume the platform has been prebuilt and skip rebuilding the platform\n(This is enabled implicitly when using `roc build` with a --target other than `--target <current machine>`, unless the target is wasm.)")
|
||||||
.possible_values(["true", "false"])
|
.action(ArgAction::SetTrue)
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let flag_wasm_stack_size_kb = Arg::new(FLAG_WASM_STACK_SIZE_KB)
|
let flag_wasm_stack_size_kb = Arg::new(FLAG_WASM_STACK_SIZE_KB)
|
||||||
.long(FLAG_WASM_STACK_SIZE_KB)
|
.long(FLAG_WASM_STACK_SIZE_KB)
|
||||||
.help("Stack size in kilobytes for wasm32 target\n(This only applies when --dev also provided.)")
|
.help("Stack size in kilobytes for wasm32 target\n(This only applies when --dev also provided.)")
|
||||||
.takes_value(true)
|
.value_parser(value_parser!(u32))
|
||||||
.validator(|s| s.parse::<u32>())
|
|
||||||
.required(false);
|
.required(false);
|
||||||
|
|
||||||
let roc_file_to_run = Arg::new(ROC_FILE)
|
let roc_file_to_run = Arg::new(ROC_FILE)
|
||||||
.help("The .roc file of an app to run")
|
.help("The .roc file of an app to run")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME);
|
.default_value(DEFAULT_ROC_FILENAME);
|
||||||
|
|
||||||
let args_for_app = Arg::new(ARGS_FOR_APP)
|
let args_for_app = Arg::new(ARGS_FOR_APP)
|
||||||
.help("Arguments to pass into the app being run\ne.g. `roc run -- arg1 arg2`")
|
.help("Arguments to pass into the app being run\ne.g. `roc run -- arg1 arg2`")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(OsString))
|
||||||
.multiple_values(true)
|
.num_args(0..)
|
||||||
.takes_value(true)
|
|
||||||
.allow_hyphen_values(true)
|
.allow_hyphen_values(true)
|
||||||
.last(true);
|
.last(true);
|
||||||
|
|
||||||
|
let build_target_values_parser =
|
||||||
|
PossibleValuesParser::new(Target::iter().map(Into::<&'static str>::into));
|
||||||
let app = Command::new("roc")
|
let app = Command::new("roc")
|
||||||
.version(concatcp!(VERSION, "\n"))
|
.version(concatcp!(VERSION, "\n"))
|
||||||
.about("Run the given .roc file, if there are no compilation errors.\nYou can use one of the SUBCOMMANDS below to do something else!")
|
.about("Run the given .roc file, if there are no compilation errors.\nYou can use one of the SUBCOMMANDS below to do something else!")
|
||||||
|
@ -151,21 +158,20 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(flag_time.clone())
|
.arg(flag_time.clone())
|
||||||
.arg(flag_linker.clone())
|
.arg(flag_linker.clone())
|
||||||
.arg(flag_prebuilt.clone())
|
.arg(flag_prebuilt.clone())
|
||||||
.arg(flag_wasm_stack_size_kb.clone())
|
.arg(flag_wasm_stack_size_kb)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_TARGET)
|
Arg::new(FLAG_TARGET)
|
||||||
.long(FLAG_TARGET)
|
.long(FLAG_TARGET)
|
||||||
.help("Choose a different target")
|
.help("Choose a different target")
|
||||||
.default_value(Target::default().into())
|
.default_value(Into::<&'static str>::into(Target::default()))
|
||||||
.possible_values(Target::iter().map(|target| {
|
.value_parser(build_target_values_parser.clone())
|
||||||
Into::<&'static str>::into(target)
|
|
||||||
}))
|
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_LIB)
|
Arg::new(FLAG_LIB)
|
||||||
.long(FLAG_LIB)
|
.long(FLAG_LIB)
|
||||||
.help("Build a C library instead of an executable")
|
.help("Build a C library instead of an executable")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -173,19 +179,20 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.long(FLAG_BUNDLE)
|
.long(FLAG_BUNDLE)
|
||||||
.help("Create an archive of a package (for example, a .tar, .tar.gz, or .tar.br file), so others can add it as a HTTPS dependency.")
|
.help("Create an archive of a package (for example, a .tar, .tar.gz, or .tar.br file), so others can add it as a HTTPS dependency.")
|
||||||
.conflicts_with(FLAG_TARGET)
|
.conflicts_with(FLAG_TARGET)
|
||||||
.possible_values([".tar", ".tar.gz", ".tar.br"])
|
.value_parser([".tar", ".tar.gz", ".tar.br"])
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_NO_LINK)
|
Arg::new(FLAG_NO_LINK)
|
||||||
.long(FLAG_NO_LINK)
|
.long(FLAG_NO_LINK)
|
||||||
.help("Do not link\n(Instead, just output the `.o` file.)")
|
.help("Do not link\n(Instead, just output the `.o` file.)")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file to build")
|
.help("The .roc file to build")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME),
|
.default_value(DEFAULT_ROC_FILENAME),
|
||||||
)
|
)
|
||||||
|
@ -203,7 +210,7 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file for the main module")
|
.help("The .roc file for the main module")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME)
|
.default_value(DEFAULT_ROC_FILENAME)
|
||||||
)
|
)
|
||||||
|
@ -243,13 +250,14 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(DIRECTORY_OR_FILES)
|
Arg::new(DIRECTORY_OR_FILES)
|
||||||
.index(1)
|
.index(1)
|
||||||
.multiple_values(true)
|
.num_args(0..)
|
||||||
.required(false)
|
.required(false)
|
||||||
.allow_invalid_utf8(true))
|
.value_parser(value_parser!(OsString)))
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_CHECK)
|
Arg::new(FLAG_CHECK)
|
||||||
.long(FLAG_CHECK)
|
.long(FLAG_CHECK)
|
||||||
.help("Checks that specified files are formatted\n(If formatting is needed, return a non-zero exit code.)")
|
.help("Checks that specified files are formatted\n(If formatting is needed, return a non-zero exit code.)")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -262,7 +270,7 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file of an app to check")
|
.help("The .roc file of an app to check")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME),
|
.default_value(DEFAULT_ROC_FILENAME),
|
||||||
)
|
)
|
||||||
|
@ -271,9 +279,8 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
Command::new(CMD_DOCS)
|
Command::new(CMD_DOCS)
|
||||||
.about("Generate documentation for a Roc package")
|
.about("Generate documentation for a Roc package")
|
||||||
.arg(Arg::new(ROC_FILE)
|
.arg(Arg::new(ROC_FILE)
|
||||||
.multiple_values(true)
|
|
||||||
.help("The package's main .roc file")
|
.help("The package's main .roc file")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME),
|
.default_value(DEFAULT_ROC_FILENAME),
|
||||||
)
|
)
|
||||||
|
@ -284,19 +291,19 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(GLUE_SPEC)
|
Arg::new(GLUE_SPEC)
|
||||||
.help("The specification for how to translate Roc types into output files.")
|
.help("The specification for how to translate Roc types into output files.")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(true)
|
.required(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(GLUE_DIR)
|
Arg::new(GLUE_DIR)
|
||||||
.help("The directory for the generated glue code.\nNote: The implementation can write to any file in this directory.")
|
.help("The directory for the generated glue code.\nNote: The implementation can write to any file in this directory.")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(true)
|
.required(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file whose exposed types should be translated.")
|
.help("The .roc file whose exposed types should be translated.")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value(DEFAULT_ROC_FILENAME)
|
.default_value(DEFAULT_ROC_FILENAME)
|
||||||
)
|
)
|
||||||
|
@ -306,23 +313,20 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.help("The .roc file for an app using the platform")
|
.help("The .roc file for an app using the platform")
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.required(true)
|
.required(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(FLAG_TARGET)
|
Arg::new(FLAG_TARGET)
|
||||||
.long(FLAG_TARGET)
|
.long(FLAG_TARGET)
|
||||||
.help("Choose a different target")
|
.help("Choose a different target")
|
||||||
.default_value(Target::default().into())
|
.default_value(Into::<&'static str>::into(Target::default()))
|
||||||
.possible_values(Target::iter().map(|target| {
|
.value_parser(build_target_values_parser)
|
||||||
Into::<&'static str>::into(target)
|
|
||||||
}))
|
|
||||||
.required(false),
|
.required(false),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.trailing_var_arg(true)
|
|
||||||
.arg(flag_optimize)
|
.arg(flag_optimize)
|
||||||
.arg(flag_max_threads.clone())
|
.arg(flag_max_threads)
|
||||||
.arg(flag_opt_size)
|
.arg(flag_opt_size)
|
||||||
.arg(flag_dev)
|
.arg(flag_dev)
|
||||||
.arg(flag_debug)
|
.arg(flag_debug)
|
||||||
|
@ -338,9 +342,9 @@ pub fn build_app<'a>() -> Command<'a> {
|
||||||
.about("Launch the Roc editor (Work In Progress)")
|
.about("Launch the Roc editor (Work In Progress)")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(DIRECTORY_OR_FILES)
|
Arg::new(DIRECTORY_OR_FILES)
|
||||||
.multiple_values(true)
|
.num_args(0..)
|
||||||
.required(false)
|
.required(false)
|
||||||
.allow_invalid_utf8(true)
|
.value_parser(value_parser!(OsString))
|
||||||
.help("(optional) The directory or files to open on launch"),
|
.help("(optional) The directory or files to open on launch"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -363,9 +367,9 @@ pub enum FormatMode {
|
||||||
|
|
||||||
fn opt_level_from_flags(matches: &ArgMatches) -> OptLevel {
|
fn opt_level_from_flags(matches: &ArgMatches) -> OptLevel {
|
||||||
match (
|
match (
|
||||||
matches.is_present(FLAG_OPTIMIZE),
|
matches.get_flag(FLAG_OPTIMIZE),
|
||||||
matches.is_present(FLAG_OPT_SIZE),
|
matches.get_flag(FLAG_OPT_SIZE),
|
||||||
matches.is_present(FLAG_DEV),
|
matches.get_flag(FLAG_DEV),
|
||||||
) {
|
) {
|
||||||
(true, false, false) => OptLevel::Optimize,
|
(true, false, false) => OptLevel::Optimize,
|
||||||
(false, true, false) => OptLevel::Size,
|
(false, true, false) => OptLevel::Size,
|
||||||
|
@ -389,25 +393,21 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||||
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let arena = Bump::new();
|
let arena = Bump::new();
|
||||||
let filename = matches.value_of_os(ROC_FILE).unwrap();
|
|
||||||
let opt_level = opt_level_from_flags(matches);
|
let opt_level = opt_level_from_flags(matches);
|
||||||
|
|
||||||
let threading = match matches
|
let threading = match matches.get_one::<usize>(FLAG_MAX_THREADS) {
|
||||||
.value_of(FLAG_MAX_THREADS)
|
|
||||||
.and_then(|s| s.parse::<usize>().ok())
|
|
||||||
{
|
|
||||||
None => Threading::AllAvailable,
|
None => Threading::AllAvailable,
|
||||||
Some(0) => user_error!("cannot build with at most 0 threads"),
|
Some(0) => user_error!("cannot build with at most 0 threads"),
|
||||||
Some(1) => Threading::Single,
|
Some(1) => Threading::Single,
|
||||||
Some(n) => Threading::AtMost(n),
|
Some(n) => Threading::AtMost(*n),
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = Path::new(filename);
|
let path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
|
|
||||||
// Spawn the root task
|
// Spawn the root task
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
let current_dir = env::current_dir().unwrap();
|
let current_dir = env::current_dir().unwrap();
|
||||||
let expected_file_path = current_dir.join(filename);
|
let expected_file_path = current_dir.join(path);
|
||||||
|
|
||||||
let current_dir_string = current_dir.display();
|
let current_dir_string = current_dir.display();
|
||||||
let expected_file_path_string = expected_file_path.display();
|
let expected_file_path_string = expected_file_path.display();
|
||||||
|
@ -454,7 +454,7 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||||
return handle_loading_problem(problem);
|
return handle_loading_problem(problem);
|
||||||
}
|
}
|
||||||
Err(LoadMonomorphizedError::ErrorModule(module)) => {
|
Err(LoadMonomorphizedError::ErrorModule(module)) => {
|
||||||
return handle_error_module(module, start_time.elapsed(), filename, false);
|
return handle_error_module(module, start_time.elapsed(), path.as_os_str(), false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let problems = report_problems_monomorphized(&mut loaded);
|
let problems = report_problems_monomorphized(&mut loaded);
|
||||||
|
@ -540,14 +540,12 @@ pub fn build(
|
||||||
use roc_build::program::build_file;
|
use roc_build::program::build_file;
|
||||||
use BuildConfig::*;
|
use BuildConfig::*;
|
||||||
|
|
||||||
let filename = matches.value_of_os(ROC_FILE).unwrap();
|
let path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
let path_buf = {
|
{
|
||||||
let path = Path::new(filename);
|
|
||||||
|
|
||||||
// Spawn the root task
|
// Spawn the root task
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
let current_dir = env::current_dir().unwrap();
|
let current_dir = env::current_dir().unwrap();
|
||||||
let expected_file_path = current_dir.join(filename);
|
let expected_file_path = current_dir.join(path);
|
||||||
|
|
||||||
let current_dir_string = current_dir.display();
|
let current_dir_string = current_dir.display();
|
||||||
let expected_file_path_string = expected_file_path.display();
|
let expected_file_path_string = expected_file_path.display();
|
||||||
|
@ -567,11 +565,12 @@ pub fn build(
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if config == BuildConfig::BuildOnly && matches.is_present(FLAG_BUNDLE) {
|
if config == BuildConfig::BuildOnly && matches.contains_id(FLAG_BUNDLE) {
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
|
|
||||||
let compression =
|
let compression =
|
||||||
Compression::try_from(matches.value_of(FLAG_BUNDLE).unwrap()).unwrap();
|
Compression::try_from(matches.get_one::<String>(FLAG_BUNDLE).unwrap().as_str())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Print a note of advice. This is mainly here because brotli takes so long but produces
|
// Print a note of advice. This is mainly here because brotli takes so long but produces
|
||||||
// such smaller output files; the idea is to encourage people to wait for brotli,
|
// such smaller output files; the idea is to encourage people to wait for brotli,
|
||||||
|
@ -608,9 +607,7 @@ pub fn build(
|
||||||
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
path.to_path_buf()
|
|
||||||
};
|
|
||||||
|
|
||||||
// the process will end after this function,
|
// the process will end after this function,
|
||||||
// so we don't want to spend time freeing these values
|
// so we don't want to spend time freeing these values
|
||||||
|
@ -624,7 +621,7 @@ pub fn build(
|
||||||
|
|
||||||
// Note: This allows using `--dev` with `--optimize`.
|
// Note: This allows using `--dev` with `--optimize`.
|
||||||
// This means frontend optimizations and dev backend.
|
// This means frontend optimizations and dev backend.
|
||||||
let code_gen_backend = if matches.is_present(FLAG_DEV) {
|
let code_gen_backend = if matches.get_flag(FLAG_DEV) {
|
||||||
if matches!(triple.architecture, Architecture::Wasm32) {
|
if matches!(triple.architecture, Architecture::Wasm32) {
|
||||||
CodeGenBackend::Wasm
|
CodeGenBackend::Wasm
|
||||||
} else {
|
} else {
|
||||||
|
@ -639,17 +636,14 @@ pub fn build(
|
||||||
CodeGenBackend::Llvm(backend_mode)
|
CodeGenBackend::Llvm(backend_mode)
|
||||||
};
|
};
|
||||||
|
|
||||||
let emit_debug_info = matches.is_present(FLAG_DEBUG);
|
let emit_debug_info = matches.get_flag(FLAG_DEBUG);
|
||||||
let emit_timings = matches.is_present(FLAG_TIME);
|
let emit_timings = matches.get_flag(FLAG_TIME);
|
||||||
|
|
||||||
let threading = match matches
|
let threading = match matches.get_one::<usize>(FLAG_MAX_THREADS) {
|
||||||
.value_of(FLAG_MAX_THREADS)
|
|
||||||
.and_then(|s| s.parse::<usize>().ok())
|
|
||||||
{
|
|
||||||
None => Threading::AllAvailable,
|
None => Threading::AllAvailable,
|
||||||
Some(0) => user_error!("cannot build with at most 0 threads"),
|
Some(0) => user_error!("cannot build with at most 0 threads"),
|
||||||
Some(1) => Threading::Single,
|
Some(1) => Threading::Single,
|
||||||
Some(n) => Threading::AtMost(n),
|
Some(n) => Threading::AtMost(*n),
|
||||||
};
|
};
|
||||||
|
|
||||||
let wasm_dev_backend = matches!(code_gen_backend, CodeGenBackend::Wasm);
|
let wasm_dev_backend = matches!(code_gen_backend, CodeGenBackend::Wasm);
|
||||||
|
@ -657,27 +651,29 @@ pub fn build(
|
||||||
let linking_strategy = if wasm_dev_backend {
|
let linking_strategy = if wasm_dev_backend {
|
||||||
LinkingStrategy::Additive
|
LinkingStrategy::Additive
|
||||||
} else if !roc_linker::supported(link_type, &triple)
|
} else if !roc_linker::supported(link_type, &triple)
|
||||||
|| matches.value_of(FLAG_LINKER) == Some("legacy")
|
|| matches.get_one::<String>(FLAG_LINKER).map(|s| s.as_str()) == Some("legacy")
|
||||||
{
|
{
|
||||||
LinkingStrategy::Legacy
|
LinkingStrategy::Legacy
|
||||||
} else {
|
} else {
|
||||||
LinkingStrategy::Surgical
|
LinkingStrategy::Surgical
|
||||||
};
|
};
|
||||||
|
|
||||||
let prebuilt = if matches.is_present(FLAG_PREBUILT) {
|
let prebuilt = {
|
||||||
matches.value_of(FLAG_PREBUILT) == Some("true")
|
let cross_compile = triple != Triple::host();
|
||||||
} else {
|
let targeting_wasm = matches!(triple.architecture, Architecture::Wasm32);
|
||||||
// When compiling for a different target, default to assuming a prebuilt platform.
|
|
||||||
// Otherwise compilation would most likely fail because many toolchains assume you're compiling for the current machine.
|
matches.get_flag(FLAG_PREBUILT) ||
|
||||||
// We make an exception for Wasm, because cross-compiling is the norm in that case.
|
// When compiling for a different target, assume a prebuilt platform.
|
||||||
triple != Triple::host() && !matches!(triple.architecture, Architecture::Wasm32)
|
// Otherwise compilation would most likely fail because many toolchains
|
||||||
|
// assume you're compiling for the current machine. We make an exception
|
||||||
|
// for Wasm, because cross-compiling is the norm in that case.
|
||||||
|
(cross_compile && !targeting_wasm)
|
||||||
};
|
};
|
||||||
|
|
||||||
let wasm_dev_stack_bytes: Option<u32> = matches
|
let wasm_dev_stack_bytes: Option<u32> = matches
|
||||||
.try_get_one::<&str>(FLAG_WASM_STACK_SIZE_KB)
|
.try_get_one::<u32>(FLAG_WASM_STACK_SIZE_KB)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.and_then(|s| s.parse::<u32>().ok())
|
|
||||||
.map(|x| x * 1024);
|
.map(|x| x * 1024);
|
||||||
|
|
||||||
let build_ordering = match config {
|
let build_ordering = match config {
|
||||||
|
@ -696,7 +692,7 @@ pub fn build(
|
||||||
let res_binary_path = build_file(
|
let res_binary_path = build_file(
|
||||||
&arena,
|
&arena,
|
||||||
&triple,
|
&triple,
|
||||||
path_buf,
|
path.to_owned(),
|
||||||
code_gen_options,
|
code_gen_options,
|
||||||
emit_timings,
|
emit_timings,
|
||||||
link_type,
|
link_type,
|
||||||
|
@ -752,7 +748,10 @@ pub fn build(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = matches.values_of_os(ARGS_FOR_APP).unwrap_or_default();
|
let args = matches
|
||||||
|
.get_many::<OsString>(ARGS_FOR_APP)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.map(|s| s.as_os_str());
|
||||||
|
|
||||||
// don't waste time deallocating; the process ends anyway
|
// don't waste time deallocating; the process ends anyway
|
||||||
// ManuallyDrop will leak the bytes because we don't drop manually
|
// ManuallyDrop will leak the bytes because we don't drop manually
|
||||||
|
@ -784,7 +783,10 @@ pub fn build(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = matches.values_of_os(ARGS_FOR_APP).unwrap_or_default();
|
let args = matches
|
||||||
|
.get_many::<OsString>(ARGS_FOR_APP)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.map(|s| s.as_os_str());
|
||||||
|
|
||||||
// don't waste time deallocating; the process ends anyway
|
// don't waste time deallocating; the process ends anyway
|
||||||
// ManuallyDrop will leak the bytes because we don't drop manually
|
// ManuallyDrop will leak the bytes because we don't drop manually
|
||||||
|
@ -795,7 +797,7 @@ pub fn build(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(BuildFileError::ErrorModule { module, total_time }) => {
|
Err(BuildFileError::ErrorModule { module, total_time }) => {
|
||||||
handle_error_module(module, total_time, filename, true)
|
handle_error_module(module, total_time, path.as_os_str(), true)
|
||||||
}
|
}
|
||||||
Err(BuildFileError::LoadingProblem(problem)) => handle_loading_problem(problem),
|
Err(BuildFileError::LoadingProblem(problem)) => handle_loading_problem(problem),
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use roc_packaging::cache::{self, RocCacheDir};
|
||||||
use std::fs::{self, FileType};
|
use std::fs::{self, FileType};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::str::FromStr;
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -35,7 +36,7 @@ fn main() -> io::Result<()> {
|
||||||
|
|
||||||
let exit_code = match matches.subcommand() {
|
let exit_code = match matches.subcommand() {
|
||||||
None => {
|
None => {
|
||||||
if matches.is_present(ROC_FILE) {
|
if matches.contains_id(ROC_FILE) {
|
||||||
build(
|
build(
|
||||||
&matches,
|
&matches,
|
||||||
BuildConfig::BuildAndRunIfNoErrors,
|
BuildConfig::BuildAndRunIfNoErrors,
|
||||||
|
@ -50,7 +51,7 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((CMD_RUN, matches)) => {
|
Some((CMD_RUN, matches)) => {
|
||||||
if matches.is_present(ROC_FILE) {
|
if matches.contains_id(ROC_FILE) {
|
||||||
build(
|
build(
|
||||||
matches,
|
matches,
|
||||||
BuildConfig::BuildAndRun,
|
BuildConfig::BuildAndRun,
|
||||||
|
@ -65,7 +66,7 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((CMD_TEST, matches)) => {
|
Some((CMD_TEST, matches)) => {
|
||||||
if matches.is_present(ROC_FILE) {
|
if matches.contains_id(ROC_FILE) {
|
||||||
test(matches, Triple::host())
|
test(matches, Triple::host())
|
||||||
} else {
|
} else {
|
||||||
eprintln!("What .roc file do you want to test? Specify it at the end of the `roc test` command.");
|
eprintln!("What .roc file do you want to test? Specify it at the end of the `roc test` command.");
|
||||||
|
@ -74,7 +75,7 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((CMD_DEV, matches)) => {
|
Some((CMD_DEV, matches)) => {
|
||||||
if matches.is_present(ROC_FILE) {
|
if matches.contains_id(ROC_FILE) {
|
||||||
build(
|
build(
|
||||||
matches,
|
matches,
|
||||||
BuildConfig::BuildAndRunIfNoErrors,
|
BuildConfig::BuildAndRunIfNoErrors,
|
||||||
|
@ -89,12 +90,12 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((CMD_GLUE, matches)) => {
|
Some((CMD_GLUE, matches)) => {
|
||||||
let input_path = Path::new(matches.value_of_os(ROC_FILE).unwrap());
|
let input_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
let output_path = Path::new(matches.value_of_os(GLUE_DIR).unwrap());
|
let output_path = matches.get_one::<PathBuf>(GLUE_DIR).unwrap();
|
||||||
let spec_path = Path::new(matches.value_of_os(GLUE_SPEC).unwrap());
|
let spec_path = matches.get_one::<PathBuf>(GLUE_SPEC).unwrap();
|
||||||
|
|
||||||
// have the backend supply `roc_alloc` and friends
|
// have the backend supply `roc_alloc` and friends
|
||||||
let backend = match matches.is_present(FLAG_DEV) {
|
let backend = match matches.get_flag(FLAG_DEV) {
|
||||||
true => CodeGenBackend::Assembly(AssemblyBackendMode::Test),
|
true => CodeGenBackend::Assembly(AssemblyBackendMode::Test),
|
||||||
false => CodeGenBackend::Llvm(LlvmBackendMode::BinaryGlue),
|
false => CodeGenBackend::Llvm(LlvmBackendMode::BinaryGlue),
|
||||||
};
|
};
|
||||||
|
@ -108,8 +109,12 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((CMD_GEN_STUB_LIB, matches)) => {
|
Some((CMD_GEN_STUB_LIB, matches)) => {
|
||||||
let input_path = Path::new(matches.value_of_os(ROC_FILE).unwrap());
|
let input_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
let target: Target = matches.value_of_t(FLAG_TARGET).unwrap_or_default();
|
let target = matches
|
||||||
|
.get_one::<String>(FLAG_TARGET)
|
||||||
|
.map(|s| Target::from_str(s).ok())
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or_default();
|
||||||
roc_linker::generate_stub_lib(
|
roc_linker::generate_stub_lib(
|
||||||
input_path,
|
input_path,
|
||||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||||
|
@ -117,11 +122,12 @@ fn main() -> io::Result<()> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Some((CMD_BUILD, matches)) => {
|
Some((CMD_BUILD, matches)) => {
|
||||||
let target: Target = matches.value_of_t(FLAG_TARGET).unwrap_or_default();
|
let target = matches
|
||||||
let link_type = match (
|
.get_one::<String>(FLAG_TARGET)
|
||||||
matches.is_present(FLAG_LIB),
|
.map(|s| Target::from_str(s).ok())
|
||||||
matches.is_present(FLAG_NO_LINK),
|
.flatten()
|
||||||
) {
|
.unwrap_or_default();
|
||||||
|
let link_type = match (matches.get_flag(FLAG_LIB), matches.get_flag(FLAG_NO_LINK)) {
|
||||||
(true, false) => LinkType::Dylib,
|
(true, false) => LinkType::Dylib,
|
||||||
(true, true) => user_error!("build can only be one of `--lib` or `--no-link`"),
|
(true, true) => user_error!("build can only be one of `--lib` or `--no-link`"),
|
||||||
(false, true) => LinkType::None,
|
(false, true) => LinkType::None,
|
||||||
|
@ -139,22 +145,18 @@ fn main() -> io::Result<()> {
|
||||||
Some((CMD_CHECK, matches)) => {
|
Some((CMD_CHECK, matches)) => {
|
||||||
let arena = bumpalo::Bump::new();
|
let arena = bumpalo::Bump::new();
|
||||||
|
|
||||||
let emit_timings = matches.is_present(FLAG_TIME);
|
let emit_timings = matches.get_flag(FLAG_TIME);
|
||||||
let filename = matches.value_of_os(ROC_FILE).unwrap();
|
let roc_file_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
let roc_file_path = PathBuf::from(filename);
|
let threading = match matches.get_one::<usize>(roc_cli::FLAG_MAX_THREADS) {
|
||||||
let threading = match matches
|
|
||||||
.value_of(roc_cli::FLAG_MAX_THREADS)
|
|
||||||
.and_then(|s| s.parse::<usize>().ok())
|
|
||||||
{
|
|
||||||
None => Threading::AllAvailable,
|
None => Threading::AllAvailable,
|
||||||
Some(0) => user_error!("cannot build with at most 0 threads"),
|
Some(0) => user_error!("cannot build with at most 0 threads"),
|
||||||
Some(1) => Threading::Single,
|
Some(1) => Threading::Single,
|
||||||
Some(n) => Threading::AtMost(n),
|
Some(n) => Threading::AtMost(*n),
|
||||||
};
|
};
|
||||||
|
|
||||||
match check_file(
|
match check_file(
|
||||||
&arena,
|
&arena,
|
||||||
roc_file_path,
|
roc_file_path.to_owned(),
|
||||||
emit_timings,
|
emit_timings,
|
||||||
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
RocCacheDir::Persistent(cache::roc_cache_dir().as_path()),
|
||||||
threading,
|
threading,
|
||||||
|
@ -203,11 +205,11 @@ fn main() -> io::Result<()> {
|
||||||
Some((CMD_REPL, _)) => Ok(roc_repl_cli::main()),
|
Some((CMD_REPL, _)) => Ok(roc_repl_cli::main()),
|
||||||
Some((CMD_EDIT, matches)) => {
|
Some((CMD_EDIT, matches)) => {
|
||||||
match matches
|
match matches
|
||||||
.values_of_os(DIRECTORY_OR_FILES)
|
.get_many::<OsString>(DIRECTORY_OR_FILES)
|
||||||
.map(|mut values| values.next())
|
.map(|mut values| values.next())
|
||||||
{
|
{
|
||||||
Some(Some(os_str)) => {
|
Some(Some(os_string)) => {
|
||||||
launch_editor(Some(Path::new(os_str)))?;
|
launch_editor(Some(Path::new(os_string)))?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
launch_editor(None)?;
|
launch_editor(None)?;
|
||||||
|
@ -218,14 +220,14 @@ fn main() -> io::Result<()> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
Some((CMD_DOCS, matches)) => {
|
Some((CMD_DOCS, matches)) => {
|
||||||
let root_filename = matches.value_of_os(ROC_FILE).unwrap();
|
let root_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
|
||||||
|
|
||||||
generate_docs_html(PathBuf::from(root_filename));
|
generate_docs_html(root_path.to_owned());
|
||||||
|
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
Some((CMD_FORMAT, matches)) => {
|
Some((CMD_FORMAT, matches)) => {
|
||||||
let maybe_values = matches.values_of_os(DIRECTORY_OR_FILES);
|
let maybe_values = matches.get_many::<OsString>(DIRECTORY_OR_FILES);
|
||||||
|
|
||||||
let mut values: Vec<OsString> = Vec::new();
|
let mut values: Vec<OsString> = Vec::new();
|
||||||
|
|
||||||
|
@ -241,8 +243,8 @@ fn main() -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(os_values) => {
|
Some(os_values) => {
|
||||||
for os_str in os_values {
|
for os_string in os_values {
|
||||||
values.push(os_str.to_os_string());
|
values.push(os_string.to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +257,7 @@ fn main() -> io::Result<()> {
|
||||||
roc_files_recursive(os_str.as_os_str(), metadata.file_type(), &mut roc_files)?;
|
roc_files_recursive(os_str.as_os_str(), metadata.file_type(), &mut roc_files)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let format_mode = match matches.is_present(FLAG_CHECK) {
|
let format_mode = match matches.get_flag(FLAG_CHECK) {
|
||||||
true => FormatMode::CheckOnly,
|
true => FormatMode::CheckOnly,
|
||||||
false => FormatMode::Format,
|
false => FormatMode::Format,
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,7 +51,7 @@ mod cli_run {
|
||||||
const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE);
|
const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE);
|
||||||
const LINKER_FLAG: &str = concatcp!("--", roc_cli::FLAG_LINKER);
|
const LINKER_FLAG: &str = concatcp!("--", roc_cli::FLAG_LINKER);
|
||||||
const CHECK_FLAG: &str = concatcp!("--", roc_cli::FLAG_CHECK);
|
const CHECK_FLAG: &str = concatcp!("--", roc_cli::FLAG_CHECK);
|
||||||
const PREBUILT_PLATFORM: &str = concatcp!("--", roc_cli::FLAG_PREBUILT, "=true");
|
const PREBUILT_PLATFORM: &str = concatcp!("--", roc_cli::FLAG_PREBUILT);
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET);
|
const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET);
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,7 @@ fn gen_from_mono_module_dev_wasm32<'a>(
|
||||||
|
|
||||||
let host_bytes = std::fs::read(preprocessed_host_path).unwrap_or_else(|_| {
|
let host_bytes = std::fs::read(preprocessed_host_path).unwrap_or_else(|_| {
|
||||||
internal_error!(
|
internal_error!(
|
||||||
"Failed to read host object file {}! Try setting --prebuilt-platform=false",
|
"Failed to read host object file {}! Try omitting --prebuilt-platform",
|
||||||
preprocessed_host_path.display()
|
preprocessed_host_path.display()
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -794,7 +794,7 @@ fn build_loaded_file<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// For example, if we're loading the platform from a URL, it's automatically prebuilt
|
// For example, if we're loading the platform from a URL, it's automatically prebuilt
|
||||||
// even if the --prebuilt-platform=true CLI flag wasn't set.
|
// even if the --prebuilt-platform CLI flag wasn't set.
|
||||||
let is_platform_prebuilt = prebuilt_requested || loaded.uses_prebuilt_platform;
|
let is_platform_prebuilt = prebuilt_requested || loaded.uses_prebuilt_platform;
|
||||||
|
|
||||||
let cwd = app_module_path.parent().unwrap();
|
let cwd = app_module_path.parent().unwrap();
|
||||||
|
@ -1036,9 +1036,10 @@ fn build_loaded_file<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalid_prebuilt_platform(prebuilt_requested: bool, preprocessed_host_path: PathBuf) {
|
fn invalid_prebuilt_platform(prebuilt_requested: bool, preprocessed_host_path: PathBuf) {
|
||||||
let prefix = match prebuilt_requested {
|
let prefix = if prebuilt_requested {
|
||||||
true => "Because I was run with --prebuilt-platform=true, ",
|
"Because I was run with --prebuilt-platform, "
|
||||||
false => "",
|
} else {
|
||||||
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
let preprocessed_host_path_str = preprocessed_host_path.to_string_lossy();
|
let preprocessed_host_path_str = preprocessed_host_path.to_string_lossy();
|
||||||
|
@ -1057,7 +1058,7 @@ fn invalid_prebuilt_platform(prebuilt_requested: bool, preprocessed_host_path: P
|
||||||
|
|
||||||
However, it was not there!{}
|
However, it was not there!{}
|
||||||
|
|
||||||
If you have the platform's source code locally, you may be able to generate it by re-running this command with --prebuilt-platform=false
|
If you have the platform's source code locally, you may be able to generate it by re-running this command omitting --prebuilt-platform
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
prefix,
|
prefix,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Provides a binary that is only used for static build servers.
|
//! Provides a binary that is only used for static build servers.
|
||||||
use clap::{Arg, Command};
|
use clap::{value_parser, Arg, Command};
|
||||||
use roc_docs::generate_docs_html;
|
use roc_docs::generate_docs_html;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -12,16 +12,15 @@ fn main() -> io::Result<()> {
|
||||||
.about("Generate documentation for a Roc package")
|
.about("Generate documentation for a Roc package")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(ROC_FILE)
|
Arg::new(ROC_FILE)
|
||||||
.multiple_values(true)
|
|
||||||
.help("The package's main .roc file")
|
.help("The package's main .roc file")
|
||||||
.allow_invalid_utf8(true)
|
.num_args(0..)
|
||||||
.required(false)
|
.value_parser(value_parser!(PathBuf))
|
||||||
.default_value(DEFAULT_ROC_FILENAME),
|
.default_value(DEFAULT_ROC_FILENAME),
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
// Populate roc_files
|
// Populate roc_files
|
||||||
generate_docs_html(PathBuf::from(matches.value_of_os(ROC_FILE).unwrap()));
|
generate_docs_html(matches.get_one::<PathBuf>(ROC_FILE).unwrap().to_owned());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn nixos_error_if_dynamic(url: &str, dest_dir: &Path) {
|
||||||
You can:\n\n\t\
|
You can:\n\n\t\
|
||||||
- Download the source of the platform and build it locally, like in this example:\n\t \
|
- Download the source of the platform and build it locally, like in this example:\n\t \
|
||||||
https://github.com/roc-lang/roc/blob/main/examples/platform-switching/rocLovesRust.roc.\n\t \
|
https://github.com/roc-lang/roc/blob/main/examples/platform-switching/rocLovesRust.roc.\n\t \
|
||||||
When building your roc application, you can use the flag `--prebuilt-platform=true` to prevent the platform from being rebuilt every time.\n\t \
|
When building your roc application, you can use the flag `--prebuilt-platform` to prevent the platform from being rebuilt every time.\n\t \
|
||||||
For some graphical platforms you may need to use https://github.com/guibou/nixGL.\n\n\t\
|
For some graphical platforms you may need to use https://github.com/guibou/nixGL.\n\n\t\
|
||||||
- Contact the author of the platform to ask them to statically link their platform.\n\t \
|
- Contact the author of the platform to ask them to statically link their platform.\n\t \
|
||||||
musl can be used to prevent a dynamic dependency on the systems' libc.\n\t \
|
musl can be used to prevent a dynamic dependency on the systems' libc.\n\t \
|
||||||
|
|
|
@ -44,8 +44,7 @@ fn main() -> io::Result<()> {
|
||||||
|
|
||||||
let args_for_app = Arg::new(ARGS_FOR_APP)
|
let args_for_app = Arg::new(ARGS_FOR_APP)
|
||||||
.help("Arguments to pass into the WebAssembly app\ne.g. `roc_wasm_interp app.wasm 123 123.45`")
|
.help("Arguments to pass into the WebAssembly app\ne.g. `roc_wasm_interp app.wasm 123 123.45`")
|
||||||
.multiple_values(true)
|
.num_args(0..);
|
||||||
.takes_value(true);
|
|
||||||
|
|
||||||
let app = Command::new("roc_wasm_interp")
|
let app = Command::new("roc_wasm_interp")
|
||||||
.about("Run the given .wasm file")
|
.about("Run the given .wasm file")
|
||||||
|
@ -53,7 +52,6 @@ fn main() -> io::Result<()> {
|
||||||
.arg(flag_debug)
|
.arg(flag_debug)
|
||||||
.arg(flag_hex)
|
.arg(flag_hex)
|
||||||
.arg(wasm_file_to_run)
|
.arg(wasm_file_to_run)
|
||||||
.trailing_var_arg(true)
|
|
||||||
.arg(args_for_app);
|
.arg(args_for_app);
|
||||||
|
|
||||||
// Parse the command line arguments
|
// Parse the command line arguments
|
||||||
|
|
|
@ -23,7 +23,7 @@ rustPlatform.buildRustPackage {
|
||||||
cargoLock = {
|
cargoLock = {
|
||||||
lockFile = ./Cargo.lock;
|
lockFile = ./Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"confy-0.5.1" = "sha256-3PQdz9W/uJd4CaUZdwAd2u3JJ100SFAoKLCFE6THRZI=";
|
"confy-0.5.1" = "sha256-KML/uoze2djsFhYk488QAtauethDaC+0aZ3q56yAhuY=";
|
||||||
"criterion-0.3.5" = "sha256-+FibPQGiR45g28xCHcM0pMN+C+Q8gO8206Wb5fiTy+k=";
|
"criterion-0.3.5" = "sha256-+FibPQGiR45g28xCHcM0pMN+C+Q8gO8206Wb5fiTy+k=";
|
||||||
"inkwell-0.1.0" = "sha256-1kpvY3naS33B99nuu5ZYhb7mdddAyG+DkbUl/RG1Ptg=";
|
"inkwell-0.1.0" = "sha256-1kpvY3naS33B99nuu5ZYhb7mdddAyG+DkbUl/RG1Ptg=";
|
||||||
"plotters-0.3.1" = "sha256-noy/RSjoEPZZbOJTZw1yxGcX5S+2q/7mxnUrzDyxOFw=";
|
"plotters-0.3.1" = "sha256-noy/RSjoEPZZbOJTZw1yxGcX5S+2q/7mxnUrzDyxOFw=";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue