Creating a PR with patch to update a FreeBSD port

From TykWiki
Jump to navigationJump to search

This article is about submitting an updated port to the FreeBSD project. It is not about updating an installed port on a system to a newer version.


The FreeBSD ports tree is huge, and as such, there is a lot of updating to do to keep everything fresh. What I used to do when I found something that was outdated was:

  • Wait for someone else to update the port
  • Send an email to ports@ or the maintainer and ask if someone can update the port

Turns out both of the above options are pretty silly, since it is very easy to update a lot of ports. Why waste someone elses time when it takes me just as long to submit a PR with a patch to update the port ?


To ease the process of creating a PR to update a port, there is a port called ports-mgmt/porttools which I install:

portmaster /usr/ports/ports-mgmt/porttools/

I then edit /home/tykling/.porttools and set name and email in that file:

[tykling@tyklappy ~]$ egrep "(EMAIL|FULLNAME)" .porttools 
FULLNAME="Thomas Steen Rasmussen"

This will make sure the values are pre-filled in the PR submit screen.

It is also important that the local MTA on the machine is working, as the send-pr program used by the port submit command submits to the local MTA. This means that if the MTA on the machine you are running this on sends mail from a local hostname, the mail with the PR probably wont get there. This needs to be fixed before attempting to sumbit a PR. How do I test the MTA ? Well, if I can do "echo lol | mail" and receive the mail, everything is probably fine :)

Updating a port

This example is for updating /usr/ports/games/openttd from 1.0.3 to 1.0.4.

First thing I do is to make a backup copy of the port dir before making any changes, so I have something to compare with when I am done making changes.

[tykling@tyklappy /usr/ports/games]$ sudo cp -rv openttd/ openttd.orig
openttd/ -> openttd.orig
openttd/files -> openttd.orig/files
openttd/files/ -> openttd.orig/files/
openttd/Makefile -> openttd.orig/Makefile
openttd/pkg-plist -> openttd.orig/pkg-plist
openttd/distinfo -> openttd.orig/distinfo
openttd/pkg-descr -> openttd.orig/pkg-descr

I make all changes in /usr/ports/games/openttd and keep /usr/ports/games/openttd.orig for later comparison.

Then I go to work on /usr/ports/games/openttd. First thing to do is to change the version number in /usr/ports/games/openttd/Makefile:

[tykling@tyklappy /usr/ports/games/openttd]$ sudo sed -i "" "s/1.0.3/1.0.4/" Makefile

Then I run port fetch which downloads the distfile and updates /usr/ports/games/openttd/distinfo with the new filesize and checksums:

[tykling@tyklappy /usr/ports/games/openttd]$ sudo port fetch
Define WITH_MIDI_PLAYER=/path/to/player to build with external MIDI player
Define WITH_MIDI_PLAYER_ARGS=arguments for external MIDI player
Define WITH_DEDICATED_SERVER_ONLY to build CLI-based dedicated server
===>  License check disabled, port has not defined LICENSE
=> openttd-1.0.4-source.tar.bz2 doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch from
openttd-1.0.4-source.tar.bz2                  100% of 5551 kB  848 kBps
Define WITH_MIDI_PLAYER=/path/to/player to build with external MIDI player
Define WITH_MIDI_PLAYER_ARGS=arguments for external MIDI player
Define WITH_DEDICATED_SERVER_ONLY to build CLI-based dedicated server
===>  License check disabled, port has not defined LICENSE
[tykling@tyklappy /usr/ports/games/openttd]$ 

The Makefile and distfile are now both updated to reflect the new version. For simple upgrades, the work is done. This is the difference between the old port and the new port:

[tykling@tyklappy ~]$ diff -u /usr/ports/games/openttd.orig/ /usr/ports/games/openttd/
diff -u /usr/ports/games/openttd.orig/Makefile /usr/ports/games/openttd/Makefile
--- /usr/ports/games/openttd.orig/Makefile      2010-09-30 00:50:23.536888236 +0200
+++ /usr/ports/games/openttd/Makefile   2010-09-30 00:52:06.553391172 +0200
@@ -6,7 +6,7 @@
 PORTNAME=      openttd
 CATEGORIES=    games
