Mac OS X Lion で javac コマンドが文字化けするのを直す

Mac OS X のターミナルで、javac を実行すると、デフォルトの文字エンコーディングがなぜか、Shift JIS になっているせいで文字化けしてしまう。

対処方法を求めてググると、以下の記事がヒットした。

(Mac OS X Tips::Snow Leopard)ターミナルでのJava文字化け対策 - jitsu102の日記

上の記事では、aliasを使った方法で、

alias javac 'javac -J-Dfile.encoding=UTF-8'

というふうに、rcファイルに定義しておくことで対処していたが、もうちょっといい方法があるんじゃないかなーと思い、探したら、Stack Overflow に自分が期待していたのに近い回答があった。

環境変数 JAVA_TOOL_OPTIONSVMを起動するときに渡すオプションを記述しておけば、いちいちjavaのツールを実行するときにオプションを渡さなくても良いらしい。

ということで、自分の場合以下のような記述を、.bashrc に記述することで対処した。

export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

ところで、なんで Shift JIS なんでしょうね? 最初っから UTF-8 で良い気がするのに... Windows を基準にしているため?

注意

JAVA_TOOL_OPTIONS では、前述のaliasの例のように'-J'は不要。理由は、'-J'はjavacのオプションで、「Java VM に渡すオプションを指定するためのオプション」であったが、JAVA_TOOL_OPTIONは、それ自体が Java VM に渡すオプションであるため。

はてなブックマーク新ユーザページ(マイページ)の招待枠アリマス

新ユーザページについては、以下を参照。
現在は招待制:はてなブックマークで新ユーザーページ公開 Twitter・Facebookと連携した「マイホットエントリー」も - ねとらぼ
http://nanapi.jp/31712/
本日βリリースしたはてなブックマークの新ユーザーページまとめ


はてなブックマークの新ユーザページ(マイページ)いいですね。

タイトルに釣られついつい、読んでしまう 2ch 系のブログとかがあまり出なくなったのがホットエントリに出なくいい感じです。また、「インタレスト」で自分の興味のあるキーワードに関連するエントリも集約できるので便利です。

今はまだベータ運用中で「招待制」ということですが、手元に招待枠が 5つ あまっています。招待希望の方はこのエントリにコメント頂ければ招待します。

LLVMで「コンソールに"Hello World"を出力するコード」を生成するコード書いた

久しぶりに日記書きます。

LLVMで遊んでみます。(まだよく分かっていないことが多いので間違ってたらコメントもらえると助かります)

LLVMとは、コンパイラ基盤とかいうやつ。
簡単にオレオレ言語のコンパイラが作れたり、はたまた、LLVM IR という中間表現を利用して、C/C++ソースコードJavascriptソースコードに変換したりとか、いろいろ面白そうなことに使えるみたいです。

さっそく Hello world してみます。

以下の手順を実行するには、LLVM Core がインストールされている必要があります。
私の環境は Mac OS X ですので、 Homebrew を使って brew install llvm でインストールできました。

確認時点のバージョンは

$ llc -version
Low Level Virtual Machine (http://llvm.org/):
  llvm version 2.9
  Optimized build.
  Built Nov 29 2011 (23:32:23).
  Host: x86_64-apple-darwin11
  Host CPU: corei7

  Registered Targets:
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64

でした。

コンソールに "Hello world" と出力する LLVM アセンブリコード を生成する C++ コード

ちょっとややこしいですが、「コンソールに"Hello world"と出力するコード」を LLVMが提供するクラス群/コマンド群を使って生成してみます。

上記のコードを hello.cpp というファイル名で保存したという前提で手順を続けます。

上記のコードをコンパイルしてみる

上記のコードをコンパイルするには、

$ g++ -o hello `llvm-config --libs core --cxxflags --ldflags` hello.cpp 

と打ち込みます。
すると、hello という実行ファイルができます。

helloを実行して、LLVM アセンブリコードを生成する

では、コマンドプロンプト./hello と打ち込んでみます。すると、以下のようなC言語に似たソースコードが出力されます。

; ModuleID = 'Hello world module'

@.str = private constant [18 x i8] c"Hello llvm world.\00"

define i32 @main() {
entry:
  %0 = call i32 @puts(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0))
  ret i32 0
}

