MacOS软件包管理器--MacPorts
摘要
- MacPorts 是 macOS 上的软件包管理器,用来安装命令行工具和库,例如
git、wget、nginx。角色和 MacOS软件包管理器--brew 相同,默认目录是/opt/local,可以和 Homebrew 装在同一台机器上。 - 安装脚本叫 Portfile,对应 Homebrew 的 formula。可选功能做成变体,安装时用
+/-选择。日常命令是port,改动系统的操作要加sudo。自己编写 Portfile 并在本机安装,见 MacPorts -- 创建自己的 Port。 - Homebrew 计划在 2027 年 9 月或更晚停止在 Intel Mac 上运行,官方建议改用 MacPorts。已经用
brew装好的软件不会自动搬过来,要在 MacPorts 里重新装。 - 本文命令对照 MacPorts Guide,安装包版本以指南页上的 2.12.6 为例。本机是 MacOS Intel Sequoia 15.7.9,安装包选带
15-Sequoia的 pkg。
安装
安装前
-
需要 Xcode Command Line Tools。系统里已经为 Homebrew 装过的话,不用再装一遍。
1 | xcode-select --version |
安装 MacPorts
-
官方推荐用和当前 macOS 版本对应的 pkg,装到
/opt/local。只有准备换安装前缀时才从源码装。下载页:GitHub releases,各系统的直链写在 Install MacPorts。 -
Sequoia 15 对应
MacPorts-2.12.6-15-Sequoia.pkg。pkg 按 macOS 大版本区分,15.7.8 升到 15.7.9 不用换包。一个系统版本一个包,Intel 和 Apple Silicon 用同一个 pkg。双击安装即可。安装程序会自己改 shell 配置,并把 ports 树更新到最新。 -
新开一个终端再验证:
1 | $ port version |
-
安装程序会把下面这行写进
~/.zprofile或~/.profile,让 MacPorts 的命令排在 PATH 前面:
1 | export PATH=/opt/local/bin:/opt/local/sbin:$PATH |
-
登录 shell 先读
~/.zprofile,再读~/.zshrc。~/.zshrc里如果还有PATH=目录:$PATH,那些目录会插到 MacPorts 前面,同名命令就不再先用/opt/local/bin。最稳妥的做法是在~/.zshrc里所有 PATH 赋值之后再声明一次。typeset -U path按第一次出现去重,.zprofile里留下的那一份不会重复出现:
1 | # 放在 ~/.zshrc 最后,所有 PATH=目录:$PATH 之后 |
-
新开一个终端后用
which git看当前是哪一份。以后再往~/.zshrc里加PATH=目录:$PATH,写在这三行上面。bash 里~/.bash_profile先于~/.bashrc,同样把上面的export PATH=...再写进~/.bashrc末尾。 -
提示
command not found时,先新开终端。仍没有,就检查上面的 PATH 是否写进了当前 shell 会读的文件。说明见指南 MacPorts and the Shell。
命令补全
-
安装包不含 Tab 补全。本机 shell 是 zsh,用 MacPorts 的 zsh-completions 0.36.0。它来自 zsh-users/zsh-completions,是一批 zsh 自带补全之外的定义。本机装上后,
/opt/local/share/zsh/site-functions里有 180 个补全脚本,例如cmake、certbot、clang-format。port只是其中的_port。MacPorts 这个 port 的说明里特意写了包含port的补全。
1 | sudo port install zsh-completions |
-
补全文件在
/opt/local/share/zsh/site-functions,port对应_port。zsh 只在执行compinit时扫描fpath。本机用 oh-my-zsh,source $ZSH/oh-my-zsh.sh时已经扫过一遍,所以这行写在它后面,并再执行一次compinit:
1 | fpath=(/opt/local/share/zsh/site-functions $fpath) # 把 MacPorts 补全目录插到 fpath 最前 |
-
新开一个终端,输入
port后按 Tab,会补出install、search、selfupdate这些子命令。写在source $ZSH/oh-my-zsh.sh前面也可以,那样不用再跑一次compinit。 -
bash 用 bash-completion 2.18.0。它要求 bash 4.1+。
1 | sudo port install bash-completion |
-
安装说明要求把下面几行写进
~/.bash_profile。port的补全脚本在/opt/local/share/bash-completion/completions/port。
1 | if [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then |
目录
1 | /opt/local # 安装前缀,对应 brew --prefix |
-
通过 MacPorts 安装的软件在
/opt/local下面,不在 Homebrew 的/usr/local/Cellar或/opt/homebrew/Cellar。
国内镜像
-
这一步可选。要换镜像的话,放在后面的
selfupdate之前做。软件列表来自sources.conf里带[default]的那一行,默认是:
1 | rsync://rsync.macports.org/macports/release/tarballs/ports.tar.gz [default] |
-
北京镜像由清华大学维护,主机名是
pek.cn.rsync.macports.org。编辑/opt/local/etc/macports/sources.conf,把上面那一行换成:
1 | rsync://pek.cn.rsync.macports.org/macports/release/tarballs/ports.tar.gz [default] |
-
改完执行
sudo port -v selfupdate。其它地区的镜像列表在 Mirrors。 -
2.10.0 起,MacPorts 本体的更新默认走 HTTP。
macports.conf里的rsync_server、rsync_dir只在 HTTP 失败、退回 rsync 时才用到。ports 树仍然看sources.conf。
日常使用
-
查帮助:
port help,某个动作再加名字,例如port help install。完整列表在man 1 port,在线版是 Using MacPorts。 -
和 Homebrew 的对应关系。后面按这个顺序说明每条命令做什么。
| 要做的事 | Homebrew | MacPorts |
|---|---|---|
| 更新软件列表和工具本身 | brew update |
sudo port selfupdate |
| 搜索 | brew search wget |
port search wget |
| 查看信息 | brew info wget |
port info wget |
| 安装选项 | 一种构建 | port variants vim |
| 安装 | brew install wget |
sudo port install wget |
| 已安装 | brew list |
port installed |
| 装了哪些文件 | brew list wget |
port contents wget |
| 点名安装的包 | brew list --installed-on-request |
port echo requested |
| 可升级 | brew outdated |
port outdated |
| 升级 | brew upgrade |
sudo port upgrade outdated |
| 卸载 | brew uninstall wget |
sudo port uninstall wget |
| 删掉升级留下的旧版本 | brew cleanup |
sudo port uninstall inactive |
| 依赖 | brew deps wget |
port deps wget |
| 递归依赖 | brew deps --tree wget |
port rdeps wget |
| 谁依赖它 | brew uses --installed wget |
port dependents wget |
| 间接依赖它的包 | brew uses --installed --recursive wget |
port rdependents wget |
| 先看不再被需要的依赖 | brew autoremove --dry-run |
port echo leaves |
| 卸掉不再被需要的依赖 | brew autoremove |
sudo port uninstall leaves |
| 清编译目录 | 安装结束会清掉 | sudo port clean wget |
| 清理下载缓存 | brew cleanup |
sudo port clean --dist all |
| 回收磁盘 | brew cleanup 与 brew autoremove |
sudo port reclaim |
| 启动后台服务 | brew services start nginx |
sudo port load nginx |
| 停止后台服务 | brew services stop nginx |
sudo port unload nginx |
| 检查环境 | brew doctor |
port diagnose |
更新
-
装新软件、查过期包之前,先更新 MacPorts 本体和 ports 树:
1 | sudo port selfupdate |
-
环境异常时用
port diagnose,对应brew doctor。
查找
-
按名字和描述搜索。
port list会把索引里所有包都打出来,又长又慢。查某个软件用port search,查已安装的包用「查看已安装」里的port installed。
1 | port search wget # 按名字和描述搜索 |
安装软件
-
有预编译包、并且许可证允许再分发时,
port install会从packages.macports.org下载,跳过编译。没有和当前变体匹配的二进制包时,就在本机按这次的选择编译。变体见下一节。
1 | sudo port install wget # 安装 wget |
-
编译失败时先清掉编译目录再重试,日志路径会打在终端里。
clean还能删下载缓存,见「清理」。
1 | sudo port clean wget # 清掉编译目录 |
变体
-
MacPorts 把可选功能做成变体,安装时才选定。默认只打开 Portfile 里标出的那些,
port variants行首的[+]就是默认项。vim 的默认是+huge,Python、Lua、Perl、Ruby 都不在里面。+python312会把 python312 加进依赖;不加,依赖里就没有 Python。本机port info vim的库依赖是 gettext、libiconv、ncurses。 -
Homebrew 官方仓库里,一个 formula 只有一种构建。vim 的 configure 打开 Python 3、Lua、Ruby、Perl 和 cscope,并关掉 GUI。Python 3、Lua、Ruby 标成编译和测试依赖:有 bottle 时,二进制里已经带这些接口,语言包要另外装才用得上;从源码编译时,这三个会作为编译依赖装进来。当前这份 formula 的 bottle 只有 Apple Silicon 和 Linux,没有 macOS x86_64。本机是 Intel,
brew install vim会按这一份配置在本机编译。想要别的组合,需要自己改 formula,或用仍保留选项的第三方 tap。 -
两边的二进制包都是已经编好的一份文件,安装时不能再改编译选项。Homebrew 2.0.0 起,官方仓库拿掉了
brew install vim --with-python这类选项,只分发这一份 bottle;带选项的构建进不了 CI,也做不成 bottle。MacPorts 仍接受变体:有和当前变体匹配的 archive 就下载,没有就按这次的选择在本机编译。
| MacPorts | Homebrew | |
|---|---|---|
| 功能 | 安装时用变体选择 | formula 里固定一种构建 |
| 依赖 | 选中的变体才引入 | 写在 formula 里 |
| 二进制 | 变体对上 archive 就下载,否则按该变体编译 | bottle 是那一种构建;没有就按同一配置编译 |
-
装之前先看有哪些变体。
+打开,-关掉默认项。多个变体写在同一条命令里。名字写错时不会提示,因为它也可能是某个依赖的变体。装完用port installed核对。
1 | port variants vim # 查看可用变体,行首 [+] 为默认项 |
-
给 YouCompleteMe 用时,Vim 需要 Python 接口,加上
+python312。已经装过默认的 vim 时,再执行这条会按新组合重新构建,原来的+huge还在。本机当前是:
1 | vim @9.2.0321_2+huge+python312 (active) |
-
以后升级会沿用这次的变体。要改组合,在安装或升级命令里把变体写上。变体说明见 Port Variants。Homebrew 拿掉官方仓库安装选项的说明见 Homebrew 2.0.0。
查看已安装
1 | port installed # active 是当前在用的版本 |
升级
-
先跑过「更新」里的
selfupdate,再看已安装的包里哪些有新版本。官方建议整批升级。变体沿用安装时的选择,见「变体」。
1 | port outdated # 列出有新版本的已安装包 |
-
升级后旧版本还留在磁盘上,标成 inactive,出问题可以切回去。确认新版本可用之后再删,命令在「卸载软件」。
卸载软件
-
这里卸的是某一个 port。卸掉 MacPorts 本体见文末「卸载 MacPorts」。
-
还有别的包依赖它时,单独
uninstall会被拒绝。先看谁依赖它,再决定是只卸这一个,还是连同依赖它的包一起卸。
1 | port dependents openssl # 已安装的包里,谁直接依赖它 |
-
自动拉进来、已经没有人依赖、也不是你点名安装的包,先看再卸:
1 | port echo leaves # 列出不再被需要的自动依赖 |
-
升级留下的旧版本:
1 | sudo port uninstall inactive # 删掉升级留下的旧版本 |
清理
-
clean删的是安装过程留下的临时文件,已安装的软件还在。源码包在/opt/local/var/macports/distfiles,安装成功后默认留着,下次再装可以不再下载。编译目录在build,成功安装后一般已经清掉;编译失败时会留下。
1 | sudo port clean wget # 默认 --work,只删编译目录 |
-
--archive只删临时目录里没下完的二进制包,不会动/opt/local/var/macports/software里已经装好的归档。旧版本占的空间用「卸载软件」里的sudo port uninstall inactive。 -
reclaim范围更大:卸掉 inactive 的包和不再被需要的依赖,并删用不到的源码包。先看清单再删:
1 | sudo port reclaim -y # 只列出,不删除 |
-
说明见 port clean、port reclaim。
服务
-
带后台进程的 port,用
load/unload交给 launchd。对应 Homebrew 的brew services。
1 | sudo port load nginx # 启动服务,交给 launchd |
和 Homebrew 装在一起
-
两个前缀不同,文件不会写进对方的目录。
/opt/local/bin排在 PATH 最前面时,同名命令会先用到 MacPorts 的那一份。~/.zshrc若在~/.zprofile之后又改了 PATH,见「安装 MacPorts」里末尾再声明的那三行。用which git确认当前是哪一个。 -
同一个软件只保留一套。编译 MacPorts 的包时如果和
/usr/local里的库冲突,安装命令加上-t,见「安装软件」。 -
gem只安装 Ruby 的库,不能用来装git、wget、nginx这种通用软件,也不能代替 MacPorts。
升级 macOS 之后
-
同一个大版本里的小更新,例如 Sequoia 15.7 升到 15.7.9,原来的安装继续用。更新 MacPorts 和已装软件:
1 | sudo port selfupdate # 更新 MacPorts 本体和 ports 树 |
-
跨大版本,例如 Sequoia 15 升到 Tahoe 26,已装的 port 是按旧系统编译的,只跑
selfupdate不够。MacPorts 2.10.0 起用port migrate,它会按当前系统重装 MacPorts 本体,并重装和当前系统不兼容的 port。步骤见 Migration。
1 | # 1. 先把 Xcode Command Line Tools 更新到新系统对应的版本 |
-
迁移前会给已安装的包做快照。有的包装失败时,等上游修好后再执行
sudo port restore --last。快照不再需要时,用port snapshot --list看编号,再sudo port snapshot --delete <编号>删掉。 -
2.10.0 之前没有
port migrate。那种情况要先装上当前系统对应的 pkg(已安装的 port 还在),再执行上面的sudo port migrate。
卸载 MacPorts
-
先卸掉所有 port,再删掉 MacPorts 本体。配置和数据库在
/opt/local/etc,需要保留就先挪走。完整步骤见 Uninstall MacPorts。
1 | sudo port -fp uninstall installed # 强制卸掉全部已装 port;-f 强制,-p 遇错继续 |
-
Catalina 及更新的系统开着 SIP 时,要先删
macports用户,再删/opt/local。