Как сохранить номер версии в статической библиотеке?

StackOverflow https://stackoverflow.com/questions/1638207

  •  08-07-2019
  •  | 
  •  

Вопрос

Как я могу сохранить номер версии в статической библиотеке (файл.a) и позже проверить наличие ее версии в Linux?

P.S.Мне нужна возможность проверять версию файла в любое время без какого-либо специального исполняемого файла, используя только утилиты оболочки.

Это было полезно?

Решение

Может быть, вы могли бы создать строку с версией, подобной этой:

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

и чтобы иметь возможность проверить это из оболочки, просто используйте:

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 в вашей библиотеке.Вы можете использовать это для выполнения дальнейших проверок, создавая функции внутри вашей библиотеки и получая к ним доступ из вызывающего приложения и т.д.

Создаем новый ответ на основе вашей правки...Просто чтобы избежать путаницы :)

Если вы ищете некодовый способ решения проблемы, вы могли бы попробовать это.Это (в очередной раз) альтернатива 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 $";
int main() { return printf("%s\n", rcsid) == EOF; }

и f.c компилируется в f.o, затем команда

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 должен показать аналогичный результат.Если у вас есть несколько аналогично построенных [a-z].o в вашем az.a вы должны найти все их строки в 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; }

и f.c компилируется в f.o, затем команда

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 смотрите эту тему: Переход от CVS к git:$Id: эквивалент в долларах? хотя хэш не совпадает с номером версии.:)

Если вы используете 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 (Это также приведет к отсутствию комментариев к версии компилятора в скомпилированных объектах)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top