diff mbox

Erlang

Message ID 20160623054441.GA11139@jasmine
State New
Headers show

Commit Message

Leo Famulari June 23, 2016, 5:44 a.m. UTC
Erlang 19.0 has recently been released:
http://www.erlang.org/news/105

Version 19.0 includes this desirable change, copied from the README [0]:
"The compiler will no longer put the compilation date and time into BEAM
files.  That means that two BEAM files compiled on the same computer
from the same source code and compilation options will be identical."

While version 19.0 was being prepared by the Erlang maintainers, Pjotr
and I made sure we could build Erlang itself without any pesky
timestamps making the package unreproducible.

I'm happy to present this latest attempt at an Erlang package. It passes
--rounds=2 for me.

It is mostly the same as the package used by Pjotr in his bioinformatics
Guix repository [1]. The differences are:
* This package installs the man pages and COPYRIGHT file.
* The list of licenses was increased based on the COPYRIGHT file.
* I added Pjotr to the list of authors.
* There are cosmetic / formatting changes.

Your comments are welcome :)

[0]
http://erlang.org/download/otp_src_19.0.readme

[1]
https://github.com/genenetwork/guix-bioinformatics/blob/elixir/gn/packages/erlang.scm

Comments

Pjotr Prins June 23, 2016, 6:32 p.m. UTC | #1
I used this package to build Elixir and 3000+ tests passed. I think
it should go in :). 

Thanks Leo for patching the remaining files that write time stamps.
Erlang itself now is deterministic and compiles reproducible targets
making those deterministic. 

Very important package.

Pj.

On Thu, Jun 23, 2016 at 01:44:41AM -0400, Leo Famulari wrote:
> Erlang 19.0 has recently been released:
> http://www.erlang.org/news/105
> 
> Version 19.0 includes this desirable change, copied from the README [0]:
> "The compiler will no longer put the compilation date and time into BEAM
> files.  That means that two BEAM files compiled on the same computer
> from the same source code and compilation options will be identical."
> 
> While version 19.0 was being prepared by the Erlang maintainers, Pjotr
> and I made sure we could build Erlang itself without any pesky
> timestamps making the package unreproducible.
> 
> I'm happy to present this latest attempt at an Erlang package. It passes
> --rounds=2 for me.
> 
> It is mostly the same as the package used by Pjotr in his bioinformatics
> Guix repository [1]. The differences are:
> * This package installs the man pages and COPYRIGHT file.
> * The list of licenses was increased based on the COPYRIGHT file.
> * I added Pjotr to the list of authors.
> * There are cosmetic / formatting changes.
> 
> Your comments are welcome :)
> 
> [0]
> http://erlang.org/download/otp_src_19.0.readme
> 
> [1]
> https://github.com/genenetwork/guix-bioinformatics/blob/elixir/gn/packages/erlang.scm

