Diff for /wikisrc/pkgsrc/intro_to_packaging.mdwn between versions 1.1 and 1.5

version 1.1, 2014/07/08 14:19:33 version 1.5, 2014/07/09 12:28:19
Line 1 Line 1
 This guide should allow you to learn how to create a new port or simply fix a port that you need. There are three target demographics listed below:  This guide should allow you to learn how to create a new port or
   simply fix a port that you need. There are three target demographics
   listed below:
   
         - binary packages user with pkgin or pkg_add           - binary packages user with pkgin or pkg_add
                 (you should be confident here)                  (you should be confident here)
         - build from source, use options           - build from source, use options
                 (you will know this after reading the guide)                  (you will know this after reading the guide)
         - port developers          - port developers
                 (you should be able to get started here)                  (you should be able to get started here)
Line 10  This guide should allow you to learn how Line 12  This guide should allow you to learn how
   
 ## pkgsrc tree  ## pkgsrc tree
   
 You should have a copy of the pkgsrc tree sitting somewhere on your disk, already bootstrapped, see this [blog post](http://saveosx.org/pkgsrc-bootstrap/) on how to do this.  You should have a copy of the pkgsrc tree sitting somewhere on your
   disk, already bootstrapped, see this [blog
   post](http://saveosx.org/pkgsrc-bootstrap/) on how to do this.
   
   The tree contains a `Makefile`, a `README`, distfiles, packages,
   category directories containing the ports, the bootstrap directory
   and some documentation.
   
 The tree contains a `Makefile`, a `README`, distfiles, packages, category directories containing the ports, the bootstrap directory and some documentation.  The `mk/*` directory contains the pkgsrc framework Makefiles but
   also shell and Awk scripts
   
 The `mk/*` directory contains the pkgsrc framework Makefiles but also shell and Awk scripts  `pkglocate` is a script to find port names in the tree, though
   `pkgtools/pkgfind` is much faster.
 `pkglocate` is a script to find port names in the tree, though `pkgtools/pkgfind` is much faster.  
   
   
 ## use the right tools  ## use the right tools
   
 If you want to get started working on ports like creating new ones or simply fix ones you need, you should know about these tools:  If you want to get started working on ports like creating new ones
   or simply fix ones you need, you should know about these tools:
   
  - install package developer utilities:    - install package developer utilities:
                   
                 pkgin -y in pkg_developer                  pkgin -y in pkg_developer
   
 It contains very useful programs like:  It contains very useful programs like:
   
  - checkperms:    - checkperms:
                                   
                 verify file permissions                  verify file permissions
  - createbuildlink:   - createbuildlink:
    
                 create buildlink3.mk files, which I'll explain later                  create buildlink3.mk files, which I'll explain later
  - digest:   - digest:
    
                 create hashes for messages with crypto algorithms such as sha512 and many others                  create hashes for messages with crypto algorithms such as sha512 and many others
  - lintpkgsrc:   - lintpkgsrc:
   
Line 48  It contains very useful programs like: Line 57  It contains very useful programs like:
   
                 create archives of installed programs for later use on other machines or backups                  create archives of installed programs for later use on other machines or backups
  - pkgdiff:   - pkgdiff:
    
                 show diffs of patched files                   show diffs of patched files
  - pkglint:   - pkglint:
   
                 verify the port you're creating for common mistakes (very useful!)                  verify the port you're creating for common mistakes (very useful!)
Line 68  It contains very useful programs like: Line 77  It contains very useful programs like:
   
 A pkgsrc port should at least contain:  A pkgsrc port should at least contain:
   
 - `Makefile` : a comment, developer info, software download site and lots of other possibilities  - `Makefile` : a comment, developer info, software download site
 - `DESCR` : a paragraph containing the description for the software of the port we're making    and lots of other possibilities
 - `PLIST` : the list of files to install, pkgsrc will only install the files listed here to your prefix  - `DESCR` : a paragraph containing the description for the software
 - `distinfo` : hashes of the software archive and patches or files in the port    of the port we're making
   - `PLIST` : the list of files to install, pkgsrc will only install
     the files listed here to your prefix
   - `distinfo` : hashes of the software archive and patches or files
     in the port
   
   
 Here's how they would look like for a small port I submitted not long ago in pkgsrc-wip  Here's how they would look like for a small port I submitted not
   long ago in pkgsrc-wip
   
 Makefile:   Makefile:
                   
 {% highlight make %}  [[!format make """
 # $NetBSD$  # [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
 PKGNAME=      osxinfo-0.1  PKGNAME=      osxinfo-0.1
 CATEGORIES=   misc  CATEGORIES=   misc
Line 99  WRKSRC= ${WRKDIR}/osxinfo-${GHCOMMIT} Line 113  WRKSRC= ${WRKDIR}/osxinfo-${GHCOMMIT}
   
 .include "../../databases/sqlite3/buildlink3.mk"  .include "../../databases/sqlite3/buildlink3.mk"
 .include "../../mk/bsd.pkg.mk"  .include "../../mk/bsd.pkg.mk"
 {% endhighlight %}  """]]
   
 DESCR:   DESCR:
                   
         Small and fast Mac OS X info program written in C          Small and fast Mac OS X info program written in C
         by Youri Mouton.          by Youri Mouton.
Line 109  DESCR:  Line 123  DESCR: 
   
 PLIST:  PLIST:
                   
         @comment $NetBSD$          @comment [[!paste id=rcsid1]][[!paste id=rcsid2]]
         bin/osxinfo          bin/osxinfo
   
 distinfo:  distinfo:
   
         $NetBSD$          [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
         SHA1 (osxinfo/de74b8960f27844f7b264697d124411f81a1eab6.tar.gz) = 83a2838ad95ff73255bea7f496a8cc9aaa4e17ca          SHA1 (osxinfo/de74b8960f27844f7b264697d124411f81a1eab6.tar.gz) = 83a2838ad95ff73255bea7f496a8cc9aaa4e17ca
         RMD160 (osxinfo/de74b8960f27844f7b264697d124411f81a1eab6.tar.gz) = 9102eb2a938be38c4adf8cfbf781c04d0844d09a          RMD160 (osxinfo/de74b8960f27844f7b264697d124411f81a1eab6.tar.gz) = 9102eb2a938be38c4adf8cfbf781c04d0844d09a
Line 123  distinfo: Line 137  distinfo:
   
 ## make  ## make
   
 Now you know what kind of files you can see when you're in a port directory. The command used to compile it is the NetBSD `make` but often `bmake` on non NetBSD systems to avoid Makefile errors. Typing make alone will only compile the program but you can also use other command line arguments to make such as extract, patch, configure, install, package, ...  Now you know what kind of files you can see when you're in a port
   directory. The command used to compile it is the NetBSD `make` but
   often `bmake` on non NetBSD systems to avoid Makefile errors. Typing
   make alone will only compile the program but you can also use other
   command line arguments to make such as extract, patch, configure,
   install, package, ...
   
 I'll try to list them and explain them in logical order. You can run them together.  I'll try to list them and explain them in logical order. You can run them together.
   
 - `make clean` will remove the source file from the work directory so you can restart with either new options, new patches, ...  - `make clean` will remove the source file from the work directory
 - `make fetch` will simply fetch the file and check if the hash corresponds. It will throw an error if it doesn't.    so you can restart with either new options, new patches, ...
 - `make distinfo` or `make mdi` to update the file hashes in the `distinfo` file mentionned above.  - `make fetch` will simply fetch the file and check if the hash
 - `make extract` extracts the program source files from it's archive in the work directory    corresponds. It will throw an error if it doesn't.
   - `make distinfo` or `make mdi` to update the file hashes in the
     `distinfo` file mentionned above.
   - `make extract` extracts the program source files from it's archive
     in the work directory
 - `make patch` applies the local pkgsrc patches to the source  - `make patch` applies the local pkgsrc patches to the source
 - `make configure` run the GNU configure script  - `make configure` run the GNU configure script
 - `make` or `make build` or `make all` will stop after the program is compiled  - `make` or `make build` or `make all` will stop after the program
 - `make stage-install` will install in the port destdir, where pkgsrc first installs program files to check if the files correspond with the `PLIST` contents before installing to your prefix. For `wget`, if you have a default WRKOBJDIR (I'll explain later), the program files will first be installed in `<path>/pkgsrc/net/wget/work/.destdir` then after a few checks, in your actual prefix like `/usr/pkg`    is compiled
   - `make stage-install` will install in the port destdir, where
     pkgsrc first installs program files to check if the files correspond
     with the `PLIST` contents before installing to your prefix. For
     `wget`, if you have a default WRKOBJDIR (I'll explain later), the
     program files will first be installed in
     `<path>/pkgsrc/net/wget/work/.destdir` then after a few checks,
     in your actual prefix like `/usr/pkg`
 - `make test` run package tests, if they have any  - `make test` run package tests, if they have any
 - `make package` create a package without installing it, it will install dependencies though  - `make package` create a package without installing it, it will
     install dependencies though
 - `make replace` upgrade or reinstall the port if already installed  - `make replace` upgrade or reinstall the port if already installed
 - `make deinstall` deinstall the program  - `make deinstall` deinstall the program
 - `make install` installs from the aforementionned `work/.destdir` to your prefix  - `make install` installs from the aforementionned `work/.destdir`
 - `make bin-install` installs a package for the port, locally if previously built or remotely, as defined by BINPKG_SITES in `mk.conf`, you can make a port install dependencies from packages rather than building them with the DEPENDS_TARGET= bin-install in `mk.conf`    to your prefix
   - `make bin-install` installs a package for the port, locally if
     previously built or remotely, as defined by BINPKG_SITES in
     `mk.conf`, you can make a port install dependencies from packages
     rather than building them with the DEPENDS_TARGET= bin-install
     in `mk.conf`
 - `make show-depends` show port dependencies  - `make show-depends` show port dependencies
 - `make show-options` show various port options, as defined by `options.mk`  - `make show-options` show various port options, as defined by `options.mk`
 - `make clean-depends` cleans all port dependencies  - `make clean-depends` cleans all port dependencies
 - `make distclean` remove the source archive  - `make distclean` remove the source archive
 - `make package-clean` remove the package  - `make package-clean` remove the package
 - `make distinfo` or `make mdi` to update the `distinfo` file containing file hashes if you have a new distfile or patch  - `make distinfo` or `make mdi` to update the `distinfo` file
 - `make print-PLIST` to generate a `PLIST` file from files found in `work/.destdir`    containing file hashes if you have a new distfile or patch
   - `make print-PLIST` to generate a `PLIST` file from files found
     in `work/.destdir`
   
 You should be aware that there are many make options along with these targets, like   You should be aware that there are many make options along with
   these targets, like
   
 - `PKG_DEBUG_LEVEL`  - `PKG_DEBUG_LEVEL`
 - `CHECK_FILES`  - `CHECK_FILES`
Line 158  You should be aware that there are many  Line 197  You should be aware that there are many 
   
 ## pkgsrc configuration  ## pkgsrc configuration
   
 The framework uses an `mk.conf` file, usually found in /etc. Here's how mine looks:  The framework uses an `mk.conf` file, usually found in /etc. Here's
   how mine looks:
   
 {% highlight make %}  [[!format make """
 # Tue Oct 15 21:21:46 CEST 2013  # Tue Oct 15 21:21:46 CEST 2013
   
 .ifdef BSD_PKG_MK          # begin pkgsrc settings  .ifdef BSD_PKG_MK          # begin pkgsrc settings
Line 192  PKG_DEVELOPER=             yes Line 232  PKG_DEVELOPER=             yes
 SIGN_PACKAGES=             gpg  SIGN_PACKAGES=             gpg
 PKG_DEFAULT_OPTIONS+=      -pulseaudio -x264 -imlib2-amd64 -dconf  PKG_DEFAULT_OPTIONS+=      -pulseaudio -x264 -imlib2-amd64 -dconf
 .endif                     # end pkgsrc settings  .endif                     # end pkgsrc settings
 {% endhighlight %}  """]]
   
 - I use `DISTDIR`, `PACKAGES`, `WRKOBJDIR` to move distfiles, packages and source files somewhere else to keep my pkgsrc tree clean  - I use `DISTDIR`, `PACKAGES`, `WRKOBJDIR` to move distfiles,
 - `PKGSRC_COMPILER`, `CC`, `CXX`, `CPP` and `ABI` are my compiler options. I'm using clang to create 64 bit binaries here    packages and source files somewhere else to keep my pkgsrc tree
 - `PKG_DBDIR`, `VARBASE`, `LOCALBASE`, `PKG_TOOLS_BIN` are my prefix and package database path and package tools settings    clean
 - `PKGINFODIR`, `PKGMANDIR` are the info and man directories   - `PKGSRC_COMPILER`, `CC`, `CXX`, `CPP` and `ABI` are my compiler
 - `BINPKG_SITES` is the remote place where to get packages with the `bin-install` make target    options. I'm using clang to create 64 bit binaries here
 - `DEPENDS_TARGET` is the way port dependencies should be installed. `bin-install` will simply install a package instead of building the port  - `PKG_DBDIR`, `VARBASE`, `LOCALBASE`, `PKG_TOOLS_BIN` are my prefix
 - `X11_TYPE` sould be `native` or `modular`, the latter meaning we want X11 libraries from pkgsrc instead of using the `native` ones usually in `/usr/X11R7` in Linux or BSD systems and `/opt/X11` on Mac OS X with XQuartz    and package database path and package tools settings
 - `TOOLS_PLATFORM.*` points to specific programs used by pkgsrc, here I use the one that was generated by pkgsrc bootstrap for maximum compatibility  - `PKGINFODIR`, `PKGMANDIR` are the info and man directories
 - `ALLOW_VULNERABLE_PACKAGES` allows you to disallow the installation of vulnerable packages in critical environments like servers  - `BINPKG_SITES` is the remote place where to get packages with the
 - `MAKE_JOBS` the number of concurrent make jobs, I set it to 8 but it breaks some ports    `bin-install` make target
 - `SKIP_LICENSE_CHECK` will skip the license check. If disabled you will have to define a list of licenses you find acceptable with `ACCEPTABLE_LICENSES`  - `DEPENDS_TARGET` is the way port dependencies should be installed.
 - `PKG_DEVELOPER` this option will show more details during the port building     `bin-install` will simply install a package instead of building
 - `SIGN_PACKAGES` allows you to `gpg` sign packages. More info in my [blog post](http://saveosx.org/signed-packages/) about it    the port
 - `PKG_DEFAULT_OPTIONS` allows you to enable or disable specific options for all ports (as defined with ports' options.mk files), I disabled a few options so less ports would break, pulseaudio doesn't build on Mac OS X for example, neither do x264, dconf  - `X11_TYPE` sould be `native` or `modular`, the latter meaning we
     want X11 libraries from pkgsrc instead of using the `native` ones
     usually in `/usr/X11R7` in Linux or BSD systems and `/opt/X11`
     on Mac OS X with XQuartz
   - `TOOLS_PLATFORM.*` points to specific programs used by pkgsrc,
     here I use the one that was generated by pkgsrc bootstrap for
     maximum compatibility
   - `ALLOW_VULNERABLE_PACKAGES` allows you to disallow the installation
     of vulnerable packages in critical environments like servers
   - `MAKE_JOBS` the number of concurrent make jobs, I set it to 8 but
     it breaks some ports
   - `SKIP_LICENSE_CHECK` will skip the license check. If disabled you
     will have to define a list of licenses you find acceptable with
     `ACCEPTABLE_LICENSES`
   - `PKG_DEVELOPER` this option will show more details during the port building
   - `SIGN_PACKAGES` allows you to `gpg` sign packages. More info in
     my [blog post](http://saveosx.org/signed-packages/) about it
   - `PKG_DEFAULT_OPTIONS` allows you to enable or disable specific
     options for all ports (as defined with ports' options.mk files),
     I disabled a few options so less ports would break, pulseaudio
     doesn't build on Mac OS X for example, neither do x264, dconf
   
 Keep in mind that there are many other available options documented in the official pkgsrc guide.  Keep in mind that there are many other available options documented
   in the official pkgsrc guide.
   
   
 ## creating a simple port  ## creating a simple port
   
 Let's create a little port using the tools we've talked about above. I will use a little window manager called 2bwm.  Let's create a little port using the tools we've talked about above.
   I will use a little window manager called 2bwm.
   
 - We need an url for the program source files archive. It can be a direct link to a tar or xz archive. Mine's `http://pkgsrc.saveosx.org/Darwin/distfiles/2bwm-0.1.tar.gz`  - We need an url for the program source files archive. It can be a
   direct link to a tar or xz archive. Mine's
   `http://pkgsrc.saveosx.org/Darwin/distfiles/2bwm-0.1.tar.gz`
   
   - Now that we have a proper link for our program source, create a
     directory for your port:
   
 - Now that we have a proper link for our program source, create a directory for your port:  
           
                 $ mkdir ~/pkgsrc/wm/2bwm                  $ mkdir ~/pkgsrc/wm/2bwm
   
 - Use `url2pkg` to create the needed files automatically:  - Use `url2pkg` to create the needed files automatically:
                                   
                 $ url2pkg http://pkgsrc.saveosx.org/Darwin/distfiles/2bwm-0.1.tar.gz                  $ url2pkg http://pkgsrc.saveosx.org/Darwin/distfiles/2bwm-0.1.tar.gz
   
 You'll be presented with a text editor like `vim` to enter basic Makefile options:  You'll be presented with a text editor like `vim` to enter basic
   Makefile options:
   
 - `DISTNAME`, `CATEGORIES`, `MASTER_SITES` should be set automatically   - `DISTNAME`, `CATEGORIES`, `MASTER_SITES` should be set automatically
 - enter your mail address for `MAINTAINER` so users know whom to contact if the port is broken  - enter your mail address for `MAINTAINER` so users know whom to
     contact if the port is broken
 - make sure the `HOMEPAGE` is set right, for 2bwm it is a github page  - make sure the `HOMEPAGE` is set right, for 2bwm it is a github page
 - write a `COMMENT`, it should be a one-line description of the program  - write a `COMMENT`, it should be a one-line description of the program
 - find out which license the program uses, in my case it is the `isc` license. You can find a list of licenses in `pkgsrc/mk/licenses.mk`.  - find out which license the program uses, in my case it is the
 - Below you will see `.include "../../mk/bsd.pkg.mk"` at the end of the Makefile and above this should go the port's needed dependencies to build, we'll leave that empty at the moment and try to figure out what 2bwm needs    `isc` license. You can find a list of licenses in `pkgsrc/mk/licenses.mk`.
 - exit vim and it should fetch and update the file hashes for you. If it says `permission denied` you can just run `make mdi` to fetch and upadate the `distinfo` file  - Below you will see `.include "../../mk/bsd.pkg.mk"` at the end
     of the Makefile and above this should go the port's needed
 So now you have valid `Makefile` and `distinfo` files but you need to write a paragraph in `DESCR`. You can usually find inspiration on the program's homepage.    dependencies to build, we'll leave that empty at the moment and
     try to figure out what 2bwm needs
 Here's how they look like at the moment:   - exit vim and it should fetch and update the file hashes for you.
             If it says `permission denied` you can just run `make mdi` to
  Makefile:    fetch and upadate the `distinfo` file
 {% highlight make %}   
 # $NetBSD$  So now you have valid `Makefile` and `distinfo` files but you need
   to write a paragraph in `DESCR`. You can usually find inspiration
   on the program's homepage.
   
   Here's how they look like at the moment:
           
   Makefile:
   [[!format make """
   # [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
 DISTNAME=       2bwm-0.1  DISTNAME=       2bwm-0.1
 CATEGORIES=     wm  CATEGORIES=     wm
Line 254  COMMENT=        Fast floating WM written Line 329  COMMENT=        Fast floating WM written
 LICENSE=        isc  LICENSE=        isc
   
 .include "../../mk/bsd.pkg.mk"  .include "../../mk/bsd.pkg.mk"
 {% endhighlight %}  """]]
   
 distinfo:  distinfo:
   
                   
         $NetBSD$          [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
         SHA1 (2bwm-0.1.tar.gz) = e83c862dc1d9aa198aae472eeca274e5d98df0ad          SHA1 (2bwm-0.1.tar.gz) = e83c862dc1d9aa198aae472eeca274e5d98df0ad
         RMD160 (2bwm-0.1.tar.gz) = d9a93a7d7ae7183f5921f9ad76abeb1401184ef9          RMD160 (2bwm-0.1.tar.gz) = d9a93a7d7ae7183f5921f9ad76abeb1401184ef9
Line 277  But our PLIST file is still empty. Line 352  But our PLIST file is still empty.
   
 #### build stage  #### build stage
   
  Let's try to build the port to see if things work but as soon as the build stage starts, we get this error:  Let's try to build the port to see if things work but as soon as
   the build stage starts, we get this error:
   
 > 2bwm.c:26:10: fatal error: 'xcb/randr.h' file not found  > 2bwm.c:26:10: fatal error: 'xcb/randr.h' file not found
   
 Let's find out which port provides this file !   Let's find out which port provides this file !
   
         $ pkgin se xcb           $ pkgin se xcb
   
 returns these possible packages:   returns these possible packages:
   
         xcb-util-wm-0.3.9nb1  Client and window-manager helpers for ICCCM and EWMH          xcb-util-wm-0.3.9nb1  Client and window-manager helpers for ICCCM and EWMH
         xcb-util-renderutil-0.3.8nb1  Convenience functions for the Render extension          xcb-util-renderutil-0.3.8nb1  Convenience functions for the Render extension
Line 295  returns these possible packages:  Line 371  returns these possible packages: 
         xcb-proto-1.9 =      XCB protocol descriptions (in XML)          xcb-proto-1.9 =      XCB protocol descriptions (in XML)
         xcb-2.4nb1           Extensible, multiple cut buffers for X          xcb-2.4nb1           Extensible, multiple cut buffers for X
   
 Package content inspection allowed me to find the right port   Package content inspection allowed me to find the right port
   
         $ pkgin pc libxcb|grep randr.h          $ pkgin pc libxcb|grep randr.h
   
 So we can add the libxcb `buildlink3.mk` file to the Makefile above the bsd.pkg.mk include:   So we can add the libxcb `buildlink3.mk` file to the Makefile above
   the bsd.pkg.mk include:
   
         .include "../../x11/libxcb/buildlink3.mk"          .include "../../x11/libxcb/buildlink3.mk"
   
 This allows the port to link 2bwm against the libxcb port. Let's try to build the port again!  This allows the port to link 2bwm against the libxcb port. Let's
   try to build the port again!
   
         $ make clean          $ make clean
         $ make          $ make
Line 318  It looks like this file is provided by x Line 396  It looks like this file is provided by x
   
 in our Makefile.  in our Makefile.
   
 Clean, build again, and add more dependencies until it passes the build stage. Here's how my Makefile ends up looking like:  Clean, build again, and add more dependencies until it passes the
   build stage. Here's how my Makefile ends up looking like:
   
 {% highlight make %}  [[!format make """
 # $NetBSD$  # [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
 DISTNAME=       2bwm-0.1  DISTNAME=       2bwm-0.1
 CATEGORIES=     wm  CATEGORIES=     wm
Line 337  LICENSE=        isc Line 416  LICENSE=        isc
 .include "../../x11/xcb-util-keysyms/buildlink3.mk"  .include "../../x11/xcb-util-keysyms/buildlink3.mk"
 .include "../../x11/xcb-util/buildlink3.mk"  .include "../../x11/xcb-util/buildlink3.mk"
 .include "../../mk/bsd.pkg.mk"  .include "../../mk/bsd.pkg.mk"
 {% endhighlight %}  """]]
   
   
 #### install phase  #### install phase
   
 Geat ! We got our program to compile in pkgsrc. Now we must generate the PLIST file so we can actually install the program, but we must `make stage-install` to make sure that it installs in the right place.  Geat ! We got our program to compile in pkgsrc. Now we must generate
   the PLIST file so we can actually install the program, but we must
   `make stage-install` to make sure that it installs in the right
   place.
   
                   
         $ find /pkgsrc/work/wm/2bwm/work/.destdir/          $ find /pkgsrc/work/wm/2bwm/work/.destdir/
Line 367  This doesn't look right since our `LOCAL Line 449  This doesn't look right since our `LOCAL
   
         $ make print-PLIST          $ make print-PLIST
   
 returns nothing, because 2bwm installs files in the wrong place so we need to fix 2bwm's own Makefile to use the right `DESTDIR` and `PREFIX`, that is set to the right place by pkgsrc. Let's inspect how 2bwm installs:  returns nothing, because 2bwm installs files in the wrong place so
   we need to fix 2bwm's own Makefile to use the right `DESTDIR` and
   `PREFIX`, that is set to the right place by pkgsrc. Let's inspect
   how 2bwm installs:
   
 From 2bwm's Makefile:   From 2bwm's Makefile:
   
 {% highlight make %}  [[!format make """
 install: $(TARGETS)  install: $(TARGETS)
         test -d $(DESTDIR)$(PREFIX)/bin || mkdir -p $(DESTDIR)$(PREFIX)/bin          test -d $(DESTDIR)$(PREFIX)/bin || mkdir -p $(DESTDIR)$(PREFIX)/bin
         install -pm 755 2bwm $(DESTDIR)$(PREFIX)/bin          install -pm 755 2bwm $(DESTDIR)$(PREFIX)/bin
Line 379  install: $(TARGETS) Line 464  install: $(TARGETS)
         test -d $(DESTDIR)$(MANPREFIX)/man1 || mkdir -p $(DESTDIR)$(MANPREFIX)/man1          test -d $(DESTDIR)$(MANPREFIX)/man1 || mkdir -p $(DESTDIR)$(MANPREFIX)/man1
         install -pm 644 2bwm.man $(DESTDIR)$(MANPREFIX)/man1/2bwm.1          install -pm 644 2bwm.man $(DESTDIR)$(MANPREFIX)/man1/2bwm.1
         install -pm 644 hidden.man $(DESTDIR)$(MANPREFIX)/man1/hidden.1          install -pm 644 hidden.man $(DESTDIR)$(MANPREFIX)/man1/hidden.1
 {% endhighlight %}  """]]
   
 This looks fine since it installs in a `DESTDIR`/`PREFIX` but it sets   This looks fine since it installs in a `DESTDIR`/`PREFIX` but it sets
   
 > PREFIX=/usr/local  > PREFIX=/usr/local
   
Line 389  and Line 474  and
   
 > MANPREFIX=$(PREFIX)/share/man  > MANPREFIX=$(PREFIX)/share/man
   
 In the beginning of the Makefile. We should remove the first line and edit the man prefix:  In the beginning of the Makefile. We should remove the first line
   and edit the man prefix:
   
 > MANPREFIX=${PKGMANDIR}  > MANPREFIX=${PKGMANDIR}
   
 so pkgsrc can install the program's files in the right place. We have two ways of modifying this file, either patch the Makefile or use `sed` substitution which is a builtin pkgsrc feature that allows you to change lines in files with a sed command before building the port.   so pkgsrc can install the program's files in the right place. We
   have two ways of modifying this file, either patch the Makefile or
   use `sed` substitution which is a builtin pkgsrc feature that allows
   you to change lines in files with a sed command before building the
   port.
   
 I will show how to do both ways so you can get an introduction on how to generate patch files for pkgsrc.  I will show how to do both ways so you can get an introduction on
   how to generate patch files for pkgsrc.
   
 #### patching the Makefile :  #### patching the Makefile :
   
Line 412  pkgdiff "/Volumes/Backup/pkgsrc/work/wm/ Line 503  pkgdiff "/Volumes/Backup/pkgsrc/work/wm/
         and this returns our diff.          and this returns our diff.
                   
   
 - create the patch with `mkpatches`, it should create a `patches` directory in the port containing the patch and an original file removed with `mkpatches -c`.   - create the patch with `mkpatches`, it should create a `patches`
     directory in the port containing the patch and an original file
     removed with `mkpatches -c`.
   
                 $ find patches/*                  $ find patches/*
                 patches/patch-Makefile                  patches/patch-Makefile
   
 - now that the patch has been created, we need to add it's hash to distinfo otherwise pkgsrc won't pick it up:  - now that the patch has been created, we need to add it's hash to
     distinfo otherwise pkgsrc won't pick it up:
   
                 $ make mdi                  $ make mdi
 you should get this new line:  you should get this new line:
Line 425  you should get this new line: Line 519  you should get this new line:
         > SHA1 (patch-Makefile) = 9f8cd00a37edbd3e4f65915aa666ebd0f3c04e04          > SHA1 (patch-Makefile) = 9f8cd00a37edbd3e4f65915aa666ebd0f3c04e04
   
   
 - you can now clean and `make patch` and `make stage-install CHECK_FILES=no` since we still haven't generated a proper PLIST. Let's see if 2wm files were installed in the right place this time:  - you can now clean and `make patch` and `make stage-install
     CHECK_FILES=no` since we still haven't generated a proper PLIST.
     Let's see if 2wm files were installed in the right place this
     time:
   
                 $ find /pkgsrc/work/wm/2bwm/work/.destdir/                  $ find /pkgsrc/work/wm/2bwm/work/.destdir/
   
Line 442  you should get this new line: Line 539  you should get this new line:
                   
         containing:          containing:
   
                 @comment $NetBSD$                  @comment [[!paste id=rcsid1]][[!paste id=rcsid2]]
                 bin/2bwm                  bin/2bwm
                 bin/hidden                  bin/hidden
   
         There you have a working port you can install normally with           There you have a working port you can install normally with
   
                 $ make install                   $ make install
   
   
 #### using the sed substitution framework  #### using the sed substitution framework
   
 You should be able to fix the prefix error much quicker than with the patching explained above thanks to the sed substitution framework. Here's how it looks like in my port Makefile:  You should be able to fix the prefix error much quicker than with
   the patching explained above thanks to the sed substitution framework.
   Here's how it looks like in my port Makefile:
   
 {% highlight make %}  [[!format make """
 SUBST_CLASSES+=         makefile  SUBST_CLASSES+=         makefile
 SUBST_STAGE.makefile=   pre-build  SUBST_STAGE.makefile=   pre-build
 SUBST_MESSAGE.makefile= Fixing makefile  SUBST_MESSAGE.makefile= Fixing makefile
 SUBST_FILES.makefile=   Makefile  SUBST_FILES.makefile=   Makefile
 SUBST_SED.makefile=     -e 's,/usr/local,${PREFIX},g'  SUBST_SED.makefile=     -e 's,/usr/local,${PREFIX},g'
 SUBST_SED.makefile+=    -e 's,share/man,${PKGMANDIR},g'  SUBST_SED.makefile+=    -e 's,share/man,${PKGMANDIR},g'
 {% endhighlight %}  """]]
   
 As you can see, you can do multiple commands on multiple files, it is very useful for very small fixes like this.  As you can see, you can do multiple commands on multiple files, it
   is very useful for very small fixes like this.
   
   
 #### pkglint  #### pkglint
   
 Now that we have a working port, we must make sure it complies to the pkgsrc rules.   Now that we have a working port, we must make sure it complies to the pkgsrc rules.
   
         $ pkglint          $ pkglint
                   
 Returns   Returns
   
         ERROR: DESCR:4: File must end with a newline.          ERROR: DESCR:4: File must end with a newline.
         ERROR: patches/patch-Makefile:3: Comment expected.          ERROR: patches/patch-Makefile:3: Comment expected.
Line 483  Fix the things pkglint tells you to do u Line 583  Fix the things pkglint tells you to do u
   
 > looks fine.  > looks fine.
   
 Then you should do some testing on the program itelf on at least two platforms such as NetBSD, Mac OS X. Other platforms supported by pkgsrc can be found at [pkgsrc.org](http://pkgsrc.org). If you would like to submit your pkgsrc upstream you can either subscribe to pkgsrc-wip or ask a NetBSD developer to add it for you.  Then you should do some testing on the program itelf on at least
   two platforms such as NetBSD, Mac OS X. Other platforms supported
 You can find the 2bwm port I submitted in [pkgsrc-wip](http://pkgsrc-wip.cvs.sourceforge.net/viewvc/pkgsrc-wip/wip/2bwm/).  by pkgsrc can be found at [pkgsrc.org](http://pkgsrc.org). If you
   would like to submit your pkgsrc upstream you can either subscribe
   to pkgsrc-wip or ask a NetBSD developer to add it for you.
 ## pkgsrc and wip   
   You can find the 2bwm port I submitted in
 If you want to submit your port for others to use you can either subscribe to pkgsrc-wip or ask a NetBSD developer to add it for you which can be tough. Even though there are many IRC channels in which you can find nice developers, you will have to take the time to get to know them. The easiest way for beginners is to submit to pkgsrc-wip so other people can review and test it first.   [pkgsrc-wip](http://pkgsrc-wip.cvs.sourceforge.net/viewvc/pkgsrc-wip/wip/2bwm/).
   
 pkgsrc-wip is hosted on [sourceforge](https://sourceforge.net/projects/pkgsrc-wip/) and you can easily get cvs access to it if you create an account on there and send an email to NetBSD developer `@wiz` (Thomas Klausner) asking nicely for commit access. I got access fairly quickly and he even fixed a port to show me how to do it properly.   
   ## pkgsrc and wip
   
   If you want to submit your port for others to use you can either
   subscribe to pkgsrc-wip or ask a NetBSD developer to add it for you
   which can be tough. Even though there are many IRC channels in which
   you can find nice developers, you will have to take the time to get
   to know them. The easiest way for beginners is to submit to pkgsrc-wip
   so other people can review and test it first.
   
   pkgsrc-wip is hosted on
   [sourceforge](https://sourceforge.net/projects/pkgsrc-wip/) and you
   can easily get cvs access to it if you create an account on there
   and send an email to NetBSD developer `@wiz` (Thomas Klausner)
   asking nicely for commit access. I got access fairly quickly and
   he even fixed a port to show me how to do it properly.
   
 You can also send me an email or talk to me on IRC so I can submit it for you.  You can also send me an email or talk to me on IRC so I can submit it for you.
   
Line 502  You can also send me an email or talk to Line 617  You can also send me an email or talk to
 You can create port options with the `options.mk` file, like for `wm/dwm`  You can create port options with the `options.mk` file, like for `wm/dwm`
   
                   
 {% highlight make %}  [[!format make """
 # $NetBSD: options.mk,v 1.2 2011/06/17 11:59:57 obache Exp $  # [[!paste id=rcsid1]][[!paste id=rcsid2]]
   
 PKG_OPTIONS_VAR=                        PKG_OPTIONS.dwm  PKG_OPTIONS_VAR=                        PKG_OPTIONS.dwm
 PKG_SUPPORTED_OPTIONS=  xinerama  PKG_SUPPORTED_OPTIONS=  xinerama
Line 527  SUBST_FILES.options=    config.mk Line 642  SUBST_FILES.options=    config.mk
 SUBST_SED.options+=     -e '/^XINERAMA/d'  SUBST_SED.options+=     -e '/^XINERAMA/d'
 .  include "../../x11/libX11/buildlink3.mk"  .  include "../../x11/libX11/buildlink3.mk"
 .endif  .endif
 {% endhighlight %}  """]]
   
 This file should be included in the Makefile:  This file should be included in the Makefile:
   
Line 560  It allows you to change configure argume Line 675  It allows you to change configure argume
   
 ## hosting a package repo  ## hosting a package repo
   
 Now that you've created a few ports, you might want to make  Now that you've created a few ports, you might want to make precompiled
 precompiled packages available for testing. You will need pkgsrc's `pkg_install` on the host system. I host my [packages](http://pkgsrc.saveosx.org/) on a FreeBSD server with a bootstrapped pkgsrc.  packages available for testing. You will need pkgsrc's `pkg_install`
   on the host system. I host my [packages](http://pkgsrc.saveosx.org/)
   on a FreeBSD server with a bootstrapped pkgsrc.
   
 I use this `zsh` function to :  I use this `zsh` function to :
   
 {% highlight bash %}   [[!format make """
 add () {  add () {
         # upload the package to remote server          # upload the package to remote server
         scp $1 yrmt@saveosx.org:/usr/local/www/saveosx/packages/Darwin/2013Q4/x86_64/All/ 2> /dev/null          scp $1 yrmt@saveosx.org:/usr/local/www/saveosx/packages/Darwin/2013Q4/x86_64/All/ 2> /dev/null
Line 578  add () { Line 695  add () {
         # pkgin update          # pkgin update
         sudo pkgin update          sudo pkgin update
 }  }
 {% endhighlight %}  """]]
   
 - upload a package   - upload a package
 - update the package summary, which is an archive containing information about all present packages that will be picked up by pkg_install and pkgin. It looks like this for one package:  - update the package summary, which is an archive containing
     information about all present packages that will be picked up by
     pkg_install and pkgin. It looks like this for one package:
   
                 PKGNAME=osxinfo-0.1                  PKGNAME=osxinfo-0.1
                 DEPENDS=sqlite3>=3.7.16.2nb1                  DEPENDS=sqlite3>=3.7.16.2nb1
Line 603  add () { Line 722  add () {
                 REQUIRES=/usr/pkg/lib/libsqlite3.0.dylib                  REQUIRES=/usr/pkg/lib/libsqlite3.0.dylib
                 FILE_NAME=osxinfo-0.1.tgz                  FILE_NAME=osxinfo-0.1.tgz
                 FILE_SIZE=9710                  FILE_SIZE=9710
                 DESCRIPTION=Small and fast Mac OS X info program written in C                   DESCRIPTION=Small and fast Mac OS X info program written in C
                 DESCRIPTION=by Youri Mouton.                  DESCRIPTION=by Youri Mouton.
                 DESCRIPTION=                  DESCRIPTION=
                 DESCRIPTION=Homepage:                  DESCRIPTION=Homepage:
                 DESCRIPTION=http://github.com/yrmt/osxinfo                  DESCRIPTION=http://github.com/yrmt/osxinfo
   
   
 - update pkgin   - update pkgin
   
   
 And this shell alias to upload all my built packages, but I still need to run `add()` mentionned above to update the pkg_summary  And this shell alias to upload all my built packages, but I still
   need to run `add()` mentionned above to update the pkg_summary
   
 {% highlight bash %}   [[!format bash """
 up='rsync -avhz --progress /pkgsrc/packages/ root@saveosx.org:/usr/local/www/saveosx/packages/Darwin/2013Q4/x86_64/'  up='rsync -avhz --progress /pkgsrc/packages/ root@saveosx.org:/usr/local/www/saveosx/packages/Darwin/2013Q4/x86_64/'
 {% endhighlight %}   """]]
   
 Then you should be able to set the url in repositories.conf to use your packages with pkgin. You can also install them directly with something like `pkg_add http://pkgsrc.saveosx.org/Darwin/2013Q4/x86_64/All/9menu-1.8nb1.tgz` of course.   Then you should be able to set the url in repositories.conf to use
   your packages with pkgin. You can also install them directly with
   something like `pkg_add
   http://pkgsrc.saveosx.org/Darwin/2013Q4/x86_64/All/9menu-1.8nb1.tgz` of
   course.
   
   
 ## build all packages  ## build all packages
   
 Bulk building pkgsrc packages is a topic for another post, see jperkin's excellent blog [posts](http://www.perkin.org.uk/posts/distributed-chrooted-pkgsrc-bulk-builds.html) about this.  Bulk building pkgsrc packages is a topic for another post, see
   jperkin's excellent blog
   [posts](http://www.perkin.org.uk/posts/distributed-chrooted-pkgsrc-bulk-builds.html)
   about this.
   
   
 ## faq  ## faq
   
 #### what if the port I'm making is a dependency for another one?  #### what if the port I'm making is a dependency for another one?
   
 You should just generate the buildlink3.mk file we've talked about earlier like this:  You should just generate the buildlink3.mk file we've talked about
   earlier like this:
   
         $ createbuildlink > buildlink3.mk          $ createbuildlink > buildlink3.mk
   
 #### what if the program is only hosted on GitHub ?  #### what if the program is only hosted on GitHub ?
   
 pkgsrc supports fetching archives from specific git commits on GitHub like this:  pkgsrc supports fetching archives from specific git commits on
 {% highlight make %}  GitHub like this:
   [[!format make """
 PKGNAME=           2bwm-0.1  PKGNAME=           2bwm-0.1
 CATEGORIES=        wm  CATEGORIES=        wm
 GHCOMMIT=          52a097ca644eb571b22a135951c945fcca57a25c  GHCOMMIT=          52a097ca644eb571b22a135951c945fcca57a25c
Line 646  DISTNAME=          ${GHCOMMIT} Line 775  DISTNAME=          ${GHCOMMIT}
 MASTER_SITES=      https://github.com/venam/2bwm/archive/  MASTER_SITES=      https://github.com/venam/2bwm/archive/
 DIST_SUBDIR=       2bwm  DIST_SUBDIR=       2bwm
 WRKSRC=            ${WRKDIR}/2bwm-${GHCOMMIT}  WRKSRC=            ${WRKDIR}/2bwm-${GHCOMMIT}
 {% endhighlight %}  """]]
   
 You can then easily update the git commit and the distinfo with it to update the program.   You can then easily update the git commit and the distinfo with it
   to update the program.
   
 #### what if the program doesn't have a Makefile  #### what if the program doesn't have a Makefile
   
 You can do all Makefile operations directly from the port's Makefile like this:   You can do all Makefile operations directly from the port's Makefile
   like this:
   
   
 {% highlight make %}  [[!format make """
 post-extract:  post-extract:
         ${CHMOD} a-x ${WRKSRC}/elementary/apps/48/internet-mail.svg          ${CHMOD} a-x ${WRKSRC}/elementary/apps/48/internet-mail.svg
   
 do-install:  do-install:
         ${INSTALL_DATA_DIR} ${DESTDIR}${PREFIX}/share/icons          ${INSTALL_DATA_DIR} ${DESTDIR}${PREFIX}/share/icons
         cd ${WRKSRC} && pax -rw -pe . ${DESTDIR}${PREFIX}/share/icons/          cd ${WRKSRC} && pax -rw -pe . ${DESTDIR}${PREFIX}/share/icons/
 {% endhighlight %}  """]]
   
 To install, but you can also build programs from the Makefile. This is what qt4-sqlite3 uses:  To install, but you can also build programs from the Makefile. This
   is what qt4-sqlite3 uses:
   
 {% highlight make %}  [[!format make """
 do-build:  do-build:
         cd ${WRKSRC}/src/tools/bootstrap && env ${MAKE_ENV} ${GMAKE}          cd ${WRKSRC}/src/tools/bootstrap && env ${MAKE_ENV} ${GMAKE}
         cd ${WRKSRC}/src/tools/moc && env ${MAKE_ENV} ${GMAKE}          cd ${WRKSRC}/src/tools/moc && env ${MAKE_ENV} ${GMAKE}
         cd ${WRKSRC}/src/plugins/sqldrivers/sqlite && env ${MAKE_ENV} ${GMAKE}          cd ${WRKSRC}/src/plugins/sqldrivers/sqlite && env ${MAKE_ENV} ${GMAKE}
 {% endhighlight %}  """]]
   
   
 You can install the following type of files:   You can install the following type of files:
   
 `INSTALL_PROGRAM_DIR` : directories that contain binaries  `INSTALL_PROGRAM_DIR` : directories that contain binaries
   
Line 701  You can install the following type of fi Line 833  You can install the following type of fi
 `INSTALL_MAN` : man pages  `INSTALL_MAN` : man pages
   
   
 `INSTALLATION_DIRS` : A list of directories relative to PREFIX that are created by pkgsrc at the beginning of the install phase. The package is supposed to create all needed directories itself before installing files to it and list all other directories here.  `INSTALLATION_DIRS` : A list of directories relative to PREFIX that
   are created by pkgsrc at the beginning of the install phase. The
   package is supposed to create all needed directories itself before
   installing files to it and list all other directories here.
   
 #### common errors  #### common errors
   
 - > Makefile:19: *** missing separator.  Stop.  - > Makefile:19: *** missing separator.  Stop.
   
 This means you're not using the right `make`. On most systems, the make installed from the pkgsrc bootstrap is called `bmake`  This means you're not using the right `make`. On most systems, the
   make installed from the pkgsrc bootstrap is called `bmake`
   
 - If you have a feeling a port is stuck in the building stage, disable make jobs in your mk.conf  - If you have a feeling a port is stuck in the building stage,
     disable make jobs in your mk.conf
   
 - Please contribute here :)  
   
   
 ## links  
 - [Jonathan Perkin's excellent blog](http://www.perkin.org.uk/)  
 - [NetBSD's very extensive pkgsrc guide](http://www.netbsd.org/docs/pkgsrc/)  
 - [NetBSD's pkgsrc wiki](http://wiki.netbsd.org/pkgsrc/)  
 - Other blog posts here :)  
   
 ## where to find me  
   
 - yrmt@edgebsd.org  
 - irc.oftc.net  
           
         `#saveosx`  
   
 [[!meta title="title: An introduction to pkgsrc"]]  [[!cut id=rcsid1 text="$Net"]]
   [[!cut id=rcsid2 text="BSD$"]]
   [[!meta title="An introduction to packaging"]]
 [[!meta author="Youri Mouton"]]  [[!meta author="Youri Mouton"]]

Removed from v.1.1  
changed lines
  Added in v.1.5


CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb