Update from Ports removes dependency data
Luke Dean
LukeD at pobox.com
Tue Apr 4 23:36:25 UTC 2006
On Mon, 3 Apr 2006, wc_fbsd at xxiii.com wrote:
> I recently noticed if I update a package from ports, the package manager
> looses the dependency data for the package. eg: updating old version of
> gettext
>
> # pkg_info -R gett*
> Information for gettext-0.14.5_1:
> Required by:
> libgpg-error-1.1
> libgcrypt-1.2.2
> gnutls-1.2.9
> p5-gettext-1.03
> gmake-3.80_2
>
> [[[ update from ports - make ; make deinstall ; make reinstall ]]]
>
> # pkg_info -R gett*
> Information for gettext-0.14.5_2:
>
> Is my procedure incorrect, or is this normal behavior?
>
> -Thanks, Wayne
This is normal. It's what makes upgrading those ports that are required
by lots of other ports so difficult.
Dependency information is version-specific.
If you run "pkg_info -r libgpg-error-1.1" you'll find that it still
depends on gettext-0.14.5_1 until you rebuild libgpg-error.
Last weekend I wrote some scripts to help me deal with stale dependencies
like this. My code is such an ugly perl hack that I'm ashamed to post it,
and my algorithm isn't really airtight, but I'll give you the algorithm
I'm using. The script just uses pkg_info, pkg_version, and grep.
1) I build a dependency hash by parsing the output of "pkg_info -ra". The
keys to the hash are the names of the installed ports with the versions
stripped off. The right-hand-side of the hash are the lists
of dependencies with the version numbers stripped off.
2) I build what I call a "full" dependency hash from the dependency hash I
built in step 1. I do this by recursively getting the dependencies for
every dependency in the hash from step 1. The result is a hash just like
the one from step one, only with the list of dependencies expanded to show
all of the dependencies' dependencies, etc. all the way down the the ports
that don't require anything.
As I'm building this, I also count how many levels down I have to recurse
to build each entry and remember this number for each port. I call this
number the "degree" for the port. To avoid rebuilding the same ports over
and over again, ports with high degrees should be built after ports with
low degrees.
3) I get a list of everything I want to upgrade by parsing the output of
"pkg_version -qL "="". That shows me which of my installed ports are not
the same version as the port in the ports tree. Usually I'll want to
upgrade those ports.
4) I add to that list all of the ports that have outdated dependencies. I
get that list by parsing "pkg_info -ra" for each port and checking
"pkg_info -e " for each dependency to see if it exists. If it doesn't
exist, then I assume I need to upgrade the requiring port. Many times the
only thing I gain by doing this is an update to the dependency information
in the ports database, but sometimes (like with the recent libiconv
upgrade) it's truly necessary. I don't know of any way to
programmatically gauge the importance of an upgrade - all I can tell is
whether the version of the port listed as a dependency still exists.
5) I take the list of ports that I built in step 3 and 4, look them up in
the "degrees" hash I built at the end of step 2, sort the output by the
degree I determined in step 2 and then print the list.
Then I use that list to tell me which ports that I should consider
rebuilding and in what order.
I used this script to help me upgrade all the ports on a system that
hadn't been upgraded in about six months. It worked pretty well. It's
not always perfect, though. Dependencies can change dramatically between
versions sometimes, and sometimes a port will depend on a port that
doesn't exist in the database (like "linux_base") but this approach is far
far better than me trying to do a big upgrade of several ports by hand
when I can't immediately see the dependencies. It also gives me the
freedom/power to choose to build the ports I want to build, and to build
them with the options I want to use.
More information about the freebsd-questions
mailing list