> From 752033bde8ef4137c15c0b26e9375ee90453b5e4 Mon Sep 17 00:00:00 2001
> From: Steve Sprang <scs@stevesprang.com>
> Date: Sat, 6 Feb 2016 12:40:53 -0800
> Subject: [PATCH] gnu: Add erlang.
> 
> * gnu/packages/erlang.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> 
> Co-authored by: Leo Famulari <leo@famulari.name>
> Co-authored by: Pjotr Prins <pjotr.public12@thebird.nl>
> ---
>  gnu/local.mk            |   1 +
>  gnu/packages/erlang.scm | 179 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 180 insertions(+)
>  create mode 100644 gnu/packages/erlang.scm
> 
> diff --git a/gnu/local.mk b/gnu/local.mk
> index ab0cf49..0b92ae5 100644
> --- a/gnu/local.mk
> +++ b/gnu/local.mk
> @@ -109,6 +109,7 @@ GNU_SYSTEM_MODULES =				\
>    %D%/packages/engineering.scm			\
>    %D%/packages/enlightenment.scm		\
>    %D%/packages/entr.scm				\
> +  %D%/packages/erlang.scm			\
>    %D%/packages/fcitx.scm			\
>    %D%/packages/feh.scm                          \
>    %D%/packages/figlet.scm			\
> diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
> new file mode 100644
> index 0000000..39da7e9
> --- /dev/null
> +++ b/gnu/packages/erlang.scm
> @@ -0,0 +1,179 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2016 Steve Sprang <scs@stevesprang.com>
> +;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
> +;;; Copyright © 2016 Pjotr Prins <pjotr.public12@thebird.nl>
> +;;;
> +;;; This file is part of GNU Guix.
> +;;;
> +;;; GNU Guix is free software; you can redistribute it and/or modify it
> +;;; under the terms of the GNU General Public License as published by
> +;;; the Free Software Foundation; either version 3 of the License, or (at
> +;;; your option) any later version.
> +;;;
> +;;; GNU Guix is distributed in the hope that it will be useful, but
> +;;; WITHOUT ANY WARRANTY; without even the implied warranty of
> +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +;;; GNU General Public License for more details.
> +;;;
> +;;; You should have received a copy of the GNU General Public License
> +;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
> +
> +(define-module (gnu packages erlang)
> +  #:use-module ((guix licenses) #:prefix license:)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix download)
> +  #:use-module (guix packages)
> +  #:use-module (gnu packages autotools)
> +  #:use-module (gnu packages fontutils)
> +  #:use-module (gnu packages gl)
> +  #:use-module (gnu packages ncurses)
> +  #:use-module (gnu packages perl)
> +  #:use-module (gnu packages tls)
> +  #:use-module (gnu packages wxwidgets))
> +
> +(define-public erlang
> +  (package
> +    (name "erlang")
> +    ;; When updating, remember to update the hash of erlang-manpages!
> +    (version "19.0")
> +    (source (origin
> +              (method url-fetch)
> +              ;; The tarball from http://erlang.org/download contains many
> +              ;; pre-compiled files, so we use this snapshot of the source
> +              ;; repository.
> +              (uri (string-append "https://github.com/erlang/otp/archive/OTP-"
> +                                  version ".tar.gz"))
> +              (file-name (string-append name "-" version ".tar.gz"))
> +              (sha256
> +               (base32
> +                "1dxyz6x1yfv33fd0xfry2ihylkyfa2d655q1vxvbz8dflyd64yqh"))))
> +    (build-system gnu-build-system)
> +    (native-inputs
> +     `(("perl" ,perl)
> +       ("autoconf" ,autoconf)
> +       ("automake" ,automake)
> +
> +       ;; Erlang's documentation is distributed in a separate tarball.
> +       ("erlang-manpages"
> +        ,(origin
> +           (method url-fetch)
> +           (uri (string-append "http://erlang.org/download/otp_doc_man_"
> +                               version ".tar.gz"))
> +           (sha256
> +            (base32
> +             "07j0l7ary936hil38xr3hvfw6j74pshkyyi98kc9cassbbcdd8y7"))))))
> +    (inputs
> +     `(("ncurses" ,ncurses)
> +       ("openssl" ,openssl)
> +       ("wxwidgets" ,wxwidgets)))
> +    (propagated-inputs
> +     `(("fontconfig" ,fontconfig)
> +       ("glu" ,glu)
> +       ("mesa" ,mesa)))
> +    (arguments
> +     `(#:test-target "release_tests"
> +       #:configure-flags
> +       (list "--disable-saved-compile-time"
> +             "--enable-dynamic-ssl-lib"
> +             "--enable-native-libs"
> +             "--enable-shared-zlib"
> +             "--enable-smp-support"
> +             "--enable-threads"
> +             "--enable-wx"
> +             (string-append "--with-ssl=" (assoc-ref %build-inputs "openssl")))
> +       #:modules ((srfi srfi-19) ; make-time, et cetera.
> +                  (guix build utils)
> +                  (guix build gnu-build-system))
> +       #:phases
> +       (modify-phases %standard-phases
> +         ;; The are several code fragments that embed timestamps into the
> +         ;; output. Here, we alter those fragments to use the value of
> +         ;; SOURCE_DATE_EPOCH instead.
> +         (add-after 'unpack 'remove-timestamps
> +           (lambda _
> +             (let ((source-date-epoch
> +                     (time-utc->date
> +                       (make-time time-utc 0 (string->number
> +                                               (getenv "SOURCE_DATE_EPOCH"))))))
> +               (substitute* "lib/reltool/src/reltool_target.erl"
> +                 (("Date = date\\(\\),")
> +                  (string-append "Date = "
> +                                 (date->string source-date-epoch
> +                                               "'{~Y,~m,~d}',"))))
> +               (substitute* "lib/reltool/src/reltool_target.erl"
> +                 (("Time = time\\(\\),")
> +                  (string-append "Time = "
> +                                 (date->string source-date-epoch
> +                                               "'{~H,~M,~S}',"))))
> +               (substitute* '("lib/reltool/src/reltool_target.erl"
> +                              "lib/sasl/src/systools_make.erl")
> +                 (("date\\(\\), time\\(\\),")
> +                  (date->string source-date-epoch
> +                                "{~Y,~m,~d}, {~H,~M,~S},")))
> +               (substitute* '("lib/dialyzer/test/small_SUITE_data/src/gs_make.erl"
> +                              "lib/gs/src/gs_make.erl")
> +                 (("tuple_to_list\\(date\\(\\)\\),tuple_to_list\\(time\\(\\)\\)")
> +                  (date->string
> +                    source-date-epoch
> +                    "tuple_to_list({~Y,~m,~d}), tuple_to_list({~H,~M,~S})")))
> +               (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl"
> +                 (("\\{Y,Mo,D\\} = date\\(\\),")
> +                  (date->string source-date-epoch
> +                                "{Y,Mo,D} = {~Y,~m,~d},")))
> +               (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl"
> +                 (("\\{H,Mi,S\\} = time\\(\\),")
> +                  (date->string source-date-epoch
> +                                "{H,Mi,S} = {~H,~M,~S},"))))))
> +         (add-after 'patch-source-shebangs 'patch-source-env
> +           (lambda _
> +             (let ((escripts
> +                    (append
> +                     (find-files "." "\\.escript")
> +                     (find-files "lib/stdlib/test/escript_SUITE_data/")
> +                     '("erts/lib_src/utils/make_atomics_api"
> +                       "erts/preloaded/src/add_abstract_code"
> +                       "lib/diameter/bin/diameterc"
> +                       "lib/reltool/examples/display_args"
> +                       "lib/reltool/examples/mnesia_core_dump_viewer"
> +                       "lib/snmp/src/compile/snmpc.src"
> +                       "make/verify_runtime_dependencies"
> +                       "make/emd2exml.in"))))
> +               (substitute* escripts
> +                 (("/usr/bin/env") (which "env"))))))
> +         (add-before 'configure 'set-erl-top
> +           (lambda _
> +             (setenv "ERL_TOP" (getcwd))))
> +         (add-before 'configure 'autoconf
> +           (lambda _ (zero? (system* "./otp_build" "autoconf"))))
> +         (add-after 'install 'patch-erl
> +           ;; This only works after install.
> +           (lambda _
> +             (substitute* (string-append (assoc-ref %outputs "out") "/bin/erl")
> +               (("sed") (which "sed")))))
> +         (add-after 'install 'install-doc
> +           (lambda* (#:key inputs outputs #:allow-other-keys)
> +             (let* ((out (assoc-ref outputs "out"))
> +                    (manpages (assoc-ref inputs "erlang-manpages"))
> +                    (share (string-append out "/share/")))
> +             (mkdir-p share)
> +             (mkdir-p (string-append share "/misc/erlang"))
> +             (with-directory-excursion share
> +               (and
> +                 (zero? (system* "tar" "xvf" manpages))
> +                 (rename-file "COPYRIGHT"
> +                              (string-append share "/misc/erlang/COPYRIGHT"))
> +                 ;; Delete superfluous files.
> +                 (for-each delete-file '("PR.template"
> +                                         "README"))))))))))
> +    (home-page "http://erlang.org/")
> +    (synopsis "The Erlang programming language")
> +    (description
> +     "Erlang is a programming language used to build massively
> +scalable soft real-time systems with requirements on high
> +availability.  Some of its uses are in telecoms, banking, e-commerce,
> +computer telephony and instant messaging.  Erlang's runtime system has
> +built-in support for concurrency, distribution and fault tolerance.")
> +    ;; Erlang is distributed under the Apache License 2.0, but some components
> +    ;; have other licenses. See 'system/COPYRIGHT' in the source distribution.
> +    (license (list license:asl2.0 license:bsd-2 license:bsd-3 license:expat
> +                   license:lgpl2.0+ license:tcl/tk license:zlib))))
> -- 
> 2.9.0
> 


