2014年2月25日火曜日

Xcode5 外部ライブラリの設定、およびデバッグオプションつけかた

前回、GMPを使ったpi計算プログラムをMacで動かしました。最初はコマンドラインだけでやってましたが、せっかくなのでXcodeのプロジェクトにし、デバッグしてみました。(1億桁の変数ってどれくらいメモリをとるのか確認してみたかった)
非常に基本的なXcodeの使い方なんですが、調べてみたら結構初心者向けに書いてあるところがなく、またVisual Studioとはかなり使い方が違っていたので、メモを残します。

1.プロジェクトの作成
プロジェクトの作成方法は、大して他の統合環境と変わりません。
new projectで、右上のCommand Line Toolを選択します。(今回は元々、コマンドラインで作成していたプログラムをXcodeでデバッグできるようにしますから、これを選択します。)

2.ソースファイルの作成
事前に作ってあったソースコードを元にプロジェクト内に必要なファイルを作成します。

3.外部ライブラリ(GMP)の指定
上記で作成したソースコードはヘッダやライブラリとして/usr/local以下にあるGMPのヘッダやライブラリが必要です。それをコンパイル・リンク時にプロジェクトが参照できるようにしないといけません。
Xcodeの画面左側ビュー内のプロジェクトを選択すると、画面中央がBuild settingsになります。
設定項目が多数ありますが、このうちSearch Pathsの項目で外部ライブラリのヘッダ、ライブラリがある場所を以下の項目に設定します。
・Header Search Paths
・Library Search Paths
それぞれ、Debug用、Release用を設定してやる必要があります。またHeader Search Pathsにはデフォルトでシステム用のパスが既に入っており、それに追加する形になります。ここが少し悩んだのですが、WindowsやLinuxだとパス名の追加は":"(コロン)でパス名を区切って続けることが多いんですが、Xcodeではそれでは区切り文字として認識してくれませんでした。色々調べてもわからず試してみたら空白で外部ライブラリのパス名を区切れば通りました。

4.外部ライブラリの指定
3項では外部ライブラリの場所を指定しただけで、リンク時のライブラリ名を追加してやらないといけません。これは先ほどのSearch Pathsより上にあるLinkingのところで、Other Linker Flagsに"-lgmp"とDebug/Release双方に設定してやればOKです。(gccのリンクオプション、そのままです。まあVisual StudioでもGUIで色々オプション指定できますが、最後の確認としてコマンドラインのオプション一覧を表示できますから、やってることは一緒か)

5.Debug/Releaseの切り替え
さて次はDebug/Releaseどちらでビルド・実行するかの指定です。これはメニューで、Product→Scheme→Edit Schemeで表示されるダイアログで切り替えます。

ここのBuild ConfigurationでDebug/Releaseを切り替えます。(このダイアログに前回書いたデバッガのLLDBの選択が表示されています。これLLDB以外のデバッガってあるんだろうか?なんか追加できそうなUIになっていますが)
またこのダイアログの別タブで、実行時の引数とか指定できます。

あとVisualStudio等と違って、実行コマンドはメニューからRunしかありません。先ほどのBuild ConfigurationがDebugになっていたらRunすれば自動的にデバッグモードでの実行になります。Visual Studioだとメイン画面のUIで直接切り替えれたし、メニューにもRun, Debug両方あったため、そちらに慣れてしまい、当初はどうやってデバッグしたらいいのかかなり悩みました。ただ考えてみれば一度Release版でビルドしたら、そうそうDebug/Releaseを行き来するシチュエーションも通常はないでしょうから、これはこれで合理的かも。

2014年2月16日日曜日

Mac Mavericks:gdbがない!?

最近、家で簡単なプログラムを作るときはLinuxからMacが増えてます。(LinuxマシンはデスクトップPCで昔のゲーミング用なので、ファンの音がうるさい!それに比べて、自分が現在持っているMacはすべてノートPCで、基本は静か)
まあそれでも、OpenSourceだといきなりMacでやるのは冒険すぎるんで、まだまだLinuxマシンも使います。(時にはバージョンの違うLinuxで動きを見る必要がでてきて、WindowsのVMPlayer上のも動かすときがありますが)

Mavericksになって普通にgccが使えたから気にしてなかったんですが、デバッガを動かしたくなりgdbとコマンドを打つと"command not found"といってきます。XcodeやCommand Line Toolsはインストールしてあるのに、何で?
調べてみたら、Mavericksになってからgcc、ccはLLVM(Low Level VIrtual Machineらしいが、現在は固有名詞としているらしい)になり、結局clang一つが動いているようになったそうです。
その際、gdbは削除され代わりに"lldb"というコマンドになったそうです。実際、ターミナルで"-g"オプションをつけたバイナリをデバッグしてみると、普通にgdbのコマンドが使えました。結局、仮想化技術を使ってデバッガを統一しているんですかね? (調べてたらgdbを無理矢理Mavericksにインストールする方法をかいてたサイトもありましたが、lldbでデバッガが使えるなら、これでいいや)
ただこれだと普段、emacs上でソースコードを見ながらgdbでデバッグするスタイルができなくなり、ちょっと困っています。

追記:
Xcodeの"Edit schme"で、プロジェクトのRelease/Debugを切り替えるところをよく見たら、利用するデバッガとしてちゃんと"LLDB"と書いてありました。

2014年2月13日木曜日

GMPの紹介

何となくπを多数桁(100万桁)のオーダーで計算するのに、今のPCだとどれくらいかかるんだろうと思い、ネットをググっていたら、アルゴリズムやプログラムの紹介をしているサイトがありました。
そこで使われているライブラリがGMP(Gnu Multipule Precision Arithmetic Library)でして、以前少し耳にはしていましたが詳しいことを調べてなかったので、ちょっと見てみました。
(注:πの多数桁は計算プログラムがサイトに乗っており、その方の計算時間、自分で試した計算時間を見ても1億桁やっても10分ちょっとでできてしまうことがわかり、興味がなくなりました。ただメモリの消費量を見ていると、32bit OSではギリギリに近くなってます。これ以上の桁数の計算をしようと思うと、64bit OSにしないと。)

さてGMPですが、任意の精度で数学計算を行うライブラリです。(もちろんメモリが許す限り、という大前提はつきますが。) https://gmplib.org/ に本家があります。最新が2013.9更新になっていますから、まだ活動は続いているようです。
とりあえずインストールの説明をします。

1.ソースをDLしてくる。
私は、gmp-5.1.3.tar.bz2を落としてきました。リリースノートを見てみると、CPU(ここではintel, ARMが対象になっていました)毎に最適化をしてより高速化を目標にしているようです。

2.tarボールの解凍、ビルド、インストール
適当な作業用ディレクトリを作り、そこで先ほどDLしてきたtarボールを解凍します。今回、自分はPCとして、Ubuntu 13.10、Mac OSX Mavericksの2台で試してみました。(Mac OSXの方はインストールに少し難があると本家サイトの中に記載がありましたが、特に問題はおきませんでした。ただ困ったのは、OSXでは/usr/local以下にインストールしたものをデフォルトではコンパイル対象にしてくれなくてサンプルプログラムのコンパイルに少し手間がかかりました。)

$ ./configure --enable-cxx  (c++でも使えるようにオプション追加です)

$ make

$ make check        (単体試験を多数やってくれます)

$ sudo make install     (/usr/local以下にライブラリをインストールします)

3.テストプログラム
雰囲気が味わえる程度の簡単なものを示します。

(1)整数の加算
まず基本として整数の加算です。


#include 
#include 

int main (int argc, char* argv[]) {

  mpz_t a, b, c;
  mpz_init(a);
  mpz_init(b);
  mpz_init(c);

  mpz_set_ui(a, 12345);
  mpz_set_str(b, "12345678910987654321", 10);

  mpz_add(c, a, b);
  mpz_out_str(stdout, 10, a);
  printf("\n");

  mpz_out_str(stdout, 10, b);
  printf("\n");

  mpz_out_str(stdout, 10, c);
  printf("\n");

  mpz_clear(a);
  mpz_clear(b);
  mpz_clear(c);

  return 0;
}



