From d1b9c9d2cddf2e57964fde7e4f468c8767a77b3b Mon Sep 17 00:00:00 2001 From: Gleb Peregud Date: Sat, 17 Jun 2017 16:28:41 +0200 Subject: [PATCH 1/5] erlang: refactor: build packages per Erlang/OTP. This change introduces a fixpoint, which allows to do deep override when building packages defined in pkgs/development/beam-modules/default.hex. This allows to provide beam.packages.erlang{,R16,R17,R18,R19} which contains the same packages built with different Erlang/OTP versions. Top-level attribute beamPackages points at beam.packages.erlangR18, the same applies to other top-level Erlang packages. TODO: - beam.packages.erlang{R16,R17} is almost useless, since rebar/rebar3 does not build using these versions; - all packages in beam.packages which use buildMix are actually built with erlangR18; - update documentation. --- pkgs/development/beam-modules/build-hex.nix | 3 +- pkgs/development/beam-modules/default.nix | 55 ++++++++++++++++----- pkgs/top-level/all-packages.nix | 2 +- pkgs/top-level/beam-packages.nix | 27 +++++----- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/pkgs/development/beam-modules/build-hex.nix b/pkgs/development/beam-modules/build-hex.nix index ff6e47e5a80..27ce64582f3 100644 --- a/pkgs/development/beam-modules/build-hex.nix +++ b/pkgs/development/beam-modules/build-hex.nix @@ -1,13 +1,14 @@ { stdenv, buildRebar3, fetchHex }: { name, version, sha256 +, builder ? buildRebar3 , hexPkg ? name , ... }@attrs: with stdenv.lib; let - pkg = self: buildRebar3 (attrs // { + pkg = self: builder (attrs // { src = fetchHex { pkg = hexPkg; diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index 1fd899c53c9..00443350a7d 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -1,16 +1,45 @@ -{ stdenv, pkgs }: +{ stdenv, pkgs, erlang, overrides ? (self: super: {}) }: let - self = rec { - hexPackages = import ./hex-packages.nix { stdenv = stdenv; callPackage = self.callPackage; pkgs = pkgs; }; - callPackage = pkgs.lib.callPackageWith (pkgs // self // hexPackages); - buildRebar3 = callPackage ./build-rebar3.nix {}; - buildHex = callPackage ./build-hex.nix {}; - buildErlangMk = callPackage ./build-erlang-mk.nix {}; - buildMix = callPackage ./build-mix.nix {}; + inherit (stdenv.lib) fix' extends; - ## Non hex packages - hex = callPackage ./hex {}; - webdriver = callPackage ./webdriver {}; - }; -in self // self.hexPackages + # FIXME: add support for overrideScope + callPackageWithScope = scope: drv: args: stdenv.lib.callPackageWith scope drv args; + mkScope = scope: pkgs // scope; + + packages = self: + let + defaultScope = mkScope self; + callPackage = drv: args: callPackageWithScope defaultScope drv args; + in + import ./hex-packages.nix { + inherit pkgs stdenv callPackage; + } // { + inherit callPackage erlang; + beamPackages = self; + + rebar = callPackage ../tools/build-managers/rebar { }; + rebar3-open = callPackage ../tools/build-managers/rebar3 { + hermeticRebar3 = false; + }; + rebar3 = callPackage ../tools/build-managers/rebar3 { + hermeticRebar3 = true; + }; + + hexRegistrySnapshot = callPackage ./hex-registry-snapshot.nix { }; + fetchHex = callPackage ./fetch-hex.nix { }; + + buildRebar3 = callPackage ./build-rebar3.nix {}; + buildHex = callPackage ./build-hex.nix {}; + buildErlangMk = callPackage ./build-erlang-mk.nix {}; + buildMix = callPackage ./build-mix.nix {}; + + ## Non hex packages + hex = callPackage ./hex {}; + webdriver = callPackage ./webdriver {}; + + hex2nix = callPackage ../tools/erlang/hex2nix { }; + cuter = callPackage ../tools/erlang/cuter { }; + relxExe = callPackage ../tools/erlang/relx-exe {}; + }; +in fix' (extends overrides packages) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index f2fc65da558..ac90f7b3b95 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -5986,7 +5986,7 @@ with pkgs; erlangR18 erlangR18_odbc erlangR18_javac erlangR18_odbc_javac erlangR19 erlangR19_odbc erlangR19_javac erlangR19_odbc_javac; - inherit (beam.packages) + inherit (beam.packages.erlang) rebar rebar3-open rebar3 hexRegistrySnapshot fetchHex beamPackages hex2nix cuter relxExe; diff --git a/pkgs/top-level/beam-packages.nix b/pkgs/top-level/beam-packages.nix index 3451816c0c5..ccf22d6c534 100644 --- a/pkgs/top-level/beam-packages.nix +++ b/pkgs/top-level/beam-packages.nix @@ -3,10 +3,11 @@ rec { lib = import ../development/beam-modules/lib.nix { inherit pkgs; }; + # Each interpreters = rec { - # R18 is the Default version. - erlang = erlangR18; + # R18 is the default version. + erlang = erlangR18; # The main switch to change default Erlang version. erlang_odbc = erlangR18_odbc; erlang_javac = erlangR18_javac; erlang_odbc_javac = erlangR18_odbc_javac; @@ -44,22 +45,24 @@ rec { odbcSupport = true; }; - # Other Beam languages. + # Other Beam languages. These are built with beam.interpreters.erlang. elixir = callPackage ../development/interpreters/elixir { debugInfo = true; }; lfe = callPackage ../development/interpreters/lfe { }; }; + # Helper function to generate package set with a specific Erlang version. + packagesWith = erlang: callPackage ../development/beam-modules { inherit erlang; }; + + # Each field in this tuple represents all Beam packages in nixpkgs built with + # appropriate Erlang/OTP version. packages = rec { - rebar = callPackage ../development/tools/build-managers/rebar { }; - rebar3-open = callPackage ../development/tools/build-managers/rebar3 { hermeticRebar3 = false; }; - rebar3 = callPackage ../development/tools/build-managers/rebar3 { hermeticRebar3 = true; }; - hexRegistrySnapshot = callPackage ../development/beam-modules/hex-registry-snapshot.nix { }; - fetchHex = callPackage ../development/beam-modules/fetch-hex.nix { }; - beamPackages = callPackage ../development/beam-modules { }; - hex2nix = beamPackages.callPackage ../development/tools/erlang/hex2nix { }; - cuter = callPackage ../development/tools/erlang/cuter { }; + # Packages built with default Erlang version. + erlang = packagesWith interpreters.erlang; + erlangR16 = packagesWith interpreters.erlangR16; + erlangR17 = packagesWith interpreters.erlangR17; + erlangR18 = packagesWith interpreters.erlangR18; + erlangR19 = packagesWith interpreters.erlangR19; - relxExe = callPackage ../development/tools/erlang/relx-exe {}; }; } From f66b0186dc9764b83ad76f9dcaec341b0f6f83a0 Mon Sep 17 00:00:00 2001 From: Gleb Peregud Date: Sun, 18 Jun 2017 16:17:40 +0200 Subject: [PATCH 2/5] erlang: fix rebar3-nix-bootstrap in Erlang < R18. --- .../build-managers/rebar3/rebar3-nix-bootstrap | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap b/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap index 81257dd8c0c..b839a4a3b09 100755 --- a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap +++ b/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap @@ -180,14 +180,14 @@ make_sure_registry_snapshot_exists(RegistrySnapshot) -> erlang:halt(1) end. --spec gather_required_data_from_the_environment(#data{}) -> {ok, map()}. +-spec gather_required_data_from_the_environment(#data{}) -> {ok, #data{}}. gather_required_data_from_the_environment(ArgData) -> {ok, ArgData#data{ version = guard_env("version") - , erl_libs = os:getenv("ERL_LIBS", []) - , plugins = os:getenv("buildPlugins", []) + , erl_libs = get_env("ERL_LIBS", []) + , plugins = get_env("buildPlugins", []) , root = code:root_dir() , name = guard_env("name") - , compile_ports = nix2bool(os:getenv("compilePorts", "")) + , compile_ports = nix2bool(get_env("compilePorts", "")) , registry_snapshot = guard_env("HEX_REGISTRY_SNAPSHOT")}}. -spec nix2bool(any()) -> boolean(). @@ -196,9 +196,17 @@ nix2bool("1") -> nix2bool("") -> false. +get_env(Name) -> + os:getenv(Name). +get_env(Name, Def) -> + case get_env(Name) of + false -> Def; + Val -> Val + end. + -spec guard_env(string()) -> string(). guard_env(Name) -> - case os:getenv(Name) of + case get_env(Name) of false -> stderr("Expected Environment variable ~s! Are you sure you are " "running in a Nix environment? Either a nix-build, " From 7797e1a1dda661476dbb312b1f26896d32831ef5 Mon Sep 17 00:00:00 2001 From: Gleb Peregud Date: Sun, 18 Jun 2017 19:24:18 +0200 Subject: [PATCH 3/5] erlang: put Elixir/LFE into per-OTP packageset. This makes beam.package.erlangR19.abnf to be actually built with R19, instead of the default R18. It means that Elixir and LFE are provided in two versions, one built with R18 and with R19. Please note that Elixir does not build with R16 and R17 - trying to access beam.packages.erlang{R16,R17}.elixir will throw an error. --- pkgs/development/beam-modules/default.nix | 16 ++++++++++++---- pkgs/development/beam-modules/lib.nix | 11 ++++++++++- pkgs/top-level/beam-packages.nix | 10 ++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/pkgs/development/beam-modules/default.nix b/pkgs/development/beam-modules/default.nix index 00443350a7d..0db695befe6 100644 --- a/pkgs/development/beam-modules/default.nix +++ b/pkgs/development/beam-modules/default.nix @@ -1,7 +1,9 @@ { stdenv, pkgs, erlang, overrides ? (self: super: {}) }: let - inherit (stdenv.lib) fix' extends; + inherit (stdenv.lib) fix' extends getVersion versionAtLeast; + + lib = pkgs.callPackage ./lib.nix {}; # FIXME: add support for overrideScope callPackageWithScope = scope: drv: args: stdenv.lib.callPackageWith scope drv args; @@ -34,12 +36,18 @@ let buildErlangMk = callPackage ./build-erlang-mk.nix {}; buildMix = callPackage ./build-mix.nix {}; - ## Non hex packages + # BEAM-based languages. + elixir = if versionAtLeast (lib.getVersion erlang) "18" + then callPackage ../interpreters/elixir { debugInfo = true; } + else throw "Elixir requires at least Erlang/OTP R18."; + lfe = callPackage ../interpreters/lfe { }; + + # Non hex packages hex = callPackage ./hex {}; webdriver = callPackage ./webdriver {}; - hex2nix = callPackage ../tools/erlang/hex2nix { }; - cuter = callPackage ../tools/erlang/cuter { }; + hex2nix = callPackage ../tools/erlang/hex2nix {}; + cuter = callPackage ../tools/erlang/cuter {}; relxExe = callPackage ../tools/erlang/relx-exe {}; }; in fix' (extends overrides packages) diff --git a/pkgs/development/beam-modules/lib.nix b/pkgs/development/beam-modules/lib.nix index ae2705613f0..009bfb4975b 100644 --- a/pkgs/development/beam-modules/lib.nix +++ b/pkgs/development/beam-modules/lib.nix @@ -1,4 +1,4 @@ -{ pkgs }: +{ pkgs, stdenv }: rec { @@ -12,6 +12,15 @@ rec { callPackage = callPackageWith pkgs; + /* Erlang/OTP-specific version retrieval, returns 19 for OTP R19 */ + getVersion = x: + let + parse = drv: (builtins.parseDrvName drv).version; + in builtins.replaceStrings ["B" "-"] ["." "."] ( + if builtins.isString x + then parse x + else x.version or (parse x.name)); + /* Uses generic-builder to evaluate provided drv containing OTP-version specific data. diff --git a/pkgs/top-level/beam-packages.nix b/pkgs/top-level/beam-packages.nix index ccf22d6c534..9e0234ac1e2 100644 --- a/pkgs/top-level/beam-packages.nix +++ b/pkgs/top-level/beam-packages.nix @@ -1,7 +1,7 @@ { pkgs, stdenv, callPackage, wxGTK30, darwin }: rec { - lib = import ../development/beam-modules/lib.nix { inherit pkgs; }; + lib = callPackage ../development/beam-modules/lib.nix {}; # Each interpreters = rec { @@ -45,9 +45,11 @@ rec { odbcSupport = true; }; - # Other Beam languages. These are built with beam.interpreters.erlang. - elixir = callPackage ../development/interpreters/elixir { debugInfo = true; }; - lfe = callPackage ../development/interpreters/lfe { }; + # Other Beam languages. These are built with `beam.interpreters.erlang`. To + # access for example elixir built with different version of Erlang, use + # `beam.packages.erlangR19.elixir`. + elixir = packages.erlang.elixir; + lfe = packages.erlang.lfe; }; # Helper function to generate package set with a specific Erlang version. From 0fccd5bba40ce903ff25bb8f2ca09e86f3bef19d Mon Sep 17 00:00:00 2001 From: Gleb Peregud Date: Sun, 18 Jun 2017 23:05:18 +0200 Subject: [PATCH 4/5] erlang: update documentation. The documentation got a bit stale compared to actual contents of nixpkgs. This commit focuses on updating existing docs, not on making sure all details of beam packages are covered. --- doc/languages-frameworks/beam.xml | 140 ++++++++++++++---- pkgs/development/beam-modules/mix-bootstrap | 20 ++- .../rebar3/rebar3-nix-bootstrap | 2 +- 3 files changed, 120 insertions(+), 42 deletions(-) diff --git a/doc/languages-frameworks/beam.xml b/doc/languages-frameworks/beam.xml index efb2e60cf3a..28dec9f77de 100644 --- a/doc/languages-frameworks/beam.xml +++ b/doc/languages-frameworks/beam.xml @@ -2,36 +2,85 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-beam"> - Beam Languages (Erlang & Elixir) + Beam Languages (Erlang, Elixir & LFE)
Introduction In this document and related Nix expressions we use the term - Beam to describe the environment. Beam is + Beam to describe the environment. BEAM is the name of the Erlang Virtial Machine and, as far as we know, - from a packaging perspective all languages that run on Beam are + from a packaging perspective all languages that run on BEAM are interchangable. The things that do change, like the build system, are transperant to the users of the package. So we make no distinction.
-
+
+ Structure + + All Beam-related things are available via top-level + beam attribute, which includes: + + + + + interpreters: contains a set of compilers running + on Beam, including multiple Erlang/OTP versions + (beam.interpreters.erlangR19, etc), Elixir + (beam.interpreters.elixir) and LFE + (beam.interpreters.lfe). + + + + + packages: contains a set of package sets, each + compiled with a specific Erlang/OTP version, e.g. + beam.packages.erlangR19. + + + + + Default Erlang compiler is defined by + beam.interpreters.erlang and aliased as + erlang. Default package set with Beam packages is + defined by beam.packages.erlang and aliased at + top-level as beamPackages. + + + If you want to create a package set built with a custom Erlang version, + use lambda beam.packagesWith, which accepts an + Erlang/OTP derivative and produces a package set similar to + beam.packages.erlang. + + + Many Erlang/OTP distributions available in + beam.interpreters have their versions with ODBC and/or + Java enabled. For example there's + beam.interpreters.erlangR19_odbc_javac which + corresponds to beam.interpreters.erlangR19. + + + We also provide beam.packages.erlang.callPackage, which + simplifies writing Beam package definitions, by injecting all packages from + beam.packages.erlang into top-level context. + +
+
Build Tools
Rebar3 - By default Rebar3 wants to manage it's own dependencies. In the - normal non-Nix, this is perfectly acceptable. In the Nix world it - is not. To support this we have created two versions of rebar3, + By default Rebar3 wants to manage it's own dependencies. This is perfectly + acceptable in the normal non-Nix setup. In the Nix world it is not. To + support this we have created two versions of rebar3, rebar3 and rebar3-open. The - rebar3 version has been patched to remove the - ability to download anything from it. If you are not running it a - nix-shell or a nix-build then its probably not going to work for - you. rebar3-open is the normal, un-modified - rebar3. It should work exactly as would any other version of - rebar3. Any Erlang package should rely on - rebar3 and thats really what you should be - using too. + rebar3 version has been patched to remove the ability + to download anything from it. If you are not running it a nix-shell or a + nix-build then its probably not going to work for you. + rebar3-open is the normal, un-modified rebar3. It + should work exactly as would any other version of rebar3. Any Erlang + package should rely on rebar3 and thats really what you + should be using too. See buildRebar3 below.
@@ -43,16 +92,17 @@ buildMix and buildErlangMk derivations.
-
How to install Beam packages - Beam packages are not registered in the top level simply because - they are not relevant to the vast majority of Nix users. They are - installable using the beamPackages attribute - set. + Beam packages are not registered in the top level simply because they are + not relevant to the vast majority of Nix users. They are installable using + the beam.packages.erlang attribute set and aliased as + beamPackages. This attribute points at packages built by + the default Erlang/OTP version in Nixpkgs as defined by + beam.interpreters.erlang. You can list the avialable packages in the beamPackages with the following command: @@ -87,10 +137,11 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
Rebar3 Packages - There is a Nix functional called - buildRebar3. We use this function to make a - derivation that understands how to build the rebar3 project. For - example, the epression we use to build the buildRebar3 (defined + in beam.packages.erlang.buildRebar3 and aliased at + top-level). We use this function to make a derivation that understands + how to build the rebar3 project. For example, the expression we use to + build the hex2nix project follows. @@ -111,10 +162,18 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse beamDeps = [ ibrowse jsx erlware_commons ]; } + + This derivation is callable with + beam.packages.erlang.callPackage (see above). If you + want to call this package using normal callPackage, + you should refer to dependency packages via + beamPackages, e.g. + beamPackages.ibrowse. + The only visible difference between this derivation and something like stdenv.mkDerivation is that we - have added erlangDeps to the derivation. If + have added beamDeps to the derivation. If you add your Beam dependencies here they will be correctly handled by the system. @@ -171,6 +230,27 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; }; + beamDeps = [ plug absinthe ]; + + meta = { + description = ''A plug for Absinthe, an experimental GraphQL + toolkit''; + license = stdenv.lib.licenses.bsd3; + homepage = "https://github.com/CargoSense/absinthe_plug"; + }; + } + + + Alternatively one can use buildHex as a shortcut for the above: + + + { buildHex, buildMix, plug, absinthe }: + buildHex { + name = "absinthe_plug"; + version = "1.0.0"; + sha256 = + "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; + builder = buildMix; beamDeps = [ plug absinthe]; meta = { @@ -264,7 +344,7 @@ let name = "hex2nix"; version = "0.1.0"; src = ./.; - erlangDeps = [ ibrowse jsx erlware_commons ]; + beamDeps = [ ibrowse jsx erlware_commons ]; }; drv = beamPackages.callPackage f {}; @@ -272,10 +352,10 @@ in drv
- Building in a shell + Building in a shell (for mix projects) - We can leveral the support of the Derivation, regardless of - which build Derivation is called by calling the commands themselv.s + We can leverage the support of the Derivation, regardless of + which build Derivation is called by calling the commands themselves. # ============================================================================= @@ -351,7 +431,7 @@ analyze: build plt hex2nix tool. Given the path to the Erlang modules (usually pkgs/development/erlang-modules). It will - happily dump a file called + dump a file called hex-packages.nix. That file will contain all the packages that use a recognized build system in Hex. However, it can't know whether or not all those packages are buildable. diff --git a/pkgs/development/beam-modules/mix-bootstrap b/pkgs/development/beam-modules/mix-bootstrap index c4a1b364daa..6c9a20c6de2 100755 --- a/pkgs/development/beam-modules/mix-bootstrap +++ b/pkgs/development/beam-modules/mix-bootstrap @@ -3,18 +3,16 @@ %%! -smp enable %%% --------------------------------------------------------------------------- %%% @doc -%%% The purpose of this command is to prepare a rebar3 project so that -%%% rebar3 understands that the dependencies are all already -%%% installed. If you want a hygienic build on nix then you must run -%%% this command before running rebar3. I suggest that you add a -%%% `Makefile` to your project and have the bootstrap command be a -%%% dependency of the build commands. See the nix documentation for +%%% The purpose of this command is to prepare a mix project so that mix +%%% understands that the dependencies are all already installed. If you want a +%%% hygienic build on nix then you must run this command before running mix. I +%%% suggest that you add a `Makefile` to your project and have the bootstrap +%%% command be a dependency of the build commands. See the nix documentation for %%% more information. %%% -%%% This command designed to have as few dependencies as possible so -%%% that it can be a dependency of root level packages like rebar3. To -%%% that end it does many things in a fairly simplistic way. That is -%%% by design. +%%% This command designed to have as few dependencies as possible so that it can +%%% be a dependency of root level packages like mix. To that end it does many +%%% things in a fairly simplistic way. That is by design. %%% %%% ### Assumptions %%% @@ -37,7 +35,7 @@ main(Args) -> %% @doc %% This takes an app name in the standard OTP - format -%% and returns just the app name. Why? because rebar is doesn't +%% and returns just the app name. Why? Because rebar doesn't %% respect OTP conventions in some cases. -spec fixup_app_name(file:name()) -> string(). fixup_app_name(Path) -> diff --git a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap b/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap index b839a4a3b09..aa7e6c5f912 100755 --- a/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap +++ b/pkgs/development/tools/build-managers/rebar3/rebar3-nix-bootstrap @@ -146,7 +146,7 @@ make_symlink(Path, TargetFile) -> %% @doc %% This takes an app name in the standard OTP - format -%% and returns just the app name. Why? because rebar doesn't +%% and returns just the app name. Why? Because rebar doesn't %% respect OTP conventions in some cases. -spec fixup_app_name(string()) -> string(). fixup_app_name(FileName) -> From 505508a813d7680d8ada10eb8875a62de79e5aac Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Thu, 22 Jun 2017 04:32:46 -0500 Subject: [PATCH 5/5] Update BEAM docs Improve beam docs: * correct spelling * update per pandoc changes * capitalize titles * capitalize BEAM throughout and use "the BEAM" when referring to the virtual machine. * tweak grammar and phrasing * reformat build-tools-rebar3 section * add more links * re-wrap s Also update s * normalize whitespace * don't double quote homepage * use $ in all shell snippets --- doc/default.nix | 2 +- doc/languages-frameworks/beam.xml | 344 ++++++++++++++++-------------- 2 files changed, 182 insertions(+), 164 deletions(-) diff --git a/doc/default.nix b/doc/default.nix index 540a209c2ac..cfd51fba257 100644 --- a/doc/default.nix +++ b/doc/default.nix @@ -26,7 +26,7 @@ pkgs.stdenv.mkDerivation { extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" ''; in '' { - pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--chapters"} \ + pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--top-level-division=chapter"} \ --smart \ | sed -e 's|||' \ diff --git a/doc/languages-frameworks/beam.xml b/doc/languages-frameworks/beam.xml index 28dec9f77de..1a18ed27237 100644 --- a/doc/languages-frameworks/beam.xml +++ b/doc/languages-frameworks/beam.xml @@ -2,30 +2,29 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-beam"> - Beam Languages (Erlang, Elixir & LFE) + BEAM Languages (Erlang, Elixir & LFE)
Introduction - In this document and related Nix expressions we use the term - Beam to describe the environment. BEAM is - the name of the Erlang Virtial Machine and, as far as we know, - from a packaging perspective all languages that run on BEAM are - interchangable. The things that do change, like the build - system, are transperant to the users of the package. So we make - no distinction. + In this document and related Nix expressions, we use the term, + BEAM, to describe the environment. BEAM is the name + of the Erlang Virtual Machine and, as far as we're concerned, from a + packaging perspective, all languages that run on the BEAM are + interchangeable. That which varies, like the build system, is transparent + to users of any given BEAM package, so we make no distinction.
Structure - All Beam-related things are available via top-level + All BEAM-related expressions are available via the top-level beam attribute, which includes: - interpreters: contains a set of compilers running - on Beam, including multiple Erlang/OTP versions + interpreters: a set of compilers running on the + BEAM, including multiple Erlang/OTP versions (beam.interpreters.erlangR19, etc), Elixir (beam.interpreters.elixir) and LFE (beam.interpreters.lfe). @@ -33,36 +32,37 @@ - packages: contains a set of package sets, each - compiled with a specific Erlang/OTP version, e.g. + packages: a set of package sets, each compiled with + a specific Erlang/OTP version, e.g. beam.packages.erlangR19. - Default Erlang compiler is defined by - beam.interpreters.erlang and aliased as - erlang. Default package set with Beam packages is - defined by beam.packages.erlang and aliased at - top-level as beamPackages. + The default Erlang compiler, defined by + beam.interpreters.erlang, is aliased as + erlang. The default BEAM package set is defined by + beam.packages.erlang and aliased at the top level as + beamPackages. - If you want to create a package set built with a custom Erlang version, - use lambda beam.packagesWith, which accepts an - Erlang/OTP derivative and produces a package set similar to + To create a package set built with a custom Erlang version, use the + lambda, beam.packagesWith, which accepts an Erlang/OTP + derivation and produces a package set similar to beam.packages.erlang. Many Erlang/OTP distributions available in - beam.interpreters have their versions with ODBC and/or - Java enabled. For example there's - beam.interpreters.erlangR19_odbc_javac which + beam.interpreters have versions with ODBC and/or Java + enabled. For example, there's + beam.interpreters.erlangR19_odbc_javac, which corresponds to beam.interpreters.erlangR19. - - We also provide beam.packages.erlang.callPackage, which - simplifies writing Beam package definitions, by injecting all packages from - beam.packages.erlang into top-level context. + + We also provide the lambda, + beam.packages.erlang.callPackage, which simplifies + writing BEAM package definitions by injecting all packages from + beam.packages.erlang into the top-level context.
@@ -70,42 +70,52 @@
Rebar3 - By default Rebar3 wants to manage it's own dependencies. This is perfectly - acceptable in the normal non-Nix setup. In the Nix world it is not. To - support this we have created two versions of rebar3, - rebar3 and rebar3-open. The - rebar3 version has been patched to remove the ability - to download anything from it. If you are not running it a nix-shell or a - nix-build then its probably not going to work for you. - rebar3-open is the normal, un-modified rebar3. It - should work exactly as would any other version of rebar3. Any Erlang - package should rely on rebar3 and thats really what you - should be using too. See buildRebar3 below. + By default, Rebar3 wants to manage its own dependencies. This is perfectly + acceptable in the normal, non-Nix setup, but in the Nix world, it is not. + To rectify this, we provide two versions of Rebar3: + + + + rebar3: patched to remove the ability to download + anything. When not running it via nix-shell or + nix-build, it's probably not going to work as + desired. + + + + + rebar3-open: the normal, unmodified Rebar3. It + should work exactly as would any other version of Rebar3. Any Erlang + package should rely on rebar3 instead. See . + + +
Mix & Erlang.mk - Both Mix and Erlang.mk work exactly as you would expect. There - is a bootstrap process that needs to be run for both of - them. However, that is supported by the - buildMix and buildErlangMk derivations. + Both Mix and Erlang.mk work exactly as expected. There is a bootstrap + process that needs to be run for both, however, which is supported by the + buildMix and buildErlangMk + derivations, respectively.
- How to install Beam packages + How to Install BEAM Packages - Beam packages are not registered in the top level simply because they are + BEAM packages are not registered at the top level, simply because they are not relevant to the vast majority of Nix users. They are installable using - the beam.packages.erlang attribute set and aliased as - beamPackages. This attribute points at packages built by - the default Erlang/OTP version in Nixpkgs as defined by + the beam.packages.erlang attribute set (aliased as + beamPackages), which points to packages built by the + default Erlang/OTP version in Nixpkgs, as defined by beam.interpreters.erlang. - You can list the avialable packages in the - beamPackages with the following command: + To list the available packages in + beamPackages, use the following command: @@ -119,145 +129,152 @@ beamPackages.meck meck-0.8.3 beamPackages.rebar3-pc pc-1.1.0 - To install any of those packages into your profile, refer to them by - their attribute path (first column): + To install any of those packages into your profile, refer to them by their + attribute path (first column): $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse - The attribute path of any Beam packages corresponds to the name - of that particular package in Hex or its OTP Application/Release name. + The attribute path of any BEAM package corresponds to the name of that + particular package in Hex or its + OTP Application/Release name.
- Packaging Beam Applications + Packaging BEAM Applications
Erlang Applications
Rebar3 Packages - There is a Nix function called buildRebar3 (defined - in beam.packages.erlang.buildRebar3 and aliased at - top-level). We use this function to make a derivation that understands - how to build the rebar3 project. For example, the expression we use to - build the hex2nix - project follows. + The Nix function, buildRebar3, defined in + beam.packages.erlang.buildRebar3 and aliased at the + top level, can be used to build a derivation that understands how to + build a Rebar3 project. For example, we can build hex2nix as + follows: - {stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }: + { stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }: - buildRebar3 rec { - name = "hex2nix"; - version = "0.0.1"; + buildRebar3 rec { + name = "hex2nix"; + version = "0.0.1"; - src = fetchFromGitHub { - owner = "ericbmerritt"; - repo = "hex2nix"; - rev = "${version}"; - sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg"; - }; + src = fetchFromGitHub { + owner = "ericbmerritt"; + repo = "hex2nix"; + rev = "${version}"; + sha256 = "1w7xjidz1l5yjmhlplfx7kphmnpvqm67w99hd2m7kdixwdxq0zqg"; + }; beamDeps = [ ibrowse jsx erlware_commons ]; } - This derivation is callable with - beam.packages.erlang.callPackage (see above). If you - want to call this package using normal callPackage, - you should refer to dependency packages via + Such derivations are callable with + beam.packages.erlang.callPackage (see ). To call this package using the normal + callPackage, refer to dependency packages via beamPackages, e.g. beamPackages.ibrowse. - The only visible difference between this derivation and - something like stdenv.mkDerivation is that we - have added beamDeps to the derivation. If - you add your Beam dependencies here they will be correctly - handled by the system. + Notably, buildRebar3 includes + beamDeps, while + stdenv.mkDerivation does not. BEAM dependencies added + there will be correctly handled by the system. - If your package needs to compile native code via Rebar's port - compilation mechenism. You should add compilePort = - true; to the derivation. + If a package needs to compile native code via Rebar3's port compilation + mechanism, add compilePort = true; to the derivation.
Erlang.mk Packages - Erlang.mk functions almost identically to Rebar. The only real - difference is that buildErlangMk is called - instead of buildRebar3 + Erlang.mk functions similarly to Rebar3, except we use + buildErlangMk instead of + buildRebar3. - { buildErlangMk, fetchHex, cowlib, ranch }: - buildErlangMk { - name = "cowboy"; - version = "1.0.4"; - src = fetchHex { - pkg = "cowboy"; - version = "1.0.4"; - sha256 = - "6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac"; - }; - beamDeps = [ cowlib ranch ]; + { buildErlangMk, fetchHex, cowlib, ranch }: - meta = { - description = ''Small, fast, modular HTTP server written in - Erlang.''; - license = stdenv.lib.licenses.isc; - homepage = "https://github.com/ninenines/cowboy"; - }; + buildErlangMk { + name = "cowboy"; + version = "1.0.4"; + + src = fetchHex { + pkg = "cowboy"; + version = "1.0.4"; + sha256 = "6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac"; + }; + + beamDeps = [ cowlib ranch ]; + + meta = { + description = '' + Small, fast, modular HTTP server written in Erlang + ''; + license = stdenv.lib.licenses.isc; + homepage = https://github.com/ninenines/cowboy; + }; }
Mix Packages - Mix functions almost identically to Rebar. The only real - difference is that buildMix is called - instead of buildRebar3 + Mix functions similarly to Rebar3, except we use + buildMix instead of buildRebar3. { buildMix, fetchHex, plug, absinthe }: + buildMix { name = "absinthe_plug"; version = "1.0.0"; + src = fetchHex { pkg = "absinthe_plug"; version = "1.0.0"; - sha256 = - "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; + sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; }; - beamDeps = [ plug absinthe ]; + + beamDeps = [ plug absinthe ]; meta = { - description = ''A plug for Absinthe, an experimental GraphQL - toolkit''; + description = '' + A plug for Absinthe, an experimental GraphQL toolkit + ''; license = stdenv.lib.licenses.bsd3; - homepage = "https://github.com/CargoSense/absinthe_plug"; - }; - } + homepage = https://github.com/CargoSense/absinthe_plug; + }; + } - Alternatively one can use buildHex as a shortcut for the above: + Alternatively, we can use buildHex as a shortcut: { buildHex, buildMix, plug, absinthe }: + buildHex { name = "absinthe_plug"; version = "1.0.0"; - sha256 = - "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; + + sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33"; + builder = buildMix; - beamDeps = [ plug absinthe]; + + beamDeps = [ plug absinthe ]; meta = { - description = ''A plug for Absinthe, an experimental GraphQL - toolkit''; + description = '' + A plug for Absinthe, an experimental GraphQL toolkit + ''; license = stdenv.lib.licenses.bsd3; - homepage = "https://github.com/CargoSense/absinthe_plug"; + homepage = https://github.com/CargoSense/absinthe_plug; }; } @@ -265,18 +282,18 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse
- How to develop + How to Develop
Accessing an Environment - Often, all you want to do is be able to access a valid - environment that contains a specific package and its - dependencies. we can do that with the env - part of a derivation. For example, lets say we want to access an - erlang repl with ibrowse loaded up. We could do the following. + Often, we simply want to access a valid environment that contains a + specific package and its dependencies. We can accomplish that with the + env attribute of a derivation. For example, let's say + we want to access an Erlang REPL with ibrowse loaded + up. We could do the following: - ~/w/nixpkgs ❯❯❯ nix-shell -A beamPackages.ibrowse.env --run "erl" + $ nix-shell -A beamPackages.ibrowse.env --run "erl" Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] Eshell V7.0 (abort with ^G) @@ -317,20 +334,19 @@ $ nix-env -f "<nixpkgs>" -iA beamPackages.ibrowse 2> - Notice the -A beamPackages.ibrowse.env.That - is the key to this functionality. + Notice the -A beamPackages.ibrowse.env. That is the key + to this functionality.
Creating a Shell Getting access to an environment often isn't enough to do real - development. Many times we need to create a - shell.nix file and do our development inside - of the environment specified by that file. This file looks a lot - like the packaging described above. The main difference is that - src points to project root and we call the - package directly. + development. Usually, we need to create a shell.nix + file and do our development inside of the environment specified therein. + This file looks a lot like the packaging described above, except that + src points to the project root and we call the package + directly. { pkgs ? import "<nixpkgs"> {} }: @@ -349,13 +365,14 @@ let drv = beamPackages.callPackage f {}; in - drv + + drv
- Building in a shell (for mix projects) + Building in a Shell (for Mix Projects) - We can leverage the support of the Derivation, regardless of - which build Derivation is called by calling the commands themselves. + We can leverage the support of the derivation, irrespective of the build + derivation, by calling the commands themselves. # ============================================================================= @@ -415,42 +432,43 @@ analyze: build plt - If you add the shell.nix as described and - user rebar as follows things should simply work. Aside from the + Using a shell.nix as described (see ) should just work. Aside from test, plt, and - analyze the talks work just fine for all of - the build Derivations. + analyze, the Make targets work just fine for all of the + build derivations.
- Generating Packages from Hex with Hex2Nix + Generating Packages from Hex with <literal>hex2nix</literal> - Updating the Hex packages requires the use of the - hex2nix tool. Given the path to the Erlang - modules (usually - pkgs/development/erlang-modules). It will - dump a file called - hex-packages.nix. That file will contain all - the packages that use a recognized build system in Hex. However, - it can't know whether or not all those packages are buildable. + Updating the Hex package set + requires hex2nix. Given the + path to the Erlang modules (usually + pkgs/development/erlang-modules), it will dump a file + called hex-packages.nix, containing all the packages that + use a recognized build system in Hex. It can't be determined, however, + whether every package is buildable. - To make life easier for our users, it makes good sense to go - ahead and attempt to build all those packages and remove the - ones that don't build. To do that, simply run the command (in - the root of your nixpkgs repository). that follows. + To make life easier for our users, try to build every Hex package and remove those that fail. + To do that, simply run the following command in the root of your + nixpkgs repository: $ nix-build -A beamPackages - That will build every package in - beamPackages. Then you can go through and - manually remove the ones that fail. Hopefully, someone will - improve hex2nix in the future to automate - that. + That will attempt to build every package in + beamPackages. Then manually remove those that fail. + Hopefully, someone will improve hex2nix in the + future to automate the process.