224 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <chapter xmlns="http://docbook.org/ns/docbook"
 | ||
|          xmlns:xlink="http://www.w3.org/1999/xlink"
 | ||
|          xml:id="chap-language-support">
 | ||
| 
 | ||
| <title>Support for specific programming languages</title>
 | ||
| 
 | ||
| <para>The <link linkend="chap-stdenv">standard build
 | ||
| environment</link> makes it easy to build typical Autotools-based
 | ||
| packages with very little code.  Any other kind of package can be
 | ||
| accomodated by overriding the appropriate phases of
 | ||
| <literal>stdenv</literal>.  However, there are specialised functions
 | ||
| in Nixpkgs to easily build packages for other programming languages,
 | ||
| such as Perl or Haskell.  These are described in this chapter.</para>
 | ||
| 
 | ||
| 
 | ||
| <section xml:id="ssec-language-perl"><title>Perl</title>
 | ||
| 
 | ||
| <para>Nixpkgs provides a function <varname>buildPerlPackage</varname>,
 | ||
| a generic package builder function for any Perl package that has a
 | ||
| standard <varname>Makefile.PL</varname>.  It’s implemented in <link
 | ||
| xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/perl-modules/generic"><filename>pkgs/development/perl-modules/generic</filename></link>.</para>
 | ||
| 
 | ||
| <para>Perl packages from CPAN are defined in <link
 | ||
| xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/perl-packages.nix"><filename>pkgs/perl-packages.nix</filename></link>,
 | ||
| rather than <filename>pkgs/all-packages.nix</filename>.  Most Perl
 | ||
| packages are so straight-forward to build that they are defined here
 | ||
| directly, rather than having a separate function for each package
 | ||
| called from <filename>perl-packages.nix</filename>.  However, more
 | ||
| complicated packages should be put in a separate file, typically in
 | ||
| <filename>pkgs/development/perl-modules</filename>.  Here is an
 | ||
| example of the former:
 | ||
| 
 | ||
| <programlisting>
 | ||
| ClassC3 = buildPerlPackage rec {
 | ||
|   name = "Class-C3-0.21";
 | ||
|   src = fetchurl {
 | ||
|     url = "mirror://cpan/authors/id/F/FL/FLORA/${name}.tar.gz";
 | ||
|     sha256 = "1bl8z095y4js66pwxnm7s853pi9czala4sqc743fdlnk27kq94gz";
 | ||
|   };
 | ||
| };
 | ||
| </programlisting>
 | ||
| 
 | ||
| Note the use of <literal>mirror://cpan/</literal>, and the
 | ||
| <literal>${name}</literal> in the URL definition to ensure that the
 | ||
| name attribute is consistent with the source that we’re actually
 | ||
| downloading.  Perl packages are made available in
 | ||
| <filename>all-packages.nix</filename> through the variable
 | ||
| <varname>perlPackages</varname>.  For instance, if you have a package
 | ||
| that needs <varname>ClassC3</varname>, you would typically write
 | ||
| 
 | ||
| <programlisting>
 | ||
| foo = import ../path/to/foo.nix {
 | ||
|   inherit stdenv fetchurl ...;
 | ||
|   inherit (perlPackages) ClassC3;
 | ||
| };
 | ||
| </programlisting>
 | ||
| 
 | ||
| in <filename>all-packages.nix</filename>.  You can test building a
 | ||
| Perl package as follows:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-build -A perlPackages.ClassC3
 | ||
| </screen>
 | ||
| 
 | ||
| <varname>buildPerlPackage</varname> adds <literal>perl-</literal> to
 | ||
| the start of the name attribute, so the package above is actually
 | ||
| called <literal>perl-Class-C3-0.21</literal>.  So to install it, you
 | ||
| can say:
 | ||
| 
 | ||
| <screen>
 | ||
| $ nix-env -i perl-Class-C3
 | ||
| </screen>
 | ||
| 
 | ||
| (Of course you can also install using the attribute name:
 | ||
| <literal>nix-env -i -A perlPackages.ClassC3</literal>.)</para>
 | ||
| 
 | ||
| <para>So what does <varname>buildPerlPackage</varname> do?  It does
 | ||
| the following:
 | ||
| 
 | ||
| <orderedlist>
 | ||
| 
 | ||
|   <listitem><para>In the configure phase, it calls <literal>perl
 | ||
|   Makefile.PL</literal> to generate a Makefile.  You can set the
 | ||
|   variable <varname>makeMakerFlags</varname> to pass flags to
 | ||
|   <filename>Makefile.PL</filename></para></listitem>
 | ||
| 
 | ||
|   <listitem><para>It adds the contents of the <envar>PERL5LIB</envar>
 | ||
|   environment variable to <literal>#! .../bin/perl</literal> line of
 | ||
|   Perl scripts as <literal>-I<replaceable>dir</replaceable></literal>
 | ||
|   flags.  This ensures that a script can find its
 | ||
|   dependencies.</para></listitem>
 | ||
| 
 | ||
|   <listitem><para>In the fixup phase, it writes the propagated build
 | ||
|   inputs (<varname>propagatedBuildInputs</varname>) to the file
 | ||
|   <filename>$out/nix-support/propagated-user-env-packages</filename>.
 | ||
|   <command>nix-env</command> recursively installs all packages listed
 | ||
|   in this file when you install a package that has it.  This ensures
 | ||
|   that a Perl package can find its dependencies.</para></listitem>
 | ||
| 
 | ||
| </orderedlist>
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| <para><varname>buildPerlPackage</varname> is built on top of
 | ||
| <varname>stdenv</varname>, so everything can be customised in the
 | ||
| usual way.  For instance, the <literal>BerkeleyDB</literal> module has
 | ||
| a <varname>preConfigure</varname> hook to generate a configuration
 | ||
| file used by <filename>Makefile.PL</filename>:
 | ||
| 
 | ||
| <programlisting>
 | ||
| {buildPerlPackage, fetchurl, db4}:
 | ||
| 
 | ||
| buildPerlPackage rec {
 | ||
|   name = "BerkeleyDB-0.36";
 | ||
|   
 | ||
|   src = fetchurl {
 | ||
|     url = "mirror://cpan/authors/id/P/PM/PMQS/${name}.tar.gz";
 | ||
|     sha256 = "07xf50riarb60l1h6m2dqmql8q5dij619712fsgw7ach04d8g3z1";
 | ||
|   };
 | ||
| 
 | ||
|   preConfigure = ''
 | ||
|     echo "LIB = ${db4}/lib" > config.in
 | ||
|     echo "INCLUDE = ${db4}/include" >> config.in
 | ||
|   '';
 | ||
| }
 | ||
| </programlisting>  
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| <para>Dependencies on other Perl packages can be specified in the
 | ||
| <varname>buildInputs</varname> and
 | ||
| <varname>propagatedBuildInputs</varname> attributes.  If something is
 | ||
| exclusively a build-time dependency, use
 | ||
| <varname>buildInputs</varname>; if it’s (also) a runtime dependency,
 | ||
| use <varname>propagatedBuildInputs</varname>.  For instance, this
 | ||
| builds a Perl module that has runtime dependencies on a bunch of other
 | ||
| modules:
 | ||
| 
 | ||
| <programlisting>
 | ||
| ClassC3Componentised = buildPerlPackage rec {
 | ||
|   name = "Class-C3-Componentised-1.0004";
 | ||
|   src = fetchurl {
 | ||
|     url = "mirror://cpan/authors/id/A/AS/ASH/${name}.tar.gz";
 | ||
|     sha256 = "0xql73jkcdbq4q9m0b0rnca6nrlvf5hyzy8is0crdk65bynvs8q1";
 | ||
|   };
 | ||
|   propagatedBuildInputs = [
 | ||
|     ClassC3 ClassInspector TestException MROCompat
 | ||
|   ];
 | ||
| };
 | ||
| </programlisting>
 | ||
| 
 | ||
| </para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section><title>Python</title>
 | ||
| 
 | ||
| <para>
 | ||
|   Python packages that
 | ||
|   use <link xlink:href="http://pypi.python.org/pypi/setuptools/"><literal>setuptools</literal></link>,
 | ||
|   which many Python packages do nowadays, can be built very simply using
 | ||
|   the <varname>buildPythonPackage</varname> function.  This function is
 | ||
|   implemented
 | ||
|   in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/generic/default.nix"><filename>pkgs/development/python-modules/generic/default.nix</filename></link>
 | ||
|   and works similarly to <varname>buildPerlPackage</varname>. (See
 | ||
|   <xref linkend="ssec-language-perl"/> for details.)
 | ||
| </para>
 | ||
| 
 | ||
| <para>
 | ||
|   Python packages that use <varname>buildPythonPackage</varname> are
 | ||
|   defined
 | ||
|   in <link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/python-packages.nix"><filename>pkgs/top-level/python-packages.nix</filename></link>.
 | ||
|   Most of them are simple.  For example:
 | ||
| 
 | ||
|   <programlisting>
 | ||
| twisted = buildPythonPackage {
 | ||
|   name = "twisted-8.1.0";
 | ||
| 
 | ||
|   src = fetchurl {
 | ||
|     url = http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2;
 | ||
|     sha256 = "0q25zbr4xzknaghha72mq57kh53qw1bf8csgp63pm9sfi72qhirl";
 | ||
|   };
 | ||
| 
 | ||
|   propagatedBuildInputs = [ pkgs.ZopeInterface ];
 | ||
| 
 | ||
|   meta = {
 | ||
|     homepage = http://twistedmatrix.com/;
 | ||
|     description = "Twisted, an event-driven networking engine written in Python";
 | ||
|     license = "MIT";
 | ||
|   };
 | ||
| };
 | ||
|   </programlisting>
 | ||
| </para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section><title>Java</title>
 | ||
| 
 | ||
| <para>Java packages should install JAR files in
 | ||
| <filename>$out/lib/java</filename>.</para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <!--
 | ||
| <section><title>Haskell</title>
 | ||
| 
 | ||
| <para>TODO</para>
 | ||
| 
 | ||
| </section>
 | ||
| 
 | ||
| 
 | ||
| <section><title>TeX / LaTeX</title>
 | ||
| 
 | ||
| <para>* Special support for building TeX documents</para>
 | ||
| 
 | ||
| </section>
 | ||
| -->
 | ||
| 
 | ||
| 
 | ||
| </chapter>
 | 