最初に整数変数a,b,cを定義しています。(特にprecision(精度)は規定していませんが、整数の場合は必要なだけ確保されるようです)
面白いのが、"mpz_set_str()"関数ですが、通常のC言語では扱えないような多数桁の整数を初期値に使えるように、文字列で設定できる関数です。c=a+bを行い、最後にa,b,cを出力しています。

・実行結果
12345
12345678910987654321
12345678910987666666


ちゃんと加算されていることがわかります。"mpz_out_str()"が出力関数なんですが、第1引数がFILE*で今は標準出力にしていますが、もちろんファイルへの出力にも使えます。また第2引数の"10"ですが、これは基数をいくつで出力するかです。(といっても、8,10,16くらいしか使わないと思いますが)

(2)階乗の計算
多数桁の計算が自由にできるということで、サンプルで階乗の計算プログラムを示します。


#include 
#include 

int main (int argc, char* argv[]) {

  unsigned long int i;
  mpz_t a;

  mpz_init(a);
  mpz_set_ui(a, 1);

  for (i = 1; i <= 100; i++) {
    mpz_mul_ui(a, a, i);
  }

  printf("%ld! = ", (i-1));
  mpz_out_str(stdout, 10, a);
  printf("\n");

  mpz_clear(a);
  return 0;
}


・実行結果
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

今回は結果の表示を考えて100までにしましたが、10000でも簡単に計算してくれます。

(3)浮動小数点の計算
基本は整数と変わりません。ただGMPの内部では浮動小数点は指数部は通常の浮動小数点形式と同じ(つまり固定長)、その代わり仮数部が任意の桁数にできます。また、変数を宣言/初期化する時に、その仮数部の桁数(正確にはbit長)を指定してやらないといけません。

・例
int digits1 = 20;
int prec1 = digits1 * log2(10);

mpf_t a;

mpf_set_default_prec(prec1);
mpf_init(a);


例に示したものでは変数aの仮数部を20桁で持つように設定してます。(mpf_set_default_prec()で設定するときbit長で指定しないといけないので、20桁が何ビットになるか計算してます)

但し、いくら仮数部を多数桁もてたとしても、指数部の極端に異なる浮動小数点同士で演算を行えば桁落ちは発生します。そのあたりの注意事項は変わりません。(仮数部をかなり大きく持てるので、計算誤差は大分減らせるでしょうが)

(4)分数の計算
GMPではなんと分数の計算もできます。


#include 
#include 

int main (int argc, char* argv[]) {
 mpq_t a, b, c;

 mpq_init(a);
 mpq_init(b);
 mpq_init(c);

 mpq_set_si(a, 4, 7);
 mpq_set_si(b, 3, 8);

 mpq_add(c, a, b);

 mpq_out_str(stdout, 10, a);
 printf("\n");

 mpq_out_str(stdout, 10, b);
 printf("\n");

 mpq_out_str(stdout, 10, c);
 printf("\n");

 return 0;
}



内部的には整数の分子と分母で持っているのかな。上記は、4/7 + 3/8の計算をしています。

・実行結果
4/7
3/8
53/56


こんな感じで、ちゃんと分数形式で出力もしてくれます。当然、分数で計算後、浮動小数点への変換をしてくれる関数も持っていますので、やたら沢山の(整数の)分数を掛けたり、割ったりしなければいけない計算式の計算がかなり誤差を気にしなくてもよくなります。

さてこんな便利なGMPライブラリなんですが、残念ながら完全にはWindowsに対応していません。独自にVisual Studioのprojを作っている人がいましたが、make check(単体試験)まで対応できているんだろうか?Windowsにインストールしている人はほとんどcygwinでした。(Linux, Mac使っている人間が今更cygwinを使う必要性が殆ど無いので、これは試していません。)
configureをCMakeあたりにしてくれると面白いんですが、それでも単体試験の問題は残るでしょうし。(本家のサイト読んでたら、とにかくmake checkは必ずやれとうるさく書いてありました。OSの環境、CPUのバージョンの微妙な違いでFPUの結果が変わったりしますから、そこでライブラリの保証をしないと、危なくて使えないモノになってしまいますしね。)

