Search code examples
makefileocamleval

How can I run eval function on my makefile


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.


Solution

  • 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.)