Merge pull request #26668 from gleber/fixpoint-erlang-packages

erlang: refactor: build packages per Erlang/OTP version.
This commit is contained in:
Daiderd Jordan 2017-06-22 21:49:30 +02:00 committed by GitHub
commit aba574c4fa
9 changed files with 338 additions and 182 deletions

View File

@ -26,7 +26,7 @@ pkgs.stdenv.mkDerivation {
extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" ''; extraHeader = ''xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" '';
in '' in ''
{ {
pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--chapters"} \ pandoc '${inputFile}' -w docbook ${lib.optionalString useChapters "--top-level-division=chapter"} \
--smart \ --smart \
| sed -e 's|<ulink url=|<link xlink:href=|' \ | sed -e 's|<ulink url=|<link xlink:href=|' \
-e 's|</ulink>|</link>|' \ -e 's|</ulink>|</link>|' \

View File

@ -2,60 +2,120 @@
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
xml:id="sec-beam"> xml:id="sec-beam">
<title>Beam Languages (Erlang &amp; Elixir)</title> <title>BEAM Languages (Erlang, Elixir &amp; LFE)</title>
<section xml:id="beam-introduction"> <section xml:id="beam-introduction">
<title>Introduction</title> <title>Introduction</title>
<para> <para>
In this document and related Nix expressions we use the term In this document and related Nix expressions, we use the term,
<emphasis>Beam</emphasis> to describe the environment. Beam is <emphasis>BEAM</emphasis>, to describe the environment. BEAM is the name
the name of the Erlang Virtial Machine and, as far as we know, of the Erlang Virtual Machine and, as far as we're concerned, from a
from a packaging perspective all languages that run on Beam are packaging perspective, all languages that run on the BEAM are
interchangable. The things that do change, like the build interchangeable. That which varies, like the build system, is transparent
system, are transperant to the users of the package. So we make to users of any given BEAM package, so we make no distinction.
no distinction.
</para> </para>
</section> </section>
<section xml:id="build-tools"> <section xml:id="beam-structure">
<title>Structure</title>
<para>
All BEAM-related expressions are available via the top-level
<literal>beam</literal> attribute, which includes:
</para>
<itemizedlist>
<listitem>
<para>
<literal>interpreters</literal>: a set of compilers running on the
BEAM, including multiple Erlang/OTP versions
(<literal>beam.interpreters.erlangR19</literal>, etc), Elixir
(<literal>beam.interpreters.elixir</literal>) and LFE
(<literal>beam.interpreters.lfe</literal>).
</para>
</listitem>
<listitem>
<para>
<literal>packages</literal>: a set of package sets, each compiled with
a specific Erlang/OTP version, e.g.
<literal>beam.packages.erlangR19</literal>.
</para>
</listitem>
</itemizedlist>
<para>
The default Erlang compiler, defined by
<literal>beam.interpreters.erlang</literal>, is aliased as
<literal>erlang</literal>. The default BEAM package set is defined by
<literal>beam.packages.erlang</literal> and aliased at the top level as
<literal>beamPackages</literal>.
</para>
<para>
To create a package set built with a custom Erlang version, use the
lambda, <literal>beam.packagesWith</literal>, which accepts an Erlang/OTP
derivation and produces a package set similar to
<literal>beam.packages.erlang</literal>.
</para>
<para>
Many Erlang/OTP distributions available in
<literal>beam.interpreters</literal> have versions with ODBC and/or Java
enabled. For example, there's
<literal>beam.interpreters.erlangR19_odbc_javac</literal>, which
corresponds to <literal>beam.interpreters.erlangR19</literal>.
</para>
<para xml:id="erlang-call-package">
We also provide the lambda,
<literal>beam.packages.erlang.callPackage</literal>, which simplifies
writing BEAM package definitions by injecting all packages from
<literal>beam.packages.erlang</literal> into the top-level context.
</para>
</section>
<section xml:id="build-tools">
<title>Build Tools</title> <title>Build Tools</title>
<section xml:id="build-tools-rebar3"> <section xml:id="build-tools-rebar3">
<title>Rebar3</title> <title>Rebar3</title>
<para> <para>
By default Rebar3 wants to manage it's own dependencies. In the By default, Rebar3 wants to manage its own dependencies. This is perfectly
normal non-Nix, this is perfectly acceptable. In the Nix world it acceptable in the normal, non-Nix setup, but in the Nix world, it is not.
is not. To support this we have created two versions of rebar3, To rectify this, we provide two versions of Rebar3:
<literal>rebar3</literal> and <literal>rebar3-open</literal>. The <itemizedlist>
<literal>rebar3</literal> version has been patched to remove the <listitem>
ability to download anything from it. If you are not running it a <para>
nix-shell or a nix-build then its probably not going to work for <literal>rebar3</literal>: patched to remove the ability to download
you. <literal>rebar3-open</literal> is the normal, un-modified anything. When not running it via <literal>nix-shell</literal> or
rebar3. It should work exactly as would any other version of <literal>nix-build</literal>, it's probably not going to work as
rebar3. Any Erlang package should rely on desired.
<literal>rebar3</literal> and thats really what you should be </para>
using too. </listitem>
<listitem>
<para>
<literal>rebar3-open</literal>: the normal, unmodified Rebar3. It
should work exactly as would any other version of Rebar3. Any Erlang
package should rely on <literal>rebar3</literal> instead. See <xref
linkend="rebar3-packages"/>.
</para>
</listitem>
</itemizedlist>
</para> </para>
</section> </section>
<section xml:id="build-tools-other"> <section xml:id="build-tools-other">
<title>Mix &amp; Erlang.mk</title> <title>Mix &amp; Erlang.mk</title>
<para> <para>
Both Mix and Erlang.mk work exactly as you would expect. There Both Mix and Erlang.mk work exactly as expected. There is a bootstrap
is a bootstrap process that needs to be run for both of process that needs to be run for both, however, which is supported by the
them. However, that is supported by the <literal>buildMix</literal> and <literal>buildErlangMk</literal>
<literal>buildMix</literal> and <literal>buildErlangMk</literal> derivations. derivations, respectively.
</para> </para>
</section> </section>
</section> </section>
<section xml:id="how-to-install-beam-packages"> <section xml:id="how-to-install-beam-packages">
<title>How to install Beam packages</title> <title>How to Install BEAM Packages</title>
<para> <para>
Beam packages are not registered in the top level simply because BEAM packages are not registered at the top level, simply because they are
they are not relevant to the vast majority of Nix users. They are not relevant to the vast majority of Nix users. They are installable using
installable using the <literal>beamPackages</literal> attribute the <literal>beam.packages.erlang</literal> attribute set (aliased as
set. <literal>beamPackages</literal>), which points to packages built by the
default Erlang/OTP version in Nixpkgs, as defined by
<literal>beam.interpreters.erlang</literal>.
You can list the avialable packages in the To list the available packages in
<literal>beamPackages</literal> with the following command: <literal>beamPackages</literal>, use the following command:
</para> </para>
<programlisting> <programlisting>
@ -69,33 +129,34 @@ beamPackages.meck meck-0.8.3
beamPackages.rebar3-pc pc-1.1.0 beamPackages.rebar3-pc pc-1.1.0
</programlisting> </programlisting>
<para> <para>
To install any of those packages into your profile, refer to them by To install any of those packages into your profile, refer to them by their
their attribute path (first column): attribute path (first column):
</para> </para>
<programlisting> <programlisting>
$ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse $ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse
</programlisting> </programlisting>
<para> <para>
The attribute path of any Beam packages corresponds to the name The attribute path of any BEAM package corresponds to the name of that
of that particular package in Hex or its OTP Application/Release name. particular package in <link xlink:href="https://hex.pm">Hex</link> or its
OTP Application/Release name.
</para> </para>
</section> </section>
<section xml:id="packaging-beam-applications"> <section xml:id="packaging-beam-applications">
<title>Packaging Beam Applications</title> <title>Packaging BEAM Applications</title>
<section xml:id="packaging-erlang-applications"> <section xml:id="packaging-erlang-applications">
<title>Erlang Applications</title> <title>Erlang Applications</title>
<section xml:id="rebar3-packages"> <section xml:id="rebar3-packages">
<title>Rebar3 Packages</title> <title>Rebar3 Packages</title>
<para> <para>
There is a Nix functional called The Nix function, <literal>buildRebar3</literal>, defined in
<literal>buildRebar3</literal>. We use this function to make a <literal>beam.packages.erlang.buildRebar3</literal> and aliased at the
derivation that understands how to build the rebar3 project. For top level, can be used to build a derivation that understands how to
example, the epression we use to build the <link build a Rebar3 project. For example, we can build <link
xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link> xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link> as
project follows. follows:
</para> </para>
<programlisting> <programlisting>
{stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }: { stdenv, fetchFromGitHub, buildRebar3, ibrowse, jsx, erlware_commons }:
buildRebar3 rec { buildRebar3 rec {
name = "hex2nix"; name = "hex2nix";
@ -112,43 +173,52 @@ $ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse
} }
</programlisting> </programlisting>
<para> <para>
The only visible difference between this derivation and Such derivations are callable with
something like <literal>stdenv.mkDerivation</literal> is that we <literal>beam.packages.erlang.callPackage</literal> (see <xref
have added <literal>erlangDeps</literal> to the derivation. If linkend="erlang-call-package"/>). To call this package using the normal
you add your Beam dependencies here they will be correctly <literal>callPackage</literal>, refer to dependency packages via
handled by the system. <literal>beamPackages</literal>, e.g.
<literal>beamPackages.ibrowse</literal>.
</para> </para>
<para> <para>
If your package needs to compile native code via Rebar's port Notably, <literal>buildRebar3</literal> includes
compilation mechenism. You should add <literal>compilePort = <literal>beamDeps</literal>, while
true;</literal> to the derivation. <literal>stdenv.mkDerivation</literal> does not. BEAM dependencies added
there will be correctly handled by the system.
</para>
<para>
If a package needs to compile native code via Rebar3's port compilation
mechanism, add <literal>compilePort = true;</literal> to the derivation.
</para> </para>
</section> </section>
<section xml:id="erlang-mk-packages"> <section xml:id="erlang-mk-packages">
<title>Erlang.mk Packages</title> <title>Erlang.mk Packages</title>
<para> <para>
Erlang.mk functions almost identically to Rebar. The only real Erlang.mk functions similarly to Rebar3, except we use
difference is that <literal>buildErlangMk</literal> is called <literal>buildErlangMk</literal> instead of
instead of <literal>buildRebar3</literal> <literal>buildRebar3</literal>.
</para> </para>
<programlisting> <programlisting>
{ buildErlangMk, fetchHex, cowlib, ranch }: { buildErlangMk, fetchHex, cowlib, ranch }:
buildErlangMk { buildErlangMk {
name = "cowboy"; name = "cowboy";
version = "1.0.4"; version = "1.0.4";
src = fetchHex { src = fetchHex {
pkg = "cowboy"; pkg = "cowboy";
version = "1.0.4"; version = "1.0.4";
sha256 = sha256 = "6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac";
"6a0edee96885fae3a8dd0ac1f333538a42e807db638a9453064ccfdaa6b9fdac";
}; };
beamDeps = [ cowlib ranch ]; beamDeps = [ cowlib ranch ];
meta = { meta = {
description = ''Small, fast, modular HTTP server written in description = ''
Erlang.''; Small, fast, modular HTTP server written in Erlang
'';
license = stdenv.lib.licenses.isc; license = stdenv.lib.licenses.isc;
homepage = "https://github.com/ninenines/cowboy"; homepage = https://github.com/ninenines/cowboy;
}; };
} }
</programlisting> </programlisting>
@ -156,28 +226,55 @@ $ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse
<section xml:id="mix-packages"> <section xml:id="mix-packages">
<title>Mix Packages</title> <title>Mix Packages</title>
<para> <para>
Mix functions almost identically to Rebar. The only real Mix functions similarly to Rebar3, except we use
difference is that <literal>buildMix</literal> is called <literal>buildMix</literal> instead of <literal>buildRebar3</literal>.
instead of <literal>buildRebar3</literal>
</para> </para>
<programlisting> <programlisting>
{ buildMix, fetchHex, plug, absinthe }: { buildMix, fetchHex, plug, absinthe }:
buildMix { buildMix {
name = "absinthe_plug"; name = "absinthe_plug";
version = "1.0.0"; version = "1.0.0";
src = fetchHex { src = fetchHex {
pkg = "absinthe_plug"; pkg = "absinthe_plug";
version = "1.0.0"; version = "1.0.0";
sha256 = sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
"08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
}; };
beamDeps = [ plug absinthe];
beamDeps = [ plug absinthe ];
meta = { meta = {
description = ''A plug for Absinthe, an experimental GraphQL description = ''
toolkit''; A plug for Absinthe, an experimental GraphQL toolkit
'';
license = stdenv.lib.licenses.bsd3; license = stdenv.lib.licenses.bsd3;
homepage = "https://github.com/CargoSense/absinthe_plug"; homepage = https://github.com/CargoSense/absinthe_plug;
};
}
</programlisting>
<para>
Alternatively, we can use <literal>buildHex</literal> as a shortcut:
</para>
<programlisting>
{ buildHex, buildMix, plug, absinthe }:
buildHex {
name = "absinthe_plug";
version = "1.0.0";
sha256 = "08459823fe1fd4f0325a8bf0c937a4520583a5a26d73b193040ab30a1dfc0b33";
builder = buildMix;
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;
}; };
} }
</programlisting> </programlisting>
@ -185,18 +282,18 @@ $ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse
</section> </section>
</section> </section>
<section xml:id="how-to-develop"> <section xml:id="how-to-develop">
<title>How to develop</title> <title>How to Develop</title>
<section xml:id="accessing-an-environment"> <section xml:id="accessing-an-environment">
<title>Accessing an Environment</title> <title>Accessing an Environment</title>
<para> <para>
Often, all you want to do is be able to access a valid Often, we simply want to access a valid environment that contains a
environment that contains a specific package and its specific package and its dependencies. We can accomplish that with the
dependencies. we can do that with the <literal>env</literal> <literal>env</literal> attribute of a derivation. For example, let's say
part of a derivation. For example, lets say we want to access an we want to access an Erlang REPL with <literal>ibrowse</literal> loaded
erlang repl with ibrowse loaded up. We could do the following. up. We could do the following:
</para> </para>
<programlisting> <programlisting>
~/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] 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) Eshell V7.0 (abort with ^G)
@ -237,20 +334,19 @@ $ nix-env -f &quot;&lt;nixpkgs&gt;&quot; -iA beamPackages.ibrowse
2> 2>
</programlisting> </programlisting>
<para> <para>
Notice the <literal>-A beamPackages.ibrowse.env</literal>.That Notice the <literal>-A beamPackages.ibrowse.env</literal>. That is the key
is the key to this functionality. to this functionality.
</para> </para>
</section> </section>
<section xml:id="creating-a-shell"> <section xml:id="creating-a-shell">
<title>Creating a Shell</title> <title>Creating a Shell</title>
<para> <para>
Getting access to an environment often isn't enough to do real Getting access to an environment often isn't enough to do real
development. Many times we need to create a development. Usually, we need to create a <literal>shell.nix</literal>
<literal>shell.nix</literal> file and do our development inside file and do our development inside of the environment specified therein.
of the environment specified by that file. This file looks a lot This file looks a lot like the packaging described above, except that
like the packaging described above. The main difference is that <literal>src</literal> points to the project root and we call the package
<literal>src</literal> points to project root and we call the directly.
package directly.
</para> </para>
<programlisting> <programlisting>
{ pkgs ? import &quot;&lt;nixpkgs&quot;&gt; {} }: { pkgs ? import &quot;&lt;nixpkgs&quot;&gt; {} }:
@ -264,18 +360,19 @@ let
name = "hex2nix"; name = "hex2nix";
version = "0.1.0"; version = "0.1.0";
src = ./.; src = ./.;
erlangDeps = [ ibrowse jsx erlware_commons ]; beamDeps = [ ibrowse jsx erlware_commons ];
}; };
drv = beamPackages.callPackage f {}; drv = beamPackages.callPackage f {};
in in
drv drv
</programlisting> </programlisting>
<section xml:id="building-in-a-shell"> <section xml:id="building-in-a-shell">
<title>Building in a shell</title> <title>Building in a Shell (for Mix Projects)</title>
<para> <para>
We can leveral the support of the Derivation, regardless of We can leverage the support of the derivation, irrespective of the build
which build Derivation is called by calling the commands themselv.s derivation, by calling the commands themselves.
</para> </para>
<programlisting> <programlisting>
# ============================================================================= # =============================================================================
@ -335,42 +432,43 @@ analyze: build plt
</programlisting> </programlisting>
<para> <para>
If you add the <literal>shell.nix</literal> as described and Using a <literal>shell.nix</literal> as described (see <xref
user rebar as follows things should simply work. Aside from the linkend="creating-a-shell"/>) should just work. Aside from
<literal>test</literal>, <literal>plt</literal>, and <literal>test</literal>, <literal>plt</literal>, and
<literal>analyze</literal> the talks work just fine for all of <literal>analyze</literal>, the Make targets work just fine for all of the
the build Derivations. build derivations.
</para> </para>
</section> </section>
</section> </section>
</section> </section>
<section xml:id="generating-packages-from-hex-with-hex2nix"> <section xml:id="generating-packages-from-hex-with-hex2nix">
<title>Generating Packages from Hex with Hex2Nix</title> <title>Generating Packages from Hex with <literal>hex2nix</literal></title>
<para> <para>
Updating the Hex packages requires the use of the Updating the <link xlink:href="https://hex.pm">Hex</link> package set
<literal>hex2nix</literal> tool. Given the path to the Erlang requires <link
modules (usually xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link>. Given the
<literal>pkgs/development/erlang-modules</literal>). It will path to the Erlang modules (usually
happily dump a file called <literal>pkgs/development/erlang-modules</literal>), it will dump a file
<literal>hex-packages.nix</literal>. That file will contain all called <literal>hex-packages.nix</literal>, containing all the packages that
the packages that use a recognized build system in Hex. However, use a recognized build system in <link
it can't know whether or not all those packages are buildable. xlink:href="https://hex.pm">Hex</link>. It can't be determined, however,
whether every package is buildable.
</para> </para>
<para> <para>
To make life easier for our users, it makes good sense to go To make life easier for our users, try to build every <link
ahead and attempt to build all those packages and remove the xlink:href="https://hex.pm">Hex</link> package and remove those that fail.
ones that don't build. To do that, simply run the command (in To do that, simply run the following command in the root of your
the root of your <literal>nixpkgs</literal> repository). that follows. <literal>nixpkgs</literal> repository:
</para> </para>
<programlisting> <programlisting>
$ nix-build -A beamPackages $ nix-build -A beamPackages
</programlisting> </programlisting>
<para> <para>
That will build every package in That will attempt to build every package in
<literal>beamPackages</literal>. Then you can go through and <literal>beamPackages</literal>. Then manually remove those that fail.
manually remove the ones that fail. Hopefully, someone will Hopefully, someone will improve <link
improve <literal>hex2nix</literal> in the future to automate xlink:href="https://github.com/erlang-nix/hex2nix">hex2nix</link> in the
that. future to automate the process.
</para> </para>
</section> </section>
</section> </section>

