The MacPorts system is composed of three Tcl libraries:
MacPorts API - MacPorts public API for handling Portfiles, dependencies, and registry
Ports API - API for Portfile parsing and execution
pextlib - C extensions to Tcl
The code for the Port API is located in
base/src/port1.0
. The Port API provides all the
primitives required for a Portfile to be parsed, queried, and executed.
It also provides a single procedure call that the MacPorts API uses to
kick off execution: eval_targets
. The port Tcl library supplies these
procedures, all of which are generated at run-time using the
options
procedure in portutil.tcl.
The macports Tcl library loads the Portfile into a sub-interpreter, within which all port-specific code is run. This process ensures that there will never be pollution of the Tcl space of other ports, nor the MacPorts libraries, nor the calling application.
Portfiles are executed in a Tcl interpreter as Tcl code (and not truly parsed strictly speaking), so every Portfile option must be a Tcl procedure.
The Ports API performs the following functions:
Manages target registrations. All targets register themselves with the Port API. Accordingly, the Port API creates pre-/post-/main overrides for each of the targets.
Option/Default handling. All Portfile options (name, version, revision ...) are registered by targets. The Port API creates procedures for these options, and sets up the complex variable traces necessary to support option defaults.
Executes target procedures, including the pre/post/main routines.
Manages a state file containing information about what variants were specified and what targets have run successfully.
Provides essential Portfile Tcl extensions (reinplace, xinstall, etc).
Provides simple access to the ui_event mechanism by providing the various ui_ procedures (i.e., ui_msg, ui_error).
The code for the MacPorts API is located in
base/src/macports1.0
. The MacPorts API provides a
public API into the MacPorts system by providing simple primitives for
handling Portfiles, dependencies, and registry operations, and exports
the MacPorts API for the port command line utility,
or any other. The API has very little information about the contents
Portfiles; instead, it relies entirely upon the port
Tcl library. By keeping the high level API simple and generic, revisions
to the underlying ports system will not necessarily require a revision
of the high level MacPorts API.
The MacPorts API is also responsible for loading user specified
options into a sub-interpreter to be evaluated by the ports API. In that
case it sets the variable name in the sub-interpreter and adds the
option to the sub-interpreter's global array user_options(). User
options are passed as part of the call to mportopen
.
The MacPorts API performs the following functions:
Dependency support.
This is implemented in a highly generic fashion, and is used throughout the system. The dependency functions are exported to the Port API, and the Port API uses them to execute targets in the correct order.
Dependency processing.
Software dependencies are handled at this layer using the dependency support layer.
UI abstractions.
UI Abstractions are handled at this layer. Each port action is provided a context, and a mechanism for posting user interface events is exported to the Port API (ui_event).
Registry management routines.
Manages the SQLite port registry in
${prefix}/var/macports/registry/
. See also
Section 6.5, “The MacPorts Registry”.
Exports the MacPorts API for use by client applications.
The following routines are defined.
mportinit:
Initializes the MacPorts system.
Should be called before trying to use any other
procedure.
mportsearch:
Given a regexp, searches the
PortIndex
for ports with matching
names.
mportopen:
Given a URI to a port, opens a
Portfile and returns an opaque handle to it.
mportclose:
Given a port handle, closes a
Portfile.
mportexec:
Given a port handle, executes a
target (e.g., install).
mportinfo:
Given a port handle, this returns
the PortInfo array (as a flat list of array elements). This is a
little tricky and unstable and only used by
portindex.
mportdepends:
Given a port handle, returns a
list of ports upon which the specified port depends.
For an example of the MacPorts API, when one executes port search cm3, the port utility:
Calls the mportsearch
function to find all ports
containing “cm3”.
Returns Tcl array(s) containing data from the
PortIndex
: port name, version, revision,
variants, etc.
Formats the list of arrays in the standard viewing format.
For another MacPorts API example, when one executes port install cm3, the port utility:
Calls the mportsearch
function to find the first
port that matches the name “cm3”.
Calls the mportopen
function to open the
port.
Calls the mportexec
function to execute the
install target in the port.
Calls the mportclose
function to close the
port.