2009-10-28 8 views
7

静的ライブラリ(file.a)にバージョン番号を格納し、後でそのバージョンをLinuxで確認できますか?静的ライブラリにバージョン番号を格納する方法は?

P.S.私は、シェルユーティリティだけを使って特別な実行可能ファイルなしで、いつでもファイルのバージョンをチェックする可能性が必要です。

+0

以下の解決策(私が書いた2つの方法)は共に共用ライブラリでも利用可能です。 –

+0

ちょうどあなたの編集に基づいて別の答えが追加されました。 – jheddings

答えて

8

たぶん、あなたはこのようなバージョンで文字列を作成することができます。

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

とシェルからそれを確認できるようにするだけで使用します。

strings library.a | grep Version | cut -d " " -f 2 
+0

もちろん、ポインタのスペースを節約するために、 'const char library_version [] =" 1.3.6 ";'にしてください。そして、ライブラリのヘッダ(またはライブラリと一緒に配布されたヘッダ)に変数を宣言します。 –

+0

私の質問を再チェックしてください - それは更新されました – Pirks

+1

シェルからバージョンを確認するための情報を追加しました – Puppe

8

また静的な文字列を提供しますPuppeが述べたように、互換性のためにバージョンチェックを取得するマクロを提供するのが一般的な方法です。たとえば、あなたは(あなたのライブラリーで使用されるヘッダファイルで宣言された)次のマクロを持つことができます:MYLIB_CHECK_VERSIONマクロで

#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)) 

お知らせを、私はあなたが特定の主要な回転とマイナーリビジョンをしたいと仮定していますあなたの希望するバージョン以上。アプリケーションに応じて変更してください。

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

このアプローチはバージョン情報が含まれるヘッダファイルから来るようになります:

その後のようなものは、呼び出し元のアプリケーションからそれを使用しています。さらに、呼び出し元アプリケーションのコンパイル時に最適化されます。もう少し作業すれば、ライブラリ自体から抽出することができます。 Read on ...

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と呼ばれる構造体を作成します。あなただけの混乱を避けるために...あなたの編集に基づいて、新しい答えを作成する

+1

私が見ているMYLIB_VERSION_CHECKの唯一の問題は、コンパイル時に評価され、すべてがOKなら良いオプティマイザがチェックを取り除き、無条件にprintf()を呼び出すということです - fprintf(stderr、...) )、そうですか? - とexit()。定数式を使用するのではなく、ロジックを埋め込んだ関数を呼び出すほうがよいでしょう。 –

+0

ええ、ここで良い点は...私は後でこの理由のためにライブラリに情報を埋め込むことを含むように自分の投稿を編集しました。説明をありがとう。 – jheddings

+0

私の質問を再確認してください - 更新されました – Pirks

3

など、あなたのライブラリ内の関数を作成し、呼び出し元のアプリケーションからそれらにアクセスすることにより、更なる検証を行うためにこれを使用することができます:)

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

version_1.2.3という名前のファイルに触れ、アーカイブに追加するだけでもかまいません。その後、あなたはarコマンド使用して、バージョンファイルを探すことでバージョンを確認できます。

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

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

+0

** 'man 1 ident' **についてはどうですか? –

+0

この方法はバージョン管理には適していません。 –

+0

@ vitaly.v.ch linyux以外では利用できません。 – MarcusJ

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.aに追加した場合はident f.aにも同様の出力が表示されます。同じようなものが複数ある場合は、az.a[a-z].oを組み込み、az.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は、コマンド

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 
、FOにコンパイルされます

PS:identwhatは、特定の集中型ソース管理システムに付属するコマンドです。分散ソース管理システム(gitのような)を使用している場合、コンセプト全体が意味をなさないかもしれません。 gitを使用しているアイデアについては、このスレッド:Moving from CVS to git: $Id:$ equivalent?を参照してください。ハッシュはバージョン番号と同じではありません。これは、あなたがコンパイルできるようになります

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

:gccを使用している場合:)

0

は、あなただけの、次のいずれかを使用したバージョンを取得するには#identディレクティブ

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

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

関連する問題