- 论坛徽章:
- 0
|
The Ports System
Then, there's the second category; those programs which are add-on packages. In the BSD world, this is usually called the "ports system". That name is chosen for a specific reason.
Traditionally, when you wanted to run a package on your system, the first thing you had to do was compile it. And often before you could compile it, you'd have to fiddle with it. Your system would require different header files. Sometimes, manifest constants would be different. Sometimes, you'd even need to rewrite parts of it from scratch, because of basic assumption that didn't hold on your system.
Or, in other words, you'd have to "port" it to your OS, and/or to your specific system. The basic intent of the ports system is to do all that "porting" stuff for you. That it also automates building and installing, and provides packaging services (for things like 'uninstall') isn't as well reflected in the name.
But as with many things, it grew past its name into the beast it is today. The current FreeBSD ports collection has close to 10,000 packages in it (this number will, of course, be outdated quickly, but that's the nature of development). The most obvious feature of ports is that it builds things from source all the time, rather than just install pre-built binaries. This, it seems, is another one of those blatant differences that trip people up when trying to look at BSD from a Linux perspective. That it builds from source is just a side effect, it's not the primary purpose or difference. Binary packages are also available; in fact, binary packages are built from the ports tree!
Now, it's true that most Linux users install binary packages, and most BSD users install by building from source. Partly, that's a result of the tools; the ports system is designed around the concept of building from source, with the ability to make and install binary packages being something of an afterthought, while Linux packaging like RPM and dpkg and such are designed around the concept of installing a binary package, with building from source as an afterthought. Some of this is historical; binary packaging historically isn't a predominant theme in Unix systems, as I mentioned earlier. For that matter, packaging itself is a more recent thing. Traditionally, you'd deal with uninstalling and such manually.
Gentoo is a Linux distribution gaining in prominence these days. One of its big selling points is its portage system, which is often considered very similar to BSD ports. Perhaps most visibly, in that it compiles from source. That avoids a lot of the problem of binary packages. I've never used it myself, but the impressions I've gotten from information I've seen on it, and people I know who have used it, is that it's taken some good ideas from everyone, and smooshed them together. It'll be very interesting to see how it progresses and matures over the next few years. It's still much more Linux than BSD, but it may well be the closest to the BSD style of the major Linux distributions.
Now, there are advantages to pre-compiled binaries; mostly time (as in much less), and usually it'll take a lot less space to install a pre-compiled package, than it would to compile the package. There are also advantages to building from source, like avoiding all sorts of library versioning ugliness (my personal pet peeve with binary packages). You can install binary packages on Linux or BSD; you can build from source on Linux or BSD. But the users seem to be biased differently, because the systems are biased differently, because the users are biased differently... it all dovetails.
I guess what's important here is to realize that the difference between ports and RPM's isn't just that ports compile and RPM's just install. Ports are designed to cover the full range of bits and pieces of installing stuff; encoding and tracking and installing dependencies, packaging, installing and deinstalling, local changes necessary to build on your system, compile-time configuration tweaks... all those things. An RPM is just a binary package. If you want to auto-install dependencies, you have to have a higher-level tool like urpmi or apt-get to do it. And, since it's binary, you have to deal with library versioning conflicts, or missing compile options, or any of the other limitations you incur by not building it on your own system.
And further, ports, like the rest of the BSD systems, are centralized. The "ports tree" is really just a big directory tree with a bunch of categorized directories, each containing a Makefile with some variable definitions, a checksum file, a packing list, and various other possible things. Each of those directories represents a single program, which is described by the files present. A bunch of black magic happens behind the scenes so that when you run make, it finds and downloads the distribution file from wherever it is, makes any changes or patches necessary, recursively finds and installs all the dependencies, calls GNU configure or imake or whatever preparation programs are necessary with the right options, starts the compile with the right options, etc.
But all those files in that big directory tree are maintained by the FreeBSD project itself. When somebody wrote KDE, for instance, it didn't magically appear in ports trees everywhere. Somebody had to write all the necessary "glue" to build a port for it, then commit the files into the FreeBSD CVS repository so it would be in the ports collection. So again, there's some level of assurance that it works with other things in the ports collection. Any dependencies it has will be there, because it can't declare a dependency on something not in ports.
Things break, of course. Maybe a dependency will have its main site disappear, so nobody can download the source file and start to install it. Maybe a new version of some third program will break a program, which will keep other things that depend on it from working. So of course it doesn't solve all the problems. But the incidence of "I want A, which requires B, which I can't find" is a lot less than it is with such essentially decentralized systems like RPM's turn out to be.
For more detailed information (as always), see the section in the handbook about ports.
Release it!
Now we've got a working understanding of the dichotomy between the 'base system' and the 'ports tree', which I think really trips a lot of Linux users up. Let's talk a bit about releases and upgrading.
Release Engineering
The BSDs all keep the system under revision control; all the free BSDs use CVS. Revision control (in extremely brief) is a process by which editing a program means checking out a file or group of files, making the changes, then checking in the new versions, along with a message describing the change. A full history of all changes is kept in the revision control system, so you can view a history of the changes, check out an old version, look at the differences between arbitrary versions, etc.
All the BSDs provide public access to their CVS repositories in one way or another; generally through anonymous CVS, or CVSup checkout or mirroring, or often both. That means that, as a user, you can see exactly what changes happened when, who did them, and why they did them. You can also always get your hands on the latest changes (within a few hours, anyway, depending on mirroring strategies). All of the free BSDs have mailing lists that you can subscribe to and see the changes as they're made. In fact, they all have web frontends as well; you can poke around FreeBSD's entire source tree online at http://cvsweb.freebsd.org/src/, and see all the history of every file.
Linux, historically, hasn't used any version control for the kernel. Somewhere in mid-2.4 days the kernel began being kept in a public BitKeeper repository. Many of the other utilities use revision control, but since they're all developed separately, there isn't any central place you can go to to look through the changes. So it's sometimes hard to get a historic picture of even any one part; to so do for a whole distribution is practically impossible.
Note: There's been some contention about the last paragraph. While many developers have used CVS for parts of the kernel, available information says that Linus never used it for the kernel, thus the whole thing wasn't in a coherent version control system until the move to Bitkeeper. See this paper for details.
This leads to a lot of differences. In a very real sense, BSD systems are constantly developed; I can always update my system to the absolute latest code, irrespective of "releases". In Linux, that doesn't really have as much meaning, because the release process is very different. I think the most appropriate verb for a Linux release is "assembled". A Linux release is assembled from version A.B of this program, plus version C.D of this program, plus version E.F of this program... all together with version X.Y.Z of the Linux kernel. In BSD, however, since the pieces are all developed together, the verb "cut" makes a lot more sense; a release is "cut" at a certain time.
Linux releases kernels in two parallel lines (well, often more than 2, but we're simplifying); a version with an odd minor release number, as a "development" version, and a version with an even minor release number, as a "production" version. The BSDs also have "development" and "production" tracks, but they're handled rather differently.
CVS, like most version control systems, has the concept of "branches". It's easy to understand, but somewhat difficult to explain. Basically, when you "branch" a file or a set of files (or a whole directory tree), you create a new version of the file which exists in parallel with the primary version. When you make changes to the primary version, it doesn't affect the branched version. And you can make changes to the branched version without affecting the primary.
In FreeBSD, there's usually 2 active development lines; one called "-CURRENT", which is the development version, and the other called "-STABLE", which is the production version. Both, of course, are under development, and both have some attempt to be made to keep them usable. -STABLE, as a rule, gets bug and security fixes, but only gets new features and such that are well tested, usually by a stint in -CURRENT first. -CURRENT gets new features, big architectural changes, and all those sorts of new development stuff. It should be noted that the naming of the branches doesn't necessarily mean what it seems to; while -STABLE usually is "stable" as in "robust", it isn't always. The term "stable" refers more to the fact that the codebase itself doesn't have major changes made to it.
In the Linux world, Debian does a similar thing with their release engineering. They have a "stable" release , which mostly only gets major bugfixes. This is roughly the same as a FreeBSD -RELEASE. Then, they have a "testing" release, which gets more in the way of new features, but only after they've been tested for a while and don't seem to have any major problems. This is similar to FreeBSD's -STABLE branch. And, they have an "unstable" release, which is where new development happens, new features are developed, and new versions of packages come in. This, then, corresponds to FreeBSD's -CURRENT branch. (Note: I don't really know Debian's release process that well; this is my understanding of it, which could be completely wrong. Hopefully, someone will send me correct info if I am.)
I repeat, because it's important; these are BRANCHES. Not releases. Branches. They're not points; they're constant streams of development, changing from day to day and hour to hour and often minute to minute. If I grab -STABLE now, and -STABLE tomorrow, they'll likely be different. However, because it's under revision control, I can say something like "Give me -STABLE as of 11:30pm on October 13th, 2003", and always get the same code back.
In fact, that's all a release is; a snapshot at some point along a branch. For instance, what we call "2.2.6-RELEASE" is actually just a snapshot of what the 2.2-STABLE branch looked like on March 24, 1998. On March 25, it was called "2.2.6-STABLE", even though practically nothing had changed. And it kept being called "2.2.6-STABLE" until July 21, when a new snapshot was called "2.2.7-RELEASE". And so on, down the line.
Now, you'll note that there's numbering on these branches too. We've got 2.1-STABLE, and 2.2-STABLE, and 3-STABLE, and 4-STABLE. To understand that, we'll look at where these branches come from. At one point, there was 3-CURRENT. In CVS terms, that was the HEAD of the tree; not a branch, but the main line. Eventually, there was a time when it was decided to start making this branch production-ready, so a tag was laid declaring a certain point as "3.0-RELEASE". At that time, the 3-branch was still -CURRENT; 2.2 was -STABLE. As we approached 3.1-RELEASE, it was decided that it was time to create the 3-STABLE branch. So, a branch was created and called "3-STABLE", and -CURRENT was renamed to "4-CURRENT".
The same thing occured (roughly) when 4 became -STABLE and -CURRENT became 5, and the same will happen again when 5 becomes -STABLE and -CURRENT moves on to 6. Sometimes only the x.0 release is cut before the branch becomes -STABLE, sometimes .1 and even .2 are. 5.0-RELEASE is a snapshot of 5-CURRENT. So's 5.1-RELEASE. So's 5.2-RELEASE. At the current time, the plan is for 5.3-RELEASE to be the first -RELEASE off the to-be-created 5-STABLE branch, though that may change. All depends on the state of the tree.
You'll note, of course, that even though 4.x or 4-STABLE is still (for the moment) the "production" stream, that 3-STABLE still exists (though it hasn't gotten any changes in a long time). For that matter, 2.2-STABLE and 2.1-STABLE are still around too, though they haven't gotten any changes in even longer. Conventionally, -STABLE without a number, then, refers to the latest -STABLE branch. Really, the only time there's any confusion is when a new branch has just been created, so a lot of people are still on the old one. And then you can just use the number to make it unambiguous.
Also, note that 5.1-RELEASE happened before 4.9-RELEASE. And 5.0-RELEASE was before 4.8-RELEASE. This is the time, when one branch is in its ending days, and another branch is in its starting days, when things get really confusing. It's then that the -CURRENT and -STABLE difference comes into place. To make a very rough analogy, 5-CURRENT is like Linux 2.5, while 4-STABLE is like Linux 2.4. But, before that, 4-CURRENT was like Linux 2.3, and in the future, 5-STABLE will be like Linux 2.6. It's not a perfect analogy, of course, partly because we're talking about the full system with all its pieces, not just the kernel. But it's close enough to get the idea.
So. What does that all mean? Not much, perhaps. But, with that background, perhaps you can get a better feel for what happens when, and what the branch names and release numbers mean.
Some more information on -CURRENT vs -STABLE is available in the FreeBSD handbook. There's also an article in the documentation about the release engineering process.
Releases get old
So, now you have a better understanding of where releases come from, and what this -CURRENT and -STABLE nonsense is about. But all releases get old eventually, and need to be brought up to date. So, let's move on to upgrading. |
|