--- [管理番号 140] (最終更新 2004/04/09 05:05:18) Q. プロファイラ・プロファイリングって何ですか? プロファイラの 使い方がわかりません。 A. プログラムの各関数が何回呼ばれ、実行時間がどれくらいかかったか 統計をとることをプロファイリングと言います。プロファイラは その際に使用するツールです。 プログラムの高速化をしたい場合、手あたり次第に修正するの ではなく、まずプロファイラで解析し、どこがボトルネックに なっているか見極めましょう。 以下、C 言語でのプロファイリングの例を紹介します。 [ステップ 1] プログラムをコンパイルするとき、-pg オプションを付けます。 % cc -pg hoge.c もし % cc -pg hoge.c ld: -lc_p: no match とエラーなった場合は、/usr/lib/libc_p.a がないと言われて いますので、基本配布物である proflibs をインストールしま しょう。 [ステップ 2] コンパイルしたプログラムを実行します。 % ./a.out カレントディレクトリに a.out.gmon というファイルが作ら れているはずです (環境によっては gmon.out かもしれません)。 このファイルには、関数に入るときと出るときの時刻などの 情報が記録されています。 [ステップ 3] 統計結果を表示します。 % gprof a.out a.out.gmon (略) % cumulative self self total time seconds seconds calls ms/call ms/call name 63.9 2.53 2.53 1 2534.18 2733.40 func1 [2] 5.0 3.32 0.20 1 199.22 199.22 func2 [7] 4.3 3.49 0.17 main [1] 3.4 3.63 0.14 664580 0.00 0.00 vfprintf [4] (略) func1 が全体の実行時間の 63.9% を占めているのに対し、 func2 は 5.0% であることがわかります。 func1 を 2倍高速化すれば、プログラム全体では 31% の実行 時間削減につながりますが、func2 を 2倍高速化した場合は 2.5% しか削減されません。 これにより、まずは func1 の高速化に着手すべき、という 結論が得られます。より詳細な情報は gprof(1) を参照して ください。 gprof は、C 言語用のプロファイラです。他の言語でも、プロ ファイラが用意されているはずです。例えば Perl なら DProf パッケージを使います (p5-Devel-DProf として port/package が用意されています)。 --- [管理番号 147] (最終更新 2004/07/12 23:14:38) Q. FreeBSD 上で動作する ML (Meta Language) はありますか? A. 2001年9月初旬の時点で、以下のものが ports に入っています。 詳しくは、それぞれの pkg-comment、pkg-descr ファイルを参照して下さい。 [Standard ML of New Jersey] ports/lang/sml-nj/ ports/lang/sml-nj-devel/ the SML '97 definition に準拠した実装です。(Standard ML には 1990 年の定義と 1997年の定義の 2種類があり、それぞれ SML '97、SML '90 とも呼ばれます)。 次の Moscow ML の方が軽いそうです。 [Moscow ML] ports/lang/moscow_ml 1996 年に見直された Standard ML の中心となる言語の実装です。 モジュール機構は Version 2.0 以降で実装されています。 [Caml Light] ports/lang/caml-light Standard ML に似た (つまり少し違う) ML 言語です。 [Objective Caml] ports/lang/ocaml Caml Light をベースに、クラスに基づいたオブジェクト指向拡張と Standard ML 風の強力なモジュール機構を加えたものです。 [nML] ports/lang/nml Standard ML と Objective Caml を融合した両者の方言です。 Standard ML については を参照して下さい。 尚、code を書くのに emacs を使用している場合は、ports/lang/sml-mode.el も役に立つでしょう。 --- [管理番号 279] (最終更新 2000/12/07 02:36:22) Q. X Window System(Motifベース)上でビジュアルにGUI構築を行えるようなツー ルはありますか? A. 売りものですが、TeleUSE という物があります(けっこうな値段です)。 また、X Inside の Accelerated MWM FreeBSD を使うと WSM が付いてきますが、これは どうでしょう。ただし、バグってるので、core を吐いて MWM ごと落ちて しまうことがあります。 Motif ベースではですが、XForms というライブラリを使えば、fdesign という GUI 構築ツールが付いてきます。フリーです。XForms はホーム ページがあります。 C ではなく、Tcl/Tk ですが、Sun が SpecTcl なる物を開発しています。 結果の外見はほぼ Motif です。 Tcl 物で、XF という物もあります。 Windows95上の Boaland Latteや Microsoft J++などの Java 開発環境で クロス開発して、UNIX の Java 環境(例えば Netscape)で動作させる方法も あります。 --- [管理番号 286] (最終更新 1999/02/17 23:58:45) Q. FreeBSDでI/Oポートを直接制御するには、どうするのでしょうか? A. /dev/ioをオープンすると、そのプロセスは直接I/O命令を使えるようにな ります。 --- [管理番号 321] (最終更新 2004/07/12 23:14:37) Q. FreeBSD で動く JDK (Java 環境) はありませんか? A. まずは FreeBSD Java Project ミラーサイト 日本語訳 を御覧下さい。 --- [管理番号 329] (最終更新 2001/08/12 05:25:00) Q. perl スクリプトに実行許可属性を付けて % ./foo.pl としたときと % perl foo.pl の場合で挙動が異なることがあります。 A. 前者と後者で起動される perl(1) のパス(とバージョン)が異なっているためです。 前者の形式でスクリプトが実行されると、Unix はスクリプトの1行目を見て どのプログラムを起動するか判断します。起動されるプログラムは行頭の #! に続くパス名で、例えば catman(1) のように #!/usr/bin/perl となっていれ ば、/usr/bin/perl が起動されます。 後者は普通のコマンド実行と同じく、shell によってコマンド検索パスを検索 して見つけ出した perl が使われますので、環境変数 $PATH の設定によって 変化する可能性があります。どの perl が使われるか確認するには which(1) コマンドを利用して以下の様に入力します。 % which perl /usr/bin/perl (実行結果) それぞれの perl がどんなバージョンのものか確認するには -v オプション を使います。*フルパス* で perl を実行して比べてみてください。 たとえば /usr/local/bin にある perl を確認するには % /usr/local/bin/perl -v This is perl, version 5.005_03 built for i386-freebsd ... (省略) ... と入力します。 なお、/usr/bin/perl については FreeBSD 2.2 系列では Version 4、 FreeBSD 3.0-RELEASE 以降では Version 5 になっています。 --- [管理番号 400] (最終更新 1999/02/17 23:58:45) Q. FreeBSD で POSIX スレッド (POSIX pThread) は使えますか? A. はい、使えます。 FreeBSD は IEEE Std 1003.1c-1995 (Threads) に準拠しています。 FreeBSD をインストール後、配布ファイルからシステムマニュアルページ (man) とソースのシステムライブラリ (lib) をインストールし、man pthread を実行すると表示される説明を読んでください。 --- [管理番号 401] (最終更新 2002/03/07 15:32:11) Q. a.out 形式のシェアドライブラリを作成、利用する例があったら教えてください。 A. 以下に例を説明します。 まず、同じディレクトリに shared.c、test_shared.c を以下の内容で作成 します。 以下は shared.c (共有ライブラリ) の内容です。 ----------------- ここから --------- int shared(int a) { a *= 5; return(a); } ----------------- ここまで --------- 以下は test_shared.c (ライブラリを使用する実行ファイル) の内容です。 ----------------- ここから --------- #include extern int shared(int); int main(void) { int a; printf("number ?:"); scanf("%d", &a); printf("result: %d\n", shared(a)); return(0); } ----------------- ここまで --------- まず、シェアドライブラリを構成するオブジェクトを作成します。オプション -fpic はシェアドライブラリを構成するオブジェクトを作成するために必要 です。オプション -c はリンクを行わないでソースをコンパイルするために 必要です。 % gcc -fpic -o libshared.SO -c shared.c 次にシェアドライブラリを作成します。 % gcc -shared -Wl,-soname,libshared.so.1 -o libshared.so.1 libshared.SO そして、ld(1) に見つけてもらうために リンクを張ります。 % ln -s libshared.so.1 libshared.so 最後に、このシェアドライブラリを利用する実行バイナリを作成します。 % gcc -L. -lshared -Wl,-rpath=. -o main test_shared.c さあ、実行してみましょう。"number ?:" の後に数字を入力してください。こ こでは 5 を入力しています。 % ./main number ?:5 result: 25 ダイナミックリンクが本当に行われているか、shared.c を変更し、 libshared.so.1.0 を再作成して、main を実行するとその変更が反映される ことを確認しましょう。たとえば、shared.c の "a *= 5;" を "a *= 10;" に 変更します。 ----参考---- コンパイル時に -fpic を付ける意味 [FreeBSD-tech-jp 2036] Linux とは違い、FreeBSD では lib${name}.so.X だけ作ればよい。 [FreeBSD-users-jp 60134] -rpath や $LD_RUN_PATH の $LD_LIBRARY_PATH との違い。 共有ライブラリとのリンクから実行までの過程。 推奨されるライブラリ作成の手順。 [FreeBSD-users-jp 60135] Executable and Linkable Format (ELF) V1.1 The Linux Japanese FAQ Project ELF HOW-TO, GCC HOW-TO など。 --- [管理番号 509] (最終更新 2000/05/24 21:07:45) Q. Xlib を用いた C プログラムをコンパイルすると % cc file.c -lX11 file.c:1: X11/Xlib.h: No such file or directory file.c:2: X11/Xutil.h: No such file or directory と、エラーになってしまいます。 A. そのソースコードには #include #include と書いてあるはずですが、このファイルが見付からなかったということです。 #include 命令で インクルードされるファイルの指定には "" で囲む方法 と <> で囲む方法の2通りがあります。 C コンパイラ (正確にはプリプロセッサ) は #include "file.h" と書いてあった場合、インクルードファイルを ソースファイルと同じ ディレクトリの中から探し、もし見付からなければ次に標準のディレクトリ から探します。 一方、 #include と書いてあった場合は、ソースファイルと同じディレクトリは探さずに、 最初から標準のディレクトリだけを探します。 通常 標準のディレクトリは、/usr/include/ になっていますので、 /usr/include/X11/Xlib.h や /usr/include/X11/Xutil.h が存在しないため 上記のエラーが発生したのです。 X11/Xlib.h や X11/Xutil.h などの X の include ファイルは /usr/X11R6/include/ に置いてあるため、この問題を回避するには コンパイラが /usr/X11R6/include/ を探すようにすればいいわけです。 以下に示す解決策のうち、いずれかを選んで下さい。 1. -I オプションで、インクルードファイルが置いてあるディレクトリを 指定できます。コマンドラインからは、 % cc file.c -I /usr/X11R6/include などと入力します。この例では、標準のディレクトリである /usr/include と、-I で指定した /usr/X11R6/include から インクルードファイルを探します。 ただし、最終的にリンク時にライブラリが見付からないというエラーに なるでしょうから、 % cc file.c -I /usr/X11R6/include -lX11 -L /usr/X11R6/lib としなければいけません。→[管理番号 1609] 2. imake/xmkmf (Imakefile というファイルがある場合) や autoconf (configure というファイルがある場合) などの、Makefile を自動的に 生成するツールを使っているものは、インクルードファイルの検索対象 ディレクトリを指定するためのオプションが用意されていることが 多いです。それぞれのプログラムに付属するドキュメントをよく読んで みましょう。 --- [管理番号 587] (最終更新 2003/10/16 23:20:14) Q. gccで "long double" を使用して数値計算を行ないましたが、同じ CPU での Linux の結果と比べて計算精度が悪く、計算結果が異なります。 A. FreeBSD の標準カーネルでは浮動小数点の仮数部の精度が (IEEE754 と異なり) 53bit に設定されているために起きる現象です。 long double の仮数部の精度は64bitです。(double の仮数部の精度は 53bit です) Intel x86 系の FPU の仮数部の精度は 24/53/64bit に設定可能です。 FreeBSD では仮数部の精度が 53bit に設定されているために、long double を使用しても仮数部の精度が 53bit (つまり、double と同じ) しかありません。 精度を上げて数値計算を行なうには: 1. 関数 fpsetprec()/fpgetprec() を使用して、FPU の仮数部の精度を 64bit に変更する事が出来ます。fpsetprec(3) を御覧下さい。 2. GNU Multiple Precision Arithmetic Library (GMP)、PARI 等 FreeBSD 標 準以外の数値演算ライブラリを利用してもよいでしょう。 1. fpsetprec()/fpgetprec() について FreeBSD users MLの以下のメールから始まるスレッドが参考になるでしょう。 Subject: [FreeBSD-users-jp 24352] gcc bug Subject: [FreeBSD-users-jp 46648] long double その他、オンラインマニュアル fpsetround(3)、math(3)、ieee(3)などが参考 になります。 ただし、fpsetprec は double の内部演算も 64bit 精度にしてしまうという 副作用があります。double での演算結果が変わってしまう可能性がありますの で注意して下さい。 long double 使用上の注意点: * FreeBSD の printf(3) は 5.1-RELEASE から long double に対応しました。 それ以前 (少なくとも 4.8-RELEASE までと、5.0-RELEASE) は、書式で "%Lf" 等を使用してもエラーにはなりませんが、double の精度でしか表示されません。 * long double 用の算術関数 sqrtl(), sinl() 等が標準で用意されていません。 ([管理番号 588] 参照) プログラム例: ---------------------------- #ifdef __FreeBSD__ #include #endif ... int main() { long double tmp1, tmp2; ... #ifdef __FreeBSD__ fpsetprec(FP_PE); /* 仮数部の精度を 64bit にする。 */ #endif ... } ---------------------------- 2. 非標準の数値演算ライブラリについて GMP (ports/math/libgmp4) は、任意多倍長の整数、整数を法とした計算 (modular arithmetic)、有理数、浮動小数点数の四則などが出来ます。但し、 三角関数、対数関数などの初等的な関数もないので、用途が限られるかも知れ ません (自分で頑張って書けば、勿論問題ないですが)。 PARI (ports/math/pari) は、GMP 同様の数の他、p 進数や、それぞれの数 を係数とした多項式、羃級数、行列やベクトルの計算ができ、初等超越関数 (三角関数や指数対数関数) の他、これでもかというくらい様々な関数が実装 されています。本来は、整数論用のライブラリ集 (と、対話的に計算するため の gp というコマンド (bc の様な感じ)) で、ちょっとした用途には大げさ かも知れません。 いずれも C から使うことになるでしょう。(PARIは、Fortran や Pascal から も使えるようです)。 他に参考になるものとしては SAL: があります。 --- [管理番号 588] (最終更新 2000/06/25 02:30:06) Q. FreeBSD には long double 用の算術関数 sqrtl()、sinl() はないのですか。 A. ありません。しかし、FPU を持っている CPU の場合は、次のような方法が あります。 一部の算術関数は gcc に最適化フラグ -O -ffast-math -mfancy-math-387 を付ける事により、builtin function 扱いになり、アセンブラ上に FPU の 命令が直接生成され、使えるようになります。 ただし fmodl() など、使えない算術関数もあります。 どういう関数が使えるかは、gcc の i386.md ファイルを参照して下さい。 (/usr/src/contrib/gcc/config/i386/i386.md) FreeBSD では long double の算術関数のプロトタイプ宣言が math.h で 行なわれていないので、プログラム中で宣言が必要です。使う関数の プロトタイプ宣言を Cの参考書等を参考にして追加してください。 FreeBSD の long double は使用上の注意点があります。[管理番号 587] をご覧ください。 プログラム例 -------------------------------------------------------- #include #include #ifdef __FreeBSD__ /* [管理番号 587] を参考ください */ #include #endif /* __FreeBSD__ */ #ifdef __FreeBSD__ /* プロトタイプ宣言 */ extern long double sinl(long double); extern long double sqrtl(long double); #endif /* __FreeBSD__ */ int main() { long double ld; double d; #ifdef __FreeBSD__ /* [管理番号 587] を参考ください */ fpsetprec(FP_PE); /* 仮数部の精度を 64bit にする。 */ #endif /* __FreeBSD__ */ ld = sinl(1.1); d = sin(1.1); printf("double = %.20f\n", d); printf("long double = %.20Lf\n", ld); printf("ld-d = %e\n", (double)(ld-d)); return 0; } --- [管理番号 627] (最終更新 1999/02/17 23:58:45) Q. FreeBSDで X (Xlib を使った) のプログラミングをしようと思ったのですが、 コンパイルがうまくいきません。先頭に #include #include を入れるとうまくコンパイルできないのですが、どうしたらよいでしょうか? A. コンパイル時に注意することはいくつかあります。 まず最初に Xlib.h Xutil.h をインクルードする際には、Xlib.h → Xutil.h の順番にインクルードする必要があります。だからソースの先頭は #include #include と書かなければ失敗します。注意しましょう。 その他 file.c:??: X11/Xlib.h: No such file or directory (?? の部分は 数字) の様なエラーが発生するときは [管理番号 509] を参照してください。 --- [管理番号 694] (最終更新 1999/02/17 23:58:45) Q. shellスクリプトなどで、起動したプログラムの戻り値を得るには どうすればよいのでしょうか? A. sh系のshellと、csh系のshellとで方法が違います。 sh系 -> $? という変数に戻り値が入っています。 csh系 -> $status という変数に戻り値が入っています。 また、exec ??? でプログラムを起動すると、シェル自身が起動したプログラム になり、起動したプログラムの戻り値はそのシェルの戻り値になります。 --- [管理番号 705] (最終更新 1999/02/17 23:58:45) Q. FreeBSD の kernel の source file を見ていて、次のような記述を見掛け ました。 #endif NETATALK #endif の後に、コメントがあるのは良く見ますが、このような記述もあるの でしょうか? A. 昔使われていた記述方法です。 info で、cpp -> conditionals -> Conditional Syntax -> #if Directive とたどっていくと、次のような説明があります。 In fact, you can put anything at all after the `#endif' and it will be ignored by the GNU C preprocessor, but only comments are acceptable in ANSI Standard C. FreeBSD で使われる cc は、GNU C compiler ですので、このような記述がさ れていても無視されるようです。 GNU C compiler で、option に -ansi -pedantic を付けて compile すると、 ANSI Standard C として動作し warning が出されます。 実際に、option に -ansi -pedantic を付けて compile すると、次のように warning が出ました。(gcc version 2.7.2.1 にて) cc -c -O -pipe -Wreturn-type -Wcomment -Wredundant-decls -Wimplicit -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wuninitialized -ansi -pedantic -nostdinc -I- -I. -I../.. -I../../../include -DKERNEL -include opt_global.h ../../net/if_loop.c ../../net/if_loop.c:83: warning: text following `#endif' violates ANSI standard ../../net/if_loop.c:252: warning: text following `#endif' violates ANSI standard ../../net/if_loop.c:94: warning: ANSI C does not allow extra `;' outside of a function ../../net/if_loop.c: In function `loopattach': ../../net/if_loop.c:119: warning: overflow in implicit constant conversion --- [管理番号 841] (最終更新 2001/08/12 02:51:17) Q. FreeBSD で使える Pascal の処理系はありますか? A. Pascal のソースを C 言語のソースに変換し、それをさらに C コンパイラで コンパイルするタイプのものは、p2c と ptoc があります。どちらも ports/packages に含まれています。sqrt(3) などの libc に含まれない関数を 使う場合は、オプションに -lm を付ける必要があります。→ [管理番号 1609] また、ネイティブコンパイラ (C 言語に変換しないタイプ) の GNU Pascal Compiler というものもあります。lang/gpc として port/package が用意されて います。 --- [管理番号 1207] (最終更新 1999/04/07 06:23:54) Q. C言語の printf 文で日本語を表示させようとすると、コンパイル時に エラーが出るときがあるんですが(コンパイルできる時もある)。 A. ソースの日本語コードが JISコードになっていませんか? % echo 'あいう' | nkf -j | hexdump -c 0000000 033 $ B $ " $ $ $ & 033 ( B \n でわかるように、JIS コードの「あ」には " というキャラクタコードが 含まれているため、printf("..") の "" の対応がおかしくなり コンパイル時にエラーになります。しかし % echo 'ほげほげ' | nkf -j | hexdump -c 0000000 033 $ B $ [ $ 2 $ [ $ 2 033 ( B \n のように、JIS コードには常に " が含まれているわけではないので、 表示させたい文字によって、エラーになったりならなかったりします。 EUC だと、日本語部分のコードは ASCII コードとは重ならない値を使うため、 エラーにはなりませんので、ソースを EUC コードに変換してください。 変換方法は [管理番号 1253] Q. ファイルの文字コードを変換したいのですが。 [管理番号 1289] Q. 新規ファイルをエディタで作成したときの、文字コード(JIS、EUCなど)を 指定したいのですが。 を参照してください。 --- [管理番号 1218] (最終更新 1999/06/03 03:50:53) Q. package/ports にある、日本語対応の perl (jperl) をインストール したのですが、日本語に対して split 等を使っても、オリジナルの perl と同じ挙動になります。 A. jperl (パッケージ名 ja-perl) の日本語機能を使う場合は、 1) スクリプトの先頭行を #!/usr/local/bin/perl でなく、 #!/usr/local/bin/jperl と書く。 2) 日本語を使う前に perl スクリプトに use I18N::Japanese qw(re); と書いておく。 のどちらかを行ってください。どちらの条件も満たしていない場合、 jperl はオリジナルの perl として動作します。 また、処理対象の文字列の文字コードを確認してください。→[管理番号 1254] jperl は、コンパイル時に EUC か SJIS のどちらかを指定してコンパイル されます。この指定と、処理する文字列の文字コードが合っていないと 正しく処理されません。package/ports の jperl は EUC版になっています。 ただし、-Lsjis オプションをつけると SJIS 版として動きます。 つまり、スクリプトの先頭を #!/usr/local/bin/jperl あるいは #!/usr/local/bin/jperl -Leuc とすると EUC を扱えますし、 #!/usr/local/bin/jperl -Lsjis とすれと SJIS を扱うことができます。 --- [管理番号 1541] (最終更新 2001/10/22 01:18:34) Q. 浮動小数点演算を行なう program が SIGFPE で core dump してしまいます。 同じ program が他の OS では問題無く動くのに何故でしょうか。 A. 浮動小数例外 (SIGFPE) のデフォルトアクションが「コアイメージの作成」 (core dump) になっている為です。そのため FreeBSD 3.5-RELEASE 以前では、 SIGFPE が発生すると core dump してしまいます。4.0-RELEASE 以降、及び 3.5-STABLE では、標準で SIGFPE が Mask されるようになったので、この ような問題は起りません。 問題の回避方法について詳しくは を御覧下さい。 他にも、オンラインマニュアル fpsetmask(3)、math(3) や [FreeBSD-ports-jp 1993] [FreeBSD-users-jp 46652] Re: long double が参考になるでしょう。 --- [管理番号 1609] (最終更新 2000/05/24 21:06:42) Q. C のソースをコンパイルすると、 ... undefined reference to `sin' ... undefined reference to `XOpenDisplay' などというエラーになります。 A. コンパイルは成功し、オブジェクトファイル (*.o) が生成されましたが、 リンク時に sin・XOpenDisplay という関数が見付からなかったという エラーです。 /usr/lib/ や /usr/X11R6/lib、/usr/local/lib/ には lib*.so.* や lib*.a というファイルがあります。これらはライブラリと言い、 コンパイル済の関数群が入っています。 sin は /usr/lib/libm.so.* に、XOpenDisplay は /usr/X11R6/lib/libX11.so.* に含まれていますので、この場所を教えてやればいいのです。 例えば、sin が見付からないなら % cc foo.c -lm とします。XOpenDisplay が見付からないなら % cc foo.c -lX11 -L /usr/X11R6/lib とします。 -lm というのは、リンカ (/usr/bin/ld) に 「libm.so.* というライブラリを探しなさい」 というオプションです。 同様に -lX11 というのも 「libX11.so.* というライブラリを探しなさい」 という意味なのですが、ld はデフォルトでは、/usr/lib からしか ライブラリを探しません。そのため、/usr/X11R6/lib や /usr/local/lib のライブラリを使う場合は、-L /usr/X11R6/lib などとライブラリの 置いてある場所を指定しなければなりません。 ただし、X のプログラムの場合は、インクルードファイルの場所を指定 しなければいけないので、最終的には、 % cc foo.c -I /usr/X11R6/include -lX11 -L /usr/X11R6/lib などと -I オプションも指定しなければいけないでしょう。ですから、 Makefile や autoconf などを利用する方が楽です。→[管理番号 509] なお、どのライブラリにどの関数が含まれているかを調べるには、 まずマニュアルを見ましょう。man sin の SEE ALSO に math(3) と ありますので、man math を見ると、 These functions constitute the C math library, libm. とありますので、libm に含まれていることがわかります。 マニュアルから読み取れなかったら、 % nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T sin$' /usr/lib/libm.so.2:0000b3d8 T sin % nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T XOpenDisplay$' /usr/X11R6/lib/libX11.so.6:00020adc T XOpenDisplay とすればわかります。libm.so.2 なら -lm だし、libX11.so.6 なら -lX11 ですね。 --- [管理番号 2228] (最終更新 2004/07/12 23:14:38) Q. 乱数を得ようと rand(3) を使ったのですが、生成される乱数の質が悪いよ うです A. FreeBSD の rand(3) 関数は、オンラインマニュアルにもあるとおり、非常 に質の悪い乱数生成関数ですので、使わない方がよいでしょう。 なお、乱数の質とはどのようなものかここでは触れませんので、後述の参 考文献 (*1) 等を参照してください。 乱数の利用目的とそれに応じた要求は大きく分けると次の2通りです。 (1) モンテカルロ (Monte Carlo) 法等のシミュレーション 再現性のある擬似乱数が必要です。 (決定論的乱数) (2) 暗号 乱数列が推測できてはいけません。(非決定論的乱数) (1) シミュレーション等に用いる擬似乱数 推奨はできませんが、どうしてもシステムで用意されている疑似乱数生 成関数を使いたい場合は、random(3) がいくぶんましです。 シミュレーション向けの擬似乱数については、2004年現在 Mersenne Twister が最も良いでしょう。 詳しくは「間違いだらけの擬似乱数選び」 をご覧ください。 実装については、上記サイトで紹介されているものの他、C# 版が で公開されています。 また、言語によっては処理系や広く使われているライブラリで提供され ています。例えば: boost (C++, ports/devel/boost) Blitz++ (C++, ports/math/blitz++) ports/math/p5-Math-Random-MT (perl) (2) 暗号 暗号に用いる場合、簡単にいうと、生成される乱数列が推測できてはい けません。FreeBSD では、/dev/random が利用できます。また、RC4 暗 号に用いられる疑似乱数生成関数 arc4random() も用意されています。 それぞれ、random(4)、arc4random(3) のマニュアルを参照してください。 5.0-RELEASE 以降では、random(4) が Yarrow アルゴリズム を使うように書き直され、かなり良いものになったようです。 FreeBSD に依存しないものだと、OpenSSL で乱数生成用の API が提供さ れています (RAND_*)。engine(3)、rand(3) 等、関連するマニュアルを 参照してください。 詳しいことは暗号関連の参考書を調べてください。 なお、OpenSSL のマニュアル rand(3) はシステムの rand(3) 関数と重なって いるので、man -a 3 rand と -a オプションを指定しないと読めないでしょう。 (*1) 乱数に関する参考資料 日本語の書籍としては、 ・『準数値算法/乱数』 D.E. Knuth 著、渋谷 政昭 訳 (サイエンス社) "The Art of Computer Programming, vol.2: Seminumerical Algorithms" 2nd ed. Addison-Wesley, Reading, Mass. の訳です。 ・『乱数』 伏見 正則 著 (東京大学出版会、ISBN 4-13-064072-0) を挙げておきます。ただし、後者には「乱数とは何か?」という話はあり ません。WWW では、次の Random Number Generators また、Diehard という乱数生成器を試験するソフトウェアもあります。 (ports/math/diehard) 参考: [FreeBSD-users-jp 69480] とそれを含むスレッド --- [管理番号 2611] (最終更新 2004/07/12 23:14:37) Q. Java2 SDK 1.3 (jdk13) をインストールする方法を教えてください。 A. 現在 FreeBSD 上で動作し、ports となっている jdk13 の実装は以下の5種類です。 java/linux-sun-jdk13 (Linux版・バイナリ配布) java/linux-ibm-jdk13 (Linux版・バイナリ配布) java/linux-blackdown-jdk13 (Linux版・バイナリ配布) java/diablo-jdk13 (FreeBSD版・バイナリ配布) java/jdk13 (FreeBSD版・ソースからのビルドが必要) linux-sun-jdk13, linux-ibm-jdk13, linux-blackdown-jdk13 は Linux版バイナリのため、動作させるには Linux emulation を有効にしなければ なりません。 diablo-jdk13 は The FreeBSD Foundation が Sun からの正式なライセンスを受け バイナリ配布している、FreeBSD ネイティブな JDK です。 ただし、バイナリ互換性の問題により、現在のところ FreeBSD 4.x 上でしか 動作させることができません。 java/jdk13 はソースからビルドする、FreeBSD ネイティブな JDK です。 FreeBSD 5.x 上では diablo-jdk13 は動作しないため、ネイティブな JDK が 必要な場合はこちらをインストールする必要があります。 また、diablo-jdk13 では native threads や HotSpot がサポートされていないので、 これらの機能を使用したい場合にも java/jdk13 をインストールする必要があります。 java/jdk13 のインストールの流れを簡単にまとめると以下のようになります。 1. ビルド用の jdk をインストールする。 2. jdk のソース・FreeBSD 用のパッチを /usr/ports/distfiles/ に置く。 3. ports の java/jdk13 を make install する。 以下、個別に解説します。 1. ビルド用の jdk をインストールする。 java/jdk13 をビルドするためには、bootstrap となる JDK が 別途必要となります。 (一度 java/jdk13 をビルドしてしまえば、bootstrap 用 JDK は アンインストールしても構いません。) FreeBSD 4.x では java/diablo-jdk13 をインストールしておきます。 FreeBSD 5.x では Linux emulation を有効にしたうえで、 java/linux-blackdown-jdk13 をインストールしておきます。 Linux emulation を有効にする方法は、ハンドブックを参照してください。 2. jdk のソース・FreeBSD 用のパッチを /usr/ports/distfiles/ に置く。 jdk13 を ports からインストールしようとすると以下のようにエラーと なります。 # cd /usr/ports/java/jdk13 # make ===> jdk-1.3.1pX_Y : Because of licensing restrictions, you must fetch the source distribution manually. Please access http://www.sun.com/software/java2/download.html with a web browser and follow the "Download" link for the "Java(TM) SDK 1.3.1". You will be required to log in and register, but you can create an account on this page. After registration and accepting the Sun Community Source License, select "J2SESDK" and download the source file, j2sdk-1_3_1-src.tar.gz. Please place this file in /usr/ports/distfiles. つまりライセンスの制限により、Sun のサイトからJDK のソースを手動で ダウンロードし、/usr/ports/distfiles/ にファイルを置く必要があると いうことです。ソースのダウンロードにはユーザ登録が必要です (上記 ページで登録可能。ちなみに無料)。 メッセージに従い、j2sdk-1_3_1-src.tar.gz を /usr/ports/distfiles/ に置き、再度 make します。 # cd /usr/ports/java/jdk13 # make ===> jdk-1.3.1pX_Y : The source distribution exists on your system, but due to licensing restrictions you still need to download the patchset, bsd-jdk131-patches-Z.tar.gz, from http://www.eyesbeyond.com/freebsddom/java/jdk13.html. Please place the patchset in /usr/ports/distfiles. Sun のソースをそのまま FreeBSD でコンパイルすることはできず、 FreeBSD 用のパッチをあてる必要があります。このパッチもライセンスの 制限により上記サイトから手動でダウンロードする必要があります。 ダウンロードした bsd-jdk131-patches-Z.tar.gz を /usr/ports/distfiles/ に 置き、再度 make します。 3. java/jdk13 を make install する。 FreeBSD 5.1〜5.2-RELEASE: # cd /usr/ports/java/jdk13 # make WITH_LINUX_BOOTSTRAP=yes install 注: 単に make install とすると、以下のエラーが発生します。 ERROR: Your BOOTDIR environment variable does not point to a valid Java 2 SDK for bootstrapping this build. A Java 2 SDK 1.3.1 build must be bootstrapped against any 1.3 build. Please update your ALT_BOOTDIR setting, or just unset it, and start your build again. JDK をコンパイルするために bootstrap となる JDK が 必要となるのですが、WITH_LINUX_BOOTSTRAP=yes とする ことで java/linux-blackdown-jdk13 が bootstrap として 使用されます。 FreeBSD 5.2.1-RELEASE 以降: # cd /usr/ports/java/jdk13 # make install 注: FreeBSD 5.2.1-RELEASE 以降でも bootstrap の JDK が 必要なのは同じですが、ports 内部で自動的に WITH_LINUX_BOOTSTRAP=yes とセットされますので、 make install だけで OK です。 最後に、確認のため Java アプリケーションの Hello World を コンパイル・実行してみましょう。java/jdk13 のバイナリは /usr/local/jdk1.3.1/bin/ にインストールされます。 ソース作成 % cat HelloWorld.java public class HelloWorld { public static void main(String[] args){ System.out.println("Hello World"); } } コンパイル % /usr/local/jdk1.3.1/bin/javac HelloWorld.java HelloWorld.class が生成されたことを確認 % ls ls HelloWorld.* HelloWorld.class HelloWorld.java 実行 % /usr/local/jdk1.3.1/bin/java HelloWorld Hello World