diff --git a/en_US.ISO8859-1/books/porters-handbook/plist/chapter.xml b/en_US.ISO8859-1/books/porters-handbook/plist/chapter.xml index 1ac0b0b6eb..183d67a813 100644 --- a/en_US.ISO8859-1/books/porters-handbook/plist/chapter.xml +++ b/en_US.ISO8859-1/books/porters-handbook/plist/chapter.xml @@ -1,727 +1,727 @@ Advanced <filename>pkg-plist</filename> Practices Changing <filename>pkg-plist</filename> Based on Make Variables Some ports, particularly the p5- ports, need to change their pkg-plist depending on what options they are configured with (or version of perl, in the case of p5- ports). To make this easy, any instances in the pkg-plist of %%OSREL%%, %%PERL_VER%%, and %%PERL_VERSION%% will be substituted for appropriately. The value of %%OSREL%% is the numeric revision of the operating system (e.g., 4.9). %%PERL_VERSION%% and %%PERL_VER%% is the full version number of perl (e.g., 5.8.9). Several other %%VARS%% related to port's documentation files are described in the relevant section. If you need to make other substitutions, you can set the PLIST_SUB variable with a list of VAR=VALUE pairs and instances of %%VAR%% will be substituted with VALUE in the pkg-plist. For instance, if you have a port that installs many files in a version-specific subdirectory, you can put something like OCTAVE_VERSION= 2.0.13 PLIST_SUB= OCTAVE_VERSION=${OCTAVE_VERSION} in the Makefile and use %%OCTAVE_VERSION%% wherever the version shows up in pkg-plist. That way, when you upgrade the port, you will not have to change dozens (or in some cases, hundreds) of lines in the pkg-plist. If your port installs files conditionally on the options set in the port, the usual way of handling it is prefixing the pkg-plist lines with a %%OPT%% for lines needed when the option is enabled, or %%NO_OPT%% when the option is disabled, and adding OPTIONS_SUB=yes to the Makefile. See for more information. For instance, if there are files that are only installed when the X11 option is enabled, and the Makefile has: OPTIONS_DEFINE= X11 OPTIONS_SUB= yes In the pkg-plist file, put %%X11%% in front of the lines only being installed when the option is enabled, like this : %%X11%%bin/foo-gui This substitution will be done between the pre-install and do-install targets, by reading from PLIST and writing to TMPPLIST (default: WRKDIR/.PLIST.mktmp). So if your port builds PLIST on the fly, do so in or before pre-install. Also, if your port needs to edit the resulting file, do so in post-install to a file named TMPPLIST. Another way of modifying a port's packing list is based on setting the variables PLIST_FILES, PLIST_DIRS, and PLIST_DIRSTRY. The value of each variable is regarded as a list of pathnames to write to TMPPLIST along with PLIST contents. Names listed in PLIST_FILES, PLIST_DIRS, and PLIST_DIRSTRY are subject to %%VAR%% substitution as described above. Except for that, names from PLIST_FILES will appear in the final packing list unchanged, while @dirrm and @dirrmtry will be prepended to names from PLIST_DIRS and PLIST_DIRSTRY, respectively. To take effect, PLIST_FILES, PLIST_DIRS, and PLIST_DIRSTRY must be set before TMPPLIST is written, i.e., in pre-install or earlier. From time to time, the OPTIONS_SUB construct is not enough, in those cases, adding a specific TAG to the PLIST_SUB variable inside the Makefile with a special value of @comment, makes package tools to ignore the line. For instance, if some files are only installed when the X11 option is on and the architecture is i386: .include <bsd.port.pre.mk> .if ${PORT_OPTIONS:MX11} && ${ARCH} == "i386" PLIST_SUB+= X11I386="" .else PLIST_SUB+= X11I386="@comment " .endif Empty Directories Cleaning Up Empty Directories When being de-installed, A port has to remove empty directories it created. This is usually accomplished by adding @dirrm lines for all directories that are specifically created by the port. You need to delete subdirectories before you can delete parent directories. : lib/X11/oneko/pixmaps/cat.xpm lib/X11/oneko/sounds/cat.au : @dirrm lib/X11/oneko/pixmaps @dirrm lib/X11/oneko/sounds @dirrm lib/X11/oneko However, sometimes @dirrm will give you errors because other ports share the same directory. You can use @dirrmtry to remove only empty directories without warning. @dirrmtry share/doc/gimp This will neither print any error messages nor cause pkg delete (see &man.pkg-delete.8;) to exit abnormally even if ${PREFIX}/share/doc/gimp is not empty due to other ports installing some files in there. Creating Empty Directories Empty directories created during port installation need special attention. They will not get created when installing the package, because packages only store the files, and both pkg add and pkg install creates directories for them as needed. To make sure the empty directory is created when installing the package, add this line to pkg-plist above the corresponding @dirrm line: @exec mkdir -p %D/share/foo/templates Configuration Files If your port installs configuration files to PREFIX/etc (or elsewhere) do not simply list them in the pkg-plist. That will cause pkg delete to remove the files carefully edited by the user, and a re-installation will wipe them out. Instead, install sample file(s) as filename.sample, and for each sample file, add this line to your pkg-plist. @sample etc/orbit.conf.sample If there is a very good reason not to install a working configuration file by default, only list the sample filename in pkg-plist, without the @sample part, and add a message pointing out that the user must copy and edit the file before the software will work. When a port installs its configuration in a subdirectory of ${PREFIX}/etc, it should be in ETCDIR, which defaults to ${PREFIX}/etc/${PORTNAME}, it can be overrided in the ports Makefile if there is a convention for the port to use some other directory. The %%ETCDIR%% macro should be used in its stead in the pkg-plist file. The sample configuration files should always have the .sample suffix. If for some historical reason you cannot use the standard suffix, you can still use this construct: @unexec if cmp -s %D/etc/orbit.conf-dist %D/etc/orbit.conf; then rm -f %D/etc/orbit.conf; fi etc/orbit.conf-dist @exec if [ ! -f %D/etc/orbit.conf ] ; then cp -p %D/%F %B/orbit.conf; fi The order of these lines is important. On deinstallation, the sample file is compared to the actual configuration file. If these files are identical, no changes have been made by the user and the actual file can be safely deleted. Because the sample file must still exist for the comparison, the @unexec line comes before the sample configuration file name. On installation, if an actual configuration file is not already present, the sample file is copied to the actual file. The sample file must be present before it can be copied, so the @exec line comes after the sample configuration file name. To debug any issues, temporarily remove the -s flag to &man.cmp.1; for more output. See &man.pkg-create.8; for more information on %D and related substitution markers. Dynamic Versus Static Package List A static package list is a package list which is available in the Ports Collection either as a pkg-plist file (with or without variable substitution), or embedded into the Makefile via PLIST_FILES, PLIST_DIRS, and PLIST_DIRSTRY. Even if the contents are auto-generated by a tool or a target in the Makefile before the inclusion into the Ports Collection by a committer (e.g., using make makeplist>), this is still considered a static list, since it is possible to examine it without having to download or compile the distfile. A dynamic package list is a package list which is generated at the time the port is compiled based upon the files and directories which are installed. It is not possible to examine it before the source code of the ported application is downloaded and compiled, or after running a make clean. While the use of dynamic package lists is not forbidden, maintainers should use static package lists wherever possible, as it enables users to &man.grep.1; through available ports to discover, for example, which port installs a certain file. Dynamic lists should be primarily used for complex ports where the package list changes drastically based upon optional features of the port (and thus maintaining a static package list is infeasible), or ports which change the package list based upon the version of dependent software used (e.g., ports which generate docs with Javadoc). Automated Package List Creation First, make sure the port is almost complete, with only pkg-plist missing. Running make makeplist will show what should be put in pkg-plist. The output of makeplist must be double checked for correctness as it tries to automatically guess a few things, and can get it wrong. User configuration files should be installed as filename.sample, as it is described in . The info/dir file should not be listed and appropriate install-info lines should be added as noted in the info files section. Any libraries installed by the port should be listed as specified in the shared libraries section. Expanding Package List with Keywords <literal>@fc</literal> <replaceable>directory</replaceable> Add a @dirrmtry entry for the directory passed as an argument, and run fc-cache -s on that directory after installation and deinstallation. <literal>@fcfontsdir</literal> <replaceable>directory</replaceable> Add a @dirrmtry entry for the directory passed as an argument, and run fc-cache -s, mkfontscale and mkfontdir on that directory after installation and deinstallation. Additionally, on deinstallation, it removes the fonts.scale and fonts.dir cache files if they are empty. <literal>@fontsdir</literal> <replaceable>directory</replaceable> Add a @dirrmtry entry for the directory passed as an argument, and run mkfontscale and mkfontdir on that directory after installation and deinstallation. Additionally, on deinstallation, it removes the fonts.scale and fonts.dir cache files if they are empty. <literal>@info</literal> <replaceable>file</replaceable> Add the file passed as argument to the plist, and updates the info document index on installation and deinstallation. Additionally, it removes the index if empty on deinstallation. <literal>@sample</literal> <replaceable>file</replaceable> Add the file passed as argument to the plist. On installation, check for a real file with just the base name (the name without the .sample extension). If the real file is not found, copy the sample file to the base file name. On deinstallation, remove the configuration file if it has not been modified. See for more information. <literal>@shell</literal> <replaceable>file</replaceable> Add the file passed as argument to the plist. On installation, add the full path to file to - /etc/shells, while making sure it's not + /etc/shells, while making sure it is not added twice. On deinstallation, remove it from /etc/shells. Base Keywords There are a few historic keywords that are hardcoded, and documented in &man.pkg-create.8;. For the sake of completeness, they are also documented here. <literal>@cwd</literal> [<replaceable>directory</replaceable>] Set the internal directory pointer to point to directory. All subsequent filenames are assumed relative to this directory. <literal>@exec</literal> <replaceable>command</replaceable> (deprecated) Execute command as part of the unpacking process. If command contains any of the following sequences somewhere in it, they are expanded inline. For the following examples, assume that @cwd is set to /usr/local and the last extracted file was bin/emacs. %F Expand to the last filename extracted (as specified). In the example case bin/emacs. %D Expand to the current directory prefix, as set with @cwd. In the example case /usr/local. %B Expand to the basename of the fully qualified filename, that is, the current directory prefix plus the last filespec, minus the trailing filename. In the example case, that would be /usr/local/bin. %f Expand to the filename part of the fully qualified name, or the converse of %B. In the example case, emacs. <literal>@unexec</literal> <replaceable>command</replaceable> (deprecated) Execute command as part of the deinstallation process. Expansion of special % sequences is the same as for @exec. This command is not executed during the package add, as @exec is, but rather when the package is deleted. This is useful for deleting links and other ancillary files that were created as a result of adding the package, but not directly known to the package's table of contents (and hence not automatically removable). <literal>@mode</literal> <replaceable>mode</replaceable> Set default permission for all subsequently extracted files to mode. Format is the same as that used by &man.chmod.1;. Use without an arg to set back to default permissions (mode of the file while being packed). <literal>@owner</literal> <replaceable>user</replaceable> Set default ownership for all subsequent files to user. Use without an argument to set back to default ownership (root). <literal>@group</literal> <replaceable>group</replaceable> Set default group ownership for all subsequent files to group. Use without an arg to set back to default group ownership (wheel). <literal>@comment</literal> <replaceable>string</replaceable> This line is ignored when packing. <literal>@dirrm</literal> <replaceable>directory</replaceable> Declare directory name to be deleted at deinstall time. By default, directories created by a package installation are not deleted when the package is deinstalled. This provides an explicit directory cleanup method. These directives should appear at the end of the package list. If the directory is not empty a warning is printed, and the directory is not removed. <literal>@dirrmtry</literal> <replaceable>directory</replaceable> Declare directory name to be removed, as for @dirrm, but does not issue a warning if the directory cannot be removed. Creating Your Own Keyword Package list files can be extended by keywords that are defined in the ${PORTSDIR}/Keywords directory. The settings for each keyword lives in a YAML file named keyword.yaml. The file must contain at least one of the following sections: attributes Changes the owner, group, or mode used by the keyword. Contains an associative array where the possible keys are owner, group, and mode. The values are, respectively, a user name, a group name, and a file mode. For example: attributes: { owner: "games", group: "games", mode: 0555 } action Defines what happens to the keyword's parameter. Contains an array where the possible values are: setprefix Set the prefix for the next plist entries. dirrm Register a directory to be deleted on deinstall. dirrmtry Register a directory to try and deleted on deinstall. file Register a file. setmode Set the mode for the next plist entries. setowner Set the owner for the next plist entries. setgroup Set the group for the next plist entries. comment Does not do anything, equivalent to not entering an action section. ignore_next Ignore the next entry in the plist. pre-install post-install pre-deinstall post-deinstall pre-upgrade post-upgrade These keywords contains a &man.sh.1; script to be executed before or after installation, deinstallation, or upgrade of the package. In addition to the usual @exec %foo placeholders described in , there is a new one, %@, which represents the argument of the keyword. Example of a <literal>@dirrmtryecho</literal> Keyword This keyword does two things, it adds a @dirrmtry directory line to the packing list, and echoes the fact that the directory is removed when deinstalling the package. actions: [dirrmtry] post-deinstall: | echo "Directory %D/%@ removed." Real Life Example, How the <literal>@sample</literal> Could be Implemented This keyword does three things, it adds the filename passed as an argument to @sample to the packing list, it adds to the post-install script instructions to copy the sample to the actual configuration file if it does not already exist, and it adds to the post-deinstall instructions to remove the configuration file if it has not been modified. actions: [file] post-install: | sample_file="%D/%@" target_file="${sample_file%.sample}" if ! [ -f "${target_file}" ]; then /bin/cp -p "${sample_file}" "${target_file}" fi pre-deinstall: | sample_file="%D/%@" target_file="${sample_file%.sample}" if cmp -s "${target_file}" "${sample_file}"; then rm -f "${target_file}" fi