declare i32 @puts(i8*)

これが、LLVM アセンブリコードです。

LLVM アセンブリコードからビットコードを生成してJITで実行する

アセンブリ言語からマシンコードを生成する、asコマンドに相当するのが、llvm-asです。
ただし、llvm-asはネイティブなマシンコードの代わりに、ビットコード(Bitcode)という LLVMの中間表現(LLVM IR)をバイナリ表現に置き換えたものを出力します。

hello が出力した、LLVM アセンブリコードを llvm-as に渡してビットコードを生成してみます。

$ ./hello > hello.ll   # helloが生成する LLVM アセンブリコードを hello.ll に出力
$ llvm-as hello.ll     # hello.ll をアセンブルして hello.bc を出力

これで、カレントディレクトリにhello.bcというファイルが出来ているはずです。

llvm-asは標準入力を読み込ませることができるので、以下のようにやっても同じ結果となります。

$ ./hello | llvm-as -o hello.bc

この場合、-o hello.bcのように明示的に出力ファイル名を指定してあげる必要があるので注意。

ビットコードをJIT上で実行してみる

ビットコードを lliコマンドに渡すと、JIT(Just-In-Time コンパイラ)上で実行することができます。

$ lli hello.bc
Hello llvm world.

無事、"Hello llvm world." とコンソールに表示されたら成功です。

ビットコードから LLVM アセンブリコードを取り出す

ちなみに、llvm-disコマンドを使うと ビットコードから LLVM アセンブリコード を取り出すことができます。

以下のように使います。

$ llvm-dis hello.bc

すると、hello.ll というファイルに LLVM アセンブリコードが出力されます。
./hello を実行したのと同じ LLVM アセンブリコードが出力されているものと思います。
llvm-di hello.bc -o -とすると、標準出力にコードを出力できます。

ビットコード又は LLVM アセンブリコードからネイティブなアセンブリコード*1に変換する

llcコマンドにビットコードまたは LLVM アセンブリコード を渡すとターゲットアーキテクチャ向けのアセンブリコードが生成できます。

$ llc hello.bc

または、

$ llc hello.ll

を実行すると、hello.s がカレントディレクトリに作成されます。

hello.s の中身は、以下のようなアセンブリ言語ソースコードになっています。(生成されるアセンブリ言語ソースコードはOSやCPUアーキテクチャによって異なる場合があるので、まったく一緒とはならないかもしれません...)

  .section  __TEXT,__text,regular,pure_instructions                                                                                    
  .globl  _main
  .align  4, 0x90
_main:                                  ## @main
## BB#0:                                ## %entry
  pushq %rax
  leaq  L_.str(%rip), %rdi
  callq _puts
  xorl  %eax, %eax
  popq  %rdx
  ret

  .section  __TEXT,__const
L_.str:                                 ## @.str
  .asciz   "Hello world"


.subsections_via_symbols

アセンブリ言語ソースをコンパイルして実行ファイルを得る

上記で生成したアセンブリ言語ソースコードは、gccコマンドでコンパイルできます。

$ gcc hello.s

すると、a.out がカレントディレクトリに出力されているので、これを実行すると

$ ./a.out
Hello llvm world.

のように出力されたら成功です。

これで無事、
LLVMアセンブリコード生成>(ビットコード生成)>ネイティブなアセンブリコード生成>実行コード生成>コード実行
の手順で、"Hello world"が出力できました。

次回は、オレオレ言語のコンパイラを作る手順を紹介してみたいと思います。

参考

The LLVM Compiler Infrastructure Project
LLVMプロジェクトのオフィシャルページ

Getting Started with LLVM System
LLVMをはじめよう」的なドキュメント