diff -u /usr/ports/games/openttd.orig/distinfo /usr/ports/games/openttd/distinfo
--- /usr/ports/games/openttd.orig/distinfo      2010-09-30 00:50:23.537887246 +0200
+++ /usr/ports/games/openttd/distinfo   2010-09-30 00:55:43.648371399 +0200
@@ -1,3 +1,3 @@
-MD5 (openttd-1.0.3-source.tar.bz2) = cff60c624913a491ed3c91474e845722
-SHA256 (openttd-1.0.3-source.tar.bz2) = f52f2381c678de024d26ee465c8203323eb3484300c4dc182c0d68c439ee8c57
-SIZE (openttd-1.0.3-source.tar.bz2) = 5395672
+MD5 (openttd-1.0.4-source.tar.bz2) = e11e81bee589c04abd3cc4f3fafcb2b1
+SHA256 (openttd-1.0.4-source.tar.bz2) = 2c6b1c314f6d5e2d72543cad78769d47837d59b69c98c4356d0076498db6426c
+SIZE (openttd-1.0.4-source.tar.bz2) = 5684460

When finished there is a way to test a bunch of things concerning the port. The command port test will check a lot of things while building the port, and output warnings if something is wrong. This is the first run after updating OpenTTD to 1.0.4:

[tykling@tyklappy /usr/ports/games/openttd]$ port test
===> Validating port with portlint
WARN: Makefile: [50]: possible direct use of command "false" found. use ${FALSE} instead.
WARN: Makefile: CFLAGS/CXXFLAGS are not needed in CONFIGURE_ENV as they are already added there in
Use of uninitialized value $cflags in pattern match (m//) at /usr/local/bin/portlint line 2103.
FATAL: Makefile: CXXFLAGS are clobbered in CONFIGURE_ENV.  Alter CXXFLAGS in the Makefile with CXXFLAGS+=... instead
WARN: Makefile: only one MASTER_SITE configured.  Consider adding additional mirrors.
WARN: /usr/ports/games/openttd/work/pkg-message: possible use of absolute pathname "/usr/local/share/ope...".
WARN: /usr/ports/games/openttd/work/pkg-message: possible direct use of "/usr/local" found. if so, use ${PREFIX} or ${LOCALBASE}, as appropriate.
1 fatal error and 5 warnings found.
Error validating port

Well, that won't do. The WARNINGS are one thing, but the FATAL needs to be fixed. I am in no way an expert in C and Makefiles, so fortunately a friendly person was kind enough to help me figure out what to change in the Makefile to make the FATAL (and a couple of the WARNINGS) go away.

NOTE WELL: The tests performed here are not extensive enough to handle all edge cases, and as such, these messages are not guarenteed to be errors. The recommendations from the port test command should never be followed blindly. If I am not certain what a proposed change does, I either leave it alone or get help from someone smarter than me. If I am certain a port works even though port test fails with a FATAL error, the check can be disabled before submitting with the -L option to port submit.

When port test succeeds in building the port, it is ready to be submitted. This is as easy as typing:

[tykling@tyklappy /usr/ports/games/openttd]$ port submit -m update -d .orig

The command creates a diff between the original and the updated port, and fills out a PR that is ready to be submitted. The PR is shown in vi and I haven't had to change anything in it. I just press :wq and answer s for send when the program asks me if I want to submit the PR.

Additional considerations

The tests performed by port test are as mentioned earlier not as thorough as they could be. The more correct way to test an updated port is to use /usr/ports/ports-mgmt/tinderbox as mentioned in the [FreeBSD Porters Handbook]. I'll have to try it out and update this article when I do.

--Tykling 01:21, 30 September 2010 (UTC)