我参加了推介会UCL 教授就 Spectre 和 Meltdown 发表了一篇文章。他建议了几种缓解 Spectre 2(分支目标注入)的方法,即升级到 High Sierra 并使用开关 --mretpoline 从源代码安装所有软件(已在 LLVM 和 GCC 中部署)。我想以这种方式在 macOS High Sierra 上安装 R 和 RStudio。我下载了两者的源代码。R 和 RStudio 的安装过程类似。R 的 INSTALL 文件说我应该运行
./configure
make
我检查了“configure”文件和 makefile(Makeconf.in、Makefile.in、Makefile.in)。我没有看到添加开关的明显方法。我调用了 make 的帮助,它也没有提到如何添加开关。
我在网上搜索了这个问题,能找到最接近的解释是对 retpoline 和 Spectre 2 的解释。
如何使用 make 从源代码编译软件并包含 --mretpoline 开关?
答案1
简洁版本:经过大量调查,我无法使用和llvm
标志-mretpoline
或gcc
和-mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register
标志从源代码在 MacOS 上安装软件。这似乎比R
和更具体MacOS
,所以我相应地更改了标题。我怀疑截至 2018 年 4 月 27 日,这在 Mac 上无法完成。我正在运行 macOS High Sierra 版本 10.13.3 (17D102)。
长版本:以下内容适用于 GnuPG,我决定在 R 之前安装它(因为 R 需要 gfortran,而 gfortran 又需要 gcc,而 gcc 又需要平均血红蛋白,它带有我想要验证的 GPG 签名)。我按照从 Git 安装 GPG 的步骤。
最新的 LLVM (使用 Homebrew)
Apple 的 LLVM 失败了(见下文),所以我使用 LLVM clang 6 来修复这个问题,并使用 homebrew 进行安装(这有点违背了使用特定标志从源代码编译的目的,但我没时间了)。我使用以下方法安装了 homebrew:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
然后用它更新了两次
brew update
使用 Homebrew 安装 clang 需要 XCode,因此我从 App Store 安装了它。然后我按照以下步骤操作这一页:
brew install --with-toolchain llvm
然后,我将-mretpoline
标志添加到两者中C
,将路径添加到C
和C++
编译器中,然后从 GPG 调用 shell 脚本:
export CFLAGS='-mretpoline'
export CC=/usr/local/opt/llvm/bin/clang
export CXX=/usr/local/opt/llvm/bin/clang++
./autogen.sh
./configure --sysconfdir=/etc --enable-maintainer-mode && make
我收到此错误:
checking whether the C compiler works... no
日志文件config.log
提供了更多详细信息:
configure:4049: /usr/local/opt/llvm/bin/clang -mretpoline conftest.c >&5
fatal error: error in backend: MachO doesn't support COMDATs, '__llvm_retpoline_r11' cannot be lowered.
clang-6.0: error: clang frontend command failed with exit code 70 (use -v to see invocation)
此主题底部有一条 2018 年 1 月的评论,称 Mac 尚不支持-mretpoline
:
samkellett:@chandlerc 是否故意省略了对 MacOS 的支持 (即尚未实现)? chandlerc:完全不是,我只是没有 Mac 系统可以测试...
从此以后就没有任何反应了。因此使用 LLVM 安装失败。
GCC (带有 Homebrew)
另一种选择是使用gcc
LLVM 进行编译。我安装了最新版本的 clang (6.0),
brew install gcc
我添加了gcc
来自这一页,这与 LLVM 不同。此 bash 脚本将标志添加到C
和C++
,提供两个编译器的路径,并从 GPG 调用 shell 脚本:
export CFLAGS='-mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register'
export CXXFLAGS=$CFLAGS
export CC=/usr/local/opt/gcc/bin/gcc-7
export CXX=/usr/local/opt/gcc/bin/g++-7
./autogen.sh
./configure --sysconfdir=/etc --enable-maintainer-mode && make
我再次收到错误:
checking whether the C compiler works... no
日志文件config.log
提供了更多详细信息:
configure:4027: checking whether the C compiler works
configure:4049: /usr/local/opt/gcc/bin/gcc-7 -mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register conftest.c >&5
Undefined symbols for architecture x86_64:
"__x86_return_thunk", referenced from:
_main in ccZuBhFQ.o
(maybe you meant: ___x86_return_thunk)
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
configure:4053: $? = 1
configure:4091: result: no
奇怪的是,编译器知道发音相似的名称,但带有一个额外的下划线。
所以gcc
也失败了。现在我很茫然。
附录:Apple 的 LLVM
以下 bash 脚本导出 GnuPG 的标志make
并调用其 shell 脚本:
export CFLAGS='-mretpoline'
export CXXFLAGS=$CFLAGS
echo $CFLAGS
echo $CXXFLAGS
./autogen.sh
./configure --sysconfdir=/etc --enable-maintainer-mode && make
它在 Apple 附带的编译器下失败,但它显示标志正在到达编译器:
configure:4045: gcc -mretpoline -mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register conftest.c >&5
clang: error: unknown argument: '-mretpoline'
所以@seth 关于如何向编译器发送标志的评论是正确的。