How can I switch the opam compiler in an easy way and what is the --set-switch flag? - ocaml

Consider:
$ opam switch set ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1
# Run eval $(opam env --switch=ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1) to update the current shell environment
$ eval $(opam env --switch=ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1)
[NOTE] To make opam select the switch ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1 in the current shell, add --set-switch or set OPAMSWITCH
But then it doesn't tell me at all where --set-switch should go. Why? Where?
Related:
Switch environment in OPAM

It's confusing why it gives you a command, but then the command doesn't work. If you browse the opam man page, it says (opam-switch):
opam switch set sets the default switch globally. The shell hook, when enabled, synchronises the current shell session with this switch, unless the current directory is a local switch, when that local switch is used instead. You can always use eval $(opam env --switch=SWITCH --set-switch) to specify the switch explicitly, which overrides the shell hook.
Then it works if you do:
eval $(opam env --switch=ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1 --set-switch)
See:
$ opam switch
# switch compiler description
coq-8.10 ocaml-base-compiler.4.07.1 coq-8.10
default ocaml.4.14.0 default
→ ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1 ocaml-variants.4.07.1+flambda ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1
It is really annoying and confusing.

Related

How does one install a specific ocaml compiler when it doesn't appear on the opam switch list?

I've installed this compiler before in a docker container, but I don't understand why it's missing right now. Command and error:
(iit_synthesis) brando9~ $ opam switch create ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1 ocaml-variants.4.07.1+flambda
[ERROR] No compiler matching `ocaml-variants.4.07.1+flambda' found, use `opam switch list-available' to see what is available, or use `--packages' to
select packages explicitly.
but it's not in the list:
(iit_synthesis) brando9~ $ opam switch list-available
# Listing available compilers from repositories: default
# Name # Version # Synopsis
ocaml-option-32bit 1 Set OCaml to be compiled in 32-bit mode for 64-bit Linux and OS X hosts
ocaml-option-flambda 1 Set OCaml to be compiled with flambda activated
ocaml-option-nnpchecker 1 Set OCaml to be compiled with --enable-naked-pointers-checker
ocaml-option-spacetime 1 Set OCaml to be compiled with spacetime activated
ocaml-options-vanilla 1 Ensure that OCaml is compiled with no special options enabled
Opam update fails
Output:
$ opam update --all
<><> Updating package repositories ><><><><><><><><><><><><><><><><><><><><><><>
Processing 1/1: [default: http]
Processing 1/1: [default: http]
[default] synchronised from https://opam.ocaml.org
[ERROR] Could not update repository "default": "~/anaconda/bin/patch -p1 -i /dfs/scratch0/brando9/.opam/log/patch-99014-0624b6" exited with code 2
I probably should have started with this but I installed opam with "manually" with deb because I don't have sudo. In particular I did this:
# - opam (snap, no sudo)
# ref: https://askubuntu.com/questions/339/how-can-i-install-a-package-without-root-access
apt-get download opam
#apt-get download opam_1.2.2-4_amd64
# manually checked the opam name
#ls | less
mkdir -p ~/.local
dpkg -x opam_1.2.2-4_amd64.deb ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc.user
source ~/.bashrc.user
tr ':' '\n' <<< "$PATH"
opam --version
before that I did try installing opam with conda (which has worked in the past) but it failed. I wonder if that screwed things up :/. Will try to reproduce to post the conda error. But I ran conda install -c conda-forge opam.
related:
How to install a specific version of ocaml compiler with opam
https://discuss.ocaml.org/t/why-doesnt-my-server-show-the-ocaml-compiler-that-i-need/10917
https://www.reddit.com/r/ocaml/comments/zed88p/how_does_one_install_a_specific_ocaml_compiler/
How does one install opam without sudo priveledges on linux/ubuntu?

OCaml: Can't find version

When I enter ocaml --version it returns
/usr/bin/ocaml: unknown option '--version'.
I installed it using OPAM and ran the instructions
opam init
eval $(opam env)
eval opam env
opam switch create 4.07.0
and everything seemed to go fine. Entering which ocaml returns a correct-looking path. And when entering a terminal session it seems to work fine. I don't see this error mentioned anywhere when I search for it.
OCaml tools are weird and usually do not follow the POSIX guidelines of using double dashes for command line options. At this point probably for historic reasons and because the standard Arg module parses command line arguments this way. In any case, this will do the trick:
ocaml -version

Can't run utop after installation

I've just installed utop on openSUSE but when i type utop in terminal i have
If 'utop' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf utop
Typing eval 'opam config env' gives me this:
OPAM_SWITCH_PREFIX='/home/jadw1/.opam/default'; export OPAM_SWITCH_PREFIX;
CAML_LD_LIBRARY_PATH='/home/jadw1/.opam/default/lib/stublibs:/usr/lib64/ocaml/stublibs:/usr/lib64/ocaml'; export CAML_LD_LIBRARY_PATH;
OCAML_TOPLEVEL_PATH='/home/jadw1/.opam/default/lib/toplevel'; export OCAML_TOPLEVEL_PATH;
MANPATH='/usr/local/man:/usr/share/man:/home/jadw1/.opam/default/man'; export MANPATH;
PATH='/home/jadw1/.opam/default/bin:/home/jadw1/bin:/usr/local/bin:/usr/bin:/bin:/usr/lib/mit/sbin'; export PATH;
You're supposed to type this:
$ eval `opam config env`
Not this:
$ opam config env
What happens is that opam config env writes out some shell commands that you want to execute. That's what the eval does. If you see output like you saw, it means you left out the eval.
eval is a command that constructs commands from the arguments it's given and executes them.
eval 'opam config env', with apostrophes, is therefore equivalent to just running opam config env directly, which just writes out a sequence of shell commands.
If you replace the apostrophes with backticks, however, it will first execute the quoted command, then pass its output to eval and execute that.
eval `opam config env`
is therefore more or less equivalent to running opam config env, then copying and pasting the output back into the console, which you could also do.