View File

@ -1,13 +1,14 @@
{ stdenv, buildRebar3, fetchHex }: { stdenv, buildRebar3, fetchHex }:
{ name, version, sha256 { name, version, sha256
, builder ? buildRebar3
, hexPkg ? name , hexPkg ? name
, ... }@attrs: , ... }@attrs:
with stdenv.lib; with stdenv.lib;
let let
pkg = self: buildRebar3 (attrs // { pkg = self: builder (attrs // {
src = fetchHex { src = fetchHex {
pkg = hexPkg; pkg = hexPkg;

View File

@ -1,16 +1,53 @@
{ stdenv, pkgs }: { stdenv, pkgs, erlang, overrides ? (self: super: {}) }:
let let
self = rec { inherit (stdenv.lib) fix' extends getVersion versionAtLeast;
hexPackages = import ./hex-packages.nix { stdenv = stdenv; callPackage = self.callPackage; pkgs = pkgs; };
callPackage = pkgs.lib.callPackageWith (pkgs // self // hexPackages); lib = pkgs.callPackage ./lib.nix {};
# 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 {}; buildRebar3 = callPackage ./build-rebar3.nix {};
buildHex = callPackage ./build-hex.nix {}; buildHex = callPackage ./build-hex.nix {};
buildErlangMk = callPackage ./build-erlang-mk.nix {}; buildErlangMk = callPackage ./build-erlang-mk.nix {};
buildMix = callPackage ./build-mix.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 {}; hex = callPackage ./hex {};
webdriver = callPackage ./webdriver {}; webdriver = callPackage ./webdriver {};
hex2nix = callPackage ../tools/erlang/hex2nix {};
cuter = callPackage ../tools/erlang/cuter {};
relxExe = callPackage ../tools/erlang/relx-exe {};
}; };
in self // self.hexPackages in fix' (extends overrides packages)

View File

@ -1,4 +1,4 @@
{ pkgs }: { pkgs, stdenv }:
rec { rec {
@ -12,6 +12,15 @@ rec {
callPackage = callPackageWith pkgs; 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 /* Uses generic-builder to evaluate provided drv containing OTP-version
specific data. specific data.

View File

@ -3,18 +3,16 @@
%%! -smp enable %%! -smp enable
%%% --------------------------------------------------------------------------- %%% ---------------------------------------------------------------------------
%%% @doc %%% @doc
%%% The purpose of this command is to prepare a rebar3 project so that %%% The purpose of this command is to prepare a mix project so that mix
%%% rebar3 understands that the dependencies are all already %%% understands that the dependencies are all already installed. If you want a
%%% installed. If you want a hygienic build on nix then you must run %%% hygienic build on nix then you must run this command before running mix. I
%%% this command before running rebar3. I suggest that you add a %%% suggest that you add a `Makefile` to your project and have the bootstrap
%%% `Makefile` to your project and have the bootstrap command be a %%% command be a dependency of the build commands. See the nix documentation for
%%% dependency of the build commands. See the nix documentation for
%%% more information. %%% more information.
%%% %%%
%%% This command designed to have as few dependencies as possible so %%% This command designed to have as few dependencies as possible so that it can
%%% that it can be a dependency of root level packages like rebar3. To %%% be a dependency of root level packages like mix. To that end it does many
%%% that end it does many things in a fairly simplistic way. That is %%% things in a fairly simplistic way. That is by design.
%%% by design.
%%% %%%
%%% ### Assumptions %%% ### Assumptions
%%% %%%
@ -37,7 +35,7 @@ main(Args) ->
%% @doc %% @doc
%% This takes an app name in the standard OTP <name>-<version> format %% This takes an app name in the standard OTP <name>-<version> 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. %% respect OTP conventions in some cases.
-spec fixup_app_name(file:name()) -> string(). -spec fixup_app_name(file:name()) -> string().
fixup_app_name(Path) -> fixup_app_name(Path) ->

View File

@ -146,7 +146,7 @@ make_symlink(Path, TargetFile) ->
%% @doc %% @doc
%% This takes an app name in the standard OTP <name>-<version> format %% This takes an app name in the standard OTP <name>-<version> 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. %% respect OTP conventions in some cases.
-spec fixup_app_name(string()) -> string(). -spec fixup_app_name(string()) -> string().
fixup_app_name(FileName) -> fixup_app_name(FileName) ->
@ -180,14 +180,14 @@ make_sure_registry_snapshot_exists(RegistrySnapshot) ->
erlang:halt(1) erlang:halt(1)
end. 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) -> gather_required_data_from_the_environment(ArgData) ->
{ok, ArgData#data{ version = guard_env("version") {ok, ArgData#data{ version = guard_env("version")
, erl_libs = os:getenv("ERL_LIBS", []) , erl_libs = get_env("ERL_LIBS", [])
, plugins = os:getenv("buildPlugins", []) , plugins = get_env("buildPlugins", [])
, root = code:root_dir() , root = code:root_dir()
, name = guard_env("name") , name = guard_env("name")
, compile_ports = nix2bool(os:getenv("compilePorts", "")) , compile_ports = nix2bool(get_env("compilePorts", ""))
, registry_snapshot = guard_env("HEX_REGISTRY_SNAPSHOT")}}. , registry_snapshot = guard_env("HEX_REGISTRY_SNAPSHOT")}}.
-spec nix2bool(any()) -> boolean(). -spec nix2bool(any()) -> boolean().
@ -196,9 +196,17 @@ nix2bool("1") ->
nix2bool("") -> nix2bool("") ->
false. 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(). -spec guard_env(string()) -> string().
guard_env(Name) -> guard_env(Name) ->
case os:getenv(Name) of case get_env(Name) of
false -> false ->
stderr("Expected Environment variable ~s! Are you sure you are " stderr("Expected Environment variable ~s! Are you sure you are "
"running in a Nix environment? Either a nix-build, " "running in a Nix environment? Either a nix-build, "

View File

@ -5986,7 +5986,7 @@ with pkgs;
erlangR18 erlangR18_odbc erlangR18_javac erlangR18_odbc_javac erlangR18 erlangR18_odbc erlangR18_javac erlangR18_odbc_javac
erlangR19 erlangR19_odbc erlangR19_javac erlangR19_odbc_javac; erlangR19 erlangR19_odbc erlangR19_javac erlangR19_odbc_javac;
inherit (beam.packages) inherit (beam.packages.erlang)
rebar rebar3-open rebar3 rebar rebar3-open rebar3
hexRegistrySnapshot fetchHex beamPackages hexRegistrySnapshot fetchHex beamPackages
hex2nix cuter relxExe; hex2nix cuter relxExe;

View File

@ -1,12 +1,13 @@
{ pkgs, stdenv, callPackage, wxGTK30, darwin }: { pkgs, stdenv, callPackage, wxGTK30, darwin }:
rec { rec {
lib = import ../development/beam-modules/lib.nix { inherit pkgs; }; lib = callPackage ../development/beam-modules/lib.nix {};
# Each
interpreters = rec { interpreters = rec {
# R18 is the Default version. # R18 is the default version.
erlang = erlangR18; erlang = erlangR18; # The main switch to change default Erlang version.
erlang_odbc = erlangR18_odbc; erlang_odbc = erlangR18_odbc;
erlang_javac = erlangR18_javac; erlang_javac = erlangR18_javac;
erlang_odbc_javac = erlangR18_odbc_javac; erlang_odbc_javac = erlangR18_odbc_javac;
@ -44,22 +45,26 @@ rec {
odbcSupport = true; odbcSupport = true;
}; };
# Other Beam languages. # Other Beam languages. These are built with `beam.interpreters.erlang`. To
elixir = callPackage ../development/interpreters/elixir { debugInfo = true; }; # access for example elixir built with different version of Erlang, use
lfe = callPackage ../development/interpreters/lfe { }; # `beam.packages.erlangR19.elixir`.
elixir = packages.erlang.elixir;
lfe = packages.erlang.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 { 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 { }; # Packages built with default Erlang version.
hex2nix = beamPackages.callPackage ../development/tools/erlang/hex2nix { }; erlang = packagesWith interpreters.erlang;
cuter = callPackage ../development/tools/erlang/cuter { }; erlangR16 = packagesWith interpreters.erlangR16;
erlangR17 = packagesWith interpreters.erlangR17;
erlangR18 = packagesWith interpreters.erlangR18;
erlangR19 = packagesWith interpreters.erlangR19;
relxExe = callPackage ../development/tools/erlang/relx-exe {};
}; };
} }