Topic: Creating packages from installed ports in FreeBSD
Installing from ports often gives you more up-to-date and optimized software than does installing from packages, but ports are compiled from source. There may be many situations where that is not optimal, for example, a heavily loaded server or a slow machine.
If you are fortunate enough to have a fast machine that isn't in production, you can also install ports on that machine. Then, you can build a package from the port and add it to the slow machine or heavily loaded server with pkg_add.
There are many other circumstances where you might want to do this. For example, recently I was having a somewhat obscure problem with samba. I finally found the problem on their buglist, and was able to patch the samba code to make it work. To avoid having to do that on each machine we have that uses samba, I then created a package, which I was easily able to install on each machine. Otherwise, I would have had to do make extract then patch the source code on each box.
The technique is quite simple. Suppose I have the screen utility on the fast workstation. I also want to put it on a busy server.
So, first, I need the version number that is installed on my workstation.
ls /var/db/pkg | grep screen
It gives me back the answer (as of 17 February, 2006)
Now, I want to create the package
Oddly enough, the program that creates a package is called---yup, pkg_create.
I use the -b flag to create the package.
pkg_create -b screen-4.0.2_3
I will then be returned to a command prompt. Assuming I have write permission to the directory I was in when I ran the command, the package will be created there. Now, doing ls | grep screen will show me
I can now ssh it over to the server, and then, on the server, as root or with root privilege
In reality, I'd be using tab completion, and as long as I was in the directory of the package, I would do pkg_add scre and hit the tab key.
Sometimes, packages have dependencies that have to be kept up to date. No problem. The pkg_create command has the -R flag. If you use it, it will also make packages for each dependency. The -R flag has to come before the -b flag. For example, if I do pkg_create -bR <pkgname> I get an error message, with an exclamation point no less, saying Can't find package 'R' installed.
So, if I wanted to create a package for w3m which has boehm as a dependency
pkg_create -Rb w3m-0.5.1_3
it will create a w3m package and a boehm package.
These packages can also be used with portupgrade. By default, if you ask portupgrade to use a package if one is available (by use of the -P flag) it first looks in /usr/ports/packages/All. You might have to create that directory if it doesn't exist. However, if I move my screen package into the other machine's /usr/ports/packages/All directory, then, on the second machine type
portupgrade -P screen
it will look in /usr/ports/packges/All, see the screen package and install the program from the package. This saves compiling time and resources.
Lastly phoenix has mentioned that if using portupgrade, it's always a good idea to use the -b flag. Most of us, including myself, find this out the hard way. With portupgrade, the -b flag creates backup packages of the program being installed or upgraded. Then if the newly upgraded program doesn't work, you can simply deinstall it and replace it with the older version's package that you cleverly created with portupgrade's -b flag.
(You could have also used the pkg_create -b to create a backup package BEFORE doing portupgrade, but that seems a waste of effort--portupgrade's -b flag does it for you. The point is that both will create a package of the program)
If you fail to do this, and the upgraded program doesn't work, then usually, your only option is to use the portdowngrade utility, which, although not difficult, takes much more work than simply deleting the newly upgraded, not working properly package and replacing it with the older version from a package.
It can save an enormous amount of time, especially if you're installing a new machine. Rather than having to download and compile everything, assuming they're running the same version of FreeBSD you can simply create packages from an existing machine and install them with pkg_add.
Obviously (hopefully) the two machines should be running the same version of FreeBSD. Packages created on a 6.x machine will seldom work on one running 5.x and vice versa.
Last edited by scottro (2006-02-17 19:59:39)