How to install a specific version of ocaml compiler with opam

How can I install a specific version of ocaml compiler (and compatible packages) using opam (or another package manger)?
I took a quick look through the opam documentation, but I don't find a relevant information.
I need ocaml compiler (preferably the native code compiler) to build unison, a software for file synchronization. I need to build unison on two machines using the same version of ocaml, or otherwise unison emits an error and aborts its duty (yiiii!).
I tried building ocaml version 4.04.0 from a tar ball and then using it for building unison, but on one of the machine the build of unison failed with the error message,
make[1]: Entering directory '/home/norio/Downloads/unison/unison-2.48.4_expand/src'
ocamlc -o mkProjectInfo unix.cma str.cma mkProjectInfo.ml
File "mkProjectInfo.ml", line 1:
Error: Error while linking /home/norio/Downloads/unison/ocaml_for_unison/lib/ocaml/unix.cma(Unix):
The external function `unix_has_symlink' is not available
if [ -f `which etags` ]; then \
etags *.mli */*.mli *.ml */*.ml */*.m *.c */*.c *.txt \
; fi
make[1]: Leaving directory '/home/norio/Downloads/unison/unison-2.48.4_expand/src'
I don't want to set off for the quest of unix_has_symlink function and devote myself for the exploration of the swamp of library dependencies where many developers had fallen before the civilization came and package managers were invented.
Is there anything like,
opam install ocamlc-4.04 and opam install all-packages?
Addendum
The error message about unix_has_symlink was observed on a machine running Linux Mint 18 Cinnamon 64 bit. Is this function a part of some unix/linux library, rather than ocaml package?
To create a switch with a particular version of the compiler do
opam switch create <compiler-version>
(Note: for the old opam 1.x it was opam switch <compiler-version>)
E.g.,
opam switch create 4.07.0
Or, if you want to create a fresh new switch that uses the same compiler as some other switch, then the syntax is
opam switch create <name> <compiler-version>
E.g.,
opam switch create myproj 4.07.0
Note, that if <name> is a folder, then a local switch will be created, e.g., opam switch ./myproj 4.07.0 will create a switch directly in the myproj folder.
To start with a specific version, i.e., when you first install opam, just do
opam init --compiler=<version>
E.g.,
opam init --compiler=4.07.0
To list available versions do
opam switch
To see even more, do
opam switch list-available
To install a variant of a compiler, e.g., a compiler with flambda or spacetime, use the following general syntax,
opam switch create <switch-name> ocaml-variants.<version>+options <options>...
E.g.,
opam switch create myswitch ocaml-variants.4.13.0+options ocaml-option-flambda
use opam search ocaml-options for the full list of available options. It is possible to specify several options, e.g.,
opam switch create myswitch ocaml-variants.4.13.0+options ocaml-option-flambda ocaml-option-spacetime ocaml-option-static

Running the "exec" command in Jenkins "Execute Shell"

I'm running Jenkins on a Linux host. I'm automating the build of a C++ application. In order to build the application I need to use the 4.7 version of g++ which includes support for c++11. In order to use this version of g++ I run the following command at a command prompt:
exec /usr/bin/scl enable devtoolset-1.1 bash
So I created a "Execute shell" build step and put the following commands, which properly builds the C++ application on the command prompt:
exec /usr/bin/scl enable devtoolset-1.1 bash
libtoolize
autoreconf --force --install
./configure --prefix=/home/tomcat/.jenkins/workspace/project
make
make install
cd procs
./makem.sh /home/tomcat/.jenkins/workspace/project
The problem is that Jenkins will not run any of the commands after the "exec /usr/bin/scl enable devtoolset-1.1 bash" command, but instead just runs the "exec" command, terminates and marks the build as successful.
Any ideas on how I can re-structure the above so that Jenkins will run all the commands?
Thanks!
At the begining of your "Execute shell" script, execute source /opt/rh/devtoolset-1.1/enable to enable the devtoolet "inside" of your shell.
Which gives:
source /opt/rh/devtoolset-1.1/enable
libtoolize
autoreconf --force --install
./configure --prefix=/home/tomcat/.jenkins/workspace/project
make
make install
cd procs
./makem.sh /home/tomcat/.jenkins/workspace/project
I needed to look up what scl actually does.
Examples
scl enable example 'less --version'
runs command 'less --version' in the environment with collection 'example' enabled
scl enable foo bar bash
runs bash instance with foo and bar Software Collections enabled
So what you are doing is running a bash shell. I guess, that the bash shell returns immediately, since you are in non-interactive mode. exec runs the the command within the shell without creating a new shell. That means if the newly opened bash ends it also ends your shell prematurely. I would suggest to put all your build steps into a bash script (e.g. run_my_build.sh) and call it in the following way.
exec /usr/bin/scl enable devtoolset-1.1 run_my_build.sh
This kind of thing normally works in "find" commands, but may work here. Rather than running two, or three processes, you run one "sh" that executes multiple things, like this:
exec sh -c "thing1; thing2; thing3"
If you require each step to succeed before the next step, replace the semi-colons with double ampersands:
exec sh -c "thing1 && thing2 && thing3"
I have no idea which of your steps you wish to run together, so I am hoping you can adapt the concept to fit your needs.
Or you can put the whole lot into a script and exec that.