-
Notifications
You must be signed in to change notification settings - Fork 82
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
Enable CI on windows and fix it. #329
Conversation
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.
This looks okay overall, see one question on the stderr rediction.
I'm not fond of the generalized use of explicit newline quoting in string literals in the testsuite, I find that it really hurts readability. Can we use quoted string literals instead?
testsuite/internal.ml
Outdated
flag [\"library\"; \"ocaml\"; \"record_foo_stubs\"]\n\ | ||
(S ([A \"-cclib\"; A \"-lfoo_stubs\"]));\n\ | ||
| _ -> ()\n\ | ||
end\n\ |
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.
Urgh, can you use quoted literals instead to avoid the many escapes here? (If there is a problem with \r\n
somehow, we could inject a small helper function that removes the \r
.)
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've pushed 0f2342a
src/my_std.ml
Outdated
@@ -279,7 +279,7 @@ let sys_command = | |||
match Sys.os_type with | |||
| "Win32" -> fun cmd -> | |||
if cmd = "" then 0 else | |||
let cmd = "bash --norc -c " ^ Filename.quote cmd in | |||
let cmd = "bash --norc -c " ^ Filename.quote cmd ^ " 2>&1" in |
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.
Can you explain why we need this change?
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'm not happy with this change but it makes the testsuite pass.
I think the explanation is as follow:
- if
is_degraded
or Sys.win32
is true,execute_many
falls back tosys_command
to implementexecute_many
. - otherwise, the logic from
Ocamlbuild_executor.execute
is used, which reads both stderr and stdout into ajob_buffer
. - The testuite sometime expect some output on stdout.
I'm still looking for a better solution.
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've moved the stderr redirection to command.ml
where I think it belongs and added a small comment.
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 went to look at the code of ocamlbuild_executor to understand what is going on. ocamlbuild_executor
does not just redirect stderr into stdout, it lets the command write to different places and then on job termination it adds stdout, then stderr, to the job buffer, in that order. The change that you implemented does not match this behavior, it only works for commands that have only stdout or only stderr output.
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.
Out of curiosity: in the execute_many
definition, have you tried removing the "or we are on Windows" condition, to get the ocamlbuild_executor logic to run also on Windows? When ocamlbuild was first written, I think the Windows support in stdlib and Unix was weaker than it is now, there is a small chance that removing those alternate paths could work today.
(We could probably also get rid of the "is_degraded" notion, which I think was designed to let ocamlbuild build the compiler in constrained environments. ocamlbuild is not considered as build system for the OCaml compiler anymore, so maybe we could forget about this case altogether. But this is more work than I was considering putting in ocamlbuild again.)
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've tried removing the special case for windows in execute_many but it fails in various ways. It seems that the patch https://raw.githubusercontent.com/ocaml-opam/opam-repository-mingw/354a87b397856f2a70024c5c83fc5001074935b6/packages/ocamlbuild/ocamlbuild.0.14.2/files/ocamlbuild-0.14.2.patch is doing that better. I could look at merging that patch but I'd rather first have a working CI for windows
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 went to look at the code of ocamlbuild_executor to understand what is going on.
ocamlbuild_executor
does not just redirect stderr into stdout, it lets the command write to different places and then on job termination it adds stdout, then stderr, to the job buffer, in that order. The change that you implemented does not match this behavior, it only works for commands that have only stdout or only stderr output.
Looking at the code quickly, my impression is that it can interleave stdout and stderr. In the main loop
, you can see
chrfds, do_read ~loop:false;
which tries to read any both stdout and stderr and push the content to job_buffer
.
Maybe I'm misunderstanding the logic.
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.
Ok, this suggests that I misunderstood, and there may be no good way to ensure that we get the same output. In that context I am okay with your current choice even though it is sort of a hack.
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.
Out of curiosity: in the
execute_many
definition, have you tried removing the "or we are on Windows" condition, to get the ocamlbuild_executor logic to run also on Windows? When ocamlbuild was first written, I think the Windows support in stdlib and Unix was weaker than it is now, there is a small chance that removing those alternate paths could work today.(We could probably also get rid of the "is_degraded" notion, which I think was designed to let ocamlbuild build the compiler in constrained environments. ocamlbuild is not considered as build system for the OCaml compiler anymore, so maybe we could forget about this case altogether. But this is more work than I was considering putting in ocamlbuild again.)
76c30c1
to
5e26de4
Compare
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.
Looks fine on first glance with my minimal Windows experience.
cc-ing more experienced Windows users @dra27 @jonahbeckford
src/shell.ml
Outdated
@@ -39,7 +39,7 @@ let run args target = | |||
let cmd = String.concat " " (List.map quote_filename_if_needed args) in | |||
if !*My_unix.is_degraded || Sys.os_type = "Win32" then | |||
begin | |||
Log.event cmd target Tags.empty; | |||
if false then Log.event cmd target Tags.empty; |
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 is this disabled?
if false then Log.event cmd target Tags.empty; | |
Log.event cmd target Tags.empty; |
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.
It make the testsuite fail because it output cmd
on stdout.
I wonder if we should prefix the command with "+ "
similar to what is done in non-degraded mode. The testsuite filters theses lines out already.
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've added the +
prefix
Ideally what I would like to do is to get good Windows support without making the codebase worse than it already is. I think that the current PR you propose is okay in this respect, the changes are relatively minimal and at the same time justified, and the risk of regression for non-Windows users is low. I propose to merge it and build up from there. On the other hand I am more worried about the fdopen patches in #330, which look like a mix of good ideas (I like getting rid of the "or is win32" case in the "is degraded?" test), inscrutable hacks, and things in the middle, and was never really tested on non-Windows systems if I understand correctly. Taking the good pieces out of it is an excellent idea, and maybe all of it is good and I just don't understand it yet. But making our codebase harder to understand (obscure changes with little explanations and no commit message) is getting convenience right now but also even more pain later, so I would not be in favor. Note: I noticed the same |
Could you cherry-pick that commit (or amend the author information on your own commit) to properly credit fdopen in the metadata? |
… with My_unix (win32 only)
Done |
@kit-ty-kate are you okay with merging this? My reasoning is: the patch looks okay, the potential for non-Windows regression is minimal, and I want to make it as easy as reasonably possible for @hhugo (or of course anyone else) to improve the state of ocamlbuild on Windows. |
(@dbuenzli, just for information, do you have any plan to drop your dependency on ocamlbuild ?, any ETA ?) |
I went ahead and merged. Thanks @hhugo! |
(It may be possible to close the issues that you helpfully linked, but at least the most recent one had more changes that were more contentious, and might deserve a discussion of their own. I hope that the part that you included solves most of the issues with less risk of regression.) |
Not really, but I'd say within two or three years. |
Merging is fine as long as we remember to not release before getting the double-check/approval of the two people i've cc'd above. I'd like to especially double-check the change made to
|
This is a somewhat minimal list of changes to make the testsuite pass on windows.
If you look at the CI jobs, you should see that the testsuite pass under windows.
Includes:
Probably fix #316