8

バージョン番号を静的ライブラリ (file.a) に保存し、後で Linux でそのバージョンを確認するにはどうすればよいですか?

PSシェルユーティリティのみを使用して、特別な実行可能ファイルを使用せずに、いつでもファイルのバージョンを確認できるようにする必要があります。

4

5 に答える 5

10

Puppe で言及されているように静的文字列を提供することに加えて、互換性のためにバージョン チェックを取得するマクロを提供するのが一般的です。たとえば、次のマクロを使用できます (ライブラリで使用するヘッダー ファイルで宣言されています)。

#define MYLIB_MAJOR_VERSION 1
#define MYLIB_MINOR_VERSION 2
#define MYLIB_REVISION 3
#define MYLIB_VERSION "1.2.3"
#define MYLIB_VERSION_CHECK(maj, min) ((maj==MYLIB_MAJOR_VERSION) && (min<=MYLIB_MINOR_VERSION))

マクロで注意してMYLIB_CHECK_VERSIONください。特定のメジャー リビジョンと、目的のバージョン以上のマイナー リビジョンが必要であると想定しています。アプリケーションの必要に応じて変更します。

次に、次のような呼び出し元のアプリケーションから使用します。

if (! MYLIB_VERSION_CHECK(1, 2)) {
    fprintf(stderr, "ERROR: incompatible library version\n");
    exit(-1);
}

このアプローチにより、バージョン情報がインクルードされたヘッダー ファイルから取得されます。さらに、呼び出し元のアプリケーションのコンパイル時に最適化されます。もう少し作業すれば、ライブラリ自体から抽出できます。読む...

Puppe が述べたように、この情報を使用して、ライブラリ内に格納された静的文字列を作成することもできます。ライブラリ内に次のようなものを配置します。

struct {
    const char* string;
    const unsigned major;
    const unsigned minor;
    const unsigned revision;
} mylib_version = {
    MYLIB_VERSION, MYLIB_MAJOR_VERSION, MYLIB_MINOR_VERSION, MYLIB_REVISION
};

これにより、ライブラリで呼び出される構造体が作成mylib_versionされます。これを使用して、ライブラリ内に関数を作成し、呼び出し元のアプリケーションからそれらにアクセスするなどして、さらに検証を行うことができます。

于 2009-10-28T16:19:37.823 に答える
10

おそらく、次のようなバージョンで文字列を作成できます。

char* library_version = { "Version: 1.3.6" };

シェルからチェックできるようにするには、次を使用します。

strings library.a | grep Version | cut -d " " -f 2
于 2009-10-28T16:06:37.710 に答える
3

編集に基づいて新しい回答を作成しています...混乱を避けるために:)

問題を解決するためのコード以外の方法を探している場合は、これを試すことができます。stringsこれは (またしても) Puppe によって定義されたアプローチに代わるものです。

というファイルに触れversion_1.2.3て、アーカイブに追加することもできます。次に、ar コマンドを使用してバージョン ファイルを検索することで、バージョンを特定できます。

ar t libmylib.a | grep 'version_' | sed -e 's/^version_//'

これで必要なものが得られるかどうかはわかりませんが、このようなメタデータをアーカイブに埋め込む標準的な方法はありません。アーカイブ用にこの「メタファイル」に保存したい他の情報が見つかるかもしれません。

于 2009-10-28T17:09:51.450 に答える
1

gcc を使用している場合は、#ident ディレクティブを使用できます

#ident "Foo Version 1.2.3.4"
void foo(void){ /* foo code here */ }

バージョンを取得するには、次のいずれかを使用します。

strings -a foo.o | grep "Foo Version"
strings -a foo.a | grep "Foo Version"
strings -a foo.so | grep "Foo Version"

これにより、バージョンをライブラリにコンパイルして、後で使用してstrip -R .comment your_file削除するか、渡すことで完全に省略することができます-fno-ident(これにより、コンパイルされたオブジェクトからコンパイラ バージョンのコメントも省略されます)。

于 2016-06-02T18:25:41.210 に答える
0

何度かman 1 ident言及されているので、ここではその方法の使用について詳しく説明します。

identは RCS (Revision Control System) に付属するコマンドですが、CVS (Concurrent Versions System) または Subversion を使用している場合にも使用できる場合があります。

次のように使用します (man ページから複製):

#include <stdio.h>
static char const rcsid[] =
    "$Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $";
int main() { return printf("%s\n", rcsid) == EOF; }

fc は fo にコンパイルされ、次にコマンド

ident f.c f.o

出力します

   f.c:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $
   f.o:
       $Id: f.c,v 5.4 1993/11/09 17:40:15 eggert Exp $

静的ライブラリにf.o追加された場合、同様の出力が表示されるはずです。同様のものがいくつか組み込まれている場合は、それらのすべての文字列がファイル内にあるはずです。f.aident f.a[a-z].oaz.aaz.a

注意: それらが .a ファイルにあるからといって、それらがプログラム ファイルに含まれるわけではありません。プログラムがそれらを参照しない限り、リンカーはそれらを含める必要はないと判断します。したがって、通常、各モジュールには文字列を返すメソッドが必要であり、アプリはそのメソッドを呼び出す必要があります。実際に参照せずに必要なシンボルであることをほとんどのリンカーに納得させる方法はありますが、それはリンカーに依存しており、この回答の範囲を超えています。

代わりに SCCS (ソース コード管理システム) に精通している場合は、man 1 what代わりにそれを使用します。これは次のようになります (利用可能な柔軟性を示すためにマクロを使用)。

#include <stdio.h>
#define VERSION_STR "5.4"
#define CONFIG "EXP"
#define AUTHOR "eggert"
static char const sccsid[] =
    "@(#) " CONFIG " v " VERSION_STR " " __DATE__ " " __TIME__ " " AUTHOR;
int main() { return printf("%s\n", sccsid) == EOF; }

fc は fo にコンパイルされ、次にコマンド

what f.c f.o

出力します

   f.c:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert
   f.o:
       @(#) EXP v 5.4 1993/11/09 17:40:15 eggert

PS:identwhatはどちらも、特定の集中型ソース管理システムに付属するコマンドです。分散ソース管理システム (git など) を使用している場合、概念全体が意味をなさない場合があります。使用方法については、次のgitスレッドを参照してください: Moving from CVS to git: $Id:$ equal? ただし、ハッシュはバージョン番号と同じではありません。:)

于 2016-06-02T16:31:35.597 に答える