Как получить номер версии библиотеки в Linux

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Как получить номер версии библиотеки в Linux

Сообщение mrPG »

Есть необходимость контролировать номер версии подключаемой динамической библиотеки(*.so).
Для Win / Delphi использую GetFileVersionInfo.
В Linux для приложения номер версии получаю через TFileVersionInfo, в котором используется имя исполняемого файла из paramstr(1).

Как получить значение FileVersion для библиотеки?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Универсальный вариант (если у Вас rpm-дистрибутив):

Код: Выделить всё

rpm -qi libmpfr6 | grep Version
Вместо "libmpfr6" пишете правильное название нужной библиотеки.
Как запустить эту команду из своей программы:
http://freepascal.ru/article/freepascal/20191121080000/
mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Сообщение mrPG »

Vadim писал(а):Универсальный вариант (если у Вас rpm-дистрибутив):

Код: Выделить всё

rpm -qi libmpfr6 | grep Version
Вместо "libmpfr6" пишете правильное название нужной библиотеки.
Как запустить эту команду из своей программы:
http://freepascal.ru/article/freepascal/20191121080000/
Если следовать совету получится так : приложение вызывает функцию из библиотеки, а та в свою очередь вызывает внешнюю программу(rpm).
Хочется найти аналог GetModuleFileName для получения информации о файле библиотеки
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

mrPG писал(а):приложение вызывает функцию из библиотеки, а та в свою очередь вызывает внешнюю программу(rpm).
Не совсем понимаю о чём Вы, но если у библиотеки есть функция возвращающая её версию, то Вам ничего кроме этой функции вызывать уже не надо. А вот если такой функции нет, то ничего ни из какой библиотеки не вызываете - сразу и непосредственно запускаете команду и всё.
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

mrPG писал(а):Как получить значение FileVersion для библиотеки?
Никак. Vadim все правильно говорит, только с помощью менеджера пакетов. И то не всегда...
mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Сообщение mrPG »