Try out LLVM and Clang in your browser!
C/C++ソースコードを、ターゲットCPU向けアセンブリコード、あるいは LLVMアセンブリコード や そのコードを生成する LLVMAPIを使ったC++コード を生成することができるCGI

Writing Your Own Toy Compiler Using Flex, Bison and LLVM (gnuu.org)
Flex, Bison を使ってオレオレ言語のコンパイラを作る手順を紹介した記事(記事に掲載されているサンプルコードは古いので、最新のコードは http://github.com/lsegal/my_toy_compiler を参照したほうがいい)

LLVM で hello, world - 言語ゲーム
この記事を書くのにとても参考になりました。

*1:「ネイティブなアセンブリコード」と書いているが、この表現が正しいのかは良く分かっていない。llvmのドキュメントを直訳すると、「特定のアーキテクチャ向けのアセンブリ言語」(assembly language for specified architecture)という表現

Growl for Windows の 2.0.7 がリリースされた(あと、最近のGfWとか)

GfW version 2.0.7 released - growl for windows | Google Groups

を適当に翻訳。間違いとかあればコメントしてもらえると嬉しいです。

2.0.7 での変更点 (v2.0.7.1)

  • 全てのアイコンを本家 Mac 版の新しいデザインにあわせた。
    こんな感じ:20110918162827
  • 履歴のテキストをコピー可能にした(項目を選択してCtrl+Cでコピー)
  • 履歴に保持する期間を利用者が設定できるようにした(user.configのHistoryDaysToStore)
  • Websocketのプロトコルバージョン draft-ietf-hybi-thewebsocketprotocol-14をサポートするように変更した。
  • 古い履歴のサムネイル画像がディスクから削除されていない問題を修正した。
  • 高解像度設定を起因とする標準ディスプレイスタイルの問題を修正した。
  • コールバックのデータに含まれる改行文字(\n)が正しく扱われない問題を修正した。

※また、何かGfW本体の問題について困っている点があれば、この記事にコメントしてもらえれば、気が向いたときにMLやプロジェクトの Issue tracker などに登録するかもしれません。

その他

"GfW Apprication Integration Guide"の日本語訳が、Natsuki Mori さんによって進行中っぽいです。応援しとこう。

とどちらを使うべきか?

以下の記事の抄訳
C++ Tip : Should I use iostream.h or iostream? - CodeProject

結論から言うと、iostream を使うべき。

理由として、挙げられているのは以下のとおり

  • .hという記述方法は5年も前に廃止された。廃止されたものを使い続けるのはよろしくない。
  • がテンプレート化されたクラスや、ワイドキャラクタをサポートしているのに対して、は char しかサポートしていない。
  • C++標準仕様においてのインターフェースは微妙に変更されている。従って、といくつか違いが存在する。
  • コンポーネントは std 名前空間に定義されるが、はグローバルに定義される。

上記のような違いから、を混在させて使用すると、問題が発生する場合があるので注意が必要、とのこと。

追記:2011/08/29

コメント頂いたので、もう少し調べてみた。
そもそも、上記に挙げているiostream.hというヘッダファイルは「標準」には存在しなかったようだ。おそらく、標準が固まる以前に特定のコンパイラに付属していたものに関する記述と思われる。

標準で提供しているヘッダファイルの名前に関する過去の経緯については、以下のページが参考になる。(回答内容を裏づける公式な情報は見つけ切れなかったが、おそらくそのとおりじゃないかと思う)

なぜ、C++の標準ヘッダをインクルードするとき拡張子をつけないのか。 - C・C++ - 教えて!goo

あと参考になりそうなページ

OS X Lion の「Web共有」機能でWordPress動かそうとしたら、"unix:///var/mysql/mysql.sock"が無いとか言われた

とりあえず、以下のサイトを参考にして php.ini を修正したらうまくいった。

Problems connecting to unix:///var/mysql/mysql.sock | Westsworld

以下のように、mysql.sock ファイルのパスを変更した。

変更前:

pdo_mysql.default_socket=/var/mysql/mysql.sock
mysql.default_socket = /var/mysql/mysql.sock
mysqli.default_socket = /var/mysql/mysql.sock

変更後:

pdo_mysql.default_socket=/tmp/mysql.sock
mysql.default_socket = /tmp/mysql.sock
mysqli.default_socket = /tmp/mysql.sock

php.ini は /private/etc/php.ini を参照していた。
php.ini が無い場合は、 php.ini.default をコピーして作れば良い。
上記を変更したら、いったん「Web共有」機能を再起動(機能のON/OFF)する必要がある。

補足:MySQLが作成するソケットファイルの場所の確認

mysqladmin versionコマンドで確認できる。

$ mysqladmin version
mysqladmin  Ver 8.42 Distrib 5.5.14, for osx10.7 on i386
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Server version          5.5.14
Protocol version        10
Connection              Localhost via UNIX socket
UNIX socket             /tmp/mysql.sock
Uptime:                 3 hours 59 min 7 sec

Threads: 1  Questions: 1042  Slow queries: 0  Opens: 56  Flush tables: 1  Open tables: 38  Queries per second avg: 0.72

バージョン関係

$ php --version
PHP 5.3.6 with Suhosin-Patch (cli) (built: Jun 16 2011 22:26:57) 
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
$ mysql --version
mysql  Ver 14.14 Distrib 5.5.14, for osx10.7 (i386) using readline 5.1

LaunchyをVS2010でビルドする手順

いろいろ手間取ったのメモ

ビルド環境は以下のとおり

  • OS: Windows7 Professional
  • VisualStudio 2010 Pro *1

おおまかな手順は以下の通り、なんやかんやで半日くらいかかった。

  • Qt をダウンロード (この記事を書いてる時点では 4.7.1)
  • Qt をビルド/インストール
  • Boost をダウンロード
  • Boost をインストール
  • qmake で Launchy のソリューションを作成
  • VS2010 で Launchy のソリューションをビルド

以下、この手順の詳細

Qt のダウンロード

http://qt.nokia.com/downloads
上記のページから、LGPLの Qt: Framework only を選択

Qt のビルド/インストール

インストーラー任せでQtをインストール。
すると、 c:\Qt\4.7.1 の下にソースコード等が展開される。

環境変数の設定

LaunchyのBUILD.txtに記述されているように、QMAKESPECQTDIRを設定する。

あと、Qtのツール類が使えるようにPathを通しておく。

configure && namake

Visual Studio コマンドプロンプトを開いて、Qtをインストールしたディレクトc:\Qt\4.7.1 に移動し、

> configure -opensource -no-webkit

して

> nmake

で、Qtのビルドが完了。

Boost のダウンロード/インストール

http://www.boost.org/users/download/#releases
上記のページから Packaged release を選択してダウンロード

インストールはインストーラ任せ。

Launchyのビルド

やっとLaunchyのビルドの手順に入る。

svn で Launchy のソースコード取得
$ svn checkout https://launchy.svn.sourceforge.net/svnroot/launchy/trunk/Launchy_QT/
qmake で Launchy のソリューションを作成

svnからチェックアウトしたディレクトリに移動して、

$ qmake  -tp vc -r launchy.pro

コマンドを実行すると、Launchyのソリューション(.sln)ファイルが作成される。

VS2010 で Launchy のソリューションをビルド

qmakeで作成された Launchy.sln を、Visual Studio 2010 で開いて、ビルドする。(その前にQtのdllへのPathを反映するために、OS再起動が必要かもしれない)

デフォルトでは Debug フォルダの下に Launchy.exe が作成されるのでそいつを起動してみる。

このようにデバッグログとともに Launhcy が起動したらとりあえずビルド成功。

次回は、Launchyプラグインを作成してみる。

*1:VC++ Express Edition でももしかしたらいけるかも