Date: Tue, 4 Oct 2005 13:58:14 +0200 From: Csaba Henk <csaba-ml@creo.hu> To: Eric Schuele <e.schuele@computer.org>, freebsd-questions@freebsd.org Subject: Re: Determining what a port will install... (more than pretty-print-*) [Soln] Message-ID: <20051004115814.GA99762@beastie.creo.hu> In-Reply-To: <43416280.80403@computer.org> References: <43416280.80403@computer.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Oct 03, 2005 at 11:55:28AM -0500, Eric Schuele wrote: > Hello, > > Some time back I posted a question regarding how to determine what > ports/packages would need to be installed on my machine when I install a > new (new to the local machine) port. > > For example, if I do not presently have openoffice installed... what > will get installed when I 'make install clean' it? Note that I want the > differences between what is needed to build/run the port and what is > already present on the machine. > > At the time no one responded with a clear way to do this... so I finally > had a few minutes to write a script to do it for me. I thought someone > else might find it useful... So I'm posting it here for comments and > thoughts (be gentle, I'm new to awk). Here is an improved/spoiled (decide by yourself) version. I aimed to sport a more orthogonal design and avoid some gotchas I run into (see comments in awk code). -------------------------------- #! /bin/sh # Script to determine the differences between what is necessary for # a port, and what is already present on the local machine. awkprgt='{ count = 0 pkgs = "" for(i=5; i<=NF-2; i++) { pkg = $i # the "if" is here to hack it around when you get: # This port requires package(s) "" to build. if (pkg != "\"\"") { if (index(pkg, "\"") == 1) {pkg = substr(pkg, 2, length(pkg)-1)} if (index(pkg, "\"") > 1) {pkg = substr(pkg, 1, length(pkg)-1)} if ( system("pkg_info -e " pkg) == 1) { pkgs = pkgs " " pkg count++ } } } if ( count ) { print "You need the following (%s) perequisites:" print pkgs } else { print "All (%s) prerequisites are present." } } END { # triggered, eg., by audio/artswrapper (on my box, at least) if( ! FNR) { print "Bogus (empty) %s dependency information" } } ' awkit() { # Resolve "%s"-s via sed is a blunt hack # but good enough here and thus we don't have # to care about the number of occurrences awk "`echo "$awkprgt" | sed s/%s/$1/g`" } make pretty-print-build-depends-list | awkit build make pretty-print-run-depends-list | awkit run -------------------------------- Alas... while I was making these changes, I succeeded to recall why I abandoned my earlier attempt to put together a script which fulfils this (highly desired) functionality. Because all such scripts are fundamentally broken. When make decides which ports to pull in, it doesn't only use the flat data of build and run dependencies, but uses its full Turing complete computing power. Eg., what happens when a port needs a postscript interpreter? Should it use the AFPL or the GNU edition as a dependency? Of course, doing a favor toward one of them (and taking away user's choice) is unacceptable. So what happens is that make directly checks whether the gs executable is present. See, for example, print/gv. Your script's output will include ghostscript-gnu-7.07_13 both as a build and a run dependency. Yet when I type make, my ghostscript-gnu-7.07_12 installation will be happily utilized as the following output snippet shows: => Checksum OK for gv-3.6.1.tar.gz. ===> Patching for gv-3.6.1 ===> Applying FreeBSD patches for gv-3.6.1 ===> gv-3.6.1 depends on executable: gmake - found ===> gv-3.6.1 depends on executable: gs - found ===> gv-3.6.1 depends on shared library: Xaw3d - found ===> gv-3.6.1 depends on shared library: X11.6 - found ===> Configuring for gv-3.6.1 The approach taken by FreeBSD's ports is to have more flexibility but less predictability, and now we have to live with it. Maybe the Gentoo guys are the ones who succeeded to find the proper balance between these two quantities -- they made up a mini-markup-language for denoting dependencies, which is clever enough to cover all cases but it's still just an easy to parse flat data. One solution for FreeBSD could be digging deep into the make backend of the ports framework and insert the necessary hooks everywhere to produce a reliable dry-run. Or severely refactor the whole ports framework and switch to Gentoo style dependency handling. This won't happen any soon IMHO as ports API changes should be pushed through all ports... (OFF: to have a bit of bitter laugh, I think Gentoo's portage suffers from a fundamental design flaw: they can't tune installation prefixes (which would be necessary to make it an acceptable cross platform 3rd party package manager, akin to pkgsrc, but it would have other uses, too). This is again such a thing which can be changed only by rewriting all of their e-builds.) Regards, Csaba
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051004115814.GA99762>