-
Notifications
You must be signed in to change notification settings - Fork 409
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
Add experimental toolchain subcommand #10470
Conversation
6bed95a
to
8dbec6e
Compare
I think this PR is missing a description of the motivation why this command is needed. |
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 think this is good, but it can probably be even further simplified with some amount of Unix trickery :-)
bin/toolchain.ml
Outdated
; `Blocks Common.help_secs | ||
] | ||
in | ||
Cmd.info "toolchain" ~doc ~man |
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 think it would be better if this was something like x-experimental-toolchain
as we don't want people to call dune toolchain get 4.14
themselves, this is only something for the cram tests.
otherlibs/stdune/src/fpath.ml
Outdated
let touch ?(perms = 0o666) path = | ||
let fd = Unix.openfile path [ O_CREAT ] perms in | ||
Unix.close fd | ||
;; |
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 was testing the behavior of touch
and Unix.openfile
and I think this only matches when touch
is creating a file. touch
is also often used to update the timestamps (I assume that's what its name refers to), which this doesn't do.
$ stat foo
Access: 2024-04-30 16:09:47.051473084 +0200
Modify: 2024-04-30 16:09:47.051473084 +0200
Change: 2024-04-30 16:09:47.051473084 +0200
Birth: 2024-04-30 16:09:47.051473084 +0200
$ touch foo
$ stat foo
Access: 2024-04-30 16:11:11.278876572 +0200
Modify: 2024-04-30 16:11:11.278876572 +0200
Change: 2024-04-30 16:11:11.278876572 +0200
Birth: 2024-04-30 16:09:47.051473084 +0200
Surprisingly Unix.openfile path [ O_CREAT ]
doesn't even seem to change the atime
.
I suggest either renaming this into something like ensure_exists
or implementing the timestamp update (as something like updating timestamps can indeed be useful for cache operations etc).
src/dune_pkg/toolchain.ml
Outdated
[ Pp.textf "Expected %s to be a directory but it is not." (Path.to_string path) ] | ||
;; | ||
|
||
let cache_dir () = |
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 think this can be simplified using Xdg.cache_dir
.
src/dune_pkg/toolchain.ml
Outdated
run_command | ||
~dir:source_dir | ||
configure_script | ||
[ sprintf "--prefix=%s" (Path.to_string prefix) ] |
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.
[ sprintf "--prefix=%s" (Path.to_string prefix) ] | |
[ "--prefix"; (Path.to_string prefix) ] |
I just checked OCaml's configure script also accepts --prefix <path>
so we can simplify this a tiny amount.
src/dune_pkg/toolchain.ml
Outdated
module Version = struct | ||
type t = | ||
| V_4_14_2 | ||
| V_5_1_1 |
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 think simplifying this to type t = string
would be enough, otherwise the maintenance if 4.14.3
or any other new version happens would start to explode.
bin/toolchain.ml
Outdated
"exec" | ||
~doc: | ||
"Run a command in an environment which includes a toolchain's bin directory in \ | ||
PATH after making sure that the specified toolchain version is intsalled." |
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.
PATH after making sure that the specified toolchain version is intsalled." | |
PATH after making sure that the specified toolchain version is installed." |
I tried to motivate the commands with:
Note that this PR is targeting a newly created "toolchains" branch rather than main. Once we have a working prototype of the toolchains feature we'll make a PR against main and possibly remove the |
I'll get rid of the |
8dbec6e
to
54835c9
Compare
I think I've applied all the feedback. Main changes are that I removed the exec subcommand and changed the The only slightly awkward bit is that when installing with |
This adds a command and module for downloading, building, and installing the ocaml compiler toolchain inside the user's ~/.cache directory. For now this works by hardcoding specific supported versions of the compiler toolchain. In the future we will probably changes this to read information about toolchain packages from the opam repo. Signed-off-by: Stephen Sherratt <stephen@sherra.tt>
54835c9
to
f204c49
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 good! I've added a few minor suggestions.
Testing it it seems to have failed with the cross device link error (with the fix in #10214 I assume), might be useful to cherry-pick that one onto the toolchains
branch.
| Some p -> p | ||
| None -> | ||
User_error.raise | ||
~hints:[ Pp.text "Install \"make\" with your system package manager." ] |
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: I think we have a Pp
formatter for commands.
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 intentionally left this with regular quotes because it's referring to the package name and not the command.
type t = string | ||
|
||
let all = [ "4.14.2"; "5.1.1" ] | ||
let all_by_string = List.map all ~f:(fun t -> t, t) |
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 appears to be unused, maybe not necessary anymore?
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's still used to create the Version.conv
value used when parsing arguments to dune x-experimental-toolchain get
.
|
||
let toolchain_dir t = | ||
let d = Path.relative (Dir.toolchain_base_dir ()) (to_string t) in | ||
Dir.make_and_check_dir d; |
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.
make_and_check_dir
is already called by toolchain_base_dir
and while it doesn't hurt, it also doesn't help.
Maybe make_and_check_dir
could just get inlined into toolchain_base_dir
?
them into the target directory. This two stage installation means | ||
that we can guarantee that if the target directory exists then it | ||
contains the complete installation of the toolchain. *) | ||
let tmp_install_dir t = Path.relative (toolchain_dir t) "_install" |
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.
Suggestion: instead of calling this $XDG_CACHE_DIR/dune/toolchains/_install
it could contain the name of the toolchain in addition. That way the risk of clashes is minimized, if for some reason two toolchains are built at the same time, while making this only very marginally more complex.
(Reducing the risk completely would require locking and I would argue that its not worth the complexity at this moment)
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.
The temporary directory is actually $XDG_CACHE_DIR/dune/toolchains/<version>/_install
. I added a comment which hopefully clarifies this.
Thanks for the feedback @Leonidas-from-XIV! In the interest of simplifying my subsequent PR I'm going to merge this now as is and apply all your additional feedback in a later change. |
Thanks for clarifying. The implementation of the feature looks fine, but the UX needs to be different. Manually managing toolchains doesn't really work with the kind of guarantees we provide with the dune. So I'd like it if we could think of a way to hide all of this from the user. For example, it's completely fine to use this toolchain mechanism to build the compiler when executing the rules. Even if that requires working around the engine a little. |
The plan is to have dune automatically download, build and install the toolchain necessary to build a project while building the project. I added a command for manually managing toolchains so that the logic for managing toolchains can be exercised without needing to set up a project. Can you clarify whether you still see this as posing a problem? |
Without setting up a project or a workspace, how would one specify dependencies anyway? |
The dependencies would need to be specified in the project indeed. The toolchain command can be used to manually install a compiler, no need for a project for that as they are in a shared location and accessible from any project that specifies a matching version of the compiler. |
So why not specify the "toolchain" inside the project as a dependency in the first place? |
Note that this is the highly undesirable part. There's no need for manual installation or anything and installation itself shouldn't even be a concept in dune apart from the |
I think we actually agree and the issue is just one of a misunderstanding of the purpose of the CLI.
Yes, that's the idea, that if you have say, In a way this is more comparable to |
If it's just for testing, you could also just make it a separate binary. This particular detail isn't that important though. |
This adds a command and module for downloading, building, and installing the ocaml compiler toolchain inside the user's ~/.cache directory.
For now this works by hardcoding specific supported versions of the compiler toolchain. In the future we will probably changes this to read information about toolchain packages from the opam repo.
Here's an example of running the
dune toolchain exec <VERSION> <PROG> <ARGS>
command which downloads, builds and installs a toolchain version before running a command in an environment where the toolchain's bin directory is prepended to PATH.There is also a
dune toolchain get <VERSION>
command that just downloads, builds and installs the specified toolchain.The subcommands are just here to allow us to test toolchain logic as we work on it. The main component of this change is the module defined in dune_pkg/toolchain.ml which defines the logic for downloading, building and installing toolchains.