2014年2月8日土曜日

Mac OSX Xcodeの実行形式保存場所について

非常に謎なんですが、Xcodeってビルドしたあとのバイナリファイルがどこに入っているのか全然わかりません。これだと、ファイルの入出力するプログラムかくのも困るし、そもそも手動で動かしたいときどうしたらいいのかわからない。

Mavericksで変わったのかなとも思いましたが、そうではなくやっと位置がわかりました。

$HOME/Library/Developer/Xcode/DerivedData/(プロジェクト名)-何か文字列

以下に、Build/Prodeuct/debug等のフォルダが作成されて、そこに格納されていました。いやらしいのが何か勝手に文字列を追加されたフォルダに格納されるところです。本人は同じプロジェクトを修正しているつもりなんですが、バイナリ自体は日ごとによりどこに保存されるのか直接はわからなくなっています。なんでこんな仕様になっているのか。。。せっかくgitも標準装備(但しXcodeをインストールしろとは言ってきますが)で入っているんだし、ビルドしたバイナリをなんでプロジェクトフォルダ直下におくようにしなかったか意味がわかりません。

あともう一つ重要なことを書き忘れました。上記フォルダ、$HOME/Librryですが初期設定では不可視フォルダになっていて見えません。以下のコマンドを端末からうちこんでください。]

$ defaults write com.apple.finder AppleShowAllFiles true
$ killall Finder

なんでこんな意味のわからないコマンドを打ち込まないといけないのかわかりませんが、これで不可視属性のファイルが表示されるようになります。ただ、desktopにも.DSStoreとか変なのが表示されてきますので、気持ち悪かったら、trueのところををfalseに変えてくれれば元にもどります。(自分は基本、すべてのファイルが見たいので、いつもこの設定にしています)

2014年2月7日金曜日

LibreOfficeのビルド(その2)

前回、メモリ1GBのPCでチャレンジして時間がひどくかかり苦労しましたが再チャレンジです。


前回、ビルド中の使用メモリが1GBを超えてswapの嵐になっていたので、今回はWindows7(64bit)、メモリ6MBのマシンにVMplayerでUbuntu(32bit)を動かし、それに2core/メモリ2GBを設定しました。さすがに今度は4,5時間でビルドが終わりましたが、no-troubeではすみませんでした(-_-;)

以下に作業手順をメモしておきます。

1.作業領域の確保
$ mkdir LibreOffice

$ cd LibreOffice/


2.リポジトリの取得
$ git clone git://gerrit.libreoffice.org/core

$ cd core

作業したい(checkoutしたい)タグ(バージョン)を確認する
$ git tag -l

とりあえず4.2で作業します
$ git checkout libreoffice-4.2.0.4

LibreOfficeのビルドに必要なパッケージをインストールしてくれる以下のコマンドを実行します。

$ sudo apt-get build-dep libreoffice
→ccacheまでインストールしてくれちゃいました

日本語にローカライズするので、これも必要か?最初に参考にしたHPでは要求してませんでしたが、念のためインストールしておきます。

$ sudo apt-get install translate-toolkit dos2unix


3.makefile作成のコマンド
$ ./autogen.sh --with-lang="ja"

→デフォルトのUbuntuでは、autoconf, automakeがないといわれちゃいました
 apt-get install autoconfで、両方インストールしてくれます

前回はかなりwithoutにしたんですが、今回は必要なものを一括してインストールしてくれるコマンドがあったおかげか、「--with-lang="ja"」だけで済みました。

さてこれでno-troubleかと思いきや、やはり単体試験で通らない箇所がでました。前回はメモリ不足のせいか落ちながら少しづつビルドが進んでいきましたが、今回は同じところで止まります。(xmlエクスポートの箇所らしい)
ググってみると、TDFのメールアーカイブに本件に関する問い合わせと回答がありました。(ちょうど4.2.0alpha1のとき)CppunitTest_sw_ooxmlexportでは特定のfontがないだけでエラーになるようです。(試験用に用意されているドキュメントのフォントがシステムに存在してなくて、別の代替フォントで出力してしまいページ数が合わないということらしい)
そこんとこは以下の方法がworkaroundとして記載されていました。

