ELF 形式でプログラムを作るには gcc
を普通に使うだけです。
a.out 形式でコンパイルするには gcc -b i486-linuxaout
としてく
ださい。
そろそろ ``もし a.out 形式のコンパイラがデフォルトで生成する実行プログ
ラムの名前が a.out
なら、ELF コンパイラがデフォルトで生成する
プログラムの名前は何と言うの?''という問いに答えましょう。やっぱり
a.out
、というのが答えなんです。残念でしたか :-)
共有ライブラリとして libfoo.so を作る基本的な手順は以下の通りです。
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so
$ export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
これで libfoo.so.1.0
と言う共有ライブラリができ、ld が識別す
べきリンク(libfoo.so
) も張られ、動的リンカも見つけることがで
きます(libfoo.so.1
)。テストのために、このプログラムのあるディ
レクトリを LD_LIBRARY_PATH
に追加しています。
もし作った共有ライブラリがちゃんと動くようなら、適切な場所、例えば
/usr/local/lib
にでも移して、必要なリンクを張りましょう。
libfoo.so
が libfoo.so.1
を指すようにリンクを張って、
マイナーバージョンナンバーが変わる度に update しなくても済むようにして
おきましょう。libfoo.so.1
から libfoo.so.1.0
へのリンクは
ldconfig
によって、たいていのシステムでは起動時に更新されるよ
うにっています。
$ su
# cp libfoo.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )
この問題については H J Lu 作の「ELF プログラミングドキュメント」と
ld.so パッケージに附属の dlopen(3)
のマニュアルページにくわし
く解説してあります。ここでは簡単な例を示すに留めましょう。以下のプログ
ラムを -ldl
オプションを付けてリンクしてみてください。
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call=dlsym(libc,"printf");
(*printf_call)("hello, world\n");
}
}
お手持ちの gdb
は ELF プログラムに対しても特に変更なしで動くはず
です(たいていの場合)。しかし、tsx-11 の GCC
ディレクトリにある新し
いバージョンの gdb は動的ローディングにも対応し、ELF 形式のコアにも対
応しているそうです。
しかしながら、この文書を書いている時点では、ELF プログラムがコアダンプ するためにはカーネルにパッチを当てる必要があります。問題が多少専門的に なるので、この文書ではそこまで扱いません。