In short:
Do I use correctly Opam for managing a local switch? (in order to get “a clean switch per project in sync with the dependencies specified in the opam file”)
This follows the recommendation from @Leonidas. See https://discuss.ocaml.org/t/connection-between-libraries-in-opam-dune-and-findlib/2536/6
__
1/ Switching between local and global switches
Playing with Opam 2 switch commands, in order to understand them, I created an Opam switch local to the project called project2 and located in /home/test/Documents/project2/.
$ opam switch create ./ ocaml-base-compiler.4.06.1
This creates an _opam directory with all the required stuff:
$ ls
_opam
It seems that since there is this a new switch local to this project, the opam switch command doesn’t have the same behaviour:
$ opam switch
# switch compiler description
→ ~/Documents/project2 ocaml-base-compiler.4.07.0 ~/Documents/project2
4.02.3 ocaml-base-compiler.4.02.3 base-bigarray.base base-ocamlbuild.base
base-threads.base base-unix.base
ocaml-base-compiler.4.02.3
4.06.1 ocaml-base-compiler.4.06.1 4.06.1
4.07.0 ocaml-base-compiler.4.07.0 4.07.0
Then:
$ opam switch 4.06.1 && opam switch
(same result = the global 4.06.1 switch is NOT selected. The local switch is still selected.)
Finally, the following command worked for selecting a global switch:
$ eval $(opam env --switch=4.06.1 --set-switch)
[NOTE] Current switch is set globally and through the OPAMSWITCH variable.
Thus, the local switch found at ~/Documents/project2 was ignored.
And it also worked for selecting again a local switch:
$ eval $(opam env --switch=~/Documents/project2 --set-switch)
[NOTE] Current switch is set globally and through the OPAMSWITCH variable.
Thus, the local switch found at /home/test/Documents/project2 was ignored.
Q: Is there a way to keep things as simple as $ opam switch [name]
from within /project2 directory where there is an opam (or project2.opam) file or from anywhere else, where [name] is the name of the global switch or the path to the project where there is an opam file ?
Q: Why is an opam file created whereas we see in many projects a foo.opam file (foo being the name of the project)?
__
2/ Installing the packages dependencies for a project and keep it synchronized
The command that finally makes sense for me is (from the local directory of the project):
$ opam pin edit project2
Because it fires up a text editor with an opam file template.
Then accepting the last [Y/n] choice triggers the installation of the packages defined in thi local switch.
Save the new opam file back to "~/Documents/project2/opam"? [Y/n] y
This opam file is saved here (resulting from an opam pin command):
~/Documents/project2/_opam/.opam-switch/overlay/project2/opam
EDIT:
To get the packages specified in the opam file, I use the following command within the project directory that seems logical:
$ opam install .
Q: Is this the right way to install dependencies for a project?
If I update the opam file, the installed Opam packages that become useless are kept in the switch. Instead of manually remove them, is there a sync command?
__
3/ Repairing a "broken switch"
When only working with these Opam commands, I encountered several times the following problem in some switches (local or global):
$ ocaml
Fatal error: cannot load shared library dllunix
Reason: /home/test/Documents/project2/_opam/lib/ocaml/stublibs/dllunix.so: undefined symbol: caml_ba_element_size
Q: What is broken? (I’m not enough familiar with Ocaml and Opam)
What caused this problem?
How can I repair this broken switch instead of removing and reinstalling it from scratch? ($ opam switch remove project2 && opam switch create ./ <package-or-version>
This fixes the problem but gives no explanation)