Note

サイト
最近のコメント
 

2013-03-23

連絡

しばらく行方不明になります。

2013-03-18

[][] gcc-4.8の変更点

相変わらずchangesに何も書かれてませんのでメモっときます

4.7の時の変更が派手だったぶん、今回はおとなしいです。まあでも4.8で一番嬉しいのは-Ogと思う。

Ada2012のattributeの更なる実装

'Overlaps_Storageとか'Importとか'Conventionとか。めぼしいのはだいたい揃った感じ。

'Valueで例外発生時、エラーメッセージ引数文字列が入るようになった

地味に便利と思います。

pragma Overflow_Checks

今までコマンドラインオプションでしかON/OFFできなかったオーバーフロー検出をソース中でON/OFFできるように。

pragma Loop_Optimize

http://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Loop_005fOptimize.html

Adaフロントエンドでも自動ベクトル化ですよ奥さん。

pragma No_Inline

要るよね。

pragma Warnings

バックエンドの警告も操作できるように。

アドレス値の配置が自由に

今まで、アドレス値は必ずアライメントされてたんですが、x86みたいなアライメントが必須ではないプラットフォームではアライメントしなくてよくなりました。

protected型がロックフリー

できるようになりました。

pragmaが必要です。(デフォルトではread-write lock)

protected Prot_Obj is
   pragma Lock_Free; -- undocumented
   ...
end Prot_Obj;

protectedがロックフリーになったんですか。エッグシェルモデルやめたってことですかね?

https://twitter.com/i_yudai/status/313838044199411714

エッグシェルモデルやめてcompare-and-swapになるっぽいですね。

訂正の訂正。本当にprotected型をロックフリーにできます。

バグ修正

とりあえず直ってるのを見つけられたのは

  • 2引数以上の時のuser-defined indexingのバグが直った。
  • StringとWide_Stringのオーバーロードコンパイラが落ちるバグが直った。
  • discriminantsまわりのバグが直った。

入ってないもの

  • raise expressionはAdaCore版GNATのDev Logにはあるのですが、gccには入ってません。
  • use all typeの実装は進展ないっぽいです。
  • 4.7でControlled型の実現方法が変わって、それ関係結構バグがあったのですが、直ってないです。

2013-03-01 晴→雨

[][] headmaster 2013

URLhttps://github.com/ytomino/headmaster/wiki/Document
前回 → http://d.hatena.ne.jp/ytqwerty/20101025#p1

というわけで良いタイミングですので(?)、headmasterの現状を書いておきます

headmasterと先達プロジェクト

headmasterは、C言語を滅ぼすことを目的としたCのヘッダファイルトランスレータです。やっていることはCILの四番煎じです。ただ、CILが入力、出力ともにC言語をメインとしているのに対し、headmasterはCのライブラリを他言語から使うためのヘッダファイル変換をメインとしています。

SWIGとの違いとしては、完全なプリプロセス/構文解析/意味解析をしていますので、所謂interface fileが不要です。その辺の.hをそのまま入力として扱えます。また、特にラッパーの生成などは行わず、1対1対応の直訳を基本としています。このため、ターゲット言語はCの関数を直接呼べる言語に限ります。まあ、今のところ変換先はAdaしか実装してないわけですが……。

GNAT GPL-fdump-ada-specとの違いは……正直あんまりないです。マクロの扱いやプラットフォームの差を吸収するための#pragmaがある点では今のところ勝ってますが、相手はgccに組み込んであるだけに、未実装部分が無いのと、あと一番大きいC++対応という点では負けています。C++のパーサなんて書きたくありませんのでこの点では負けっぱなし確定。

windows.h

そんなheadmasterも、ついに当初の目標に掲げていたwindows.hの変換に成功しました。

出力例 → http://panathenaia.halfmoon.jp/alang/headmaster/demo/windows_h/

この時は、大多数と言っても良いぐらいのリツィート/ふぁぼりをいただきありがとうございます

