[OpenBSD]

OpenBSD Porting Checklist

This document describes how to make or upgrade a port. It is a useful reminder of things to do. This is neither totally accurate nor perfect. Direct comments and questions to ports@openbsd.org.
  1. If you want to be a maintainer, subscribe to ports@openbsd.org.
  2. Being a maintainer means more than just submitting ports. It also means trying to keep them up-to-date, and to answer questions about them.

  3. Check out a copy of the ports tree from cvs. You can find instructions on how to do this at http://www.openbsd.org/anoncvs.html.

  4. Pick a place to put your port and create the basic infrastructure there. Use the template Makefile at /usr/ports/infrastructure/templates/Makefile.template. NEED_VERSION is obsolete and should not be used in new ports. As you are a port developer, you are supposed to update your ports tree, including bsd.port.mk.
  5. Add the fetch portions of the Makefile.

    For more complex ports, you have more options and tools available to you:


  6. Create a checksum in distinfo by typing make makesum. Then verify the checksum is correct by typing make checksum.
  7. Extract the port with make extract. Pay attention to where the base of the sources are. Usually, it's w-${PKGNAME}${FLAVOR_EXT}/${DISTNAME}. You may need to modify the Makefile's WRKDIST variable if it is different.

  8. Read the installation documentation and note what you have to do to build the port and any special options that might be needed.

  9. Now is also a good time to figure out what kind of licensing restrictions apply to your port. Many are freely redistributable but then again, quite a few are not. We need four questions answered to distribute ports properly. These are the PERMIT_* values in the Makefile.

    Set these values to Yes if it is permitted or to a comment string stating why it is not. Pay attention to any special conditions you may need to fulfill later on. E.g., some ports require to install a copy of the license. We recommend you place the license in /usr/local/share/DISTNAME/.

  10. Add configuration options to Makefile and/or create the configuration script.
  11. Try building the port with make build.
  12. Begin and cycle of make build, generate a patch (or use make update-patches), and make clean patch.
  13. Try setting SEPARATE_BUILD.
  14. Peruse the output (if any) and tweak any options in the Makefile. To repeat issue the command `make clean configure'.

    Note: make sure host-dependent files go in /etc or /etc/<name>, but NEVER REPLACE OR MODIFY existing files in /etc. Best to have install place them in /usr/local/share/<name> and then copy to /etc or /etc/<name> only if the files do not exist. If the files exist, display a message that says such-and-such files need to be modified. This also guarantees that the files will be included in the package since everything under /usr/local is included in the PLIST. After a package has been installed the contents of pkg/MESSAGE will be displayed if it exists.

    The OpenBSD file locations are:

       user executables:			/usr/local/bin
       system admin executables:		/usr/local/sbin
       program executables:			/usr/local/libexec
       libraries				/usr/local/lib
       architecture dependent data		/usr/local/lib/<name>
       installed include files:		/usr/local/include or
    					/usr/local/include/<name>
       single-machine data:			/etc or /etc/<name>
       local state:				/var/run
       games score files:			/var/games
       GNU info files:			/usr/local/info
       man pages:				/usr/local/man/...
       read-only architecture-independent:	/usr/local/share/<name>
       misc documentation:			/usr/local/share/doc/<name>
    
  15. Begin a cycle of makes until the port is ready. Patch (see above) clean, and make until the port is generated. Get rid of all warnings if possible, especially security related warnings.

  16. Control SEPARATE_BUILD semantics. You have to do this only if the port builds with SEPARATE_BUILD defined. Ideally, the port should not modify any file in ${WRKSRC} after make patch. You can check this by making sure you don't have any write access to ${WRKSRC}. Then you can set SEPARATE_BUILD=concurrent -- someone can use the same source tree to build on distinct arches simultaneously. Otherwise, set SEPARATE_BUILD=simple -- building on distinct arches simultaneously may be met with problems, as some source files may be regenerated at awkward moments.

  17. Add COMMENT in Makefile. COMMENT is a SHORT one-line description of the port (max. 60 characters). Do NOT include the package name (or version number of the software) in the comment. Do NOT start with an uppercase letter unless semantically significant, and do NOT end with a period. DON'T EVER START WITH AN INDETERMINATE ARTICLE SUCH AS `a' or `as'; remove the article altogether.

  18. Edit pkg/DESCR, pkg/PLIST.
  19. If the application needs to create a user or a group, choose the lowest free id from /usr/ports/infrastructure/db/user.list for your port to use and make sure your port gets added to this file at commit time.

  20. Install the application with make install. If the port installs dynamic libraries, check their symbol tables with nm, as some mistaken software strips dynamic libraries, which may lead to weird failures later. On the other hand, executable binaries SHOULD be stripped; file can be used to determine this. If the port already contains code for stripping binaries, use it (i.e., an 'install-strip' target); otherwise, add a provision in the port Makefile.

  21. Check port for security holes again. This is especially important for network and setuid programs. See our security recommendations for that. Log interesting stuff and fixes in the pkg/SECURITY file. This file should list audited potential problems, along with relevant patches, so that another person can see at first glance what has been done. Example:
     
          $OpenBSD$
    
          ${WRKDIR}/receiver.c
             call to mktemp (wrapper function do_mktemp) does seem to be correct.
    
          The server makes extensive use of strlcpy/strlcat/snprintf.
    
  22. Create pkg/PLIST. After the install is complete use the developer's command, make plist which makes the file PLIST in the pkg directory. This file is a candidate packing list.

    Beware! The files are found by timestamp. This means it does NOT:

    Peruse `PLIST' and verify that everything was installed and that it was installed in the proper locations. Anything not installed can be added to a port Makefile `post-install' rule.

    Ports that install shared libraries will have another file called PFRAG.shared.


  23. Keep repeating uninstall and reinstall until perfect. Perfect is when everything installs and uninstalls in its proper location. `pkg_delete <pkg_name>' is used to uninstall. `sudo make reinstall' is used to reinstall. See the `pkg_create' man page for other commands that may be added to PLIST to ensure all is cleaned up. After an uninstall the command:
    $ find /usr/local -newer w-${PKGNAME}${FLAVOR_EXT}/fake-${MACHINE_ARCH}[-${FLAVOR}]/.install_started -print
    
    should only list standard directory names.

  24. Test the packaging. After the port installs correctly issue the command make package to create a package. To test the package first do a pkg_delete and then do a pkg_add The results after an add should EXACTLY match the results after a `make install'.

  25. Mail ports@openbsd.org with a short note asking for comments and testing. Attach the port to this email and sent it out.

    Try to get others to test it on a variety of platforms for you.


  26. Incorporate any feedback you get. Test it again on your platform. Get those who gave you feedback to test it again from your new port.

  27. Finally, include it in the "ports" tree. If you do not have CVS access, ask someone on ports@openbsd.org to commit it.

  28. If you are a developer with CVS access, check it in. We normally use "import" for a new port, rather than adding a zillion (or a dozen) files individually. Import uses "vendor branch" version numbers like 1.1.1.1, but don't worry about that! :-) If you make changes to a specific file (edit, then cvs commit), it will be 1.2, and that will be used.

    In short, import is typically used when a port is created. From that point on cvs add and cvs rm are typically used to add or remove files, and the normal edit->commit cycle for changes. You might use something like this:

    $ cd kaffe1
    $ make clean	# you really don't want to check in all of work!
    $ cvs -d cvs.openbsd.org:/cvs import -m 'kaffe port' ports/lang/kaffe1 \
    	YourName YourName_YYYY-MMM-DD
    

    As a real example, here is the output of checking in the Kaffe1 port, which one of us did on September 8, 1998:
    $ cd kaffe1
    $ make clean >/dev/null
    $ cvs import -m 'kaffe1.0(==JDK1.1) port' ports/lang/kaffe1 ian ian_1998-Sep-08
    ian@cvs.openbsd.org's password: (not shown, obviously)
    I ports/lang/kaffe1/CVS
    I ports/lang/kaffe1/files/CVS
    I ports/lang/kaffe1/pkg/CVS
    N ports/lang/kaffe1/Makefile
    cvs server: Importing /cvs/ports/lang/kaffe1/files
    N ports/lang/kaffe1/files/md5
    cvs server: Importing /cvs/ports/lang/kaffe1/pkg
    N ports/lang/kaffe1/pkg/COMMENT
    N ports/lang/kaffe1/pkg/DESCR
    N ports/lang/kaffe1/pkg/PLIST
    
    No conflicts created by this import
    $ 
    
  29. Last but not least, add a one-line entry for the new port in its parent directory's Makefile, e.g., for ports/lang/kaffe1, add it to ports/lang/Makefile.

  30. Maintain the port! As time goes by, problems may arise, or new versions of the software may be released. You should strive to keep your port up to date. In other words - iterate, test, test, iterate...

  31. When updating a port, remember to handle dependencies! You shouldn't break any port that depends on yours. In case of problems, communicate with the maintainers of such ports. Likewise, be alert for dependency updates, and check that the maintainer did their job.
Thank you for supporting the OpenBSD "ports" process!
Porting www@openbsd.org
$OpenBSD: checklist.html,v 1.51 2003/06/22 13:24:32 sturm Exp $