Honestly you are right, I could have been more curious (btw I did run that before your post).
It just seemed bizarre to me that there was no explanation or question of such a common and cryptic command. You need to know what $() is and also the ' ' since there are different ways to do the same. The difference of that and eval, what opam envâŚand to be honest, who truly likes coding in bash? Hard to be curious about such an ugly language. Ocaml and Coq are so much better
Anyway, will post an answer soon. Iâve made good progress on this.
Please note : The back ticks shown around opam env after eval are essential. They change the order of application, which is very important. The back ticks tells the system to first evaluate opam env (which returns a string of commands) and then eval executes those commands in the string. Executing them doesnât return anything, but it initializes the Opam environment behind the scenes.
tldr: it activates your opam context according to your current switch â similar to how a python virtual env is activated in python but for opam.
What eval $(opam env) does is command substitute $(opam env) i.e. run opam env in a subshell (thatâs what $( ) does) return the string it outputted and then give it to eval to evaluate as bash code. Command substitution is usually done to next the output of commands in bash. In python eval would interpret the input string to it as literal python code to evaluate, parse, run here similarly it would do the same but assume itâs bash (is my guess).
What does opam env does? It returns the current bash env variables for the current swithc (i.e. siwth approximately euqal to opam environment). So therefore, doing:
eval $(opam env)
does this:
first runs in a subshell because thats what $(cmd) does. Itâs [command substitution][1]. Usually used to nest commands.
then itâs output (so the output string of $(opam env)) is given to eval. opam env returns a string of env variables needed to "activate: the current opam env (similar to how you activate virtual envs in python).
finally eval evaluates the string it receives from the command substitution i.e. it parses the string as a bash command and runs it.
Please note : The back ticks shown around opam env after eval are essential. They change the order of application, which is very important. The back ticks tells the system to first evaluate opam env (which returns a string of commands) and then eval executes those commands in the string. Executing them doesnât return anything, but it initializes the Opam environment behind the scenes.
ref: Installing OCaml ¡ OCaml Documentation
@yawaramin Trying to understand a few things. First when is eval $(opam env) or
eval âopam envâ (use the other tick sorry donât know how to display it) supposed to be ran? If I understand it correct, it âactivates the opam environmen for a switchâ so one is supposed to get into a switch first (e.g. opam switch 4.12.1), then one does eval $(opam env) to fully activate the env for that switch. Is that correct?
Related, Iâm actually not sure what opam init does or why itâs needed despite reading multiple resources but my guess is that its only needed once during the first set up of opam. Is that right?
Context for question, I was told the following and trying to understand when to call eval $(opam env) correctly for the right switch I choose:
If you want a single global coq installation (for say your laptop):
opam switch create 4.12.1 opam switch 4.12.1 opam repo add coq-released Index of /opam/released opam install coq
If you want a local installation with a local opam environment:
opam switch create . 4.12.1 eval $(opam env) opam repo add coq-released Index of /opam/released opam install coq
The answer to both of your questions is, yes that is correct.
Now, another question may be, why even should opam require this eval $(opam env) dance? Canât it just set up the environment without it? After all, we already need to run opam switch ... to select the opam switch we want to work in.
And thatâs a valid question! Perhaps you would be interested in filing a ticket on the opam GitHub repo asking about this and seeing if it could be improved?
For Opam, Dune and many other commands you will encounter in the OCaml community, they have decent --help pages. This fact wonât be obvious to people using OCaml for the first time. (An analog would be the Python community standardizing their documentation on Sphinx webpages like https://readthedocs.org, or the OpenBSD community standardizing their documentation on man pages. If someone hadnât told you, you could get lost).
What is missing, and what I think you are asking, is how do all the individual commands connect? A --help page may not be sufficient. Here is a stab at describing the typical flow:
Command
When
DESCRIPTION from --help
opam init
Once per machine
opam init --help: The init command initialises a local âopam rootâ (by default, ~.opam) that holds opamâs data and packages. This is a necessary step for normal operation of opam. The initial software repositories are fetched âŚ
opam switch create
Once per project
opam switch --help: This command is used to manage âswitchesâ, which are independent installation prefixes with their own compiler and sets of installed and pinned packages. ⌠opam switch set sets the default switch globally, but it is also possible to select a switch in a given shell session.
opam env --switch SWITCH
Everytime you open a shell (ex. bash) terminal
opam env --help: Returns the bindings for the environment variables set in the current switch, e.g. PATH, in a format intended to be evaluated by a shell. ⌠This is most usefully used as eval $(opam env) to have further shell commands be evaluated in the proper opam context.
Note: There is a way to avoid having to type eval $(opam env) every time you open a terminal: use opam init --auto-setup once and use opam switch set SWITCH once. See the --help for what those do. I personally donât use that approach; YMMV.
@yawaramin when do we run eval $(opam env)? is eval $(opam env) supposed to be ran before opam init or after it or after the switch has been activated e.g. opam switch create debug_proj_4.09.1 4.09.1; opam switch debug_proj_4.09.1?
This is explained in the âUp and Runningâ page I linked to above and also in Jonahâs great answer above. If anything is not clear, would you mind filing an issue? Thereâs a link at the bottom right of the âUp and Runningâ page.