WAYFARER писал(а):
mrPG писал(а):Как получить значение FileVersion для библиотеки?
Никак. Vadim все правильно говорит, только с помощью менеджера пакетов. И то не всегда...
Как то безрадостно((
Под Win никакой проблемы для получения информации о загруженной dll нет, а под Linux - решения нет?
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

mrPG писал(а):Под Win никакой проблемы для получения информации о загруженной dll нет, а под Linux - решения нет?
Тут проблема в том, что требуемая вам информация в файле просто-напросто отсутствует.
Впрочем в Windows для dll она тоже далеко не всегда будет... это зависит от того, добавил ли автор информацию о версии
mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Сообщение mrPG »

WAYFARER писал(а):
mrPG писал(а):Под Win никакой проблемы для получения информации о загруженной dll нет, а под Linux - решения нет?
Тут проблема в том, что требуемая вам информация в файле просто-напросто отсутствует.
Впрочем в Windows для dll она тоже далеко не всегда будет... это зависит от того, добавил ли автор информацию о версии
Поскольку библиотеку создаю я сам, то информация о номере версии в файлах и приложения, и библиотеки есть.
С Win вообще никаких проблем.
Под linux из исполняемого файла я ее получаю, а вот как получить от динамической библиотеки - не знаю (
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

mrPG
Очень похоже, что Вы делаете проблему из пустого места. Если речь идёт о Вашей собственной библиотеке, то сделайте там функцию, которая выдаёт её версию. Это будет в высшей степени кроссплатформенный вариант.
mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Сообщение mrPG »

Vadim писал(а):mrPG
Очень похоже, что Вы делаете проблему из пустого места. Если речь идёт о Вашей собственной библиотеке, то сделайте там функцию, которая выдаёт её версию. Это будет в высшей степени кроссплатформенный вариант.
Можете подсказать как сделать так, чтобы изменять номер версии не "ручками", а читать из файла *.so при вызове содержащейся в нем функции, т.е. изнутри ?
NB : Вызывающее функцию родительское приложение не мое, поэтому номер версии должен содержаться в строке, которую функция возвращает.
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

Что то вы похоже где то перемудрили, если у вас в принципе такая проблема встала.
Вы делаете библиотеку, которую использует некое стороннее приложение? Если обязательно нужно проверять версии библиотеки, что мешает добавить функцию? прямо в этой же библиотеки. Что то типа

Код: Выделить всё

function GetVersion (): Pchar; stdcall;
begin
 result := Pchar('1.1.3');
end;  

и меняйте версию при каждом новом релизе либы.

Добавлено спустя 2 минуты 52 секунды:
mrPG писал(а):Поскольку библиотеку создаю я сам, то информация о номере версии в файлах и приложения, и библиотеки есть.
Кто вам сказал, что она есть? почитайте про структуру elf файлов.
Аватара пользователя
Alexx2000
постоялец
Сообщения: 490
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Если и программа и библиотека на FPC, то версию можно прочитать так:

Код: Выделить всё

uses
  Resource, elfreader, ...
...
function GetFileVersion(const FileName: String): String;
var
  Version: TVersionInfo;
begin
  Version:= TVersionInfo.Create;
  try
    Version.Load(FileName);
    with Version.FixedInfo do
      Result:= Format('%d.%d.%d', [FileVersion[0], FileVersion[1], FileVersion[2]]);
  except
    Result:= EmptyStr;
  end;
  Version.Free;
end;
...
initialization
  TResources.RegisterReader('.so', TElfResourceReader);
где FileName полный путь к библиотеке.
mrPG
новенький
Сообщения: 10
Зарегистрирован: 25.07.2022 12:29:39

Сообщение mrPG »

WAYFARER писал(а):Что то вы похоже где то перемудрили, если у вас в принципе такая проблема встала.
Вы делаете библиотеку, которую использует некое стороннее приложение? Если обязательно нужно проверять версии библиотеки, что мешает добавить функцию? прямо в этой же библиотеки. Что то типа

Код: Выделить всё

function GetVersion (): Pchar; stdcall;
begin
 result := Pchar('1.1.3');
end;  

и меняйте версию при каждом новом релизе либы.
Менять вручную ?? Не наш метод

Добавлено спустя 2 минуты 52 секунды:
mrPG писал(а):Поскольку библиотеку создаю я сам, то информация о номере версии в файлах и приложения, и библиотеки есть.
Кто вам сказал, что она есть? почитайте про структуру elf файлов.
Можно и почитать, но для приложения, которое обращается к библиотеке, на fpc/Lazarus номер версии прекрасно определяется с помощью TFileVersionInfo с определением имени файла через paramstr(1), Для библиотеки определить имя файла из программы не получается

Добавлено спустя 3 минуты 39 секунд:
Alexx2000 писал(а):Если и программа и библиотека на FPC, то версию можно прочитать так:

Код: Выделить всё

uses
  Resource, elfreader, ...
...
function GetFileVersion(const FileName: String): String;
var
  Version: TVersionInfo;
begin
  Version:= TVersionInfo.Create;
  try
    Version.Load(FileName);
    with Version.FixedInfo do
      Result:= Format('%d.%d.%d', [FileVersion[0], FileVersion[1], FileVersion[2]]);
  except
    Result:= EmptyStr;
  end;
  Version.Free;
end;
...
initialization
  TResources.RegisterReader('.so', TElfResourceReader);
где FileName полный путь к библиотеке.
В этом случае надо задавать полный путь к библиотеке, а он на разных ПК может различаться.
Конечно есть вариант сделать ini-файл, из которого считывать этот путь, но хотелось решить это программно.

Добавлено спустя 33 минуты 26 секунд:
Alexx2000 писал(а):Если и программа и библиотека на FPC, то версию можно прочитать так:

Код: Выделить всё

uses
  Resource, elfreader, ...
...
function GetFileVersion(const FileName: String): String;
var
  Version: TVersionInfo;
begin
  Version:= TVersionInfo.Create;
  try
    Version.Load(FileName);
    with Version.FixedInfo do
      Result:= Format('%d.%d.%d', [FileVersion[0], FileVersion[1], FileVersion[2]]);
  except
    Result:= EmptyStr;
  end;
  Version.Free;
end;
...
initialization
  TResources.RegisterReader('.so', TElfResourceReader);
где FileName полный путь к библиотеке.

К сожалению, для *.so получаю сообщение No version info load ((
Аватара пользователя
Alexx2000
постоялец
Сообщения: 490
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи
Контактная информация:

Сообщение Alexx2000 »

Путь до загруженной библиотеки можно узнать так, пример:

Код: Выделить всё

    h:= LoadLibrary('libc.so.6');
    @getrandom:= GetProcAddress(H, 'getrandom');
    WriteLn('LIB: ', mbGetModuleName(@getrandom)); 
результат
LIB: /usr/lib/libc.so.6
mrPG писал(а): К сожалению, для *.so получаю сообщение No version info load ((
Вот рабочая демка, в архиве пример библиотеки с версией и консольной программы которая её читает.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

mrPG
Давайте ещё раз уточним: Вы свою библиотеку на каком языке программирования пишите?
Ответить