ある日,rbenv
を見ていた
brew upgrade ebenv
して,
$ rbenv install -list
2.5.8
2.6.6
2.7.2
3.0.0
jruby-9.2.14.0
mruby-2.1.2
rbx-5.0
truffleruby-20.3.0
truffleruby+graalvm-20.3.0
昨年中にruby 3.0.0
が正式にリリースされ,rbenv
も対応したらしい.入れてみよっかなぁ〜俺もなぁ〜…
そのruby 3.0.0
を入れようとしてしくじった
当時の環境は以下の通りだった.
- MBP 2016 15inch
- macOS
Catalina
-
clang Apple 11.0.0
←だいたいこいつのせいだった
-
吐かれたエラー
...
linking miniruby
generating x86_64-darwin19-fake.rb
x86_64-darwin19-fake.rb updated
make: *** [exe/ruby] Segmentation fault: 11
make: *** Deleting file 'exe/ruby'
BUILD FAILED (Mac OS X 10.15.7 using ruby-build 20201225)
Inspect or clean up the working tree at /var/folders/rk/0hczm32x2znb6pr6h4858hpc0000gn/T/ruby-build.20210104003100.75691.mUe6Zo
Results logged to /var/folders/rk/0hczm32x2znb6pr6h4858hpc0000gn/T/ruby-build.20210104003100.75691.log
Last 10 log lines:
compiling enc/unicode.c
compiling enc/utf_8.c
compiling enc/trans/newline.c
./revision.h unchanged
compiling version.c
linking miniruby
generating x86_64-darwin19-fake.rb
x86_64-darwin19-fake.rb updated
make: *** [exe/ruby] Segmentation fault: 11
make: *** Deleting file 'exe/ruby'
どうやら最後のmake
のとこでしくじったらしい.
原因推定
Segmentation fault: 11
,これはなんかコンパイラが悪い気がしたので,設定や経過を見たくなった.
rbenv install -v 3.0.0
-v
しながらrbenv install
すると諸々の経過が見える,その結果
Configuration summary for ruby version 3.0.0
* Installation prefix: /Users/username/.rbenv/versions/3.0.0
* exec prefix: ${prefix}
* arch: x86_64-darwin19
* site arch: ${arch}
* RUBY_BASE_NAME: ruby
* enable shared: yes
* ruby lib prefix: ${libdir}/${RUBY_BASE_NAME}
* site libraries path: ${rubylibprefix}/${sitearch}
* vendor path: ${rubylibprefix}/vendor_ruby
* target OS: darwin19
* compiler: clang -fdeclspec
* with pthread: yes
* with coroutine: amd64
* enable shared libs: yes
* dynamic library ext: bundle
* CFLAGS: ${optflags} ${debugflags} ${warnflags}
* LDFLAGS: -L. \
-L/Users/username/.rbenv/versions/3.0.0/lib \
-fstack-protector-strong -L/usr/local/lib
* DLDFLAGS: -L/Users/username/.rbenv/versions/3.0.0/lib \
-Wl,-undefined,dynamic_lookup \
-Wl,-multiply_defined,suppress
* optflags: -O3
* debugflags: -ggdb3
* warnflags: -Wall -Wextra -Wdeprecated-declarations \
-Wdivision-by-zero \
-Wimplicit-function-declaration -Wimplicit-int \
-Wpointer-arith -Wshorten-64-to-32 \
-Wwrite-strings -Wmissing-noreturn \
-Wno-constant-logical-operand -Wno-long-long \
-Wno-missing-field-initializers \
-Wno-overlength-strings -Wno-parentheses-equality \
-Wno-self-assign -Wno-tautological-compare \
-Wno-unused-parameter -Wno-unused-value \
-Wunused-variable -Wextra-tokens
* strip command: strip -A -n
* install doc: rdoc
* JIT support: yes
* man page type: doc
* BASERUBY -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) \
[x86_64-darwin19]
を吐きながら,同じように失敗した.
* target OS: darwin19
* compiler: clang -fdeclspec
を見るに,macOS備え付けのclang
を使っていることは察せた(私はいまだにコンパイラに手を出した事がない).
$ clang -v
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
どうもビルドにはコイツを使ったらしい.
悩んでTwitterを彷徨っていたら,clang Apple 12.0.0
でruby 3.0.0
を入れたっぽい方を発見した.
またこ↑こ↓によると,macOS Big Sur
でちゃんとXCode
を入れている人は
$ clang --version
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: x86_64-apple-darwin20.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
となるらしい(私はXCode
を入れた後に消した,だってあれデカイし重いし…).
つまりclang
のバージョンが古いせいでしくじったんじゃね?と考えた.
解決編
概要
CommandLineTools
を強制的に入れ直すとclang 12.0.0
になるのでヨシ!ruby 3.0.0
も入れられる!
手順
Catalina
でsoftowareupdate
に任せてもそれ以上にCommandLineTools
は新しくならない(つまりclang 12.0.0はどう足掻いても手に入らない)ので,いっそ手動で入れ直す.
$ sudo rm -rf /Library/Developer/CommandLineTools
...
$ xcode-select --install
バージョン確認すると
$ clang -v
Apple clang version 12.0.0 (clang-1200.0.32.28)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
こうなるはず,やっぱりXCode
がなくても大丈夫だったじゃないか…
これで
$ rbenv install 3.0.0
すれば
Installed ruby-3.0.0 to /Users/username/.rbenv/versions/3.0.0
が出るはず,バージョンを変えるか変えないかはあなた次第だが
rbenv local 3.0.0
とかでできる.
終わり!閉廷!以上!みんな解散!君もう帰って良いよ
おまけ
clang 11.0.0
(やそれ以前の任意のバージョンのclang
)を使いたい時にどうするかを考えた.
概要
homebrew
でllvm
を入れて,それ経由でclang
のバージョンを任意に変えられるようにしようぜ?
llvm
とは
llvm
を開発している組織さんの公式ページはこ↑こ↓,llvmまわりのダウンロードやドキュメント等はこ↑こ↓.
llvm
自体はc
やc++
のコンパイラclang
のバックで動いているような中間言語を生成するシステムで,というかclang
がc
の仕様に対応しながらllvm
と並行で開発・維持され続けているものになっている…らしいな?
つまりある時からllvm
のバージョンがclang
のバージョンになっている,そしてbrew
で手に入れられる最新版は今だとllvm 11.0.0
で,それを入れるとclang 11.0.0
がもれなくそれについてくる…という流れになる.
ただあくまで言語やアーキテクチャに依存せずより効率の良い中間言語を生成しようとするのがllvm
で,それを利用してobjective-c
などをコンパイルするのがclang
,そんでclang
の開発の言い出しっぺはやっぱりAppleで…だからあっXCode
にちゃんと最新版のclang 12.0.0
が入って提供されている,やっぱ林檎ってすげぇわマジで…
…なのでclang
はgcc
よりも性能と使い勝手が共に良い…らしい(私は開発者ではないので全くわからないが).
事前準備
homebrew
を導入しておく.
最新版のllvm
だけで良いなら
まずは入れてみる.
$ brew install llvm <versions>
...
$ brew info llvm
...
ちゃんと注意書きを読む(抜粋).
To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have llvm first in your PATH run:
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> /Users/SolunaEureka/.bash_profile
For compilers to find llvm you may need to set:
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
keg-only
…つまりシンボリックリンクが生成されないタイプのパッケージだけど,中身はちゃんとあるからパスだけは通そうね!あとコンパイラに知らせたいフラッグにも対応しているから,使いたければパスだけは通そうね!(意訳)
…ということで,コマンドとしてのllvm
はどうもなさそうなので,それを打ってllvm
経由のclang
が有効になるような感じにするために,.bash_profile
をいじる(参考:学生たちの技術ブログ).まだbashでごめんなさい
function llvm (){ #関数を定義している
export PATH="/usr/local/opt/llvm/bin:$PATH" #以下,先の注意書きの通りにパスを追加・変更する
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
unset -f llvm #いったん呼び出されたら定義されたこの関数を破壊する
}
ここまで終わったらterminal
を立ち上げ直して
$ llvm
$ clang -v
clang version 11.0.0
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
になるはず.
新しいタブを開けば元に戻るので安心だね!
旧版のllvm
を使いたいなら
homebrew
は基本的に最新版以外は絶対に認めないマンな上に過去版のインストールに関しては仕様が変わるらしい,そんな中で個人的に現在の参考になったのはこ↑こ↓.
brew tap-new
とbrew extract
を用いて,自家製のtap
に公式のformula
をぶち込んで,そのtap
から更にbrew install
すれば良い,らしい.これを発案した人,本当に賢い…
ということで試しにllvm 10.0.0
を入れてclang 10.0.0
に切り替えようとしてみる(主要な出力を抜き出す).
$ brew tap-new llvm/1000
Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/llvm/homebrew-1000/.git/
[master (root-commit) d649d61] Create llvm/1000 tap
3 files changed, 85 insertions(+)
create mode 100644 .github/workflows/publish.yml
create mode 100644 .github/workflows/tests.yml
create mode 100644 README.md
==> Created llvm/1000
/usr/local/Homebrew/Library/Taps/llvm/homebrew-1000
$ brew extract llvm llvm/1000 --version 10.0.0
==> Searching repository history
==> Writing formula for llvm from revision 96544f6 to:
/usr/local/Homebrew/Library/Taps/llvm/homebrew-1000/Formula/llvm@10.0.0.rb
$ brew install llvm/1000/llvm@10.0.0
==> Installing llvm@10.0.0 from llvm/1000
llvm@10.0.0: A full installation of Xcode.app is required to compile
this software. Installing just the Command Line Tools is not sufficient.
Xcode can be installed from the App Store.
Error: An unsatisfied requirement failed this build.
XCode
がないとダメと言われた.なんだコレは,たまげたなぁ…
もしちゃんと入れている人がいたら試してみて欲しい.
あとはどうにかしてバージョンを切り替えてみて欲しい…
感想
コンパイラって色々あって大変だな〜とづまりすとこ
絶対もっと良いやり方があるのでは?brewはバージョン管理に不向きだしllvm
とclang
は公式サイトからDLして突っ込んで自分でちゃんと関数を組み上げた方がいいんじゃないか?問題は解決したからもう何も考えられないけど…