Monday, 8 December 2014

PREFIX and DESTDIR

PREFIX determines where the port will be installed. It defaults to /usr/local, but can be set by the user to a custom path like /opt. The port must respect the value of this variable.

DESTDIR, if set by the user, determines the complete alternative environment, usually a jail or an installed system mounted somewhere other than /. A port will actually install into DESTDIR/PREFIX, and register with the package database in DESTDIR/var/db/pkg. As DESTDIR is handled automatically by the ports infrastructure with chroot

The value of PREFIX will be set to LOCALBASE (defaulting to /usr/local). If USE_LINUX_PREFIX is set, PREFIX will be LINUXBASE (defaulting to /compat/linux).
Avoiding hard-coded /usr/local paths in the source makes the port much more flexible and able to cater to the needs of other sites. Often, this can be accomplished by replacing occurrences of /usr/local in the port's various Makefiles with ${PREFIX}. This variable is automatically passed down to every stage of the build and install processes.
Make sure the application is not installing things in /usr/local instead of PREFIX. A quick test for such hard-coded paths is:
% make clean; make package PREFIX=/var/tmp/`make -V PORTNAME`
If anything is installed outside of PREFIX, the package creation process will complain that it cannot find the files.
In addition, it is worth checking the same with the stage directory support (see Section 6.1, “Staging”):
% make stage && make check-plist && make stage-qa && make package
  • check-plist checks for files missing from the plist, and files in the plist that are not installed by the port.
  • stage-qa checks for common problems like bad shebang, symlinks pointing outside the stage directory, setuid files, and non-stripped libraries...
These tests will not find hard-coded paths inside the port's files, nor will it verify that LOCALBASE is being used to correctly refer to files from other ports. The temporarily-installed port in /var/tmp/`make -V PORTNAME` must be tested for proper operation to make sure there are no problems with paths.
PREFIX must not be set explicitly in a port's Makefile. Users installing the port may have set PREFIX to a custom location, and the port must respect that setting.
Refer to programs and files from other ports with the variables mentioned above, not explicit pathnames. For instance, if the port requires a macro PAGER to have the full pathname of less, do not use a literal path of /usr/local/bin/less. Instead, use ${LOCALBASE}:
-DPAGER=\"${LOCALBASE}/bin/less\"
The path with LOCALBASE is more likely to still work if the system administrator has moved the whole /usr/local tree somewhere else.


I am trying to make software install to a specific directory. I found several ways, but not sure what are the differences between them?
  1. ./configure --prefix=*
  2. make install --prefix=*
  3. make install DESTDIR=*                                                                                                                                                                                                                case 1 determines where the package will go when it is installed, and where it will look for its associated files when it is run. It's what you should use if you're just compiling something for use on a single host. 
  4.  case 3 is for installing to a temporary directory which is not where the package will be run from. For example this is used when building deb packages. The person building the package doesn't actually install everything into its final place on his own system. He may have a different version installed already and not want to disturb it, or he may not even be root. So he uses configure --prefix=/usr so the program will expect to be installed in /usr when it runs, then make install DESTDIR=debian/tmp to actually create the directory structure.                     
  5.   case 2: make install prefix=/foo/bar/baz. That's going to install it to a different place but not create all the directories as DESTDIR=/foo/bar/baz would. It's commonly used with GNU stow via ./configure --prefix=/usr/local && make && sudo make install prefix=/usr/local/stow/foo, which would install binaries in /usr/local/stow/foo/bin. (make install DESTDIR=/usr/local/stow/foo, by comparison, would install binaries in /usr/local/stow/foo/usr/local/bin.)

No comments:

Post a Comment