<!-- $NetBSD: plist.xml,v 1.29 2020/12/12 21:45:41 fcambus Exp $ -->

<chapter id="plist">
  <title>PLIST issues</title>

  <para>The <filename>PLIST</filename> file contains a package's
  <quote>packing list</quote>, i.e. a list of files that belong to
  the package (relative to the <filename>${PREFIX}</filename>
  directory it's been installed in) plus some additional statements
  - see the &man.pkg.create.1; man page for a full list.
  This chapter addresses some issues that need attention when
  dealing with the <filename>PLIST</filename> file (or files, see
  below!).</para>


  <sect1 id="rcs-id">
    <title>RCS ID</title>

    <para>Be sure to add a RCS ID line as the first thing in any
    <filename>PLIST</filename> file you write:</para>

<programlisting>
@comment &#36;NetBSD &#36;
</programlisting>
     <para>An artificial space has been added between NetBSD and $, this is a
workaround here to prevent CVS expanding to the filename of the guide. When
adding the RCS ID the space should be omitted.</para>
  </sect1>

  <sect1 id="automatic-plist-generation">
    <title>Semi-automatic <filename>PLIST</filename> generation</title>

    <para>You can use the <command>make print-PLIST</command> command
    to output a PLIST that matches any new files since the package
    was extracted.  See <xref linkend="build.helpful-targets"/> for
    more information on this target.</para>
  </sect1>


  <sect1 id="print-PLIST">
    <title>Tweaking output of <command>make print-PLIST</command></title>

    <para>The <varname>PRINT_PLIST_AWK</varname> variable takes a set
    of AWK patterns and actions that are used to filter the output of
    print-PLIST.  You can <emphasis>append</emphasis> any chunk of AWK
    scripting you like to it, but be careful with quoting.</para>

    <para>For example, to get all files inside the
    <filename>libdata/foo</filename> directory removed from the
    resulting PLIST:</para>

<programlisting>
PRINT_PLIST_AWK+=       /^libdata\/foo/ { next; }
</programlisting>

    <para>The <varname>PRINT_PLIST_AWK</varname> transformations are
    evaluated after the file list and directory list are sorted.
    <varname>EARLY_PRINT_PLIST_AWK</varname> is like
    <varname>PRINT_PLIST_AWK</varname> except it operates before the file
    list and directory list are sorted.</para>
  </sect1>

  <sect1 id="plist.misc">
    <title>Variable substitution in PLIST</title>

    <para>A number of variables are substituted automatically in
    PLISTs when a package is installed on a system. This includes the
    following variables:</para>

    <variablelist>
      <varlistentry>
	<term><varname>${MACHINE_ARCH}</varname>, <varname>${MACHINE_GNU_ARCH}</varname></term>

	<listitem>
	  <para>Some packages like emacs and perl embed information
	  about which architecture they were built on into the
	  pathnames where they install their files. To handle this
	  case, PLIST will be preprocessed before actually used, and
	  the symbol
	  <quote><varname>${MACHINE_ARCH}</varname></quote> will be
	  replaced by what <command>uname -p</command> gives. The
	  same is done if the string
	  <varname>${MACHINE_GNU_ARCH}</varname> is embedded in
	  PLIST somewhere - use this on packages that have GNU
	  autoconf-created configure scripts.</para>

	  <note>
	    <title>Legacy note</title>

	    <para>There used to be a symbol
	    <quote><varname>$ARCH</varname></quote> that
	    was replaced by the output of <command>uname
	    -m</command>, but that's no longer supported and has
	    been removed.</para>
	  </note>
	</listitem>
      </varlistentry>

      <varlistentry>
	<term><varname>${OPSYS}</varname>, <varname>${LOWER_OPSYS}</varname>, <varname>${OS_VERSION}</varname></term>

	<listitem>
	  <para>Some packages want to embed the OS name and version
	  into some paths.  To do this, use these variables in the
	  <filename>PLIST</filename>:
	  </para>

	  <itemizedlist>
	    <listitem>
	      <para><varname>${OPSYS}</varname> - output of <quote><command>uname -s</command></quote></para>
	    </listitem>

	    <listitem>
	      <para><varname>${LOWER_OPSYS}</varname> - lowercase common name (eg. <quote>solaris</quote>)</para>
	    </listitem>

	    <listitem>
	      <para><varname>${OS_VERSION}</varname> - <quote><command>uname -r</command></quote></para>
	    </listitem>
	  </itemizedlist>
	</listitem>
      </varlistentry>
    </variablelist>

    <para>For a list of values which are replaced by
    default, the output of <command>make help topic=PLIST_SUBST</command> as
well as searching the <filename>pkgsrc/mk</filename> directory with <command>grep</command> for
<varname>PLIST_SUBST</varname> should help.</para>

    <para>If you want to change other variables not listed above, you
    can add variables and their expansions to this variable in the
    following way, similar to <varname>MESSAGE_SUBST</varname> (see <xref
    linkend="components.optional"/>):</para>

<programlisting>
PLIST_SUBST+=   SOMEVAR="somevalue"
</programlisting>

    <para>This replaces all occurrences of <quote>${SOMEVAR}</quote>
    in the <filename>PLIST</filename> with
    <quote>somevalue</quote>.</para>


    <para>The <varname>PLIST_VARS</varname> variable can be used to simplify
    the common case of conditionally including some
    <filename>PLIST</filename> entries. It can be done by adding
    <literal><varname>PLIST_VARS</varname>+=foo</literal> and
    setting the corresponding <varname>PLIST.foo</varname> variable
    to <literal>yes</literal> if the entry should be included.
    This will substitute <quote><varname>${PLIST.foo}</varname></quote>
    in the <filename>PLIST</filename> with either
    <quote><literal>""</literal></quote> or
    <quote><literal>"@comment "</literal></quote>.
    For example, in <filename>Makefile</filename>:</para>

<programlisting>
PLIST_VARS+=    foo
.if <replaceable>condition</replaceable>
PLIST.foo=      yes
.else
</programlisting>

    <para>And then in <filename>PLIST</filename>:</para>
<programlisting>
@comment &#36;NetBSD &#36;
bin/bar
man/man1/bar.1
${PLIST.foo}bin/foo
${PLIST.foo}man/man1/foo.1
${PLIST.foo}share/bar/foo.data
</programlisting>

     <para>An artificial space has been added between NetBSD and $, this is a
workaround here to prevent CVS expanding to the filename of the guide. When
adding the RCS ID the space should be omitted.</para>

  </sect1>

  <sect1 id="manpage-compression">
    <title>Man page compression</title>

    <para>Man pages should be installed in compressed form if
    <varname>MANZ</varname> is set (in <filename>bsd.own.mk</filename>),
    and uncompressed otherwise. To handle this in the
    <filename>PLIST</filename> file, the suffix <quote>.gz</quote> is
    appended/removed automatically for man pages according to
    <varname>MANZ</varname> and <varname>MANCOMPRESSED</varname> being set
    or not, see above for details. This modification of the
    <filename>PLIST</filename> file is done on a copy of it, not
    <filename>PLIST</filename> itself.</para>
  </sect1>


  <sect1 id="using-PLIST_SRC">
    <title>Changing PLIST source with <varname>PLIST_SRC</varname></title>

    <para>To use one or more files as source for the <filename>PLIST</filename> used
    in generating the binary package, set the variable
    <varname>PLIST_SRC</varname> to the names of that file(s).
    The files are later concatenated using &man.cat.1;, and the order of things is
    important. The default for <varname>PLIST_SRC</varname> is
    <filename>${PKGDIR}/PLIST</filename>.</para>
  </sect1>


  <sect1 id="platform-specific-plist">
    <title>Platform-specific and differing PLISTs</title>

    <para>Some packages decide to install a different set of files based on
    the operating system being used. These differences can be
    automatically handled by using the following files:</para>

    <itemizedlist>
      <listitem>
	<para><filename>PLIST.common</filename></para>
      </listitem>

      <listitem>
	<para><filename>PLIST.${OPSYS}</filename></para>
      </listitem>

      <listitem>
	<para><filename>PLIST.${MACHINE_ARCH}</filename></para>
      </listitem>

      <listitem>
	<para><filename>PLIST.${OPSYS}-${MACHINE_ARCH}</filename></para>
      </listitem>

      <listitem>
	<para><filename>PLIST.common_end</filename></para>
      </listitem>
    </itemizedlist>
  </sect1>

  <sect1 id="build-plist">
    <title>Build-specific PLISTs</title>

    <para>Some packages decide to generate hard-to-guess file names
    during installation that are hard to wire down.</para>
    <para>In such cases, you can set the
    <varname>GENERATE_PLIST</varname> variable to shell code
    terminated (with a semicolon) that will output PLIST entries which
    will be appended to the PLIST</para>
    <para>You can find one example in editors/xemacs:</para>

<programlisting>
GENERATE_PLIST+=        ${ECHO} bin/${DISTNAME}-`${WRKSRC}/src/xemacs -sd`.dmp ;
</programlisting>

    <para>which will append something like
    <filename>bin/xemacs-21.4.23-54e8ea71.dmp</filename> to the
    <filename>PLIST</filename>.
    </para>
  </sect1>

  <sect1 id="faq.common-dirs">
    <title>Sharing directories between packages</title>

    <para>A <quote>shared directory</quote> is a directory where
    multiple (and unrelated) packages install files.  These
    directories were problematic because you had to add special
    tricks in the PLIST to conditionally remove them, or have some
    centralized package handle them.</para>

    <para>In pkgsrc, it is now easy: Each package should create
    directories and install files as needed; <command>pkg_delete</command>
    will remove any directories left empty after uninstalling a
    package.</para>

    <para>If a package needs an empty directory to work, create
    the directory during installation as usual, and also add an
    entry to the PLIST:

<programlisting>
@pkgdir path/to/empty/directory
</programlisting>

    or take a look at <varname>MAKE_DIRS</varname> and
    <varname>OWN_DIRS</varname>.
    </para>
  </sect1>

</chapter>
