使用 linuxbrew 安装 icu4c 出现如下错误:
[admin@v125205215 .linuxbrew]$ brew install icu4c | cat
==> Downloading http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-src.tgz
Already downloaded: /home/admin/.cache/Homebrew/icu4c-52.1.tgz
==> ./configure --prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1 --disable-samples --disable-tests --enable-static
checking whether to build release libraries... yes
checking whether the C compiler works... no
configure: error: in `/tmp/icu4c-7278/icu/source':
configure: error: C compiler cannot create executables
See `config.log' for more details
/home/admin/local/lib/ruby/2.0.0/open-uri.rb:353:in `open_http': 404 Not Found (OpenURI::HTTPError)
from /home/admin/local/lib/ruby/2.0.0/open-uri.rb:708:in `buffer_open'
from /home/admin/local/lib/ruby/2.0.0/open-uri.rb:210:in `block in open_loop'
... ...
手动将 brew 下载的包解压, 进入 source 目录执行同样的 configure 命令却没有问题.
./configure --prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1 --disable-samples --disable-tests --enable-static
brew 报错后 "/tmp/icu4c-7278/" 整个目录也删除了, 发生错误后为什么不能保留现场给用户排查问题呢? 为了想办法让 brew 保留报错现场, 真是费了老大的劲, 用尽各种 HACK 和投机取巧. 排查完问题查看 ruby 进程文件句柄, 看到原来 brew 把日志打在 "$HOME/Library/Logs/Homebrew/icu4c" 下面, "config.log" 错误日志这里也有一份. fuck, 害我折腾这么久, 以下是折腾过程.
查看 brew 命令帮助有一条 edit 命令:
Brewing:
brew create [URL [--no-fetch]]
brew edit [FORMULA...]
open https://github.com/mxcl/homebrew/wiki/Formula-Cookbook
执行 brew edit icu4c
打开了 icu4c 的安装脚本.
找到下面这段脚本是执行编译安装的地方:
def install
ENV.universal_binary if build.universal?
ENV.cxx11 if build.cxx11?
args = ["--prefix=#{prefix}", "--disable-samples", "--disable-tests", "--enable-static"]
args << "--with-library-bits=64" if MacOS.prefer_64_bit?
cd "source" do
system "./configure", *args
system "make", "VERBOSE=1"
system "make", "VERBOSE=1", "install"
end
end
尝试在 configure 前插入如下代码, 以启动 bash 手动检查测试环境.
puts args
system "bash"
重新安装 icu4c:
[admin@v125205215 source]$ brew install icu4c
==> Downloading http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-src.
Already downloaded: /home/admin/.cache/Homebrew/icu4c-52.1.tgz
--prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1
--disable-samples
--disable-tests
--enable-static
==> bash
脚本执行到 bash 命令, 但没看到正常的命令行. 在另一个终端查到 bash 命令的 pid, 发现是 bash 输出被重定向到管道了.
[observer.hany@v125205215 ~]$ pschain -C bash f
PID TTY STAT TIME COMMAND
1 ? Ss 2:00 init [3]
1233 ? Ss 3:32 /usr/sbin/sshd
26490 ? Ss 0:00 \_ sshd: observer.hany [priv]
26492 ? S 0:02 | \_ sshd: observer.hany@pts/1
26493 pts/1 Ss 0:00 | \_ -bash
8310 pts/1 S 0:00 | \_ su admin
8311 pts/1 S 0:00 | \_ bash
22570 pts/1 Sl+ 0:00 | \_ ruby -W0 /home/admin/.linuxbr
22588 pts/1 SNl+ 0:00 | \_ /home/admin/local/bin/rub
22605 pts/1 SN+ 0:00 | \_ bash
... ...
[observer.hany@v125205215 ~]$ sudo -u admin ls -l /proc/22605/fd/
[sudo] password for observer.hany:
总计 0
lrwx------ 1 admin admin 64 12-21 19:41 0 -> /dev/pts/1
l-wx------ 1 admin admin 64 12-21 19:42 1 -> pipe:[108382114]
l-wx------ 1 admin admin 64 12-21 19:42 2 -> pipe:[108382114]
在另一个终端手动进入编译目录执行 configure, 仍然执行成功没有报错.
[admin@v125205215 ~]$ ll /proc/22605/cwd
lrwxrwxrwx 1 admin admin 0 12-21 19:48 /proc/22605/cwd -> /tmp/icu4c-2599/icu/source
[admin@v125205215 ~]$ cd /tmp/icu4c-2599/icu/source
[admin@v125205215 source]$ ./configure --prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1 --disable-samples --disable-tests --enable-static
checking for ICU version numbers... release 52.1, library 52.1, unicode version 6.3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
... ...
bash 的父进程是没有重定向的, 看看能不能不重定向执行 bash,
[admin@v125205215 source]$ ll /proc/22588/fd
总计 0
lrwx------ 1 admin admin 64 12-21 19:41 0 -> /dev/pts/1
lrwx------ 1 admin admin 64 12-21 19:53 1 -> /dev/pts/1
lrwx------ 1 admin admin 64 12-21 19:44 2 -> /dev/pts/1
直接测试 system
函数默认是不重定向的, 没有找到 bash 被重定向的地方.
查看当前终端设备:
[admin@v125205215 source]$ tty
/dev/pts/1
修改 icu4c 脚本直接指定重定向到当前终端.
system "bash >/dev/pts/1 2>&1"
再运行 brew install icu4c
, 这回可以进入 bash 了.
执行 configure, 果然失败了.
[admin@v125205215 ~]$ brew install icu4c
==> Downloading http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-src.
Already downloaded: /home/admin/.cache/Homebrew/icu4c-52.1.tgz
--prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1
--disable-samples
--disable-tests
--enable-static
==> bash >/dev/pts/1 2>&1
[admin@v125205215 source]$ ./configure --prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1 --disable-samples --disable-tests --enable-static
checking for ICU version numbers... release 52.1, library 52.1, unicode version 6.3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking whether to build debug libraries... no
checking whether to build release libraries... yes
checking whether the C compiler works... no
configure: error: in `/tmp/icu4c-1582/icu/source':
configure: error: C compiler cannot create executables
See `config.log' for more details
从 "config.log" 中找到错误日志如下:
configure:2913: checking whether the C compiler works
configure:2935: /usr/bin/gcc -Os -w -pipe -march=core2 -msse4 -isystem/home/admin/.linuxbrew/include -L/home/admin/.linuxbrew/lib -Wl,-headerpad_max_install_names conftest.c >&5
cc1: error: unrecognized command line option "-msse4"
configure:2939: $? = 1
configure:2977: result: no
错误原因是不支持 "-msse4" 选项, 应该是目标机器 gcc 版本太低, 这个选项是 brew 脚本设置环境变量引入的.
[admin@v125205215 tmp]$ /usr/bin/gcc -Os -w -pipe -march=core2 -msse4 -isystem/home/admin/.linuxbrew/include -L/home/admin/.linuxbrew/lib -Wl,-headerpad_max_install_names a.c
cc1: 错误:无法识别的命令行选项“-msse4”
[admin@v125205215 tmp]$ env | grep msse
CXXFLAGS=-Os -w -pipe -march=core2 -msse4
CFLAGS=-Os -w -pipe -march=core2 -msse4
OBJCFLAGS=-Os -w -pipe -march=core2 -msse4
OBJCXXFLAGS=-Os -w -pipe -march=core2 -msse4
[admin@v125205215 tmp]$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)
Copyright (C) 2006 Free Software Foundation, Inc.
安装其他软件包也会报这个错, 这个选项应该是 linuxbrew 基础环境引入的. 搜索 linuxbrew 代码, 找到 "Library/Homebrew/extend/ENV/std.rb" 文件.
[admin@v125205215 .linuxbrew]$ find Library/ -type f | xargs grep --color msse4
Library/Formula/justniffer.rb: # 'CXXFLAGS=-O3 -w -pipe -march=core2 -msse4' 'CC=/usr/bin/llvm-gcc'
Library/Formula/justniffer.rb: # 'CFLAGS=-O3 -w -pipe -march=core2 -msse4' --cache-file=/dev/null--srcdir=.
Library/Formula/python.rb: # "-msse4" is present.)
Library/Formula/python3.rb: # "-msse4" is present.)
Library/Homebrew/extend/ENV/std.rb: DEFAULT_FLAGS = '-march=core2 -msse4'
Library/Homebrew/extend/ENV/std.rb: remove flags, %r{-msse4(\.\d)?}
Library/Homebrew/os/mac/hardware.rb: :penryn => '-march=core2 -msse4.1',
修改 "std.rb" 文件,
DEFAULT_FLAGS = '-march=core2 -msse4'
这行修改为
DEFAULT_FLAGS = '-march=core2'
由于 brew 是基于 git 的,
在 "$HOME/.linuxbrew" 下运行 git status
就可以看到我们对相关脚本的修改点.
对 "icu4c.rb" 的修改可以去掉, 再重新安装 icu4c, 终于编译安装成功.
[admin@v125205215 .linuxbrew]$ git status
# On branch linuxbrew
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: Library/Formula/icu4c.rb
# modified: Library/Homebrew/extend/ENV/std.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
[admin@v125205215 .linuxbrew]$ git checkout Library/Formula/icu4c.rb
[admin@v125205215 ~]$ brew install icu4c
==> Downloading http://download.icu-project.org/files/icu4c/52.1/icu4c-52_1-src.
Already downloaded: /home/admin/.cache/Homebrew/icu4c-52.1.tgz
==> ./configure --prefix=/home/admin/.linuxbrew/Cellar/icu4c/52.1 --disable-samp
==> make VERBOSE=1
==> make VERBOSE=1 install
... ...
brew 还能安装 python, ruby 自身, 甚至 gcc 等基础软件, 感觉是个不错的跨平台软件包管理器, 可惜用了讨厌的 ruby.
brew 将每个软件包版本安装到独立文件夹,
使用软链接管理默认使用的软件包, 类似 linux 的 update-alternatives
.
icu4c 可能跟其他软件包有冲突, 默认没有建立连接.
建立, 取消连接可使用:
brew link icu4c
brew unlink icu4c