-
-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace cli flag --prebuilt-platform
with --build-host
#6859
base: main
Are you sure you want to change the base?
Conversation
cd13762
to
8383fd6
Compare
4521f92
to
85447ec
Compare
let platform_main_roc = match &loaded.entry_point { | ||
EntryPoint::Executable { platform_path, .. } => platform_path.to_path_buf(), | ||
_ => unreachable!(), | ||
}; | ||
|
||
// For example, if we're loading the platform from a URL, it's automatically prebuilt | ||
// even if the --prebuilt-platform CLI flag wasn't set. | ||
let is_platform_prebuilt = prebuilt_requested || loaded.uses_prebuilt_platform; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should add a check here; if loaded.uses_prebuilt_platform
is true and also build_host_requested
then the platform is a URL release and we have also been instructed to rebuild the host with the flag --build-host
. These two are incompatible because roc cannot build the host.
|
||
// file name for a stubbed app dynamic library file | ||
pub fn stub_app_lib_file_name(&self) -> String { | ||
format!("libapp.{}", self.dynamic_library_file_ext()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Windows I think it may just be app.dll
, on unix* systems we need the lib
prepended
--prebuilt-platform
with --build-host
--prebuilt-platform
with --build-host
5f8ff89
to
61d6b5f
Compare
Signed-off-by: Luke Boswell <[email protected]>
61d6b5f
to
89d63f2
Compare
// Copy preprocessed host to executable location. | ||
// The surgical linker will modify that copy in-place. | ||
//std::fs::copy(&preprocessed_path, &output_exe_path).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO - investigate why this is commented out.
} | ||
|
||
#[test] | ||
#[cfg_attr(windows, ignore)] | ||
fn nqueens() { | ||
test_benchmark("nQueens.roc", &["6"], "4\n", UseValgrind::Yes) | ||
test_benchmark("nQueens.roc", vec!["6"], "4\n", UseValgrind::Yes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this use vec now?
/// Normalise the output for comparison in tests by replacing with a placeholder | ||
fn normalize_for_tests(input: &str) -> String { | ||
// normalise from windows line endings to unix line endings | ||
let without_clrf = input.replace("\r\n", "\n"); | ||
|
||
// remove ANSI color codes | ||
let without_ansi = roc_reporting::report::strip_colors(without_clrf.as_str()); | ||
|
||
// replace timings with a placeholder | ||
let regex = Regex::new(r" in (\d+) ms\.").expect("Invalid regex pattern"); | ||
let replacement = " in <ignored for test> ms."; | ||
let without_timings = regex.replace_all(&without_ansi, replacement); | ||
|
||
// replace file paths with a placeholder | ||
let filepath_regex = | ||
Regex::new(r"\[([^:]+):(\d+)\]").expect("Invalid filepath regex pattern"); | ||
let filepath_replacement = "[<ignored for tests>:$2]"; | ||
let without_filepaths = filepath_regex.replace_all(&without_timings, filepath_replacement); | ||
|
||
// replace error summary timings | ||
let error_summary_regex = | ||
Regex::new(r"(\d+) error(?:s)? and (\d+) warning(?:s)? found in \d+ ms") | ||
.expect("Invalid error summary regex pattern"); | ||
let error_summary_replacement = "$1 error and $2 warning found in <ignored for test> ms"; | ||
error_summary_regex | ||
.replace_all(&without_filepaths, error_summary_replacement) | ||
.to_string() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice :) I don't think we had this before
) | ||
let expected_ending = "Roc <3 Rust!\n🔨 Building host ...\n"; | ||
let runner = Run::new_roc() | ||
.arg(CMD_RUN) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming that run
still tries to run a program even if there are errors, that is probably not what we want to use here...
TODO
|
I'll get started on moving the build process out from under valgrind like we currently do on main |
I'm not a fan of this java style: impl Run {
pub fn new<S>(exe: S) -> Self
where
S: AsRef<OsStr>,
{
let exe: OsString = exe.as_ref().into();
Self {
args: vec![exe],
stdin_vals: vec![],
env: vec![],
cwd: None,
run_with_valgrind: false,
}
}
pub fn new_roc() -> Self {
Self::new(path_to_roc_binary())
}
pub fn command(&self) -> Command {
let mut cmd = Command::new(&self.args[0]);
for arg in self.args[1..].iter() {
cmd.arg(arg);
}
for (k, v) in self.env.iter() {
cmd.env(k, v);
}
cmd
}
pub fn valgrind_command(&self) -> (Command, NamedTempFile) {
let mut cmd = Command::new("valgrind"); I can't easily see anymore which values a function actually uses, the old version on main was not great either but I am going to take a stab at a functional refactor. Sidenote: Be careful with grouping things in utils files/folders, this can slow compilation because many crates can end up relying on a fat utils crate/file with many dependencies. Also make sure to put dependencies that are only required for testing under dev-dependencies in Cargo.toml |
This will take a while, btw I'm not getting rid of a lot, just mostly shuffling things around, feeling what makes the most sense and is least complex. I'm also going to try removing all the valgrind xml handling code, we may not be using that anymore. |
I've reviewed everything except for |
@Anton-4 the new builder style is pretty popular in Rust because of a lack of optional or named parameters. If it had those, then we wouldn't need builders. What are you planning to do instead? I think something like this could work: #[derive(Default)]
pub struct RunParams {
args: Vec<OsString>,
env: Vec<(String, String)>,
stdin_vals: Vec<&'static str>,
cwd: Option<OsString>,
run_with_valgrind: bool,
}
pub fn run_command(cmd: Command, params: RunParams);
let out =
run_command(
ROC_CLI,
RunParams {
args: ["abc", "def"].into(),
env: [("ROC_TEST", "1")].into(),
..Default::default(),
}
).unwrap(); |
.run(); | ||
out.assert_clean_success(); | ||
}); | ||
} | ||
|
||
fn test_benchmark( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that the above tests show all of the steps we're taking: build the host if necessary, run the test with these args, check the output. We don't seem to do that for the benchmark tests. Are you planning on making these two groups work the same way eventually, or is there a reason we have them working differently?
use std::path::PathBuf; | ||
use std::process::{Command, ExitStatus, Stdio}; | ||
use std::sync::Mutex; | ||
use tempfile::NamedTempFile; | ||
|
||
lazy_static::lazy_static! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: LazyLock has been stabilized, we should prefer that instead of an external library.
Right now, I just have two functions
That also seems like a nice alternative with low complexity, I'll keep it in mind. |
Still need to do some refactoring of the glue tests and valgrind tests, targeting tomorrow now... |
So... looks like the Builder does make the best trade-offs after all 😄 Just functions does not work because we need to able to clone let roc_cmd_out =
run_roc_maybe_both_linkers(
RocCmdParams {
sub_command: CMD_BUILD,
args: all_to_os_string([
roc_file_path.to_str().unwrap(),
BUILD_HOST_FLAG,
SUPPRESS_BUILD_HOST_WARNING_FLAG,
]),
..Default::default()
},
ON_LINUX
); Well, lessons learned, I should have asked more questions instead of dismissing it. |
I did make some nice improvements in other places though, I'm going to add those here. |
Need to make sure I don't forget this:
|
This PR is built on top of #6808, which should be merge first.
This PR makes progress towards decoupling roc from the host toolchains, by moving host rebuilding behind a compiler flag so it is no longer the default behaviour. It is still available where required using
--build-host
however will give a warning;I was originally working towards removing rebuilding in one go in #6696, however I realised this was a very large and difficult change due to the need to change all of the cli tests.
This PR achieves the same effect, effectively removing platform rebuilding from the cli for end users -- while keeping the cli tests as they are. This enables the cli tests to be adapted one by one instead of all at once. Once all of the tests have a build script, host rebuilding functionality can be entirely removed along with the associated dependencies.
Application authors who use a platform release from a URL package are not affected by this change. These users will continue to use a prebuilt platform.
Platform authors need to include a build script in their platform to build host binaries. This change will make running platform example less convenient if they are not using a URL release, as the platform binaries will need to be built first in a separate step. For example this workflow;
roc build.roc
using host toolchain e.g.cargo
orzig
roc examples/hello-world.roc