7

この質問は、シェル スクリプトを作成しているモンスターにとってはかなり簡単だと思います。

bash シェル スクリプトを使用して、Unix の共有ライブラリへのシンボリック リンクを作成する最もエレガントで最短の方法を探しています。

必要なのは、「libmythings.so.1.1、libotherthings.so.5.11」などの共有ライブラリ ファイルのリストから始めて、次のようなシンボリック リンクを作成することです。

libmythings.so -> libmythings.so.1 -> libmythings.so.1.1
libotherthings.so -> libotherthings.so.5 -> libotherthings.so.5.11

ライブラリ ファイルは、他のシェル スクリプトなどの他のファイルを含むディレクトリ内にあります。

編集:まあ、「ldconfig -nN」。正常に動作する可能性がありますが、「.so」の後にライブラリのメジャー番号を追加せずに、少なくとも 1 つのライブラリのリンクも必要です。これは、1 つまたは複数のライブラリが Java からの JNI 呼び出しのエントリ ポイントであるためです。 System.loadlibrary("libraryname") によってインスタンス化され、"libraryname.so.X" ではなく "libraryname.so" という名前のライブラリが必要です。

Java 部分に回避策があれば、ldconfig -nN だけを使用したソリューションが機能する可能性があります。

4

3 に答える 3

14

ldconfigこれを行う標準的なツールだと思います。

内部バージョン情報に基づいてシンボリックリンクを生成できる場所を思い出しましたが、現在ソースが見つかりません。

編集はい、実行する場合

ldconfig -v 

ライブラリの内部に基づいてすべてのリンクが生成されていることがわかります。

ldconfig /path/to/dir 

そのディレクトリ内のファイルのリンクのみを作成します

ただし、私はそれを試してみましたが、.so.{major} だけで一貫して .so$ を作成していないようです。

その内部がどのように機能するかはわかりませんが、知っています:

lib # rm libmagic.so
lib # rm libmagic.so.1
lib # ldconfig
lib # ファイル libmagic.so.1   
libmagic.so.1: 「libmagic.so.1.0.0」へのシンボリックリンク
lib # ファイル libmagic.so
libmagic.so: `libmagic.so' を開けません (そのようなファイルやディレクトリはありません)

だから、これがどのように機能するかを決定するものは私にとって謎です

さらに慎重に編集すると、.la ファイルは動作に影響を与えません。

「SO」名フィールドは、シンボリックリンクの名前を示します。

そして、1つだけになります。

0x000000000000000e (SONAME) ライブラリ soname: [libmagix.so]

これは、コードをハッキングして「.1」をスペースに置き換えた後のものです。

ldconfig によって生成された "libmagic.so" (はい、スペースが含まれています)

于 2009-01-20T16:56:48.443 に答える
7
for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shortlib=$(basename $shortlib $extn)
         ln -s $baselib $shortlib
     done
done

私はだまされました - すべてのリンクはベース ライブラリ (libmythings.so.1.1) に移動します。本当にチェーンしたい場合は、次のものが必要です。

for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shorterlib=$(basename $shortlib $extn)
         ln -s $shortlib $shorterlib
         shortlib=$shorterlib
     done
done           

注意 - テストされていないコード。


傲慢は宿敵に先行します。

上記のコードが機能しないというコメントが届きました - そしてそのコメントは正しいです。その場でのテストを含む修正バージョンは次のとおりです。

set -- libname.so.5.1.1

for baselib in "$@"
do
    shortlib=$baselib
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        echo ln -s $baselib $shortlib
    done
done

変更はsedコマンドにあります。このバージョンは、デフォルトでは何も出力せず ( -n)、ドットの後に数字が続く行のみに一致し、そのサフィックス以外のすべてを削除し、extn への割り当てのために残っているものを出力します。修正されたように、スクリプトは以下の出力を生成します。エコーを削除して、リンク コマンドを実行できるようにします。

ln -s libname.so.5.1.1 libname.so.5.1
ln -s libname.so.5.1.1 libname.so.5
ln -s libname.so.5.1.1 libname.so

このスクリプトは、シェル スクリプトに関して見落とされがちな興味深い点を示しています。while の条件ブロック内の一連の操作は、単一のコマンドである必要はありません。編集操作のある行のステータスは、テスト全体が成功するかどうかには影響しません。最後のコマンド ' [ -n "$extn" ]' の終了ステータスは、ループが継続するかどうかを制御します。

于 2009-01-20T16:58:40.157 に答える
5

Jonathan Leffler のスクリプトから派生 (これを「liblinks」というスクリプトとして ~/bin に追加しました)

#!/bin/bash
# liblinks - generate symbolic links 
# given libx.so.0.0.0 this would generate links for libx.so.0.0, libx.so.0, libx.so
#

# By adding sudo to the ls command, we get permission to do the linking (or get an empty list)
LIBFILES=`sudo ls lib*.so.*`
for FILE in $LIBFILES;
   do
   echo $FILE
    shortlib=$FILE
    basename=$FILE
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        sudo ln -fs $basename $shortlib
        basename=$shortlib
    done

   done
于 2011-11-15T23:30:51.897 に答える