如何在静态库(file.a)中存储版本号,然后在Linux中检查其版本?

P.S。我需要随时使用shell实用程序检查文件版本而无需任何特殊可执行文件。

有帮助吗?

解决方案

也许你可以用这样的版本创建一个字符串:

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

并且能够从shell中检查它只需使用:

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

其他提示

除了提供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 的结构。您可以通过在库中创建函数并从调用应用程序等访问这些函数来使用它来进行进一步的验证。

根据您的编辑创建新答案...为避免混淆:)

如果您正在寻找解决问题的非代码方式,您可以试试这个。它(又一次)是Puppe定义的 strings 方法的替代品。

也许您只需触摸名为 version_1.2.3 的文件并将其添加到存档中即可。然后,您可以使用ar命令查找版本文件来确定版本:

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

我不确定这是否能满足您的需求,但是没有标准方法可以在存档中嵌入这样的元数据。也许你会在这个“元文件”中找到你想要存储的其他信息。存档。

多次提到 man 1 ident ,所以这里有关于使用该方法的详细信息。

ident 是RCS(修订控制系统)附带的命令,但如果您使用的是CVS(并发版本系统)或Subversion,则可能也可用。

您可以像这样使用它(从手册页克隆):

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

和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 $

将输出

#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; }

如果 f.o 已添加到静态库 f.a ,则 ident f.a 应显示类似的输出。如果在 az.a 中有几个类似构建的 [az] .o ,则应在 az.a 文件中找到所有字符串。

CAVEAT:仅仅因为它们在.a文件中并不意味着它们将包含在您的程序文件中。除非程序引用它们,否则链接器不需要包含它们。因此,您通常必须在每个模块中都有一个方法来返回字符串,并且应用程序需要调用该方法。有一些方法可以说服大多数链接器它是一个必需的符号而没有实际引用它,但它取决于链接器,超出了这个答案的范围。

如果您熟悉SCCS(源代码控制系统),那么您将使用 man 1 what ,它看起来像这样(用宏来完成以显示可用的灵活性):

what f.c f.o

和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 的一些想法,请参阅此主题:从CVS到git:$ Id:$ equivalent?尽管哈希值与版本号不同。 :)

如果您使用的是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 <完全省略它/ code>(这也将省略编译对象的编译器版本注释)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top