Homebrew in Action [revised]

▎介绍

Homebrew 作为 macOS 上强大的包管理器,为系统软件提供了非常方便的安装方式,独特式的解决了包的依赖问题,并不再需要烦人的 sudo,一键式编译,无参数困扰,值得拥有。


▎安装

Homebrew 依赖于 Xcode Command Line 天 Ruby。可以在终端中输入下面命令查看本机的 Ruby 安装情况。

1
$ ruby -v

确认 Ruby 可被正常使用后,继续输入下面命令,进行 brew 的安装:

1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

> 安装背后

Homebrew 将本机的 /usr/local 目录初始化为 Git 的工作树,并将目录所有者变更为$USER,也就是你当前所操作的用户,所以以后的操作都不再需要sudo,这是安全的,全新的OS X默认是没有该目录的,也就是说该目录并非是系统所有。

在/usr/local 下创建以下目录

1
2
3
4
5
6
- bin          用于存放所安装程充的启动链接(相当于快捷方式)  
- Cellar 所以brew安装的程序,都将以[程序名/版本号]存放于本目录下
- etc brew安装程序的配置文件默认存放路径
- Library Homebrew 系统自身文件夹
+– Formula 程序的下载路径和编译参数及安装路径等配置文件存放地
+– Homebrew brew 程序自身命令集

上述为 Homebrew 所用用到的几个目录,其它也有使用,但于 brew 关联不大,请参考 Unix 系统相关资料。

最后,将 brew 的程序启动项放到 /usr/local/bin 下,所以,必须保证该目录属于Bash的环境变量,关于如何配置环境变量,请查阅相关资料。


▎开始使用

用 brew 安装第一个程序,这里使用 node 作为示例

1
$ brew install node

有些程序会同时提供两个下载,一个为稳定版,另一个为尝鲜版(通过head参数获取),如果已安装过稳定版的程序后,想同时安装尝鲜版可以通过 force参数来完成。

1
2
$ brew install --HEAD node
$ brew install --force --HEAD node

接下来可以看到 brew 启动下载,通过 Formula 目录中的 node.rb 文件中的路径去下载源码,然后就是 configure,同时指定 prefix 到 Cellar 目录,接下来 make & install。最后,将 node 的运行文件通过软链接到 /usr/loca/bin 下,方便命令行启用。因为 /usr/local 的目录所有者为当前用户,所以这里不再需要 sudo 进行提权,很方便。

然后,可以很方便的通过以下命令来卸载所安装程序

1
$ brew uninstall node

Homebrew提供update参数来对系统进行更新,其实就是对Formula目录进行Git pull,将服务器最新的程序安装配置文件同步到本地,同时,会标明新加入和更新,同时会对本机已经安装并有更新的程序用*号来标名。

1
$ brew update

如果看到已安装程序有更新版本,像node.js 刚发布0.6.2,这里运行完brew update,会看到node*的标志出现,运行以下命令来安装最新版的node 0.6.2。

1
$ brew upgrade node

这时会出现和安装一样的过程,再次在终端中输入 node -v 可看到已是最新版本。但如果同时出现多个程序的升级,一个个通过程序名升级未免过于麻烦,这时,试下下面的这条命令,所有有更新的程序都会被自动下载,编译安装。

1
$ brew upgrade

安装完最新版本后,旧的版本仍然存在,可通过 cleanup 命令来删除,和 upgrade 一样,提供单程序和所有程序旧版的移除。

1
2
$ brew cleanup node
$ brew cleanup

通过 outdated 命令查看哪些 Formula 有更新

1
$ brew outdated

如何知道 Homebrew 官方是否有某个程序的安装呢,通过search命令来查看

1
$ brew search [formula]

查看已安装程序信息,brew 提供了info和list参数,

1
$ brew info

显示该程序的安装路径,相关提示及formula服务器所在位置

1
$ brew info [formula]

显示当前所有已安装程序的名称

1
$ brew list

显示该formula的所有文件列表

1
$ brew list [formula]


▎介绍 Bottles

Mac 的平台比较简单。

如果每个人都要下载源码,然后再 build,会浪费大量的时间。如果能按平台 build 好。

就会省下很多时间。

这就是 Homebrew Bottles。


▎Formula 分析

在终端中输入brew edit [formula],默认启用textmate来编辑该formula。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
require 'formula'

