PortGroups are simply include files for portfiles. They can define as much or as little as a portgroup author feels is necessary to provide a set of definitions or behaviors common to a group of portfiles, in order that those portfiles can be expressed as simply as possible with minimum redundancy.
See the following folder for PortGroup definitions:
${prefix}/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/_resources/port1.0/group/
or if you prefer directly in GitHub .
A sample listing follows:
%%
ls -1 /opt/local/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/_resources/port1.0/group/
active_variants-1.1.tcl apache2-1.0.tcl app-1.0.tcl archcheck-1.0.tcl bitbucket-1.0.tcl cmake-1.0.tcl cmake-1.1.tcl compiler_blacklist_versions-1.0.tcl compilers-1.0.tcl conflicts_build-1.0.tcl crossbinutils-1.0.tcl crossgcc-1.0.tcl cxx11-1.0.tcl cxx11-1.1.tcl debug-1.0.tcl elisp-1.0.tcl github-1.0.tcl ...
The requirements of a minimum portfile using a portgroup varies by portgroup. The sections below devoted to each portgroup (or, for portgroups not documented there yet, the comments in the header of the portgroup file itself) should provide guidance on how each portgroup is used. Prospective MacPorts developers are also encouraged to examine existing portfiles that use these portgroups.
The github
portgroup allows for efficient porting of
software hosted on GitHub.
This portgroup greatly simplifies the porting of software hosted on
GitHub. Provided a GitHub repository author follows common GitHub
practices, a port can be almost fully configured simply by declaring the
repository coordinates. The github
portgroup is indeed
capable of configuring, amongst other things:
The port name
.
The port version
.
The distfiles
(if the project uses GitHub
releases).
The livecheck
parameters.
The main port configuration is triggered by the usage of the
github.setup
keyword:
PortGroup github 1.0 github.setup author project version [tag_prefix]
By default, the port name
will be set to the GitHub project
name (project
) and version
will be set to the
GitHub project version
. The port name can be overridden by
using the name
keyword.
The tag_prefix
is optional, and it's used to specify a prefix
to use when constructing the tag name. If, for example, the project uses
tags such as v1.0.0
, then the tag_prefix
should
be set to v
, as in the following example:
github.setup author project version v
GitHub, and as a consequence the github
portgroup, offers
multiple mechanisms to get a distfile:
The default behaviour of the portgroup is using GitHub automatically
generated distfile from a git
commit or tag. However, the
best practice should be using a GitHub release.
The default behaviour of the github
portgroup is leveraging
GitHub's ability to create a distfile from a git
tag or
commit. In this case, the distname
is irrelevant and should
not be set.
If the project's developers do not tag their releases, they should be
encouraged to do so. Until they do, or in the case in which an untagged
development version has to be used, port maintainers have the possibility
of specifying a git
commit hash and manually set the
version
field. If the project does not assign version
numbers the port maintainer has to define one. Such versions typically
format the date of the chosen commit using the YYYYMMDD
pattern. If, for example, the port maintainer decides to use a changeset
with the hash 0ff25277c3842598d919cd3c73d60768
, committed on
April 1, 2014, then the following would be used:
github.setup someone someproject 0ff25277c3842598d919cd3c73d60768 version 20140401
The github
portgroup allows maintainers to easily configure
the distfiles when the project uses GitHub releases. A release is the
best distfile candidate, and project maintainers should be encouraged to
use them. To enable this feature, the following keyword must be used:
github.tarball_from releases
By default, the github
portgroup sets distname
to:
distname ${github.project}-${github.version}
However, GitHub does not enforce any rule for release distfiles, so port
maintainers may need to override the distname
as they would
do for other ports.
Older projects use the discontinued downloads service. New GitHub downloads can no longer be created, but old ones are still available.
If the project doesn't have GitHub releases but does have GitHub downloads, they can be used using the following keyword:
github.tarball_from downloads
Since GitHub doesn't enforce any naming rules for downloads, the portgroup
can only provide a sensible default value for distname
, which
can be overridden if necessary.
Further still, many Github projects have automatically-generated archive
URLs that can be used for downloading distfiles. This can be enabled via
archive
as follows:
github.tarball_from archive
If the project uses git
submodules, some projects' tag- or
commit-based distfiles will not contain all the necessary files. Once
again, the best distfile candidate (if available) is a distfile from
GitHub releases, as described in the previous sections. However, in the
case a project doesn't provide any other alternative, a project using
submodules can be successfully retrieved by fetching the sources using
git
and then using a post-fetch
to initialize
the submodules:
fetch.type git post-fetch { system -W ${worksrcpath} "git submodule update --init" }
PortGroup gnustep allows for efficient porting of GNUstep-based open source software using the GNU objective-C runtime that defines options for the configuration, build, and destroot phases, and also defines some values for GNUstep-based software. A minimum Portfile using the gnustep PortGroup class need only define the fetch and the checksum phases.
Portfiles using the gnustep PortGroup allow for port authors to set the following keywords in addition to the general Portfile keywords.
An associative array which specifies the sub-directories relative to ${worksrcpath} and the SHARED_LD_POSTFLAGS variables to be added to GNUmakefile.preamble in those sub-directories. This helps making the patching process easier on Darwin.
Type: optional
Default: none
Example:
platform darwin { array set gnustep.post_flags { BundleSubDir "-lfoo -lbar" } }
Define the gcc compiler to use when compiling a port.
Type: optional
Default: gcc-mp-4.2
Example:
gnustep.cc gcc-mp-4.3
Many GNUstep packages include a Documentation sub-directory that is not built by default. Enabling this variant builds and installs the included documentation.
Type: optional
Example:
%%
port install gnustep-gui +with_docs
PortGroup gnustep supports both the traditional gnustep file layout and the new fhs file layout. However, a given ported application does not necessarily support both. The Portfiles have access to many procedures to handle these two layouts:
Sets GNUSTEP_MAKEFILES according to the FilesystemLayout
Sets DYLD_LIBRARY_PATH and PATH for the gnustep FilesystemLayout
Returns true (1) if current file layout is gnustep
Sets GNUSTEP_SYSTEM_LIBRARY according to the FilesystemLayout
Sets GNUSTEP_LOCAL_LIBRARY according to the FilesystemLayout
Portfiles using PortGroup gnustep do not need to define the following variables:
Default: gnustep
Default: http://www.gnustep.org/
Default: gnustep:core
Default: gnustep-core
Default: no
Default: DYLD_LIBRARY_PATH PATH
Default: CC=gcc-mp-4.2 GNUSTEP_MAKEFILES
Default: gnu
Default: DYLD_LIBRARY_PATH PATH
Default: messages=yes
Default: DYLD_LIBRARY_PATH PATH
Default: messages=yes
The golang
PortGroup allows for efficient porting of
Go-based open source software.
This PortGroup greatly simplifies the porting of software written in Go, especially when the software and its dependencies are hosted on GitHub or Bitbucket. Provided a project author follows common Go packaging practices, a port can be almost fully configured simply by declaring the package identifier.
In particular, Go has strict requirements relating to the arrangement of code on the filesystem (GOPATH). This PortGroup handles the construction of the GOPATH for you.
The main port configuration is triggered by the usage of the
go.setup
keyword:
PortGroup golang 1.0 go.setup domain/author/project version [tag_prefix] [tag_suffix]
By default, the port name
will be set to the package name
(project
) and version
will be set to the project
version
. The port name can be overridden by using the
name
keyword.
The tag_prefix
and tag_suffix
are optional, and
are used to specify a prefix/suffix to use when constructing the tag name.
If, for example, the project uses tags such as v1.0.0
, then
the tag_prefix
should be set to v
, as in the
following example:
go.setup domain/author/project version v
When the domain
is either github.com
or
bitbucket.org
, the appropriate PortGroup will be applied and
set up automatically. See those PortGroups' documentation for details.
Projects hosted elsewhere can be used, but require additional manual setup.
The PortGroup provides a keyword to facilitate listing dependencies:
go.vendors
. Supply a list of vendor package IDs, their
versions (git commit hashes, labeled "lock" as in "lockfile"), and their
checksums as follows. The packages and their versions can usually be
found in a lockfile (e.g. Gopkg.lock
,
glide.lock
) in the upstream code. All checksum types
supported by the checksums
keyword are
supported here as well.
go.vendors example.com/dep1/foo \ lock abcdef123456... \ rmd160 fedcba654321... \ sha256 bdface246135... \ size 1234 \ example.com/dep2/bar \ lock abcdef123456... \ rmd160 fedcba654321... \ sha256 bdface246135... \ size 4321
Note that go.vendors
cannot be used with dependencies hosted
outside of GitHub and Bitbucket. Such dependencies must be handled
manually.
After the extraction phase, the vendor packages will be placed alongside the main port code as appropriate in the GOPATH.
By default this PortGroup runs go build
from the
${worksrcpath}
. Assuming this results in a binary with
the same name as the project, and that there are no other files to
install, the following is sufficient for the destroot phase:
destroot { xinstall -m 755 ${worksrcpath}/${name} ${destroot}${prefix}/bin/ }
Please modify as appropriate for each individual port.
When the golang PortGroup is declared within a Portfile, the following variables are provided during port install.
Default: ${prefix}/bin/go
The Go binary location.
The package identifier of the port,
e.g. example.com/author/project
.
The individual parts of ${go.package}
.
Default: ${workpath}
/gopath
The location where source packages will be arranged after the extract phase.
Default: 386 or amd64, depending on
${build_arch}
Default: ${os.platform}
Portfiles using PortGroup golang do not need to define the following variables:
Default: see github or bitbucket PortGroups (when project hosted on GitHub or Bitbucket)
Default: port:go
Default: no
Default: darwin freebsd linux
Go can target these platforms, but individual ports should override this as necessary if only some are actually supported.
Default: ${go.bin}
build
Default: ""
Default: ""
Default: GOPATH=${gopath}
GOARCH=${goarch}
GOOS=${goos}
CC=${configure.cc}
Default: arranges the project and vendor source files appropriately in the GOPATH.
PortGroup java is useful for Java packages.
Portfiles using the java PortGroup allow for port authors to set the following keywords in addition to the general Portfile keywords.
This keyword indicates that the port requires a Java installation of the specified version. If no such installation can be located, and no fallback option is specified (see below), the port will fail at the pre-fetch phase.
The version string can indicate a specific version or a range with wildcards "+" and "*". Note that Java 8 and earlier are "1.8", etc., while Java 9 and later are "9", etc.
Type: optional
Example:
java.version 1.8+
This keyword indicates an (optional) port dependency that will be added to the ports 'depends-lib' list in the case a prior installation of Java satisfying the requested version can not be found. It is recommended that only an LTS version of Java be specified as the fallback, as non-LTS versions are only supported for 6 months.
Type: optional
Example:
java.fallback openjdk17
PortGroup perl5 allows for efficient porting of perl modules and other perl open source software.
Portfiles using the perl5 PortGroup allow for port authors to set the following keywords in addition to the general Portfile keywords.
This keyword sets the ${distfile} and ${version}.
Type: required
Example:
perl5.setup Net-Telnet 3.03
Perl modules are ordinarily assumed to be built with ExtUtils::MakeMaker. Use this keyword if a module must be built using Module::Build instead.
Type: optional
Example:
perl5.use_module_build
Portfiles using PortGroup perl5 do not need to define the following variables:
Default: perl
Default: perl_cpan:${perl5.cpandir}
Default: perl5.26
Default: no
When the perl5 PortGroup is declared within a Portfile, the following variables are provided during port install.
The MacPorts Perl version.
The Perl binary path (i.e.,
${prefix}/bin/perl
).
Path to the Perl vendor directory.
Path to the Perl architecture-dependent modules directory.
PortGroup python allows for efficient porting of python-based open source software.
Portfiles using the python PortGroup allow for port authors to set the following keywords in addition to the general Portfile keywords.
Defines the python versions supported by this port. If the
port name starts with “py-”, then a subport will be defined for each
version in the list. For example, if a port named “py-foo” declares
python.versions 39 310
, subports “py39-foo” and “py310-foo” will be
created, and will depend on python39 and python310, respectively.
If the port name does not start with “py-”, it is interpreted
as an application written in python rather than a python module. In
this case, no subports are defined, and python.versions
defaults to
the value of python.default_version
, which must be set. For example,
if a port named “mercurial” sets python.default_version 310
, then
python.versions
will automatically be set to “310”, and a dependency
on python310 will be added.
Type: required for modules, optional for apps
Example:
python.versions 38 39 310
For modules (i.e., name starts with “py-”), this sets the
subport that will be installed if the user asks to install “py-foo”
rather than, e.g., “py39-foo” or “py310-foo”. If not explicitly set, a
reasonable default is chosen from the list in python.versions
.
For applications (i.e., name does not start with “py-”), this chooses which version of python to use, and must be set. It can be changed in variants if desired.
Type: required for apps, optional for modules
Example:
python.default_version 310
If set to “yes”, the port will be built as per PEP 517. Dependencies on appropriate front end tools will be added automatically. This is supported when using Python 3.6 or later, though the supporting module ports for 3.6 and other EOL Python versions may be removed in future.
If set to “no”, the port will be built with the
traditional distutils/setuptools setup.py
commands.
Type: optional
Default (Python >= 3.7): yes
Default (Python <= 3.6): no
Example:
python.pep517 yes
This can be set to the name of the PEP 517 build back-end used by the port.
If python.pep517
is set to “yes”, dependencies on the
ports that provide the specified back-end will be added automatically.
Currently supported values are “setuptools”, “flit”,
“poetry”, “hatch”, “maturin”, and
“meson”. Clearing this option or setting it
to an unsupported value will result in no back-end dependencies being added.
Type: optional
Default: setuptools
Example:
python.pep517_backend flit
This can be set to the name of testing framework used by the port.
If test.run
is set to “yes”, dependencies on
the port that provides the specified framework will be added automatically.
Currently supported values are “pytest”, “nose”,
and “unittest”. Clearing this option or setting it to an
unsupported value will result in no framework dependency being added.
Type: optional
Default: pytest
Example:
python.test_framework nose
If set to “yes”, a dependency on a python interpreter will
be added as per python.version
, and if python.pep517
is also set to “yes”, dependencies on appropriate front- and back-end
tools will also be added.
If set to “no”, the portgroup will not add any dependencies, and all required dependencies need to be declared in the Portfile.
Type: optional
Default: yes
Example:
python.add_dependencies no
When “yes” (the default), tells the PortGroup to automatically
link any executable binaries installed in the bin/ directory within
the framework into
${prefix}/bin
.
Type: optional
Example:
python.link_binaries no
Suffix to add to the names of the links created in
${prefix}/bin
when ${python.link_binaries}
is enabled. Can be cleared if no suffix is desired.
Type: optional
Default: -${python.branch}
When yes (the default), the PortGroup will automatically
try to pass the correct arch-specific flags during build time
(via the standard CFLAGS, LDFLAGS, etc environment variables).
Set this to “no” and set up those variables in build.env
manually
if the default does not work.
Type: optional
Example:
python.add_archflags no
When the python PortGroup is declared within a Portfile, the following variables are provided.
The python version in use in the current subport. This will be
one of the versions listed in python.versions
.
The python version in use in the current subport, in normal
dotted notation. For example, if python.version
is “310”,
python.branch
will be “3.10”.
The prefix in which the current python version is installed.
For framework builds, this is ${frameworks_dir}/Python.framework/Versions/${python.branch}
,
whereas for non-framework builds, it is the same as ${prefix}
.
The path to the MacPorts Python executable.
The Python dynamic library path, i.e.,
${python.prefix}/Python
(framework builds) or
${prefix}/lib/libpython2.7.dylib
(python27).
The path to python's lib directory, i.e.,
${python.prefix}/lib/python${python.branch}
.
Path to the Python include directory.
Path to the Python site-packages directory. (i.e.,
${python.prefix}/lib/python${python.branch}/site-packages
).
Portfiles using PortGroup python do not need to define the following variables:
Default: python
Default: port:python${python.version}
Default: no
Default (python.pep517 no
): ${python.bin}
setup.py --no-user-cfg
Default (python.pep517 yes
): ${python.bin}
-m build --wheel --no-isolation --outdir ${workpath}
Default (python.pep517 no
): build
Default (python.pep517 yes
): (empty)
Default (python.pep517 no
): ${python.bin}
setup.py --no-user-cfg
Default (python.pep517 yes
): ${python.bin}
-m install --verbose
Default (python.pep517 no
): --prefix=${python.prefix}
--root=${destroot}
Default (python.pep517 yes
): --destdir ${destroot}
Default: creates directory
${destroot}${prefix}/share/doc/${subport}/examples
.
PortGroup ruby allows for efficient porting of ruby-based open source software.
When the ruby PortGroup is declared within a Portfile, the following variables are provided during port install.
The MacPorts Ruby version.
The Ruby binary location.
Path to the Ruby vendorlibdir directory (i.e.,
${prefix}/lib/ruby/vendor_ruby/${ruby.version}
)
The name for the Ruby architecture-dependent directory name
(i.e., i686-darwin8.10.1
).
Path to the Ruby vendor archdir (i.e.,
${ruby.lib}/${ruby.arch}
).
PortGroup xcode
allows for efficient porting of
Xcode-based opensource software. A minimum Portfile for PortGroup
xcode
uses defaults for the configuration, build, and destroot
phases. It also defines some values for Xcode-based software.
Using PortGroup xcode
is a way to make your port able to
tolerate Xcode version updates because the PortGroup is tested against all
supported macOS and Xcode versions.
Portfiles using PortGroup xcode
allow for port authors
to set the following keywords in addition to the general Portfile
keywords.
The path relative to ${build.dir}
and
${destroot.dir}
of the Xcode project. If unset,
Xcode Tools should be able to determine it automatically. It usually
succeeds if there is only a single project in the directory.
Type: optional
Default: none
Example:
xcode.project ${name}.xcode
Project configuration/buildstyle to use.
Type: optional
Default: Deployment
Example:
xcode.configuration Main
If present, it overrides build.target
and
destroot.target
.
Type: optional
Default: none
Example:
xcode.target ${name}
Additional settings passed to the xcodebuild tool during the build phase. These settings should be in the X=Y form.
Type: optional
Default: none
Example:
xcode.build.settings FRAMEWORK_SEARCH_PATHS=${frameworks_dir}
Type of project that will be installed. This tells the
PortGroup xcode how to destroot the project. Correct values are
application
and framework
.
Type: optional
Default: application
Example:
xcode.destroot.type framework
Where to install the build product.
Type: optional
Default: ${frameworks_dir}
or ${applications_dir}
depending on
xcode.destroot.type
.
Additional settings passed to the xcodebuild tool during the destroot phase. These settings should be in the X=Y form.
Type: optional
Default: none
Example:
xcode.destroot.settings SKIP_INSTALL=NO
Settings passed to the xcodebuild tool when the +universal variant is selected. These settings should be in the X=Y form.
Type: optional
Default: ARCHS="${universal_archs}"
MACOSX_DEPLOYMENT_TARGET=${universal_target}
SDK to use when the +universal variant is selected. The argument may be an absolute path to an SDK, or the canonical name of an SDK.
Type: optional
Default: ${universal_sysroot}
Portfiles using the PortGroup xcode do not need to define the following variables:
Default: aqua
Default: macosx
Default: no
The following Portfile phase keywords affect the PortGroup xcode in a unique way. In most cases, you will not need to set any of these keywords in the Portfile. See portfile-phase(7)
Default: ${xcodebuildcmd}
.
Default: ""
This variable will be ignored if
xcode.target
is set.
Default: build
Default: ${xcodebuildcmd}
Default: ""
This variable will be ignored if
xcode.target
is set.