Upgrading ports and preserve make options

Posted by Jonathan

FreeBSD uses make options while building ports in order to build a certain extension or (de)activate certain features.

MySQL 4.1 for example can be build with the following options:

WITH_CHARSET=charset
WITH_XCHARSET=list
WITH_COLLATION=collate
WITH_OPENSSL=yes
WITH_LINUXTHREADS=yes
WITH_PROC_SCOPE_PTH=yes
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes
WITHOUT_INNODB=yes
WITH_NDB=yes

There are two ways of utilizing these options. If the port uses OPTIONS in the Makefile, you can configure the options with

# cd /usr/ports/databases/mysql41-server
# make config

You will get an ncurses screen from which you can choose your options. Your configuration will be saved in /var/db/ports/PORTNAME/options and each time you build this port you get the same options. Reconfiguration is done through calling make config in the port directory again.

But many ports do not use the OPTIONS framework in their Makefiles. MySQL for example does not.

If you want to use some of the build options you have to do it like this:

# cd /usr/ports/databases/mysql41-server
# make -DBUILD_OPTIMIZED install clean

The problem is that you build options are not saved. So when you have to update MySQL, you can’t just use portupgrade -a because your options will be lost. You have to upgrade MySQL yourself (make && make deinstall && make install clean) and remember to use all your options again.

The author of portupgrade though of this problem and introduced /usr/local/etc/pkgtools.conf. With pkgtools.conf you can specify arguments that portupgrade uses while upgrading a port.

MAKE_ARGS = {
# a) Separate them with the space
‘databases/mysql41-’ => ‘WITH_LINUXTHREADS=1 BUILD_STATIC=1’,

# b) Specify them using an array
‘databases/mysql41-
’ => [
‘WITH_LINUXTHREADS=1’,
‘BUILD_STATIC =1’,
],
}

So you just edit all your ports with the correct build options here and you’re done right? No.

Only portupgrade will use this file so if you happen to build any of the ports yourself, your options are not used. And worse, if a port gets updated THROUGH portupgrade as a dependency of another port, the options will NOT BE USED by portupgrade.

So the only solution left is to use /etc/make.conf. In /etc/make.conf you can specify global make options.

CPUTYPE?= pentium3
CFLAGS= -O2 -mmmx -msse -pipe
COPTFLAGS= -O2 -pipe
WITHOUT_X11=yes
WITHOUT_GUI=yes

The problem with this approach is that these options will be set in every make invocation. So all my ports are build without a GUI and without X11 if this options exists in their Makefiles.

So the correct solution is to conditionally set the make variables in /etc/make.conf because I want BUILD_STATIC only set if the mysql port is compiled. You can do this with checking the CURDIR make variable that points to the current directory:

.if ${.CURDIR:M/databases/mysql}
BUILD_STATIC=yes
BUILD_OPTIMIZED=yes
WITH_LINUXTHREADS=yes
.endif

Now every time make is called in databases/mysql41-server (or better in databases/mysql* so that if I compile the client or decide to move to MySQL 5, the options are still set) make will have my options set. Even if you use portupgrade everything works as portupgrade just calls make.

Not pretty but the only real solution if you want to preserve make options through upgrades automatically.

Comments

Leave a response

  1. TracyJanuary 14, 2006 @ 08:10 PM
    One thing that I noticed on FreeBSD 6 is that there is not an /etc/defaults/make.conf to base /etc/make.conf off of. Is there some document that spells out what exactly you can put in the make.conf file?
  2. gogoJanuary 15, 2006 @ 02:35 AM
    The only thing I'm still missing is to UNDEFINE certain variables for a specific port. E.g. I want to set WITH_BLA=yes globally and undefine it for certain ports.
  3. JonathanJanuary 15, 2006 @ 01:24 PM
    @Tracy: There is no real good reference for /etc/make.conf. One point for further information is general documentation about make as most of the settings are general make settings and are not FreeBSD specific. The other point to lookt at are all files in /usr/ports/Mk/. These are used by the make while invoke in the ports tree.
  4. Steve GFebruary 07, 2006 @ 10:25 PM
    Tracy, if you do a "locate make.conf" you'll see they've tucked it away in /usr/src/share/examples/etc/make.conf . I'm not sure why, but there it is.