バージョン番号を静的ライブラリ (file.a) に保存し、後で Linux でそのバージョンを確認するにはどうすればよいですか?
PSシェルユーティリティのみを使用して、特別な実行可能ファイルを使用せずに、いつでもファイルのバージョンを確認できるようにする必要があります。
バージョン番号を静的ライブラリ (file.a) に保存し、後で Linux でそのバージョンを確認するにはどうすればよいですか?
PSシェルユーティリティのみを使用して、特別な実行可能ファイルを使用せずに、いつでもファイルのバージョンを確認できるようにする必要があります。
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されます。これを使用して、ライブラリ内に関数を作成し、呼び出し元のアプリケーションからそれらにアクセスするなどして、さらに検証を行うことができます。
おそらく、次のようなバージョンで文字列を作成できます。
char* library_version = { "Version: 1.3.6" };
シェルからチェックできるようにするには、次を使用します。
strings library.a | grep Version | cut -d " " -f 2
編集に基づいて新しい回答を作成しています...混乱を避けるために:)
問題を解決するためのコード以外の方法を探している場合は、これを試すことができます。stringsこれは (またしても) Puppe によって定義されたアプローチに代わるものです。
というファイルに触れversion_1.2.3て、アーカイブに追加することもできます。次に、ar コマンドを使用してバージョン ファイルを検索することで、バージョンを特定できます。
ar t libmylib.a | grep 'version_' | sed -e 's/^version_//'
これで必要なものが得られるかどうかはわかりませんが、このようなメタデータをアーカイブに埋め込む標準的な方法はありません。アーカイブ用にこの「メタファイル」に保存したい他の情報が見つかるかもしれません。
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(これにより、コンパイルされたオブジェクトからコンパイラ バージョンのコメントも省略されます)。
何度か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:identとwhatはどちらも、特定の集中型ソース管理システムに付属するコマンドです。分散ソース管理システム (git など) を使用している場合、概念全体が意味をなさない場合があります。使用方法については、次のgitスレッドを参照してください: Moving from CVS to git: $Id:$ equal? ただし、ハッシュはバージョン番号と同じではありません。:)