Installing more than one version of Erlang/OTP on a machine

后端 未结 6 552
说谎
说谎 2021-01-05 18:25

Is this possible to have different versions of Erlang/OTP installed simultaneously on the same platform?

相关标签:
6条回答
  • 2021-01-05 19:07

    Consider using kerl. It allows you to work with several Erlang installations https://github.com/kerl/kerl

    0 讨论(0)
  • 2021-01-05 19:09

    Using the Nix package manager there is no need to globally install interpreters (especially because sometimes multiple versions are needed), and nix-shell will open up a sub-shell with the Erlang executable available in the path.

    1. Getting only the Erlang (no shell.nix)

    For the current version in the active channel:

    nix-shell -p erlang
    

    For other versions not in the current channel, a specific channel can be given:

    nix-shell -I nixpkgs=channel:nixos-unstable -p erlangR22
    

    Or add path to the Nix expression in your NixOS/nixpkgs clone:

    $ nix-shell -I nixpkgs=~/clones/nixpkgs -p erlangR23
    

    2. More elaborate project setup configurations: use a shell.nix file

    A complex development environment can be spun up, and calling nix-shell shell.nix will take care of all - even automatically when entering a directory if set up with direnv(archived).

    2.1 Examples

    Erlang

    This will drop you in a shell with erl and rebar3 available, along with the other programs specified in buildInputs.

    { pkgs ? import ~/clones/nixpkgs {} }:
    
    pkgs.mkShell {
    
      buildInputs = with pkgs; [
        beam.packages.erlangR22.erlang
        beam.packages.erlangR22.rebar3
        curl
        ffmpeg
        git
        google-cloud-sdk
        jq
      ];
    
      # Where would be the best place for this?
      shellHook = ''
        export ERL_AFLAGS="-kernel shell_history enabled"
      '';
    
    Elixir/Phoenix web project

    This (archived) will set up an environment for an Elixir/Phoenix web app complete with a spun up PostgreSQL dev instance:

    ####################################################################
    # Importing a cloned Nixpkgs repo  (from my home directory), because
    # the latest channels don't have Elixir 1.9.
    # See https://nixos.org/nix/manual/#idm140737317975776 for the meaning
    # of `<nixpkgs>` and `~` in Nix expressions (towards the end of that
    # section).
    ####################################################################
    
    { pkgs ? import ~/clones/nixpkgs {} }:
    
    pkgs.mkShell {
    
      buildInputs = with pkgs; [
        beam.packages.erlangR22.elixir_1_9
        postgresql_11
        nodejs-12_x
        git
        inotify-tools
      ];
    
      shellHook = ''
    
        ####################################################################
        # Create a diretory for the generated artifacts
        ####################################################################
    
        mkdir .nix-shell
        export NIX_SHELL_DIR=$PWD/.nix-shell
    
        ####################################################################
        # Put the PostgreSQL databases in the project diretory.
        ####################################################################
    
        export PGDATA=$NIX_SHELL_DIR/db
    
        ####################################################################
        # Put any Mix-related data in the project directory
        ####################################################################
    
        export MIX_HOME="$NIX_SHELL_DIR/.mix"
        export MIX_ARCHIVES="$MIX_HOME/archives"
    
        ####################################################################
        # Clean up after exiting the Nix shell using `trap`.
        # ------------------------------------------------------------------
        # Idea taken from
        # https://unix.stackexchange.com/questions/464106/killing-background-processes-started-in-nix-shell
        # and the answer provides a way more sophisticated solution.
        #
        # The main syntax is `trap ARG SIGNAL` where ARG are the commands to
        # be executed when SIGNAL crops up. See `trap --help` for more.
        ####################################################################
    
        trap \
          "
            ######################################################
            # Stop PostgreSQL
            ######################################################
    
            pg_ctl -D $PGDATA stop
    
            ######################################################
            # Delete `.nix-shell` directory
            # ----------------------------------
            # The first  step is going  back to the  project root,
            # otherwise `.nix-shell`  won't get deleted.  At least
            # it didn't for me when exiting in a subdirectory.
            ######################################################
    
            cd $PWD
            rm -rf $NIX_SHELL_DIR
          " \
          EXIT
    
        ####################################################################
        # If database is  not initialized (i.e., $PGDATA  directory does not
        # exist), then set  it up. Seems superfulous given  the cleanup step
        # above, but handy when one gets to force reboot the iron.
        ####################################################################
    
        if ! test -d $PGDATA
        then
    
          ######################################################
          # Init PostgreSQL
          ######################################################
    
          pg_ctl initdb -D  $PGDATA
    
          ######################################################
          # PORT ALREADY IN USE
          ######################################################
          # If another `nix-shell` is  running with a PostgreSQL
          # instance,  the logs  will show  complaints that  the
          # default port 5432  is already in use.  Edit the line
          # below with  a different  port number,  uncomment it,
          # and try again.
          ######################################################
    
          # sed -i "s|^#port.*$|port = 5433|" $PGDATA/postgresql.conf
    
        fi
    
        ####################################################################
        # Start PostgreSQL
        # ==================================================================
        # Setting all  necessary configuration  options via  `pg_ctl` (which
        # is  basically  a wrapper  around  `postgres`)  instead of  editing
        # `postgresql.conf` directly with `sed`. See docs:
        #
        # + https://www.postgresql.org/docs/current/app-pg-ctl.html
        # + https://www.postgresql.org/docs/current/app-postgres.html
        #
        # See more on the caveats at
        # https://discourse.nixos.org/t/how-to-configure-postgresql-declaratively-nixos-and-non-nixos/4063/1
        # but recapping out of paranoia:
        #
        # > use `SHOW`  commands to  check the  options because  `postgres -C`
        # > "_returns values  from postgresql.conf_" (which is  not changed by
        # > supplying  the  configuration options  on  the  command line)  and
        # > "_it does  not reflect  parameters supplied  when the  cluster was
        # > started._"
        #
        # OPTION SUMMARY
        # --------------------------------------------------------------------
        #
        #  + `unix_socket_directories`
        #
        #    > PostgreSQL  will  attempt  to create  a  pidfile  in
        #    > `/run/postgresql` by default, but it will fail as it
        #    > doesn't exist. By  changing the configuration option
        #    > below, it will get created in $PGDATA.
        #
        #   + `listen_addresses`
        #
        #     > In   tandem  with   edits   in  `pg_hba.conf`   (see
        #     > `HOST_COMMON`  below), it  configures PostgreSQL  to
        #     > allow remote connections (otherwise only `localhost`
        #     > will get  authenticated and the rest  of the traffic
        #     > discarded).
        #     >
        #     > NOTE: the  edit  to  `pga_hba.conf`  needs  to  come
        #     >       **before**  `pg_ctl  start`  (or  the  service
        #     >       needs to be restarted otherwise), because then
        #     >       the changes are not being reloaded.
        #     >
        #     > More info  on setting up and  troubleshooting remote
        #     > PosgreSQL connections (these are  all mirrors of the
        #     > same text; again, paranoia):
        #     >
        #     >   + https://stackoverflow.com/questions/24504680/connect-to-postgres-server-on-google-compute-engine
        #     >   + https://stackoverflow.com/questions/47794979/connecting-to-postgres-server-on-google-compute-engine
        #     >   + https://medium.com/scientific-breakthrough-of-the-afternoon/configure-postgresql-to-allow-remote-connections-af5a1a392a38
        #     >   + https://gist.github.com/toraritte/f8c7fe001365c50294adfe8509080201#file-configure-postgres-to-allow-remote-connection-md
    
        HOST_COMMON="host\s\+all\s\+all"
        sed -i "s|^$HOST_COMMON.*127.*$|host all all 0.0.0.0/0 trust|" $PGDATA/pg_hba.conf
        sed -i "s|^$HOST_COMMON.*::1.*$|host all all ::/0 trust|"      $PGDATA/pg_hba.conf
    
         #  + `log*`
         #
         #    > Setting up basic logging,  to see remote connections
         #    > for example.
         #    >
         #    > See the docs for more:
         #    > https://www.postgresql.org/docs/current/runtime-config-logging.html
    
        pg_ctl                                                  \
          -D $PGDATA                                            \
          -l $PGDATA/postgres.log                               \
          -o "-c unix_socket_directories='$PGDATA'"             \
          -o "-c listen_addresses='*'"                          \
          -o "-c log_destination='stderr'"                      \
          -o "-c logging_collector=on"                          \
          -o "-c log_directory='log'"                           \
          -o "-c log_filename='postgresql-%Y-%m-%d_%H%M%S.log'" \
          -o "-c log_min_messages=info"                         \
          -o "-c log_min_error_statement=info"                  \
          -o "-c log_connections=on"                            \
          start
    
        ####################################################################
        # Install Node.js dependencies if not done yet.
        ####################################################################
    
        if test -d "$PWD/assets/" && ! test -d "$PWD/assets/node_modules/"
        then
          (cd assets && npm install)
        fi
    
        ####################################################################
        # If $MIX_HOME doesn't exist, set it up.
        ####################################################################
    
        if ! test -d $MIX_HOME
        then
    
          ######################################################
          # ...  but first,  test whether  there is  a `_backup`
          # directory. Had issues with  installing Hex on NixOS,
          # and Hex and  Phoenix can be copied  from there, just
          # in case.
          ######################################################
    
          if test -d "$PWD/_backup"
          then
            cp -r _backup/.mix .nix-shell/
          else
            ######################################################
            # Install Hex and Phoenix via the network
            ######################################################
    
            yes | mix local.hex
            yes | mix archive.install hex phx_new
          fi
        fi
    
        if test -f "mix.exs"
        then
          # These are not in the  `if` section above, because of
          # the `hex` install glitch, it  could be that there is
          # already a `$MIX_HOME` folder. See 2019-08-05_0553
    
          mix deps.get
    
          ######################################################
          # `ecto.setup` is defined in `mix.exs` by default when
          # Phoenix  project  is  generated via  `mix  phx.new`.
          # It  does  `ecto.create`,   `ecto.migrate`,  and  run
          # `priv/seeds`.
          ######################################################
          mix ecto.setup
        fi
      '';
    
      ####################################################################
      # Without  this, almost  everything  fails with  locale issues  when
      # using `nix-shell --pure` (at least on NixOS).
      # See
      # + https://github.com/NixOS/nix/issues/318#issuecomment-52986702
      # + http://lists.linuxfromscratch.org/pipermail/lfs-support/2004-June/023900.html
      ####################################################################
    
      LOCALE_ARCHIVE = if pkgs.stdenv.isLinux then "${pkgs.glibcLocales}/lib/locale/locale-archive" else "";
    }
    

    How to find packages with attributes path on the console

    $ nix-env -qaP 'erlang*'
    # ...
    nixos.erlangR20            erlang-20.3.8.9
    nixos.erlangR21            erlang-21.3.8.3
    nixos.erlang               erlang-22.1.7
    # ...
    
    $ nix-env -f ~/clones/nixpkgs/ -qaP 'erlang*'
    # ...
    nixos.erlangR20            erlang-20.3.8.9
    nixos.erlangR21            erlang-21.3.8.3
    nixos.erlang               erlang-22.1.7
    # ...
    === >>> erlangR23            erlang-23.0.2  <<<====
    
    0 讨论(0)
  • 2021-01-05 19:11

    I use Kerl to install Erlang on my machines. Quite easy to use, and allows to have several Erlang systems installed on same machine. You can then easily choose the one you want to use.

    0 讨论(0)
  • 2021-01-05 19:12

    It is no only possible, but also very frequent. On my machine I have one version that I installed for development (R13B03) it is the default version when I launch erl. A second copy of the same version associated with nitrogen. this copy is used when I start my nitrogen website. The version will not change when I will use the R16B.. for development A partial older version which came with the installation of Wings3D.

    0 讨论(0)
  • 2021-01-05 19:16

    Yes, I usually install different versions in my home directory. I build them from source:

    ./configure --prefix=$HOME/r15b01
    make && make install
    

    Then I can choose a version to use with PATH=$HOME/r15b01/bin:$PATH, and compile and run things as usual.


    These days I use asdf for this. Install asdf and add the relevant line to your .bashrc, and then run:

    asdf plugin add erlang
    asdf install erlang 22.3.3
    asdf install erlang 23.0.2
    

    Then you can set one of the Erlang versions you just built as the default version:

    asdf global erlang 23.0.2
    

    Or you can set it to be used in the current directory and its subdirectories - this will create a .tool-versions file in the current directory:

    asdf local erlang 22.3.3
    
    0 讨论(0)
  • 2021-01-05 19:18

    On a Mac, Macport helps switching, even between versions it covers and newer ones.

    E.g. with Erlang 17 installed directly from Erlang Solutions, you could switch back to RB1603 (open a new terminal window afterwards):

    sudo port activate erlang @R16B03-1_0+hipe+ssl
    

    Switch back to Erlang 17 by _de_activating the Macports install (and open a new terminal window afterwards):

    sudo port deactivate erlang @R16B03-1_0+hipe+ssl
    

    List all versions you have installed with:

    port installed erlang
    
    0 讨论(0)
提交回复
热议问题