三年前の時点では

しかしどのプロジェクトも、windows.hで記述されている意味や内容をすべて把握するには至っていません。

http://d.hatena.ne.jp/h_sakurai/20101026/p1

だったのですが、ここに技術革新が起きました!……というのは嘘で、別にwindows.hぐらいは意味解析までならCILもgcc -fdump-ada-specもとっくの昔に解析できてました(特に後者はgccその物なので当然ですね。h_sakuraiさん、黙っててごめんなさい)。windows.hは量が膨大なだけに軽く対応とは行きませんが、特にトリックめいた書き方がなされてたりするわけではありませんので。後は出力の問題。

そんなわけでトランスレータとしては、細かい点(windef.hとwinnt.h間の循環参照etc)さえ捌ければ、後は問題ないんですよ。難易度ではlibxml2やLinuxのヘッダーのほうが遥かに酷いです。ただ、CILは他言語への変換を目的にしておらず、gcc -fdump-ada-specはそうした個々のヘッダーに構うような小細工がされてない、という程度の差しかないです。

windows.h以外にも各OSの主要ヘッダーは大体いけます。このへん参照。

展望

で、まあ、まだまだ未実装部分も多いのですが、ある程度できたからには使って欲しいのが常です。

理想としては、ある程度活発な言語をサポートして、いろいろ勝手に開発してもらって、その成果をAda側で何もせずに享受する(Ada部分のユーザーは私一人で好きなように弄れる)、という風に持って行ければ……(夢は寝て見ろボケ)

あれ、実は需要無い……?

……そんな皮算用よりリファクタリングが先です。今のコードは動くところまで持っていった段階ですので、汚いったらありゃしないです。人に見せるコードじゃありません。

2013-02-28

導火線

続きを読む

[][] OCaml <-> Ada interoperability

adaside.ads *1

with System.Storage_Elements;
package adaside is
   subtype Value is System.Storage_Elements.Integer_Address;
   use type Value;
   function caml_string_length (S : Value) return System.Storage_Elements.Storage_Count;
   pragma Import (C, caml_string_length);
   function Val_long (X : Long_Integer) return Value is (Value (X) * 2 + 1);

   function The_Func (S : Value) return Value;
   pragma Export (C, The_Func, "ml_the_func");
end adaside;

adaside.adb