--
Ludovic Courtès June 24, 2016, 11:54 a.m. UTC | #2
Leo Famulari <leo@famulari.name> skribis:

> From 752033bde8ef4137c15c0b26e9375ee90453b5e4 Mon Sep 17 00:00:00 2001
> From: Steve Sprang <scs@stevesprang.com>
> Date: Sat, 6 Feb 2016 12:40:53 -0800
> Subject: [PATCH] gnu: Add erlang.
>
> * gnu/packages/erlang.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
>
> Co-authored by: Leo Famulari <leo@famulari.name>
> Co-authored by: Pjotr Prins <pjotr.public12@thebird.nl>

Go for it!  Thanks to everyone involved!

Ludo’.
Leo Famulari June 24, 2016, 2:48 p.m. UTC | #3
On Fri, Jun 24, 2016 at 01:54:14PM +0200, Ludovic Courtès wrote:
> Leo Famulari <leo@famulari.name> skribis:
> 
> > From 752033bde8ef4137c15c0b26e9375ee90453b5e4 Mon Sep 17 00:00:00 2001
> > From: Steve Sprang <scs@stevesprang.com>
> > Date: Sat, 6 Feb 2016 12:40:53 -0800
> > Subject: [PATCH] gnu: Add erlang.
> >
> > * gnu/packages/erlang.scm: New file.
> > * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> >
> > Co-authored by: Leo Famulari <leo@famulari.name>
> > Co-authored by: Pjotr Prins <pjotr.public12@thebird.nl>
> 
> Go for it!  Thanks to everyone involved!

