Recent

Author Topic: Getting a value from the .LPI file as a compile time constant  (Read 1458 times)

VisualLab

  • Full Member
  • ***
  • Posts: 216
Re: Getting a value from the .LPI file as a compile time constant
« Reply #15 on: August 21, 2023, 12:17:04 pm »
In Delphi I can get a little more detailed, but let's not go there now, I am busy trying to get reacquainted with it to move some projects back to it. The IDE is horrible.

Compared to other commercial IDEs, it's pretty decent. Which features do you mean? Which version?

KodeZwerg

  • Hero Member
  • *****
  • Posts: 1719
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Getting a value from the .LPI file as a compile time constant
« Reply #16 on: August 21, 2023, 12:34:49 pm »
fileinfo unit (from @Renat.Su 's suggestion) was what I was looking for.
Can you give an example usage not at runtime?
VersionInfo I just use in AboutBox...
I am still confused since you accept a run-time solution but explicit asked for compile-time and skipped my post.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

fedkad

  • Full Member
  • ***
  • Posts: 175
Re: Getting a value from the .LPI file as a compile time constant
« Reply #17 on: August 21, 2023, 12:42:50 pm »
I am still confused since you accept a run-time solution but explicit asked for compile-time and skipped my post.

I am also using this information mainly in the About box. I was afraid that all kind of wrong things (like unable to read the executable file) can happen at run-time and also this did not seem performance-wise a good thing. However, for the time being, I am going to continue with the solution I accepted.
Lazarus 2.2.6 / FPC 3.2.2 on x86_64-linux-gtk2 (Ubuntu/GNOME) and x86_64-win64-win32/win64 (Windows 11)

TRon

  • Hero Member
  • *****
  • Posts: 1841
Re: Getting a value from the .LPI file as a compile time constant
« Reply #18 on: August 21, 2023, 06:30:03 pm »
However, embedding some information into the EXEcutable file (and it is different in Windows and Linux) and trying to extract this information from the executable at run-time seems quite overkill and inefficient to me!
That the executable format is different is not your concern as VersionInfo takes care of that for the end-user. Overkill and inefficient ? Perhaps but you probably should have told that to the MS developers when "they" 'invented' embedding resources into their executables  :)

fedkad

  • Full Member
  • ***
  • Posts: 175
Re: Getting a value from the .LPI file as a compile time constant
« Reply #19 on: August 24, 2023, 03:21:28 pm »
Perhaps you can use some cli xpath utility in 'Project Options/Compiler Options/Compiler Commands/Execute before' to extract /CONFIG/ProjectOptions/VersionInfo/BuildNr/@Value from the *.lpi, write it to a temp file and then include it into your source with {$I temp.inc}.

It is quite easy to write such utility by yourself, see https://wiki.lazarus.freepascal.org/xpath

I decided to give a try to @alpine's suggestion. I wrote the following program:

Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. uses
  3.   laz2_dom, laz2_XMLRead;
  4.  
  5. const
  6.   pref = 'vinfo_';
  7.  
  8. var
  9.   Doc : TXMLDocument;
  10.   f   : TextFile;
  11.  
  12. procedure printVer (const Tag : String);
  13. begin
  14.   writeln(f, pref, Tag , ' = ',
  15.     Doc.GetElementsByTagName(Tag)[0].Attributes.GetNamedItem('Value').TextContent,
  16.     ';');
  17. end;
  18.  
  19. procedure printST (const st : TDOMNodeList; const a : array of String);
  20. var
  21.   i : Integer;
  22. begin
  23.   for i := low(a) to high(a) do
  24.     writeln(f, pref, a[i] , ' = ''',
  25.       st[0].Attributes.GetNamedItem(a[i]).TextContent, ''';');
  26. end;
  27.  
  28. begin
  29.   AssignFile(f, paramstr(2));
  30.   try
  31.     Rewrite(f);
  32.     ReadXMLFile(Doc, paramstr(1));
  33.     printVer('MajorVersionNr');
  34.     printVer('MinorVersionNr');
  35.     printVer('RevisionNr');
  36.     printVer('BuildNr');
  37.     printST(Doc.GetElementsByTagName('StringTable'),
  38.       ['Comments', 'CompanyName', 'FileDescription', 'InternalName', 'LegalCopyright',
  39.        'LegalTrademarks', 'OriginalFilename', 'ProductName', 'ProductVersion']);
  40.   finally
  41.     CloseFile(f);
  42.     Doc.Free;
  43.   end;
  44. end.

On Linux, you can compile it with:

fpc -Fu/usr/share/lazarus/2.2.6/components/lazutils/lib/x86_64-linux/ vinfo.pas
fpc -Fu/usr/share/lazarus/2.2.6/components/lazutils/lib/i386-linux/   vinfo.pas


On Windows, with:

\lazarus\fpc\3.2.2\bin\x86_64-win64\fpc -Fu\lazarus\components\lazutils\lib\x86_64-win64 vinfo.pas
\lazarus\fpc\3.2.2\bin\i386-win32\fpc   -Fu\lazarus\components\lazutils\lib\i386-win32   vinfo.pas


Also, on Windows run,

ren vinfo.exe vinfo

after the compilation.

Then, on Lazarus Project Options...Compiler Commands: Execute before Build put:

vinfo your_project.lpi vinfo.inc

and in your project's main unit's public const declarations insert:

Code: Pascal  [Select][+][-]
  1. {$I vinfo.inc}

After selecting RunBuild in Lazarus, you can compile your project which contains references to the vinfo_ constants created automatically from the .lpi file by the vinfo program.

« Last Edit: August 27, 2023, 12:57:28 pm by fedkad »
Lazarus 2.2.6 / FPC 3.2.2 on x86_64-linux-gtk2 (Ubuntu/GNOME) and x86_64-win64-win32/win64 (Windows 11)

Renat.Su

  • Full Member
  • ***
  • Posts: 226
    • Renat.Su
Re: Getting a value from the .LPI file as a compile time constant
« Reply #20 on: August 26, 2023, 04:23:45 pm »

I guess the undocumented (?) fileinfo unit (from @Renat.Su 's suggestion) was what I was looking for. And something like this seems enough for me:

Why is undocumented?
For example, https://wiki.freepascal.org/Show_Application_Title,_Version,_and_Company

 

TinyPortal © 2005-2018