package body adaside is
   function The_Func (S : Value) return Value is
      Len : Natural := Natural (caml_string_length (S));
      Ada_S : String (1 .. Len);
      for Ada_S'Address use System.Storage_Elements.To_Address (S);
   begin
      return Val_long (Long_Integer'Value (Ada_S)); -- use 'Value attribute
   end The_Func;
end adaside;

ocamlside.ml

external the_func: string -> int = "ml_the_func";;

print_int (the_func "16#ff#");; (* hexadecimal form of Ada *)

コンパイルと実行

$ gcc -c -gnat2012 adaside.adb
$ ocamlopt ocamlside.ml adaside.o -ccopt /usr/local/lib/gcc/x86_64-apple-darwin10/4.7.2/adalib/libgnat.a
$ ./a.out
255

*1:ここではValue is Integer_Addressとしてますが、ビットフィールド風に定義することでVal_longやらLong_valを撤去できます。ていうかmlvalue.hでもそうなってて欲しい……。valueをそのまま演算するミスは誰でも一度はやらかしますよね!

camlspottercamlspotter 2013/03/01 18:08 がんばって OCaml <-> Ada interoperability を確立してくださいなー

ytqwertyytqwerty 2013/03/01 18:55 いや、呼び出し規約が揃っている以上、がんばる必要なんて全くないわけですが……(↑)
でもOCamlが用意しているFFIのSDKがC用である以上不毛ではあります。
それと、OCamlの実装言語がCだからって、OCamlの代替として勧める言語がCである必要はないと思います。

camlspottercamlspotter 2013/03/04 10:45 すごい! C (C++) 以外でお話しているのを見たのは初めてです!

2013-02-26

[] Not_found

OCamlコードを書くときにいつも迷っていることを書いてみます。超初心者質問。いい知恵ください。Not_foundの扱いです。
コンテナデータがあった場合→データを使う、と無かった場合→データを新規に作る、で分岐する処理は頻出すると思います。

まず普通にif文。

if TABLE.mem key xs then
  let item = TABLE.find key xs in
  ...
else
  ...

これですと、探索を2回やってるわけで、遅そうです。

なので例外。

try
  let item = TABLE.find key xs in
  ... (*1*)
with Not_found -> ...

これですと、(*1*)部分に他にNot_foundを投げるような処理があった場合、例外をもみ消してしまいます。よろしくない。

なのでoption。

match (try Some (TABLE.find key xs) with Not_found -> None) with
| Some item ->
   ...
| None ->
   ...

これですと、Someのところでメモリアロケートが発生しています。こんなことで一時オブジェクトを作るのはGC的によろしくない。

例外の種類を差し替えるとか……。

try
  let item = try TABLE.find key xs with Not_found -> raise My_Not_found_2 in
  ... (*1*)
with My_Not_found_2 -> ...

……酷い無駄なコードな気がします。例外を投げたり受け止めたりというのは、普通に考えてメモリアロケートよりも重いわけで。

他の言語で行儀の悪いコードを書くなら、(*1*)でgotoしてとりあえずtryから出るようなことも可能なのですが、OCamlではそれはできません(ていうかOCaml文化以外の世界ならfindがNULLみたいな値を返して来ますよね、そもそも例外を使うような場面ではない)。一時オブジェクトを作ったりせずに、きれいにtryの範囲を限定するにはどうしたらいいでしょう。
え、一時オブジェクトを気にするな?いやまあそりゃあそうなんでしょうけど……。

camlspottercamlspotter 2013/02/27 12:50 そりゃ deforestation が無いから Some はどうしても allocate されるけどどう見ても short lived だし minor GC の範囲で気にするほどのものではないでしょう。それが気になるなら C で。

一方 option monad の bind chain が長くなって効率が気になる場合は例外を使いますね混ざっても気にしないというか混ざってほしいので。

ytqwertyytqwerty 2013/02/27 13:40 デスヨネー。
まあ最初からそれしか結論は無いわけですが、map.ml覗いてこのEmpty返す関数公開してくれと悶々してるわけです。

camlspottercamlspotter 2013/03/04 10:44 皆さんそういうの待っていられなくなったので、代替標準ライブラリが生まれ、意識高い人はそこに移ってしまいました。バニラでいる限りは残念ながらずっとぼやいているしかないかと。

2013-02-19

[] __gnat_adjust_context_for_raiseの怪

これがわからない。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50678

バグのものは、Mountain Lionでの修正でそれまで__gnat_adjust_context_for_raiseに仕込んであったWorkaroundが不要になって、逆に悪さをするようになっていたというもの。Mountain Lionの時はWorkaroundを回避するようにしたら直った、らしい。

__gnat_adjust_context_for_raiseが何をする関数かといいますと、いくつかのプラットフォームで、シグナルハンドラから例外を投げるときに、sa_sigactionの第3パラメータとしてやってきたstruct ucontext *の補正を行うもの。

なんで補正が必要かというと、シグナルから復帰するためのucontextと、gccのunwinderが使うucontextが微妙に違うから。

うん、ここまではいいんですよ。

でもですよ、なんで、シグナルハンドラ中から投げるとはいえ、gccの例外がシグナルから復帰するためのstruct ucontext *に影響されるのかがわからないのです。

だって、このstruct ucontext *を補正した所で、そもそもこのstruct ucontext *の飛び先はシグナル発生箇所そのものなわけですよ。例外の飛び先は、もっとスタックを巻き戻した先にある例外ハンドラなわけですよ。_sigtramp云々書かれてますけど、_sigtramp中に戻るならともかく、例外はそんなところ飛び越えていくわけで。飛び先は現在IPをDwrafのテーブルから検索して決めるわけで、レジスタの状態をどう戻すかも全部テーブルにあるわけですよ。

関係ないと思いませんか?

_Unwind_RaiseExceptionにこの情報が渡ってる気配のカケラも無いですし。

実際問題俺ランタイムなdrakeはこんな補正無くても動いてます。補正が必要とされてるLeopardLionで。いや、こんな補正が本当に必要なら、世に無数にあるであろうシグナルを例外に変換しているアプリは(Darwinに限らず__gnat_adjust_context_for_raiseがなんかやってるプラットフォームで)軒並み怪しい動作をしているはず。

……ですけど現実にこれで挙動が変わるらしくて、冬の怪談です。

2013-02-09

[][] Adaと64bit呼び出し規約とlldiv

lldivを呼ぶ関数を書いてたらちょっと驚きました。

こういうの。

procedure call_lldiv (x, y : long_long_integer; q, r : out long_long_integer) is
   type lldiv_t is record
      q, r : long_long_integer;
   end record;
   pragma Convention (C, lldiv_t);
   function lldiv (x, y : long_long_integer) return lldiv_t;
   pragma Import (C, lldiv, "lldiv");
   result : lldiv_t;
begin
   result := lldiv (x, y);
   q := result.q;
   r := result.r;
end call_lldiv;

最適化してコンパイルする。

gcc -S -O3 call_lldiv.adb

すると……

	.text
	.align 4,0x90
	.globl __ada_call_lldiv
__ada_call_lldiv:
LFB1:
	subq	$40, %rsp
LCFI0:
	call	_lldiv
	addq	$40, %rsp
LCFI1:
	ret

えっ。

GNATフロントエンドのスカラー値のoutパラメータの扱いは参照渡しではなくて所謂multi-value returnで、%rax、%rdxで返すっぽいです。で、64ビット呼び出し規約では小さな構造体もレジスタ返しってことになっているらしくて、lldivも値を%rax、%rdxで返すっぽくて、引数並びも一致してるから何もせずにcallして何もせずにretすることになったようです。

ですもんで-m32ですとこうなる。

	.text
	.align 4,0x90
	.globl __ada_call_lldiv
__ada_call_lldiv:
LFB1:
	pushl	%esi
LCFI0:
	subl	$56, %esp
LCFI1:
	movl	76(%esp), %eax
	leal	32(%esp), %ecx
	movl	80(%esp), %edx
	movl	%ecx, (%esp)
	movl	64(%esp), %esi
	movl	%eax, 12(%esp)
	movl	68(%esp), %eax
	movl	%edx, 16(%esp)
	movl	72(%esp), %edx
	movl	%eax, 4(%esp)
	movl	%edx, 8(%esp)
	call	_lldiv
LCFI2:
	subl	$4, %esp
LCFI3:
	movl	32(%esp), %eax
	movl	36(%esp), %edx
	movl	%eax, (%esi)
	movl	40(%esp), %eax
	movl	%edx, 4(%esi)
	movl	44(%esp), %edx
	movl	%eax, 8(%esi)
	movl	%edx, 12(%esi)
	movl	%esi, %eax
	addl	$56, %esp
LCFI4:
	popl	%esi
LCFI5:
	ret	$4

で、これを見てしまうと、どうせならスタックを$40ほど取って戻してしてるのも最適化して欲しくて、そうすれば-foptimize-sibling-callsも働いてjmp一個にできるはずなんですけれど、このスタックが強敵で色々オプションを試しても消えてくれません。なんでー?

2013-02-08

[] HFS+のファイル名を比較する厳密な方法

Macユーザーなら、HFS+の勝手なファイル名の「正規化」には悩まされてますよね!

まず浅い理解として、HFS+はファイル名をNFDに正規化する。次に、HFS+は互換漢字統合漢字にはぜず、それ以外をNFDに正規化する。まあそれで合ってるんですけれど、実際にはそんな簡単な話ではありません。

この記事では、カーネルが行なっているファイル名の変換の再現に挑戦します。

ソースコード

こういうもの一次ソースを見るのが一番です。外から挙動を推測したって見落としは出ます。Darwinのカーネルはオープンソースになってますので以下で見ることができます。

ファイルアクセスは、Darwinカーネルの中のDarwinのカーネルであるXNUというモジュールが担当してます。

http://www.opensource.apple.com/source/xnu/

うろうろ

まず、ファイルアクセスAPIからやって来るHFS+のドライバ入り口はどこでしょうか?

hfs_vnops.cにある関数テーブルがそれっぽいですが、このファイルではファイル名の処理はしていません。ところどころで、cat_なんとかいう関数を呼んでますので、多分これでしょう。

というわけでhfs_catalog.cに進みます。色々やってますが、ファイル名の処理としてはbuildkeyが怪しい。utf8_decodestrという「いかにもそれっぽい」関数を呼んでいます。

utf8_decodestr(..., ':', UTF_ESCAPE_ILLEGAL | UTF_DECOMPOSED);

':'は、実は':'と'/'は逆に記録されているというヤツでしょう。Finderではファイル名に'/'を使えますが、POSIX APIからは':'としてアクセスできます。

プログラム中では(Cocoaのよくわからないレイヤーを使わない限り)POSIX APIからは'/'は区切り、':'はファイル名に使える文字で一貫してますから、これは豆知識として頭の片隅に押しやってしまいましょう。

もうひとつ重要なのが、CompareCatalogKeys(から呼ばれているFastRelString)とCompareExtendedCatalogKeys(から呼ばれているFastUnicodeCompare)です。

buildkeyでUTF-8で渡されたファイル名を内部名にデコードして、で、このデコードされた名前がそのままファイル名になるのですが、HFS+には正規化(モドキ)の他にもうひとつ、大文字/小文字を無視するという特徴があります。

こっちの方は大文字/小文字の区別を行うフォーマットもある(ディスクユーティリティでフォーマットできる)のですが、使われているのは大文字/小文字を無視するフォーマットのほうです。

で、まあ見ていくと、FastRelStringは、所謂Pascal文字列case insensitive比較で、文字コードはmac romanっぽいです。互換用?

FastUnicodeCompareがUnicodeのcase insensitive比較です。

これで、再現するべきことはわかりました。

utf8_decodestrはファイル名のデコードを行う関数です。この関数の動作を追うことで、openやなんかのシステムコールに渡したファイル名が実際にどういう名前でディスク上に記録されるかがわかります。

FastUnicodeCompareはファイル名の比較を行う関数です。この関数の動作を追うことで、大文字/小文字が同一視される条件がわかります。

Unicodeテーブル

先にテーブルについて。

Unicodeというのは文字の並びに規則性のないコード体系で、扱うためにはテーブルが必要です。普通にUnicodeの処理を行うだけなら、http://www.unicode.org/からUCDを持ってくれば、いや、その辺のUnicodeのライブラリを使ってしまえばいいのですが、事はそう簡単ではありません。

ソースコードのCopyrightに書かれた年を見ればわかりますが、HFS+が実装されたのは2000年前後です。テーブルのバージョンを合わせないと挙動が変わってしまいます。

というわけで、XNUのソースコードに含まれるUnicodeテーブルをそのまま使いましょう。一番確実です。

正規化用 http://www.opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/vfs/vfs_utfconvdata.h

比較用 http://www.opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/hfs/hfscommon/Unicode/UCStringCompareData.h

探し回っているうちに圧縮されたバージョンの比較用テーブルも見つけました。内容は同じですが展開が必要です。

比較用(圧縮版) http://www.opensource.apple.com/source/boot/boot-132/i386/libsaio/hfs_CaseTables.h

utf8_decodestr

http://www.opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/vfs/vfs_utfconv.c

「古いUnicodeテーブル」を用いて、UTF-8をUTF-16に直しつつ、以下の展開を行なっています。

  • UTF-8のillega sequenceは、%XX (XXは16進2桁でA-Fは大文字) としてエスケープ。これはターミナルからでも簡単に試せて楽しいです。
  • decompose。decompose結果も再帰的にdecomposeしてます。互換漢字は最初からテーブルに入ってません。一応比べてみましたが、互換漢字以外は1B06〜1B43も入ってないです。これは単にテーブルが古いためと思われます。
  • 連続するcombining charactersのソート。decomposeの結果出現したものと、最初から文字列中に存在したものを合わせて、combining classで安定ソートを行なってます。これはUnicodeの仕様通りですが、やはりテーブルが古いためcombining characterとして収録されたコードがだいぶ少なく(322しかない。最新のは倍あります)、最新のテーブルを使ってしまうと食い違いが大きくなりそうです。

FastUnicodeCompare

http://www.opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/hfs/hfscommon/Unicode/UnicodeWrappers.c

古いテーブルを用いて、UCS-2(16ビット)の範囲内で、simple case mappings(コードポイント数は変化しない)で小文字にしながらの比較を行なっています。

簡単。(小文字じゃなくてcase foldingすべきでは……なんて言ってもしょうがない)

で、何を使ってどれを再実装すれば?

CoreFoundationにはCFStringGetFileSystemRepresentationという関数があって、utf8_decodestr同様の処理を行なってくれます。

でも大抵それだけでは済まなくて、CFStringGetFileSystemRepresentationの逆変換が欲しくなると思います。主に、NFDモドキにされてしまったファイル名をNFCに戻して、他のOSと相互運用できるようにする、等の用途が考えられます。でも、CoreFoundationはそういった関数は用意してくれていません。

かといって、単にNFC変換を行なってしまうと、互換漢字は潰れるわ、合成除外文字は分解されたままだわで、厳密な逆変換にはなりません。

そこでiconvです。iconvはHFS+のファイル名の変換を"utf8-mac"としてサポートしてます。(Macでもこんな妙な変換はファイル名だけにしか使われてませんので、"utf8-mac"は誤解を生むという議論は既出)
iconvなら、iconv -f utf8-mac -t utf-8 で逆変換もOKという、iconv素晴らしいよiconv。
Frameworkを使いたくない、POSIXの範囲だけでやりたい、等の理由でCoreFoundationをリンクしたくない場合も、iconvなら許せるでしょう、たぶん。

iconvも許せなければ、再実装する羽目になります。

FastUnicodeCompareのほうは、/usr/lib以下の.dylibを調べて回ったのですが、どうも該当するデータは無さそうですので、比較まで行いたければ再実装してやる必要があります。

あとまあ、Macだからって無条件にこういった処理を行うのではなくて、一応statfsぐらいはして、HFS+でなければ素通ししてやるぐらいの余裕は欲しいです。Macでも他のフォーマットを使えるのです。

NTFSを見つけた時のためにLCMapStringを再現する方法は……どなたかお願いします。

立ち返って

こういったファイルシステムの知識を必要とする実装は、厳密な処理をするためには必要ですが、普通もっと簡単な方法があります。

それは、「ファイルシステムはファイル名を変形することがある(HFS+に限らないしUnicodeに限らない)」という前提を受け入れることと、「ファイル名が変形された場合でも最初の名前でアクセスし続けることはできる」のを利用することです。

例えばファイルの上書き確認であれば、ファイルを列挙してファイル名を確認するみたいな処理はダメで、試しにstatでもしてみてアクセスできるならファイルは存在しているとみなすみたいな処理が良いってことです。

これならFAT16フロッピーディスクを急に使いたくなって、ファイル名が8.3に切り詰められても大丈夫でしょう、やったね!

でも、それだけでは済まない場合も出てくるとは思いますので、そういうときはぜひ、厳密な比較を実装してください。NFD変換なんかで済まさないで。

2013-01-11

[][] 振り返ってみる

Ada言語の現状」という検索キーワードでここにたどり着いた方がおられるらしい。ふと振り返ってみると、私が最初にAdaに触れてから、随分とAdaも変わりました。昔語りをしてみましょう。

続きを読む

2012-12-30

[] Arch LinuxVirtualBoxインストールしてみた

今年は何もしませんでしたね……我ながら酷い。4月に、headmasterでLinuxのstring.hが変換できないというissueをいただいて、12月も末になってようやく修正した、そんな年です。

こうも時間がかかったのは、VirtualBoxを使うようになったのが結構最近だからで、私の日常用途にはMacとWindows、あと借りているさくらレンタルサーバFreeBSDなのでそれ、と、OSはそれぐらいしか使ってないのです。所謂ガラケーなのでAndroidとも無縁です。Linuxなんて必要性も空いているPCもない。で、個人的な事なんですが10年前に作った自作PCをPC3Rに有償で回収してもらいました。結構面倒くさかった。リサイクルマークの付いているPCを買いましょう。で、Windows PCが減りましたし、Vista以降のWindowsに付いて行く気は全くないですし、最近はSecureBoot*1なんて物騒な話題もありますし、XP環境を保存する目的でVirtualBoxを使い出しました。クリーンインストール時のスナップショットを残しておけば変なものを入れても巻き戻せます。ゲストスワップするかホストでスワップするかの違いしか無いのでページファイルを消してしまえます。sdeleteを使えばVDIを圧縮できます。XPというのはなぜこんなに仮想マシンと相性がいいのでしょう。で、どうせならということでFreeBSDもLinuxも仮想マシン環境を作りました。どうでもいい経緯終わり。日本語言い訳しても伝わるわけがありません。

headmasterはヘッダーファイル変換ツールです。これを作るのが目的であり、Linuxのヘッダーファイルやライブラリにもだらだら文句を書きたいのが本音です。今これをLinuxから読んでおられる方はちょっとstdio.hを開いてみてください。__REDIRECTなんて書かれてますが展開してみると同じ関数が2回宣言されていたりします。しかも2回目は__asm__("...")付きです。この__asm__はインラインアセンブラではなくて、オブジェクトファイル上の外部名を指定するためのものです。つまり一個目のfscanfは_fscanfを、二個目のfscanfは___isoc99_fscanfを呼ぶための宣言であり、全くの別物です。こんなのを警告もなしに通すgccもどうかしてます。一個目と二個目の間に呼び出しを書いて、それがインライン展開されたりしたら呼ばれるのはどっちになるんでしょう?まあそんなのも今はどうでもいいです。

Arch LinuxをVirtualBoxにインストールしてみた…私がメモとしてここに残しておきたいのはこれなんです。この手の記事を書くのは久しぶりなのでテンションがおかしいのは勘弁してくださいな。

といっても、手順そのものは本家の解説や、とてもありがたい先人の記録を参考に進めていけば、手間こそかかれ特に難しいところはありませんでした。でもこの手間が問題で、そう、Arch Linuxというのはインストーラが付いてない素敵ディストリビューションなのです。*2 インストールイメージから起動するとLive CDみたいにArch Linuxが普通に立ち上がります。そこからコマンドぽちぽち打ってインストーラがやる手順を手動で再現しないといけません。なんでわざわざそんなもんをと思われるかもしれませんが、X無し、可能な限りの最小構成でインストールできるLinuxを探したんですよ、configureを走らせたりヘッダーファイルを引っこ抜いたりすることだけが目的ですので。

ようし、前置きは終わった。一気にいくぜ!

続きを読む

*1名前に反してWindows以外が起動できなくなるだけのゴミらしいです。最近はどこも囲い込みに必死で困る。

*2:昔はインストーラがあったが消えたらしい?

 
カレンダー
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 |