Pushed as 3c6e42b3bc!
diff mbox

Patch

From 752033bde8ef4137c15c0b26e9375ee90453b5e4 Mon Sep 17 00:00:00 2001
From: Steve Sprang <scs@stevesprang.com>
Date: Sat, 6 Feb 2016 12:40:53 -0800
Subject: [PATCH] gnu: Add erlang.

* gnu/packages/erlang.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.

Co-authored by: Leo Famulari <leo@famulari.name>
Co-authored by: Pjotr Prins <pjotr.public12@thebird.nl>
---
 gnu/local.mk            |   1 +
 gnu/packages/erlang.scm | 179 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 180 insertions(+)
 create mode 100644 gnu/packages/erlang.scm

diff --git a/gnu/local.mk b/gnu/local.mk
index ab0cf49..0b92ae5 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -109,6 +109,7 @@  GNU_SYSTEM_MODULES =				\
   %D%/packages/engineering.scm			\
   %D%/packages/enlightenment.scm		\
   %D%/packages/entr.scm				\
+  %D%/packages/erlang.scm			\
   %D%/packages/fcitx.scm			\
   %D%/packages/feh.scm                          \
   %D%/packages/figlet.scm			\
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
new file mode 100644
index 0000000..39da7e9
--- /dev/null
+++ b/gnu/packages/erlang.scm
@@ -0,0 +1,179 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Steve Sprang <scs@stevesprang.com>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2016 Pjotr Prins <pjotr.public12@thebird.nl>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages erlang)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix download)
+  #:use-module (guix packages)
+  #:use-module (gnu packages autotools)
+  #:use-module (gnu packages fontutils)
+  #:use-module (gnu packages gl)
+  #:use-module (gnu packages ncurses)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages tls)
+  #:use-module (gnu packages wxwidgets))
+
+(define-public erlang
+  (package
+    (name "erlang")
+    ;; When updating, remember to update the hash of erlang-manpages!
+    (version "19.0")
+    (source (origin
+              (method url-fetch)
+              ;; The tarball from http://erlang.org/download contains many
+              ;; pre-compiled files, so we use this snapshot of the source
+              ;; repository.
+              (uri (string-append "https://github.com/erlang/otp/archive/OTP-"
+                                  version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1dxyz6x1yfv33fd0xfry2ihylkyfa2d655q1vxvbz8dflyd64yqh"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("perl" ,perl)
+       ("autoconf" ,autoconf)
+       ("automake" ,automake)
+
+       ;; Erlang's documentation is distributed in a separate tarball.
+       ("erlang-manpages"
+        ,(origin
+           (method url-fetch)
+           (uri (string-append "http://erlang.org/download/otp_doc_man_"
+                               version ".tar.gz"))
+           (sha256
+            (base32
+             "07j0l7ary936hil38xr3hvfw6j74pshkyyi98kc9cassbbcdd8y7"))))))
+    (inputs
+     `(("ncurses" ,ncurses)
+       ("openssl" ,openssl)
+       ("wxwidgets" ,wxwidgets)))
+    (propagated-inputs
+     `(("fontconfig" ,fontconfig)
+       ("glu" ,glu)
+       ("mesa" ,mesa)))
+    (arguments
+     `(#:test-target "release_tests"
+       #:configure-flags
+       (list "--disable-saved-compile-time"
+             "--enable-dynamic-ssl-lib"
+             "--enable-native-libs"
+             "--enable-shared-zlib"
+             "--enable-smp-support"
+             "--enable-threads"
+             "--enable-wx"
+             (string-append "--with-ssl=" (assoc-ref %build-inputs "openssl")))
+       #:modules ((srfi srfi-19) ; make-time, et cetera.
+                  (guix build utils)
+                  (guix build gnu-build-system))
+       #:phases
+       (modify-phases %standard-phases
+         ;; The are several code fragments that embed timestamps into the
+         ;; output. Here, we alter those fragments to use the value of
+         ;; SOURCE_DATE_EPOCH instead.
+         (add-after 'unpack 'remove-timestamps
+           (lambda _
+             (let ((source-date-epoch
+                     (time-utc->date
+                       (make-time time-utc 0 (string->number
+                                               (getenv "SOURCE_DATE_EPOCH"))))))
+               (substitute* "lib/reltool/src/reltool_target.erl"
+                 (("Date = date\\(\\),")
+                  (string-append "Date = "
+                                 (date->string source-date-epoch
+                                               "'{~Y,~m,~d}',"))))
+               (substitute* "lib/reltool/src/reltool_target.erl"
+                 (("Time = time\\(\\),")
+                  (string-append "Time = "
+                                 (date->string source-date-epoch
+                                               "'{~H,~M,~S}',"))))
+               (substitute* '("lib/reltool/src/reltool_target.erl"
+                              "lib/sasl/src/systools_make.erl")
+                 (("date\\(\\), time\\(\\),")
+                  (date->string source-date-epoch
+                                "{~Y,~m,~d}, {~H,~M,~S},")))
+               (substitute* '("lib/dialyzer/test/small_SUITE_data/src/gs_make.erl"
+                              "lib/gs/src/gs_make.erl")
+                 (("tuple_to_list\\(date\\(\\)\\),tuple_to_list\\(time\\(\\)\\)")
+                  (date->string
+                    source-date-epoch
+                    "tuple_to_list({~Y,~m,~d}), tuple_to_list({~H,~M,~S})")))
+               (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl"
+                 (("\\{Y,Mo,D\\} = date\\(\\),")
+                  (date->string source-date-epoch
+                                "{Y,Mo,D} = {~Y,~m,~d},")))
+               (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl"
+                 (("\\{H,Mi,S\\} = time\\(\\),")
+                  (date->string source-date-epoch
+                                "{H,Mi,S} = {~H,~M,~S},"))))))
+         (add-after 'patch-source-shebangs 'patch-source-env
+           (lambda _
+             (let ((escripts
+                    (append
+                     (find-files "." "\\.escript")
+                     (find-files "lib/stdlib/test/escript_SUITE_data/")
+                     '("erts/lib_src/utils/make_atomics_api"
+                       "erts/preloaded/src/add_abstract_code"
+                       "lib/diameter/bin/diameterc"
+                       "lib/reltool/examples/display_args"
+                       "lib/reltool/examples/mnesia_core_dump_viewer"
+                       "lib/snmp/src/compile/snmpc.src"
+                       "make/verify_runtime_dependencies"
+                       "make/emd2exml.in"))))
+               (substitute* escripts
+                 (("/usr/bin/env") (which "env"))))))
+         (add-before 'configure 'set-erl-top
+           (lambda _
+             (setenv "ERL_TOP" (getcwd))))
+         (add-before 'configure 'autoconf
+           (lambda _ (zero? (system* "./otp_build" "autoconf"))))
+         (add-after 'install 'patch-erl
+           ;; This only works after install.
+           (lambda _
+             (substitute* (string-append (assoc-ref %outputs "out") "/bin/erl")
+               (("sed") (which "sed")))))
+         (add-after 'install 'install-doc
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (manpages (assoc-ref inputs "erlang-manpages"))
+                    (share (string-append out "/share/")))
+             (mkdir-p share)
+             (mkdir-p (string-append share "/misc/erlang"))
+             (with-directory-excursion share
+               (and
+                 (zero? (system* "tar" "xvf" manpages))
+                 (rename-file "COPYRIGHT"
+                              (string-append share "/misc/erlang/COPYRIGHT"))
+                 ;; Delete superfluous files.
+                 (for-each delete-file '("PR.template"
+                                         "README"))))))))))
+    (home-page "http://erlang.org/")
+    (synopsis "The Erlang programming language")
+    (description
+     "Erlang is a programming language used to build massively
+scalable soft real-time systems with requirements on high
+availability.  Some of its uses are in telecoms, banking, e-commerce,
+computer telephony and instant messaging.  Erlang's runtime system has
+built-in support for concurrency, distribution and fault tolerance.")
+    ;; Erlang is distributed under the Apache License 2.0, but some components
+    ;; have other licenses. See 'system/COPYRIGHT' in the source distribution.
+    (license (list license:asl2.0 license:bsd-2 license:bsd-3 license:expat
+                   license:lgpl2.0+ license:tcl/tk license:zlib))))
-- 
2.9.0