I have a makefile to install and compile an ocaml project. I need to install ocaml 4.07 to use some specific features of this version. After installing opam, I download the specific version, but in order to compile the project with this version I get a message from the terminal saying
The environment is not in sync with the current switch.
You should run: eval $(opam env)
I want to be able to run make install
and compile the project in the specific version.
I tried creating an specific rule for the eval
command to be called and tried also to call both eval $(opam env)
, eval 'opam config env'
. But none of these seem to work.
Here is the makefile that I am trying to modify
#install package dependencies
install:
sudo apt install gcc
sudo add-apt-repository ppa:avsm/ppa
sudo apt update
sudo apt install opam
opam init --yes
sudo opam instal ocaml-base-compiler
#opam init --yes
sudo apt install ocaml-nox
#eval 'opam env'
#eval $(opam env)
#ev
#clear
#run
# Building the world
run: ev depend $(EXEC)
ev:
eval $(opam env)
# Clean up
clear:
rm -f *.cm[io] *.cmx *~ .*~ #*#
rm -f $(GENERATED)
rm -f $(EXEC)
How can I compile this project with the specific version I downloaded without having to call the eval
command manually in the terminal, or are there other ways to configure this.
The advice to eval
something is correct for an interactive shell. Make by default runs each command in a separate shell - it's sort of like you would shut down and restart your computer after each command; the result of eval
is immediately lost.
There is a GNU make
extension .ONESHELL
which allows you to run all lines in a recipe in a single shell, or you can refactor your recipe to do this explicitly:
install:
sudo apt install gcc
# ... ett etc ...
opam init --yes \
&& sudo opam instal ocaml-base-compiler
opam init --yes \
&& sudo apt install ocaml-nox
eval $(opam env) \
&& ev \
&& run
(I had to guess some things about which things need to run in the same shell invocation. I am assuming ev
and run
are shell commands which need the eval
, and that clear
is the regular shell command which should probably never be used in a Makefile.)