$ sed -i '/CppunitTest_sw_ooxmlexport/d' sw/Module_sw.mk

上記は単体試験から上記テストを削除してしまう方法で、ちょっと強引なやりかたです。

これでビルドはパスしましたが、make dev-isntallしようとしたら、それはobsolete(廃止された)と怒られました。(make test-installを使えと言われた。)

test-installディレクトリが作成され、test-install/program/sofficeで実行コマンドが作成できました。
(実行したらアバウトにDev版だと表示されたw)

PS:
実は同じタイミングでMac OSX Mavericksでも試してみたんですが、autogen.shのところで先に進めなくて諦めてます。ひっかかった箇所がgccのバージョンチェックのところ。手動で当該スクリプトを実行する分には問題が起きないんですがね~。mavericksになってXcodeの開発環境まわりが少し変わったのかもしれません。もう少し様子を見ます。

2014年2月1日土曜日

Ubuntu 13.10でeclipse(adt)のメニューが操作できない!?

Ubuntu13.04のセキュリティアップデートがもうすぐ停止するので、使っている人は13.10に更新してください、というノートがでました。
これまで何度となく13.04から13.10へ更新しないか?、というDialogは出ていたのですが、もうすぐLTSの14.xが出るという話を聞いていたのでずっとそのままで使っていました。(下手に更新して使っているアプリに問題がでるのも嫌だし)さすがにこれはまずかろうということで、13.10に更新しました。(情報を調べていたら日本語設定で行うと問題がでることがあるので、upgrade専用のアカウントを作り、英語設定で行うと問題がでないという話がありました。念の為、英語設定のアカウントで更新は行いましたが、そこにあった情報通り、更新したら設定してあるうち、最低限のリポジトリ以外はoffにされていました。これは後で手動でonにしておきました。)

これまでLinuxではandroidアプリの開発はしてこなくて、eclipseすら入れていない状態だったのですが、何となく開発環境だけでも構築しておこうとgoogleさんからeclipse込のAndroid SDK(abt)をDLして解凍、さてabt内のeclipseを実行しようとしたら・・・、javaが入っていませんでした(^_^;)
ちょっとびっくりしましたが、ソフトウェアセンターでjavaを検索するとOpenJDKの方がでてきます。(デフォルトではOracleのリポジトリ入っていませんしね)まあ、これでよかろうとOpenJDK6をインストールします。(Android SDKがjava6を要求するので)
さて再度、eclipse(adt)を実行です。無事、動きました。デスクトップがUnityなんでメニューの位置がMacみたいに画面の最上部にでてきてちょっと気持ち悪いですが。
まあそのあたりは「慣れ」の問題なんで気にせず、SDK managerを開こうとWindowsメニューをクリックするも、メニューが表示されません!!つまり何も操作できない状態になってます。
最初、OpenJDKにしたのが問題だったかと思い、これを削除、以下の手順でOracleからjava6をインストールしてみました。

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer


しかし状態は変わりません。気を落ち着けてどこかに情報がないか調べてみたらstackoverflowのサイトに同じ状態に対する質問と回答がありました。どうもUbuntu 13.10で発生した問題のようです。メニューをアプリのwindowから画面上部に飛ばすのにeclipse IRCをproxy経由使っているようなのですが、これを切ればいいということらしいです。

具体的にはデフォルトの環境変数で以下のものがあります。

UBUNTU_MENUPROXY=1

これを以下にしてやります。

UBUNTU_MENUPROXY=(空白)

この設定をした端末からeclipse(adt)を実行すると、Unity上で動いているのにも関わらずメニューがアプリのwindow上に表示されます。
そして無事メニューの操作もできるようになりました。

やっぱりシステムを更新するのは怖いんだよな〜


PS
システムを最新の14.04 Trustyにしたら、この現象は消えました。よかった、よかった。