What is the use of eval `opam config env` or eval $(opam env) and their difference?
Asked Answered
F

2

6

After the installation of opam, it asks to do

eval `opam config env`

What is the exact usage of it?


Bounty: where to run eval $(opam env)?

When is eval $(opam env) supposed to be ran?

after the opam init? before the activation of a switch? e.g. if I have:

conda install -c conda-forge opam
opam init

# - install coq: see 
opam switch create debug_proj_4.09.1 4.09.1
opam switch debug_proj_4.09.1
opam repo add coq-released https://coq.inria.fr/opam/released
# install the right version of coq and pins it to it so that future opam installs don't change the coq version
opam pin add coq 8.11.0

where do I put eval $(opam env)?


more related (executing eval in python):

Frankforter answered 10/5, 2015 at 19:48 Comment(5)
how is this realted to eval $(opam env)? #72522912Boatyard
I see this: This is most usefully used as eval $(opam env) to have further shell commands be evaluated in the proper opam context. in opam.ocaml.org/doc/man/opam-env.html what does it mean?Boatyard
what is the difference between eval and $(...)?Boatyard
see an answer to this in the official ocaml discuss too: discuss.ocaml.org/t/…Boatyard
related: #72549204 details of how command substitution worksBoatyard
T
11

First of all, the modern syntax is eval $(opam env), which uses $(...) instead of the deprecated backticks and a shorterned command opam env, which is available since opam 2.1.

This invocation is used to initialize the environment variables of your shell1. These variables are necessary for the toolchain to work correctly, e.g., CAML_LD_LIBRARY_PATH tells the compiler where to search for the OCaml libraries.

Here, eval is a built-in command of your shell that evaluates its argument. And backticks (or, the preferred, $(...) syntax) perform command substitution, i.e., they evaluate what they delimit and substitute the contents with the output of the evaluated expression.

The opam env command, returns a small shell program,

$ opam env
OPAM_SWITCH_PREFIX='/home/ivg/.opam/dev'; export OPAM_SWITCH_PREFIX;
CAML_LD_LIBRARY_PATH='/home/ivg/.opam/dev/lib/stublibs:/home/ivg/.opam/dev/lib/ocaml/stublibs:/home/ivg/.opam/dev/lib/ocaml'; export CAML_LD_LIBRARY_PATH;
OCAML_TOPLEVEL_PATH='/home/ivg/.opam/dev/lib/toplevel'; export OCAML_TOPLEVEL_PATH;
PKG_CONFIG_PATH='/home/ivg/.opam/dev/lib/pkgconfig:'; export PKG_CONFIG_PATH;
MANPATH=':/home/ivg/.opam/dev/man'; export MANPATH;
PATH='/home/ivg/.opam/dev/bin:/home/ivg/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'; export PATH;

So when you do eval $(opam env), eval executes the program returned by opam env and assigns the proper values to these variables.


1)) This is a rather common approach for setting up a toolchain, cf. virtualenv in Python.

Thymus answered 10/5, 2015 at 19:56 Comment(9)
Does ocaml offer something like virtualenv?Frankforter
yes, it is called opam. I would say that this projects are very close.Thymus
How to let opam to create a virtualenv? I can't seeFrankforter
I found opam is just a easy lib installer for ocamlFrankforter
this is not that directly, your .opam installation is like virtualenv, as it will install the compiler and a set of packages. You can switch between different compiler installations, and manipulate the sets of packages. Btw, there is also a promising tool called ocp-manager, that will help you to manage your opam installations. But I personally never tried it, and I'm not sure on how current it is.Thymus
Ok, so opam's env is just by compiler? And using ocp-manager to manage different .opam?Frankforter
No, ocp-switch is a separate project, let's forget about it for a while. You can manage different installations of compilers (or the same compiler) directly with opam switch. Moreover, you can have separate "switches" for separate applications, it's like universes in multiverse. You may found this question interesting #27641397Thymus
I'm confused about one detail. Why do we need eval $(opam env) if opam switch <switch> exists? e.g. I got this suggestion from opam after creating a switch # Run eval $(opam env --switch=debug_proj_4.09.1) to update the current shell environment.Boatyard
@CharlieParker, this is how the shells work in Linux. A command, like opam, can't change your environment and affect the later commands. So you have to use special builtins, like command substitution, $(...) or . (source) to change the environment. Another alternative would be to spawn a new shell for each new switch. You will get accustomed to it, this is how operating systems typically work, nothing specific to opam or OCaml, in fact.Thymus
B
-1

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 evaluate the result of the opam env command. (here $( ) is a command substitution). Command substitution is usually done to evaluate 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 switch (i.e. switch approximately equal to opam environment). So, therefore, doing:

eval $(opam env)

does this:

  1. first runs in a subshell because that's what $(cmd) does. It's [command substitution][1]. Usually used to nest commands.
  2. then its 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).
  3. finally eval evaluates the string it receives from the command substitution i.e. it parses the string as a bash command and runs it.

For completeness see the output of opam env:

(iit_synthesis) brandomiranda~ ❯ opam env
OPAM_SWITCH_PREFIX='/Users/brandomiranda/.opam/4.12.1'; export OPAM_SWITCH_PREFIX;
CAML_LD_LIBRARY_PATH='/Users/brandomiranda/.opam/4.12.1/lib/stublibs:/Users/brandomiranda/.opam/4.12.1/lib/ocaml/stublibs:/Users/brandomiranda/.opam/4.12.1/lib/ocaml'; export CAML_LD_LIBRARY_PATH;
OCAML_TOPLEVEL_PATH='/Users/brandomiranda/.opam/4.12.1/lib/toplevel'; export OCAML_TOPLEVEL_PATH;
PATH='/Users/brandomiranda/.opam/4.12.1/bin:/Users/brandomiranda/miniconda/envs/iit_synthesis/bin:/Users/brandomiranda/miniconda/condabin:/usr/local/bin:/Users/brandomiranda/.opam/4.12.1/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin'; export PATH;

Current guess what the install order is (in a dockerfile):

# - setp up opam
#RUN conda install -c conda-forge opam
RUN opam init --disable-sandboxing
RUN opam switch create debug_proj_4.09.1 4.09.1
RUN opam switch debug_proj_4.09.1
# RUN eval $(opam env)
RUN opam repo add coq-released https://coq.inria.fr/opam/released
RUN opam pin add -y coq 8.11.0
RUN opam install -y coq-serapi
RUN eval $(opam env)

# Don't think it should work since dockerfiles are not suppose to be editable. Need to run this every time you log?
# makes sure depedencies are installed once already in the docker image
RUN pip install pycoq

Comment on backward ticks:

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: https://ocaml.org/docs/up-and-running


also see:

Boatyard answered 10/5, 2015 at 19:49 Comment(1)
I know you are not required to do this, but I'd love to be able to improve my answer -- especially if it's factually incorrect. Wouldn't want people to be take in knowledge that is wrong! (re-wording of a previous comment I made that someone delete I think. I put a lot of effort to understand this and write a good answer for this so I'd really like to given the chance to improve it if possible -- if your generous mind allows me).Boatyard

© 2022 - 2024 — McMap. All rights reserved.