class Node < Formula
url 'http://nodejs.org/dist/v0.6.2/node-v0.6.2.tar.gz'
head 'https://github.com/joyent/node.git'
homepage 'http://nodejs.org/'
md5 '875431b2c2e3d0ebf5a676b3d96bf766'

# Leopard OpenSSL is not new enough, so use our keg-only one
depends_on 'openssl' if MacOS.leopard?

fails_with_llvm :build => 2326

# Stripping breaks dynamic loading
skip_clean :all

def options
[["--debug", "Build with debugger hooks."]]
end

def install
inreplace 'wscript' do |s|
s.gsub! '/usr/local', HOMEBREW_PREFIX
s.gsub! '/opt/local/lib', '/usr/lib'
end

args = ["--prefix=#{prefix}"]
args << "--debug" if ARGV.include? '--debug'

# v0.6 appears to have a bug in parallel building
# so we'll -j1 it for now
ENV.deparallelize

system "./configure", *args
system "make install"
end

def caveats
"Please add #{HOMEBREW_PREFIX}/lib/node_modules to your NODE_PATH."
end
end

可以看出几个属性:

  • url 是指当前稳定版的下载路径
  • head 是尝鲜版的路径,可以使用 github 项目路径
  • homepage 指向到 formule 的官方网站
  • md5 则对应 formula 的下载文件校验值
  • depends_on 属于用于解决依赖关系,brew如发现当前程序依赖其它程序,便会检查依赖程序是否已经安装,如未安装,则会先安装依赖程序的稳定版。
  • options 用来指定默认编译参数
  • install 则是安装的过程,指定编译参数,make & install
  • caveats 用作安装完成之后的输出提示。

> 制作自己的 Formula

Homebrew 提供 create 命令来快速创建一个新的 Formula,通过指定下载文件源码路径,或 github 程序位置(含可用版版本号,Git Tag)即可,创建完成后,会自动打开所新建formula的配置文件,填入homepage等参数,然后在终端中通过audit命令来进行检验。

1
2
$ brew create http://example.com/foo-0.1.tar.gz
$ brew audit foo

当然,如果你想将该程序保存到github上,可以直接fork Homebrew的项目,然后通过git进行commit,push到自己的fork中,也可以将该文件合并到官方的库中,参见github。

1
2
$ git commit Library/Formula/foo.rb
$ git push


▎国内用户

因为访问 github 及 bottles 比较慢,所以这样使用替换访问源的方式,来加速。

分别是 homebrew 本身,以及 homebrew bottles 两个部分的替换。

> 替换及重置 Homebrew 默认源

Homebrew 自身是使用 Github 来更新的,所以替换的方法是将 git 地址指向到新的境内的地址上即可。

- 清华

1
2
3
4
5
6
7
git -C "$(brew --repo)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git

git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git

git -C "$(brew --repo homebrew/cask)" remote set-url origin https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-cask.git

brew update

- 还原为默认

1
2
3
4
5
6
7
git -C "$(brew --repo)" remote set-url origin https://github.com/Homebrew/brew.git

git -C "$(brew --repo homebrew/core)" remote set-url origin https://github.com/Homebrew/homebrew-core.git

git -C "$(brew --repo homebrew/cask)" remote set-url origin https://github.com/Homebrew/homebrew-cask.git

brew update

> Homebrew Bottles 源

1
2
3
echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles' >> ~/.bash_profile

source ~/.bash_profile


▎问答:

Q: 如何将第三方提供的Formula在本地使用?
A: Homebrew暂不提供第三方源的支持,但官方已表示未来会加入该功能,所以现在能做的就是将第三方formula下载后,放到/usr/local/Library/Formulas/ 然后用文件名作formula正常安装。
这里也提供一个非官方的源,安程程序会更多一些:https://github.com/adamv/homebrew-alt

Q: 关于Ruby的安装
A: 对于Ruby自身,更推荐使用RVM来进行多版本的安装管理。

Q: 为什么有时运行完update,明明看到有程序可被更新,但upgrade时总报错,说该程序已是最新?
A: 所以有时你看到一个程序有更新,但通过upgrade会获取不到,则是因为另一版本(稳定版或尝鲜版)的升级。

Q: 如何安装旧版本的Formula?
A: 参见http://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula

Q: 尝试着加了几个Formula,怎么删除?
A: 到/usr/local/Library/Formula 目录下,找到所加的formula对应文件,删除即可。如果你了解git,也可到/usr/local下运行 git clean -d -f,来清除未被track的脏数据。


▎参考: