スキップしてメイン コンテンツに移動

MacPorts の GHC が macOS Sierra でビルドできない件の回避策 (i.e. MacPorts のパッチの当て方)

多分じきに修正されて腐る内容だが、MacPorts の port にパッチする方法としてまとめておく。

会社を辞めたので久方ぶりにブログを書こうと思い、pandoc をインストールしようとしたところ GHC のビルドがコケた。 ログをみると GetTime.c というファイルのコンパイルに失敗している。MacPorts の Trac を検索してみると果たして既知の問題だった。「Haskell 処理系とそれに依存する全パッケージがインストールできない」問題が四ヶ月前に報告されていまだに直っていないという大らかさ。

幸いチケット内にパッチが提案されていたのでこれを適用してことなきを得た。

まずローカルに GHC の port をコピーし、MacPorts の ports tree として登録する:

$ sudo -i
Password:
# mkdir -p /usr/local/ports/lang/ && cd /usr/local/ports/lang/
# cp -r $(port dir ghc) ./
# cd ghc && port lint

# cp /opt/local/etc/macports/sources.conf{,.orig}
# vi /opt/local/etc/macports/sources.conf  # 作成したディレクトリをデフォルトの ports tree の前に追記する
# diff -u /opt/local/etc/macports/sources.conf{.orig,}
--- /opt/local/etc/macports/sources.conf.orig   2017-02-10 14:10:00.000000000 +0900
+++ /opt/local/etc/macports/sources.conf        2017-02-10 14:11:04.000000000 +0900
@@ -29,4 +29,5 @@
 # sites, etc.), the primary MacPorts source must always be tagged
 # "[default]", even if switched from the default "rsync://" URL.

+file:///usr/local/ports
 rsync://rsync.macports.org/release/tarballs/ports.tar [default]

# cd /usr/local/ports && portindex

これで ghc をインストールする際は /usr/local/ports 以下にあるソースが使われるようになった。port dir ghc コマンドを実行すると /usr/local/ports/lang/ghc と表示されるはずである。

続いてパッチを配置して Portfile を書き換える:

# curl -Lo $(port dir ghc)/files/patch-Fix-GetTime.c-on-Darwin-with-clock_gettime.diff https://trac.macports.org/raw-attachment/ticket/52582/patch-Fix-GetTime.c-on-Darwin-with-clock_gettime.diff
# cp $(port file ghc){,.orig}
# port edit ghc  # Portfile を編集する専用コマンド。要するに vi /usr/local/ports/lang/ghc/Portfile
# diff -u $(port file ghc){.orig,}
--- /usr/local/ports/lang/ghc/Portfile.orig     2017-02-10 14:24:42.000000000 +0900
+++ /usr/local/ports/lang/ghc/Portfile  2017-02-10 14:40:40.000000000 +0900
@@ -56,7 +56,8 @@

 patchfiles      patch-configure-workaround-bsdsed-incompatibility.diff \
                 patch-configure-disable-docs.diff \
-                patch-unix_lib_osx_sandbox_compatibility.diff
+                patch-unix_lib_osx_sandbox_compatibility.diff \
+                patch-Fix-GetTime.c-on-Darwin-with-clock_gettime.diff

 livecheck.type  none
 test.run        yes

これで改変は終わり。一般的にパッチで済む変更は port dir 以下の files ディレクトリにパッチを置いて Portfile を書き換えるだけで良い。

あとはビルドできるか試して実際にインストールするだけ。異様に時間がかかるのは GHC が巨大だからであってパッチが悪いわけではない:

# port clean ghc
# port build ghc  # この間に昼食に行って仮眠してその後コーヒーを入れるなどする
--->  Computing dependencies for ghc
--->  Fetching distfiles for ghc
--->  Verifying checksums for ghc
--->  Extracting ghc
--->  Applying patches to ghc
--->  Configuring ghc
--->  Building ghc
...
# port install ghc

この記事は Markdown で書いているので、これが公開されているということは筆者が pandoc をインストールできたということである。

参考

コメント

このブログの人気の投稿

Perl 5 to 6 - コンテキスト

2011-02-27: コメント欄で既に改訂された仕様の指摘がありました ので一部補足しました。 id:uasi に感謝します。 これはMoritz Lenz氏のWebサイト Perlgeek.de で公開されているブログ記事 "Perl 5 to 6" Lesson 06 - Contexts の日本語訳です。 原文は Creative Commons Attribution 3.0 Germany に基づいて公開されています。 本エントリには Creative Commons Attribution 3.0 Unported を適用します。 Original text: Copyright© 2008-2010 Moritz Lenz Japanese translation: Copyright© 2011 SATOH Koichi NAME "Perl 5 to 6" Lesson 06 - コンテキスト SYNOPSIS my @a = <a b c> my $x = @a; say $x[2]; # c say (~2).WHAT # Str() say +@a; # 3 if @a < 10 { say "short array"; } DESCRIPTION 次のように書いたとき、 $x = @a Perl5では $x は @a より少ない情報—— @a の要素数だけ——しか持ちません。 すべての情報を保存しておくためには明示的にリファレンスを取る必要があります: $x = \@a Perl6ではこれらは反対になります: デフォルトでは何も失うことなく、スカラ変数は配列を単に格納します。 これは一般要素コンテキスト(Perl5で scalar と呼ばれていたもの)及びより特化された数値、整数、文字列コンテキストの導入によって可能となりました。無効コンテキストとリストコンテキストは変更されていません。 特別な構文でコンテキストを強制できます。 構文 コンテキスト ~stuff 文字列 ?stuff 真理値 +stuff ...

LIBLINEAR 2.41 で One-class SVM が使えるようになったので Perl から触ってみよう

改訂 (Sep 15, 2020): 必要のない手順を含んでいたのでサンプルコードと記述を修正しました。 CPAN に Algorithm::LibLinear 0.22 がリリースされました (しました。) 高速な線形 SVM およびロジスティック回帰による複数の機械学習アルゴリズムを実装したライブラリである LIBLINEAR への Perl バインディングです。 利用している LIBLINEAR のバージョンが LIBLINEAR 2.30 から LIBLINEAR 2.41 に上がったことで新しいソルバが追加され、One-class SVM (OC-SVM) による一値分類が利用可能になっています (しました。) OC-SVM って何 一値分類を SVM でやること。 一値分類って何 ある値が学習したクラスに含まれるか否かを決定する問題。 HBO の「シリコンバレー」に出てきた「ホットドッグ」と「ホットドッグ以外」を識別するアプリが典型。「ホットドッグ以外」の方は犬でも神でも一つの指輪でも何でも含まれるのがミソ。 二値分類の場合正反両者のデータを集める必要があるのに対して、一値分類の学習器は正例データのみしか要求しない (ものが多い。) 主な用途は外れ値検出で、もちろんホットドッグやホットドッグ様のものを検出したりもできる。 使い方 手順自体は他の二値ないし多値分類問題と同じです。つまり、 訓練パラメータを決めて 訓練データセットで訓練して テストデータセットで確度を検証して 十分良くなったらモデルを保存する といういつもの流れ。 訓練パラメータ use 5.032 ; use Algorithm::LibLinear ; my $learner = Algorithm::LibLinear ->new( epsilon => 0.01 , nu => 0.75 , solver => ' ONECLASS_SVM ' , ); solver => 'ONECLASS_SVM' が一値分類用のソルバです。LIBLINEAR の train コマンドで言うところの -s 21 。 OC-SVM の良いところは (ハイパー)...

Perl の新 class 構文を使ってみる

Perl 5 のオブジェクト指向機能は基本的には Python の影響を受けたものだが、データを名前空間 (package) に bless する機構だけで Perl 4 以来の名前空間とサブルーチンをそのままクラスとメソッドに転換し第一級のオブジェクト指向システムとした言語設計は驚嘆に価する。 実際この言語のオブジェクトシステムは動的型付言語のオブジェクト指向プログラミングに要求されるおよそあらゆる機能を暗にサポートしており、CPAN には Moose を筆頭とした屋下屋オブジェクトシステムが複数存在しているがその多くは Pure Perl ライブラリである。つまり「やろうと思えば全部手書きで実現できる」わけである。 そういうわけで Perl のオブジェクト指向プログラミングサポートは機能面では (静的型検査の不在という現代的には極めて重大な欠如を除けば) 申し分ないのだが、しかし Moose その他の存在が示しているように一つ明らかな欠点がある。記述の冗長さだ。 コンストラクタを含むあらゆるメソッドは第一引数としてレシーバを受ける単なるサブルーチンとして明示的に書く必要があるし、オブジェクトのインスタンス変数 (a.k.a. プロパティ / データメンバ) は bless されたデータに直接的ないし間接的に プログラマ定義の方法 で格納されるためアクセス手段は実装依存である。これはカプセル化の観点からは望ましい性質だが、他者の書いたクラスを継承するときに問題となる。ある日データ表現を変更した親クラスがリリースされると突然自分の書いた子クラスが実行時エラーを起こすようになるわけだ。 そうならないためにはインスタンス変数へのアクセスに (protected な) アクセサを使う必要があるのだが、そのためには親クラスが明示的にそれらを提供している必要があるし、そもそも Perl にはメソッドのアクセス修飾子というものがないので完全な制御を与えるならばオブジェクトの内部状態がすべて public になってしまう。 そのような事情もあり、特にパフォーマンスが問題にならないようなアプリケーションコードでは Moose のようなリッチな語彙を提供するオブジェクトシステムを使うことが 公式のチュートリアルでも推奨 されてきた。Perl コアのオブジェクトシステムの改良は...

(multi-)term-mode に dirtrack させる zsh の設定

TL;DR .zshrc に以下を書けば良い: # Enable dirtrack on (multi-)term-mode. if [[ " $TERM " = eterm * ]]; then chpwd() { printf '\032/%s\n' " $PWD " } fi 追記 (May 14, 2025): oh-my-zsh を使っていれば emacs プラグインが勝手にやってくれる: plugins = ( emacs ) 仔細 term-mode は Emacs 本体に付属する端末エミュレータである。基本的には Emacs 内でシェルを起動するために使うもので、古い shell-mode よりも端末に近い動きをするので便利なのだが、一つ問題がある。シェル内でディレクトリを移動しても Emacs バッファの PWD がそのままでは追従しない点だ。 こういう追従を Emacs では Directory Tracking (dirtrack) と呼んだりするが、 shell-mode や eshell ではデフォルトで提供しているのに term-mode だけそうではない。 要するにシェル内で cd してもバッファの PWD は開いた時点のもの (基本的には直前にアクティヴだったバッファの PWD を継承する) のままなので、移動したつもりで C-x C-f などをするとパスが違ってアレっとなることになる。 実は term-mode にも dirtrack 機能自体は存在しているのだが、これは シェルがディレクトリ移動を伴うコマンドを実行したときに特定のエスケープシーケンスを含んだ行を印字することで Emacs 側に通知するという仕組み になっている。 Emacs と同じく GNU プロジェクトの成果物である bash は Emacs 内での動作を検出すると自動的にこのような挙動を取るが、zsh は Emacs の事情なんか知ったことではないので手動で設定する必要がある。 まずもって「ディレクトリ移動のコマンドをフックする」必要がある訳だが、zsh の場合これは簡単で cd / pushd / popd のようなディレクトリ...

Perl 5 to 6 - 遅延性

これはMoritz Lenz氏のWebサイト Perlgeek.de で公開されているブログ記事 "Perl 5 to 6" Lesson 12 - Laziness の日本語訳です。 原文は Creative Commons Attribution 3.0 Germany に基づいて公開されています。 本エントリには Creative Commons Attribution 3.0 Unported を適用します。 Original text: Copyright© 2008-2010 Moritz Lenz Japanese translation: Copyright© 2011 SATOH Koichi NAME "Perl 5 to 6" Lesson 12 - 遅延性 SYNOPSIS my @integers = 0..*; for @integers -> $i { say $i; last if $i % 17 == 0; } my @even := map { 2 * $_ }, 0..*; my @stuff := gather { for 0 .. Inf { take 2 ** $_; } } DESCRIPTION Perlプログラマは怠けがちです。彼らが使うリストも。 ここで怠惰という言葉が意味するのは、評価が可能な限り遅延されるということです。 @a := map BLOCK, @b のようなコードを書いたとき、ブロックは一切実行されません。 @a の要素にアクセスしようとしたときだけ map は実際にブロックを実行し、必要とされる分だけ @a を埋めます。 代入ではなくバインディングを使っていることに注意して下さい: 配列への代入は先行評価を強制することがあります(コンパイラがリストの無限性に気づかない限り; 無限リスト検出の詳細はまだ固まっていません)。 バインディングはそのようなことがありません。 遅延性は無限リストの取り扱いを可能にします: 引数すべてに操作を行うようなことさえしなければ、評価された要素に必要なだけのメモリしか必要としません。 しかし落とし穴があります: 長さの...