Making your package work General operation Portability of packages One appealing feature of pkgsrc is that it runs on many different platforms. As a result, it is important to ensure, where possible, that packages in pkgsrc are portable. This chapter mentions some particular details you should pay attention to while working on pkgsrc. How to pull in user-settable variables from &mk.conf; The pkgsrc user can configure pkgsrc by overriding several variables in the file pointed to by MAKECONF, which is &mk.conf; by default. When you want to use those variables in the preprocessor directives of &man.make.1; (for example .if or .for), you need to include the file ../../mk/bsd.prefs.mk before, which in turn loads the user preferences. But note that some variables may not be completely defined after ../../mk/bsd.prefs.mk has been included, as they may contain references to variables that are not yet defined. In shell commands this is no problem, since variables are actually macros, which are only expanded when they are used. But in the preprocessor directives mentioned above and in dependency lines (of the form target: dependencies) the variables are expanded at load time. Currently there is no exhaustive list of all variables that tells you whether they can be used at load time or only at run time, but it is in preparation. User interaction Occasionally, packages require interaction from the user, and this can be in a number of ways: When fetching the distfiles, some packages require user interaction such as entering username/password or accepting a license on a web page. When extracting the distfiles, some packages may ask for passwords. help to configure the package before it is built help during the build process help during the installation of a package The INTERACTIVE_STAGE definition is provided to notify the pkgsrc mechanism of an interactive stage which will be needed, and this should be set in the package's Makefile, e.g.: INTERACTIVE_STAGE= build Multiple interactive stages can be specified: INTERACTIVE_STAGE= configure install The user can then decide to skip this package by setting the BATCH variable. Handling licenses Authors of software can choose the licence under which software can be copied. This is due to copyright law, and reasons for license choices are outside the scope of pkgsrc. The pkgsrc system recognizes that there are a number of licenses which some users may find objectionable or difficult or impossible to comply with. The Free Software Foundation has declared some licenses "Free", and the Open Source Initiative has a definition of "Open Source". The pkgsrc system, as a policy choice, does not label packages which have licenses that are Free or Open Source. However, packages without a license meeting either of those tests are labeled with a license tag denoting the license. Note that a package with no license to copy trivially does not meet either the Free or Open Source test. For packages which are not Free or Open Source, pkgsrc will not build the package unless the user has indicated to pkgsrc that packages with that particular license may be built. Note that this documentation avoids the term "accepted the license". The pkgsrc system is merely providing a mechanism to avoid accidentally building a package with a non-free license; judgement and responsibility remain with the user. (Installation of binary packages are not currently subject to this mechanism; this is a bug.) One might want to only install packages with a BSD license, or the GPL, and not the other. The free licenses are added to the default ACCEPTABLE_LICENSES variable. The user can override the default by setting the ACCEPTABLE_LICENSES variable with "=" instead of "+=". The licenses accepted by default are: apache-1.1 apache-2.0 arphic-public artistic artistic-2.0 boost-license cc-by-sa-v3.0 cc0-1.0-universal cddl-1.0 cpl-1.0 epl-v1.0 gnu-fdl-v1.1 gnu-fdl-v1.2 gnu-fdl-v1.3 gnu-gpl-v1 gnu-gpl-v2 gnu-lgpl-v2 gnu-lgpl-v2.1 gnu-gpl-v3 gnu-lgpl-v3 ibm-public-license-1.0 ipafont isc lppl-1.3c lucent miros mit mpl-1.0 mpl-1.1 mpl-2.0 mplusfont ofl-v1.0 ofl-v1.1 original-bsd modified-bsd 2-clause-bsd php png-license postgresql-license public-domain python-software-foundation qpl-v1.0 sgi-free-software-b-v2.0 sleepycat-public unlicense x11 zlib zpl The license tag mechanism is intended to address copyright-related issues surrounding building, installing and using a package, and not to address redistribution issues (see RESTRICTED and NO_SRC_ON_FTP, etc.). Packages with redistribution restrictions should set these tags. Denoting that a package may be copied according to a particular license is done by placing the license in pkgsrc/licenses and setting the LICENSE variable to a string identifying the license, e.g. in graphics/xv: LICENSE= xv-license When trying to build, the user will get a notice that the package is covered by a license which has not been placed in the ACCEPTABLE_LICENSES variable: &cprompt; make ===> xv-3.10anb9 has an unacceptable license: xv-license. ===> To view the license, enter "/usr/bin/make show-license". ===> To indicate acceptance, add this line to your /etc/mk.conf: ===> ACCEPTABLE_LICENSES+=xv-license *** Error code 1 The license can be viewed with make show-license, and if the user so chooses, the line printed above can be added to &mk.conf; to convey to pkgsrc that it should not in the future fail because of that license: ACCEPTABLE_LICENSES+=xv-license When adding a package with a new license, the following steps are required: Check if the file can avoid the -license filename tag as described above by referencing Various Licenses and Comments about Them and Licenses by Name | Open Source Initiative. If this is the case, additionally add the license filename to: DEFAULT_ACCEPTABLE_LICENSES in pkgsrc/mk/license.mk default_acceptable_licenses in pkgsrc/pkgtools/pkg_install/files/lib/license.c the ACCEPTABLE_LICENSES list in pkgsrc/doc/guide/files/fixes.xml with the proper syntax as demonstrated in those files, respectively. The license text should be added to pkgsrc/licenses for displaying. A list of known licenses can be seen in this directory. When the license changes (in a way other than formatting), please make sure that the new license has a different name (e.g., append the version number if it exists, or the date). Just because a user told pkgsrc to build programs under a previous version of a license does not mean that pkgsrc should build programs under the new licenses. The higher-level point is that pkgsrc does not evaluate licenses for reasonableness; the only test is a mechanistic test of whether a particular text has been approved by either of two bodies. The use of LICENSE=shareware, LICENSE=no-commercial-use, and similar language is deprecated because it does not crisply refer to a particular license text. Another problem with such usage is that it does not enable a user to tell pkgsrc to proceed for a single package without also telling pkgsrc to proceed for all packages with that tag. Restricted packages Some licenses restrict how software may be re-distributed. Because a license tag is required unless the package is Free or Open Source, all packages with restrictions should have license tags. By declaring the restrictions, package tools can automatically refrain from e.g. placing binary packages on FTP sites. There are four restrictions that may be encoded, which are the cross product of sources (distfiles) and binaries not being placed on FTP sites and CD-ROMs. Because this is rarely the exact language in any license, and because non-Free licenses tend to be different from each other, pkgsrc adopts a definition of FTP and CD-ROM. Pkgsrc uses "FTP" to mean that the source or binary file should not be made available over the Internet at no charge. Pkgsrc uses "CD-ROM" to mean that the source or binary may not be made available on some kind of media, together with other source and binary packages, and which is sold for a distribution charge. In order to encode these restrictions, the package system defines five make variables that can be set to note these restrictions: RESTRICTED This variable should be set whenever a restriction exists (regardless of its kind). Set this variable to a string containing the reason for the restriction. It should be understood that those wanting to understand the restriction will have to read the license, and perhaps seek advice of counsel. NO_BIN_ON_CDROM Binaries may not be placed on CD-ROM containing other binary packages, for which a distribution charge may be made. In this case, set this variable to ${RESTRICTED}. NO_BIN_ON_FTP Binaries may not made available on the Internet without charge. In this case, set this variable to ${RESTRICTED}. If this variable is set, binary packages will not be included on ftp.NetBSD.org. NO_SRC_ON_CDROM Distfiles may not be placed on CD-ROM, together with other distfiles, for which a fee may be charged. In this case, set this variable to ${RESTRICTED}. NO_SRC_ON_FTP Distfiles may not made available via FTP at no charge. In this case, set this variable to ${RESTRICTED}. If this variable is set, the distfile(s) will not be mirrored on ftp.NetBSD.org. Please note that packages will to be removed from pkgsrc when the distfiles are not distributable and cannot be obtained for a period of one full quarter branch. Packages with manual / interactive fetch must have a maintainer and it is his/her responsibility to ensure this. Handling dependencies Your package may depend on some other package being present - and there are various ways of expressing this dependency. pkgsrc supports the BUILD_DEPENDS and DEPENDS definitions, the USE_TOOLS definition, as well as dependencies via buildlink3.mk, which is the preferred way to handle dependencies, and which uses the variables named above. See for more information. The basic difference between the two variables is as follows: The DEPENDS definition registers that pre-requisite in the binary package so it will be pulled in when the binary package is later installed, whilst the BUILD_DEPENDS definition does not, marking a dependency that is only needed for building the package. This means that if you only need a package present whilst you are building, it should be noted as a BUILD_DEPENDS. The format for a BUILD_DEPENDS and a DEPENDS definition is: <pre-req-package-name>:../../<category>/<pre-req-package> Please note that the pre-req-package-name may include any of the wildcard version numbers recognized by &man.pkg.info.1;. If your package needs another package's binaries or libraries to build and run, and if that package has a buildlink3.mk file available, use it: .include "../../graphics/jpeg/buildlink3.mk" If your package needs another package's binaries or libraries only for building, and if that package has a buildlink3.mk file available, use it: .include "../../graphics/jpeg/buildlink3.mk" but set BUILDLINK_DEPMETHOD.jpeg?=build to make it a build dependency only. This case is rather rare. If your package needs binaries from another package to build, use the BUILD_DEPENDS definition: BUILD_DEPENDS+= scons-[0-9]*:../../devel/scons If your package needs a library with which to link and there is no buildlink3.mk file available, create one. Using DEPENDS won't be sufficient because the include files and libraries will be hidden from the compiler. If your package needs some executable to be able to run correctly and if there's no buildlink3.mk file, this is specified using the DEPENDS variable. The print/lyx package needs to be able to execute the latex binary from the teTeX package when it runs, and that is specified: DEPENDS+= teTeX-[0-9]*:../../print/teTeX You can use wildcards in package dependencies. Note that such wildcard dependencies are retained when creating binary packages. The dependency is checked when installing the binary package and any package which matches the pattern will be used. Wildcard dependencies should be used with care. The -[0-9]* should be used instead of -* to avoid potentially ambiguous matches such as tk-postgresql matching a tk-* DEPENDS. Wildcards can also be used to specify that a package will only build against a certain minimum version of a pre-requisite: DEPENDS+= ImageMagick>=6.0:../../graphics/ImageMagick This means that the package will build using version 6.0 of ImageMagick or newer. Such a dependency may be warranted if, for example, the command line options of an executable have changed. If you need to depend on minimum versions of libraries, see the buildlink section of the pkgsrc guide. For security fixes, please update the package vulnerabilities file. See for more information. If your package needs files from another package to build, add the relevant distribution files to DISTFILES, so they will be extracted automatically. See the print/ghostscript package for an example. (It relies on the jpeg sources being present in source form during the build.) Handling conflicts with other packages Your package may conflict with other packages a user might already have installed on his system, e.g. if your package installs the same set of files as another package in the pkgsrc tree or has the same PKGNAME. These cases are handled automatically by the packaging tools at package installation time and do not need to be handled manually. In case the conflicts can not be recognized automatically (e.g., packages using the same config file location but no other shared files), you can set CONFLICTS to a space-separated list of packages (including version string) your package conflicts with. For example, if both foo/bar and foo/baz use the same config file, you would set in foo/bar/Makefile: CONFLICTS= baz-[0-9]* and in pkgsrc/foo/baz/Makefile: CONFLICTS= bar-[0-9]* Packages that cannot or should not be built There are several reasons why a package might be instructed to not build under certain circumstances. If the package builds and runs on most platforms, the exceptions should be noted with BROKEN_ON_PLATFORM. If the package builds and runs on a small handful of platforms, set BROKEN_EXCEPT_ON_PLATFORM instead. Both BROKEN_ON_PLATFORM and BROKEN_EXCEPT_ON_PLATFORM are OS triples (OS-version-platform) that can use glob-style wildcards. If a package is not appropriate for some platforms (as oopposed to merely broken), a different set of variables should be used as this affects failure reporting and statistics. If the package is appropriate for most platforms, the exceptions should be noted with NOT_FOR_PLATFORM. If the package is appropriate for only a small handful of platforms (often exactly one), set ONLY_FOR_PLATFORM instead. Both ONLY_FOR_PLATFORM and NOT_FOR_PLATFORM are OS triples (OS-version-platform) that can use glob-style wildcards. Some packages are tightly bound to a specific version of an operating system, e.g. LKMs or sysutils/lsof. Such binary packages are not backwards compatible with other versions of the OS, and should be uploaded to a version specific directory on the FTP server. Mark these packages by setting OSVERSION_SPECIFIC to yes. This variable is not currently used by any of the package system internals, but may be used in the future. If the package should be skipped (for example, because it provides functionality already provided by the system), set PKG_SKIP_REASON to a descriptive message. If the package should fail because some preconditions are not met, set PKG_FAIL_REASON to a descriptive message. Packages which should not be deleted, once installed To ensure that a package may not be deleted, once it has been installed, the PKG_PRESERVE definition should be set in the package Makefile. This will be carried into any binary package that is made from this pkgsrc entry. A preserved package will not be deleted using &man.pkg.delete.1; unless the -f option is used. Handling packages with security problems When a vulnerability is found, this should be noted in localsrc/security/advisories/pkg-vulnerabilities, and after committing that file, ask pkgsrc-security@NetBSD.org to update the file on ftp.NetBSD.org. After fixing the vulnerability by a patch, its PKGREVISION should be increased (this is of course not necessary if the problem is fixed by using a newer release of the software), and the pattern in the pkg-vulnerabilities file must be updated. Also, if the fix should be applied to the stable pkgsrc branch, be sure to submit a pullup request! Binary packages already on ftp.NetBSD.org will be handled semi-automatically by a weekly cron job. How to handle incrementing versions when fixing an existing package When making fixes to an existing package it can be useful to change the version number in PKGNAME. To avoid conflicting with future versions by the original author, a nb1, nb2, ... suffix can be used on package versions by setting PKGREVISION=1 (2, ...). The nb is treated like a . by the package tools. e.g. DISTNAME= foo-17.42 PKGREVISION= 9 will result in a PKGNAME of foo-17.42nb9. If you want to use the original value of PKGNAME without the nbX suffix, e.g. for setting DIST_SUBDIR, use PKGNAME_NOREV. When a new release of the package is released, the PKGREVISION should be removed, e.g. on a new minor release of the above package, things should be like: DISTNAME= foo-17.43 PKGREVISION should be incremented for any non-trivial change in the resulting binary package. Without a PKGREVISION bump, someone with the previous version installed has no way of knowing that their package is out of date. Thus, changes without increasing PKGREVISION are essentially labeled "this is so trivial that no reasonable person would want to upgrade", and this is the rough test for when increasing PKGREVISION is appropriate. Examples of changes that do not merit increasing PKGREVISION are: Changing HOMEPAGE, MAINTAINER, OWNER, or comments in Makefile. Changing build variables if the resulting binary package is the same. Changing DESCR. Adding PKG_OPTIONS if the default options don't change. Examples of changes that do merit an increase to PKGREVISION include: Security fixes Changes or additions to a patch file Changes to the PLIST A dependency is changed or renamed. PKGREVISION must also be incremented when dependencies have ABI changes. Substituting variable text in the package files (the SUBST framework) When you want to replace the same text in multiple files or when the replacement text varies, patches alone cannot help. This is where the SUBST framework comes in. It provides an easy-to-use interface for replacing text in files. Example: SUBST_CLASSES+= fix-paths SUBST_STAGE.fix-paths= pre-configure SUBST_MESSAGE.fix-paths= Fixing absolute paths. SUBST_FILES.fix-paths= src/*.c SUBST_FILES.fix-paths+= scripts/*.sh SUBST_SED.fix-paths= -e 's,"/usr/local,"${PREFIX},g' SUBST_SED.fix-paths+= -e 's,"/var/log,"${VARBASE}/log,g' SUBST_CLASSES is a list of identifiers that are used to identify the different SUBST blocks that are defined. The SUBST framework is heavily used by pkgsrc, so it is important to always use the += operator with this variable. Otherwise some substitutions may be skipped. The remaining variables of each SUBST block are parameterized with the identifier from the first line (fix-paths in this case.) They can be seen as parameters to a function call. SUBST_STAGE.* specifies the stage at which the replacement will take place. All combinations of pre-, do- and post- together with a phase name are possible, though only few are actually used. Most commonly used are post-patch and pre-configure. Of these two, pre-configure should be preferred because then it is possible to run bmake patch and have the state after applying the patches but before making any other changes. This is especially useful when you are debugging a package in order to create new patches for it. Similarly, post-build is preferred over pre-install, because the install phase should generally be kept as simple as possible. When you use post-build, you have the same files in the working directory that will be installed later, so you can check if the substitution has succeeded. SUBST_MESSAGE.* is an optional text that is printed just before the substitution is done. SUBST_FILES.* is the list of shell globbing patterns that specifies the files in which the substitution will take place. The patterns are interpreted relatively to the WRKSRC directory. SUBST_SED.* is a list of arguments to &man.sed.1; that specify the actual substitution. Every sed command should be prefixed with -e, so that all SUBST blocks look uniform. There are some more variables, but they are so seldomly used that they are only documented in the mk/subst.mk file. Fixing problems in the <emphasis>fetch</emphasis> phase Packages whose distfiles aren't available for plain downloading If you need to download from a dynamic URL you can set DYNAMIC_MASTER_SITES and a make fetch will call files/getsite.sh with the name of each file to download as an argument, expecting it to output the URL of the directory from which to download it. graphics/ns-cult3d is an example of this usage. If the download can't be automated, because the user must submit personal information to apply for a password, or must pay for the source, or whatever, you can set FETCH_MESSAGE to a list of lines that are displayed to the user before aborting the build. Example: FETCH_MESSAGE= "Please download the files" FETCH_MESSAGE+= " "${DISTFILES:Q} FETCH_MESSAGE+= "manually from "${MASTER_SITES:Q}"." How to handle modified distfiles with the 'old' name Sometimes authors of a software package make some modifications after the software was released, and they put up a new distfile without changing the package's version number. If a package is already in pkgsrc at that time, the checksum will no longer match. The contents of the new distfile should be compared against the old one before changing anything, to make sure the distfile was really updated on purpose, and that no trojan horse or so crept in. Please mention that the distfiles were compared and what was found in your commit message. Then, the correct way to work around this is to set DIST_SUBDIR to a unique directory name, usually based on PKGNAME_NOREV. All DISTFILES and PATCHFILES for this package will be put in that subdirectory of the local distfiles directory. (See for more details.) In case this happens more often, PKGNAME can be used (thus including the nbX suffix) or a date stamp can be appended, like ${PKGNAME_NOREV}-YYYYMMDD. DIST_SUBDIR is also used when a distfile's name does not contain a version and the distfile is apt to change. In cases where the likelihood of this is very small, DIST_SUBDIR might not be required. Additionally, DIST_SUBDIR must not be removed unless the distfile name changes, even if a package is being moved or renamed. Do not forget regenerating the distinfo file after that, since it contains the DIST_SUBDIR path in the filenames. Also, increase the PKGREVISION if the installed package is different. Furthermore, a mail to the package's authors seems appropriate telling them that changing distfiles after releases without changing the file names is not good practice. Packages hosted on github.com Helper methods exist for packages hosted on github.com which will often have distfile names that clash with other packages, for example 1.0.tar.gz. Use one of the three recipes from below: Fetch based on a tagged release If your distfile URL looks similar to http://github.com/username/exampleproject/archive/v1.0.zip, then you are packaging a tagged release. DISTNAME= exampleproject-1.0 MASTER_SITES= ${MASTER_SITE_GITHUB:=username/} #GITHUB_PROJECT= # can be omitted if same as DISTNAME GITHUB_TAG= v${PKGVERSION_NOREV} EXTRACT_SUFX= .zip Fetch based on a specific commit If your distfile URL looks similar to http://github.com/example/example/archive/988881adc9fc3655077dc2d4d757d480b5ea0e11.tar.gz, then you are packaging a specific commit not tied to a release. DISTNAME= example-1.0 MASTER_SITES= ${MASTER_SITE_GITHUB:example/} #GITHUB_PROJECT= # can be omitted if same as DISTNAME GITHUB_TAG= 988881adc9fc3655077dc2d4d757d480b5ea0e11 Fetch based on release If your distfile URL looks similar to http://github.com/username/exampleproject/releases/download/rel-1.6/offensive-1.6.zip, then you are packaging a release. DISTNAME= offensive-1.6 PKGNAME= ${DISTNAME:S/offensive/proper/} MASTER_SITES= ${MASTER_SITE_GITHUB:=username/} GITHUB_PROJECT= exampleproject GITHUB_RELEASE= rel-${PKGVERSION_NOREV} # usually just set this to ${DISTNAME} EXTRACT_SUFX= .zip Fixing problems in the <emphasis>configure</emphasis> phase Shared libraries - libtool pkgsrc supports many different machines, with different object formats like a.out and ELF, and varying abilities to do shared library and dynamic loading at all. To accompany this, varying commands and options have to be passed to the compiler, linker, etc. to get the Right Thing, which can be pretty annoying especially if you don't have all the machines at your hand to test things. The devel/libtool pkg can help here, as it just knows how to build both static and dynamic libraries from a set of source files, thus being platform-independent. Here's how to use libtool in a package in seven simple steps: Add USE_LIBTOOL=yes to the package Makefile. For library objects, use ${LIBTOOL} --mode=compile ${CC} in place of ${CC}. You could even add it to the definition of CC, if only libraries are being built in a given Makefile. This one command will build both PIC and non-PIC library objects, so you need not have separate shared and non-shared library rules. For the linking of the library, remove any ar, ranlib, and ld -Bshareable commands, and instead use: ${LIBTOOL} --mode=link \ ${CC} -o ${.TARGET:.a=.la} \ ${OBJS:.o=.lo} \ -rpath ${PREFIX}/lib \ -version-info major:minor Note that the library is changed to have a .la extension, and the objects are changed to have a .lo extension. Change OBJS as necessary. This automatically creates all of the .a, .so.major.minor, and ELF symlinks (if necessary) in the build directory. Be sure to include -version-info, especially when major and minor are zero, as libtool will otherwise strip off the shared library version. From the libtool manual: So, libtool library versions are described by three integers: CURRENT The most recent interface number that this library implements. REVISION The implementation number of the CURRENT interface. AGE The difference between the newest and oldest interfaces that this library implements. In other words, the library implements all the interface numbers in the range from number `CURRENT - AGE' to `CURRENT'. If two libraries have identical CURRENT and AGE numbers, then the dynamic linker chooses the library with the greater REVISION number. The -release option will produce different results for a.out and ELF (excluding symlinks) in only one case. An ELF library of the form libfoo-release.so.x.y will have a symlink of libfoo.so.x.y on an a.out platform. This is handled automatically. The -rpath argument is the install directory of the library being built. In the PLIST, include only the .la file, the other files will be added automatically. When linking shared object (.so) files, i.e. files that are loaded via &man.dlopen.3;, NOT shared libraries, use -module -avoid-version to prevent them getting version tacked on. The PLIST file gets the foo.so entry. When linking programs that depend on these libraries before they are installed, preface the &man.cc.1; or &man.ld.1; line with ${LIBTOOL} --mode=link, and it will find the correct libraries (static or shared), but please be aware that libtool will not allow you to specify a relative path in -L (such as -L../somelib), because it expects you to change that argument to be the .la file. e.g. ${LIBTOOL} --mode=link ${CC} -o someprog -L../somelib -lsomelib should be changed to: ${LIBTOOL} --mode=link ${CC} -o someprog ../somelib/somelib.la and it will do the right thing with the libraries. When installing libraries, preface the &man.install.1; or &man.cp.1; command with ${LIBTOOL} --mode=install, and change the library name to .la. e.g. ${LIBTOOL} --mode=install ${BSD_INSTALL_LIB} ${SOMELIB:.a=.la} ${PREFIX}/lib This will install the static .a, shared library, any needed symlinks, and run &man.ldconfig.8;. In your PLIST, include only the .la file (this is a change from previous behaviour). Using libtool on GNU packages that already support libtool Add USE_LIBTOOL=yes to the package Makefile. This will override the package's own libtool in most cases. For older libtool using packages, libtool is made by ltconfig script during the do-configure step; you can check the libtool script location by doing make configure; find work*/ -name libtool. LIBTOOL_OVERRIDE specifies which libtool scripts, relative to WRKSRC, to override. By default, it is set to libtool */libtool */*/libtool. If this does not match the location of the package's libtool script(s), set it as appropriate. If you do not need *.a static libraries built and installed, then use SHLIBTOOL_OVERRIDE instead. If your package makes use of the platform-independent library for loading dynamic shared objects, that comes with libtool (libltdl), you should include devel/libltdl/buildlink3.mk. Some packages use libtool incorrectly so that the package may not work or build in some circumstances. Some of the more common errors are: The inclusion of a shared object (-module) as a dependent library in an executable or library. This in itself isn't a problem if one of two things has been done: The shared object is named correctly, i.e. libfoo.la, not foo.la The -dlopen option is used when linking an executable. The use of libltdl without the correct calls to initialisation routines. The function lt_dlinit() should be called and the macro LTDL_SET_PRELOADED_SYMBOLS included in executables. GNU Autoconf/Automake If a package needs GNU autoconf or automake to be executed to regenerate the configure script and Makefile.in makefile templates, then they should be executed in a pre-configure target. For packages that need only autoconf: AUTOCONF_REQD= 2.50 # if default version is not good enough USE_TOOLS+= autoconf # use "autoconf213" for autoconf-2.13 ... pre-configure: cd ${WRKSRC} && autoconf ... and for packages that need automake and autoconf: AUTOMAKE_REQD= 1.7.1 # if default version is not good enough USE_TOOLS+= automake # use "automake14" for automake-1.4 ... pre-configure: set -e; cd ${WRKSRC}; \ aclocal; autoheader; automake -a --foreign -i; autoconf ... Packages which use GNU Automake will almost certainly require GNU Make. There are times when the configure process makes additional changes to the generated files, which then causes the build process to try to re-execute the automake sequence. This is prevented by touching various files in the configure stage. If this causes problems with your package you can set AUTOMAKE_OVERRIDE=NO in the package Makefile. Programming languages C, C++, and Fortran Compilers for the C, C++, and Fortran languages comes with the NetBSD base system. By default, pkgsrc assumes that a package is written in C and will hide all other compilers (via the wrapper framework, see ). To declare which language's compiler a package needs, set the USE_LANGUAGES variable. Allowed values currently are c, c++, and fortran (and any combination). The default is c. Packages using GNU configure scripts, even if written in C++, usually need a C compiler for the configure phase. Java If a program is written in Java, use the Java framework in pkgsrc. The package must include ../../mk/java-vm.mk. This Makefile fragment provides the following variables: USE_JAVA defines if a build dependency on the JDK is added. If USE_JAVA is set to run, then there is only a runtime dependency on the JDK. The default is yes, which also adds a build dependency on the JDK. Set USE_JAVA2 to declare that a package needs a Java2 implementation. The supported values are yes, 1.4, and 1.5. yes accepts any Java2 implementation, 1.4 insists on versions 1.4 or above, and 1.5 only accepts versions 1.5 or above. This variable is not set by default. PKG_JAVA_HOME is automatically set to the runtime location of the used Java implementation dependency. It may be used to set JAVA_HOME to a good value if the program needs this variable to be defined. Packages containing perl scripts If your package contains interpreted perl scripts, add perl to the USE_TOOLS variable and set REPLACE_PERL to ensure that the proper interpreter path is set. REPLACE_PERL should contain a list of scripts, relative to WRKSRC, that you want adjusted. Every occurrence of */bin/perl in a she-bang line will be replaced with the full path to the perl executable. If a particular version of perl is needed, set the PERL5_REQD variable to the version number. The default is 5.0. See for information about handling perl modules. Packages containing shell scripts REPLACE_SH, REPLACE_BASH, REPLACE_CSH, and REPLACE_KSH can be used to replace shell hash bangs in files. Please use the appropriate one, prefering REPLACE_SH in case this shell is sufficient. Each should contain a list of scripts, relative to WRKSRC, that you want adjusted. Every occurrence of the matching shell in a she-bang line will be replaced with the full path to the shell executable. When using REPLACE_BASH, don't forget to add bash to USE_TOOLS. Other programming languages Currently, there is no special handling for other languages in pkgsrc. If a compiler package provides a buildlink3.mk file, include that, otherwise just add a (build) dependency on the appropriate compiler package. Fixing problems in the <emphasis>build</emphasis> phase The most common failures when building a package are that some platforms do not provide certain header files, functions or libraries, or they provide the functions in a library that the original package author didn't know. To work around this, you can rewrite the source code in most cases so that it does not use the missing functions or provides a replacement function. Compiling C and C++ code conditionally If a package already comes with a GNU configure script, the preferred way to fix the build failure is to change the configure script, not the code. In the other cases, you can utilize the C preprocessor, which defines certain macros depending on the operating system and hardware architecture it compiles for. These macros can be queried using for example #if defined(__i386). Almost every operating system, hardware architecture and compiler has its own macro. For example, if the macros __GNUC__, __i386__ and __NetBSD__ are all defined, you know that you are using NetBSD on an i386 compatible CPU, and your compiler is GCC. The list of the following macros for hardware and operating system depends on the compiler that is used. For example, if you want to conditionally compile code on Solaris, don't use __sun__, as the SunPro compiler does not define it. Use __sun instead. C preprocessor macros to identify the operating system To distinguish between 4.4 BSD-derived systems and the rest of the world, you should use the following code. #include <sys/param.h> #if (defined(BSD) && BSD >= 199306) /* BSD-specific code goes here */ #else /* non-BSD-specific code goes here */ #endif If this distinction is not fine enough, you can also test for the following macros. Cygwin __CYGWIN__ DragonFly __DragonFly__ FreeBSD __FreeBSD__ Haiku __HAIKU__ Interix __INTERIX IRIX __sgi (TODO: get a definite source for this) Linux linux, __linux, __linux__ Mac OS X __APPLE__ MirBSD __MirBSD__ (__OpenBSD__ is also defined) Minix3 __minix NetBSD __NetBSD__ OpenBSD __OpenBSD__ Solaris sun, __sun C preprocessor macros to identify the hardware architecture i386 i386, __i386, __i386__ MIPS __mips SPARC sparc, __sparc C preprocessor macros to identify the compiler GCC __GNUC__ (major version), __GNUC_MINOR__ MIPSpro _COMPILER_VERSION (0x741 for MIPSpro 7.41) SunPro __SUNPRO_C (0x570 for Sun C 5.7) SunPro C++ __SUNPRO_CC (0x580 for Sun C++ 5.8) How to handle compiler bugs Some source files trigger bugs in the compiler, based on combinations of compiler version and architecture and almost always relation to optimisation being enabled. Common symptoms are gcc internal errors or never finishing compiling a file. Typically, a workaround involves testing the MACHINE_ARCH and compiler version, disabling optimisation for that combination of file, MACHINE_ARCH and compiler. This used to be a big problem in the past, but is rarely needed now as compiler technology has matured. If you still need to add a compiler specific workaround, please do so in the file hacks.mk and describe the symptom and compiler version as detailed as possible. Undefined reference to <quote>...</quote> This error message often means that a package did not link to a shared library it needs. The following functions are known to cause this error message over and over. FunctionLibraryAffected platforms accept, bind, connect-lsocketSolaris crypt-lcryptDragonFly, NetBSD dlopen, dlsym-ldlLinux gethost*-lnslSolaris inet_aton-lresolvSolaris nanosleep, sem_*, timer_*-lrtSolaris openpty-lutilLinux To fix these linker errors, it is often sufficient to say LIBS.OperatingSystem+= -lfoo to the package Makefile and then say bmake clean; bmake. Special issue: The SunPro compiler When you are using the SunPro compiler, there is another possibility. That compiler cannot handle the following code: extern int extern_func(int); static inline int inline_func(int x) { return extern_func(x); } int main(void) { return 0; } It generates the code for inline_func even if that function is never used. This code then refers to extern_func, which can usually not be resolved. To solve this problem you can try to tell the package to disable inlining of functions. Running out of memory Sometimes packages fail to build because the compiler runs into an operating system specific soft limit. With the UNLIMIT_RESOURCES variable pkgsrc can be told to unlimit the resources. Currently, the allowed values are any combination of cputime, datasize, memorysize, and stacksize. Setting this variable is similar to running the shell builtin ulimit command to raise the maximum data segment size or maximum stack size of a process, respectively, to their hard limits. Fixing problems in the <emphasis>install</emphasis> phase Creating needed directories The BSD-compatible install supplied with some operating systems cannot create more than one directory at a time. As such, you should call ${INSTALL_*_DIR} like this: ${INSTALL_DATA_DIR} ${PREFIX}/dir1 ${INSTALL_DATA_DIR} ${PREFIX}/dir2 You can also just append dir1 dir2 to the INSTALLATION_DIRS variable, which will automatically do the right thing. Where to install documentation In general, documentation should be installed into ${PREFIX}/share/doc/${PKGBASE} or ${PREFIX}/share/doc/${PKGNAME} (the latter includes the version number of the package). Many modern packages using GNU autoconf allow to set the directory where HTML documentation is installed with the --with-html-dir option. Sometimes using this flag is needed because otherwise the documentation ends up in ${PREFIX}/share/doc/html or other places. An exception to the above is that library API documentation generated with the textproc/gtk-doc tools, for use by special browsers (devhelp) should be left at their default location, which is ${PREFIX}/share/gtk-doc. Such documentation can be recognized from files ending in .devhelp or .devhelp2. (It is also acceptable to install such files in ${PREFIX}/share/doc/${PKGBASE} or ${PREFIX}/share/doc/${PKGNAME}; the .devhelp* file must be directly in that directory then, no additional subdirectory level is allowed in this case. This is usually achieved by using --with-html-dir=${PREFIX}/share/doc. ${PREFIX}/share/gtk-doc is preferred though.) Installing highscore files Certain packages, most of them in the games category, install a score file that allows all users on the system to record their highscores. In order for this to work, the binaries need to be installed setgid and the score files owned by the appropriate group and/or owner (traditionally the "games" user/group). Set USE_GAMESGROUP to yes to support this. The following variables, documented in more detail in mk/defaults/mk.conf, control this behaviour: GAMEDATAMODE, GAMEDIRMODE, GAMES_GROUP, GAMEMODE, GAME_USER. Other useful variables are: GAMEDIR_PERMS, GAMEDATA_PERMS and SETGID_GAMES_PERMS. An example that illustrates some of the variables described above is games/moon-buggy. OWN_DIRS_PERMS is used to properly set directory permissions of the directory where the scorefile is saved, REQD_FILES_PERMS is used to create a dummy scorefile (mbscore) with the proper permissions and SPECIAL_PERMS is used to install setgid the game binary: USE_GAMESGROUP= yes BUILD_DEFS+= VARBASE OWN_DIRS_PERMS+= ${VARBASE}/games/moon-buggy ${GAMEDIR_PERMS} REQD_FILES_PERMS+= /dev/null ${VARBASE}/games/moon-buggy/mbscore ${GAMEDATA_PERMS} SPECIAL_PERMS+= ${PREFIX}/bin/moon-buggy ${SETGID_GAMES_PERMS} Various INSTALL_* variables are also available: INSTALL_GAME to install setgid game binaries, INSTALL_GAME_DIR to install game directories that are needed to be accessed by setgid games and INSTALL_GAME_DATA to install scorefiles. A package should therefore never hard code file ownership or access permissions but rely on *_PERMS as described above or alternatively on INSTALL_GAME, INSTALL_GAME_DATA and INSTALL_GAME_DIR to set these correctly. Adding DESTDIR support to packages DESTDIR support means that a package installs into a staging directory, not the final location of the files. Then a binary package is created which can be used for installation as usual. There are two ways: Either the package must install as root (destdir) or the package can install as non-root user (user-destdir). PKG_DESTDIR_SUPPORT has to be set to none, destdir, or user-destdir. By default PKG_DESTDIR_SUPPORT is set to user-destdir to help catching more potential packaging problems. If bsd.prefs.mk is included in the Makefile, PKG_DESTDIR_SUPPORT needs to be set before the inclusion. All installation operations have to be prefixed with ${DESTDIR}. automake gets this DESTDIR mostly right automatically. Many manual rules and pre/post-install often are incorrect; fix them. If files are installed with special owner/group use SPECIAL_PERMS. In general, packages should support UNPRIVILEGED to be able to use DESTDIR. Packages with hardcoded paths to other interpreters Your package may also contain scripts with hardcoded paths to other interpreters besides (or as well as) perl. To correct the full pathname to the script interpreter, you need to set the following definitions in your Makefile (we shall use tclsh in this example): REPLACE_INTERPRETER+= tcl REPLACE.tcl.old= .*/bin/tclsh REPLACE.tcl.new= ${PREFIX}/bin/tclsh REPLACE_FILES.tcl= # list of tcl scripts which need to be fixed, # relative to ${WRKSRC}, just as in REPLACE_PERL Before March 2006, these variables were called _REPLACE.* and _REPLACE_FILES.*. Packages installing perl modules Makefiles of packages providing perl5 modules should include the Makefile fragment ../../lang/perl5/module.mk. It provides a do-configure target for the standard perl configuration for such modules as well as various hooks to tune this configuration. See comments in this file for details. Perl5 modules will install into different places depending on the version of perl used during the build process. To address this, pkgsrc will append lines to the PLIST corresponding to the files listed in the installed .packlist file generated by most perl5 modules. This is invoked by defining PERL5_PACKLIST to a space-separated list of packlist files relative to PERL5_PACKLIST_DIR (PERL5_INSTALLVENDORARCH by default), e.g.: PERL5_PACKLIST= auto/Pg/.packlist The perl5 config variables installarchlib, installscript, installvendorbin, installvendorscript, installvendorarch, installvendorlib, installvendorman1dir, and installvendorman3dir represent those locations in which components of perl5 modules may be installed, provided as variable with uppercase and prefixed with PERL5_, e.g. PERL5_INSTALLARCHLIB and may be used by perl5 packages that don't have a packlist. These variables are also substituted for in the PLIST as uppercase prefixed with PERL5_SUB_. Packages installing info files Some packages install info files or use the makeinfo or install-info commands. INFO_FILES should be defined in the package Makefile so that INSTALL and DEINSTALL scripts will be generated to handle registration of the info files in the Info directory file. The install-info command used for the info files registration is either provided by the system, or by a special purpose package automatically added as dependency if needed. PKGINFODIR is the directory under ${PREFIX} where info files are primarily located. PKGINFODIR defaults to info and can be overridden by the user. The info files for the package should be listed in the package PLIST; however any split info files need not be listed. A package which needs the makeinfo command at build time must add makeinfo to USE_TOOLS in its Makefile. If a minimum version of the makeinfo command is needed it should be noted with the TEXINFO_REQD variable in the package Makefile. By default, a minimum version of 3.12 is required. If the system does not provide a makeinfo command or if it does not match the required minimum, a build dependency on the devel/gtexinfo package will be added automatically. The build and installation process of the software provided by the package should not use the install-info command as the registration of info files is the task of the package INSTALL script, and it must use the appropriate makeinfo command. To achieve this goal, the pkgsrc infrastructure creates overriding scripts for the install-info and makeinfo commands in a directory listed early in PATH. The script overriding install-info has no effect except the logging of a message. The script overriding makeinfo logs a message and according to the value of TEXINFO_REQD either runs the appropriate makeinfo command or exit on error. Packages installing man pages All packages that install manual pages should install them into the same directory, so that there is one common place to look for them. In pkgsrc, this place is ${PREFIX}/${PKGMANDIR}, and this expression should be used in packages. The default for PKGMANDIR is man. Another often-used value is share/man. The support for a custom PKGMANDIR is far from complete. The PLIST files can just use man/ as the top level directory for the man page file entries, and the pkgsrc framework will convert as needed. In all other places, the correct PKGMANDIR must be used. Packages that are configured with GNU_CONFIGURE set as yes, by default will use the ./configure --mandir switch to set where the man pages should be installed. The path is GNU_CONFIGURE_MANDIR which defaults to ${PREFIX}/${PKGMANDIR}. Packages that use GNU_CONFIGURE but do not use --mandir, can set CONFIGURE_HAS_MANDIR to no. Or if the ./configure script uses a non-standard use of --mandir, you can set GNU_CONFIGURE_MANDIR as needed. See for information on installation of compressed manual pages. Packages installing GConf data files If a package installs .schemas or .entries files, used by GConf, you need to take some extra steps to make sure they get registered in the database: Include ../../devel/GConf/schemas.mk instead of its buildlink3.mk file. This takes care of rebuilding the GConf database at installation and deinstallation time, and tells the package where to install GConf data files using some standard configure arguments. It also disallows any access to the database directly from the package. Ensure that the package installs its .schemas files under ${PREFIX}/share/gconf/schemas. If they get installed under ${PREFIX}/etc, you will need to manually patch the package. Check the PLIST and remove any entries under the etc/gconf directory, as they will be handled automatically. See for more information. Define the GCONF_SCHEMAS variable in your Makefile with a list of all .schemas files installed by the package, if any. Names must not contain any directories in them. Define the GCONF_ENTRIES variable in your Makefile with a list of all .entries files installed by the package, if any. Names must not contain any directories in them. Packages installing scrollkeeper/rarian data files If a package installs .omf files, used by scrollkeeper/rarian, you need to take some extra steps to make sure they get registered in the database: Include ../../mk/omf-scrollkeeper.mk instead of rarian's buildlink3.mk file. This takes care of rebuilding the scrollkeeper database at installation and deinstallation time, and disallows any access to it directly from the package. Check the PLIST and remove any entries under the libdata/scrollkeeper directory, as they will be handled automatically. Remove the share/omf directory from the PLIST. It will be handled by rarian. (make print-PLIST does this automatically.) Packages installing X11 fonts If a package installs font files, you will need to rebuild the fonts database in the directory where they get installed at installation and deinstallation time. This can be automatically done by using the pkginstall framework. You can list the directories where fonts are installed in the FONTS_DIRS.type variables, where type can be one of ttf, type1 or x11. Also make sure that the database file fonts.dir is not listed in the PLIST. Note that you should not create new directories for fonts; instead use the standard ones to avoid that the user needs to manually configure his X server to find them. Packages installing GTK2 modules If a package installs GTK2 immodules or loaders, you need to take some extra steps to get them registered in the GTK2 database properly: Include ../../x11/gtk2/modules.mk instead of its buildlink3.mk file. This takes care of rebuilding the database at installation and deinstallation time. Set GTK2_IMMODULES=YES if your package installs GTK2 immodules. Set GTK2_LOADERS=YES if your package installs GTK2 loaders. Patch the package to not touch any of the GTK2 databases directly. These are: libdata/gtk-2.0/gdk-pixbuf.loaders libdata/gtk-2.0/gtk.immodules Check the PLIST and remove any entries under the libdata/gtk-2.0 directory, as they will be handled automatically. Packages installing SGML or XML data If a package installs SGML or XML data files that need to be registered in system-wide catalogs (like DTDs, sub-catalogs, etc.), you need to take some extra steps: Include ../../textproc/xmlcatmgr/catalogs.mk in your Makefile, which takes care of registering those files in system-wide catalogs at installation and deinstallation time. Set SGML_CATALOGS to the full path of any SGML catalogs installed by the package. Set XML_CATALOGS to the full path of any XML catalogs installed by the package. Set SGML_ENTRIES to individual entries to be added to the SGML catalog. These come in groups of three strings; see xmlcatmgr(1) for more information (specifically, arguments recognized by the 'add' action). Note that you will normally not use this variable. Set XML_ENTRIES to individual entries to be added to the XML catalog. These come in groups of three strings; see xmlcatmgr(1) for more information (specifically, arguments recognized by the 'add' action). Note that you will normally not use this variable. Packages installing extensions to the MIME database If a package provides extensions to the MIME database by installing .xml files inside ${PREFIX}/share/mime/packages, you need to take some extra steps to ensure that the database is kept consistent with respect to these new files: Include ../../databases/shared-mime-info/mimedb.mk (avoid using the buildlink3.mk file from this same directory, which is reserved for inclusion from other buildlink3.mk files). It takes care of rebuilding the MIME database at installation and deinstallation time, and disallows any access to it directly from the package. Check the PLIST and remove any entries under the share/mime directory, except for files saved under share/mime/packages. The former are handled automatically by the update-mime-database program, but the latter are package-dependent and must be removed by the package that installed them in the first place. Remove any share/mime/* directories from the PLIST. They will be handled by the shared-mime-info package. Packages using intltool If a package uses intltool during its build, add intltool to the USE_TOOLS, which forces it to use the intltool package provided by pkgsrc, instead of the one bundled with the distribution file. This tracks intltool's build-time dependencies and uses the latest available version; this way, the package benefits of any bug fixes that may have appeared since it was released. Packages installing startup scripts If a package contains a rc.d script, it won't be copied into the startup directory by default, but you can enable it, by adding the option PKG_RCD_SCRIPTS=YES in &mk.conf;. This option will copy the scripts into /etc/rc.d when a package is installed, and it will automatically remove the scripts when the package is deinstalled. Packages installing TeX modules If a package installs TeX packages into the texmf tree, the ls-R database of the tree needs to be updated. Except the main TeX packages such as kpathsea, packages should install files into ${PREFIX}/share/texmf-dist, not ${PREFIX}/share/texmf. Include ../../print/kpathsea/texmf.mk. This takes care of rebuilding the ls-R database at installation and deinstallation time. If your package installs files into a texmf tree other than the one at ${PREFIX}/share/texmf-dist, set TEX_TEXMF_DIRS to the list of all texmf trees that need database update. If your package also installs font map files that need to be registered using updmap, include ../../print/tex-tetex/map.mk and set TEX_MAP_FILES and/or TEX_MIXEDMAP_FILES to the list of all such font map files. Then updmap will be run automatically at installation/deinstallation to enable/disable font map files for TeX output drivers. Make sure that none of ls-R databases are included in PLIST, as they will be removed only by the kpathsea package. Packages supporting running binaries in emulation There are some packages that provide libraries and executables for running binaries from a one operating system on a different one (if the latter supports it). One example is running Linux binaries on NetBSD. The pkgtools/rpm2pkg helps in extracting and packaging Linux rpm packages. The CHECK_SHLIBS can be set to no to avoid the check-shlibs target, which tests if all libraries for each installed executable can be found by the dynamic linker. Since the standard dynamic linker is run, this fails for emulation packages, because the libraries used by the emulation are not in the standard directories. Packages installing hicolor theme icons If a package installs images under the share/icons/hicolor and/or updates the share/icons/hicolor/icon-theme.cache database, you need to take some extra steps to make sure that the shared theme directory is handled appropriately and that the cache database is rebuilt: Include ../../graphics/hicolor-icon-theme/buildlink3.mk. Check the PLIST and remove the entry that refers to the theme cache. Ensure that the PLIST does not remove the shared icon directories from the share/icons/hicolor hierarchy because they will be handled automatically. The best way to verify that the PLIST is correct with respect to the last two points is to regenerate it using make print-PLIST. Packages installing desktop files If a package installs .desktop files under share/applications and these include MIME information (MimeType key), you need to take extra steps to ensure that they are registered into the MIME database: Include ../../sysutils/desktop-file-utils/desktopdb.mk. Check the PLIST and remove the entry that refers to the share/applications/mimeinfo.cache file. It will be handled automatically. The best way to verify that the PLIST is correct with respect to the last point is to regenerate it using make print-PLIST. Marking packages as having problems In some cases one does not have the time to solve a problem immediately. In this case, one can plainly mark a package as broken. For this, one just sets the variable BROKEN to the reason why the package is broken (similar to the RESTRICTED variable). A user trying to build the package will immediately be shown this message, and the build will not be even tried. BROKEN packages are removed from pkgsrc in irregular intervals.