Recent

Author Topic: Embed libraries into executable  (Read 577 times)

cgaertner

  • Newbie
  • Posts: 4
Embed libraries into executable
« on: October 10, 2020, 11:08:12 pm »
Dear all,

for several weeks I am searching an answer for a question which seems to be so simple that I cannot believe that the information is not out there in the net. Probably I am using the wrong search terms.

Okay: I am developing Windows software with lazarus/Freepascal for several years and now I have a program that should also be used with Linux. For Windows I create one exe file, which runs on Windows XP, 7, 8, 10 - no matter if 32 bit or 64 bit. The only dll my program needs (a driver for an USB device) is in the program directory.

I successfully modified the source code using compiler directives [{$IFDEF WINDOWS}, {$IFDEF UNIX}] and the program runs successfully on Linux (Debian 10, 32 bit). If I copy the executable file to another Linux system (Ubuntu 20, 64 Bit), it does not start. Using ldd I determined that the program has a load of dependencies to "/lib/i386-linux-gnu/*" and I assume these external dependecies are the reason why the program start fails. The error message is "error while loading shared libraries: libgdk-x11-2.0.so.0: cannot open shared object file: No such file or directory".

Question 1: Are there compiler settings to integrate all the libraries into the executable file like on Windows? I am aware of the fact that even the Windows executable has external dependencies but they are compatible for each Windows version since XP.

Question 2: The reason for the error message mentioned above might be, that on Linux 32 bit the library is located in ...
/lib/i386-linux-gnu/libgdk-x11-2.0.so.0
... whereas the library on Linux 64 bit is located in ...
/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
But I have not hard coded the path to the library, so why isn't it found, although it's the same name and version?

Question 3: How can I build a portable app with Lazarus/Freepacal? I habe read the page "Deploying Your Application" several times, but I cannot figure out how this would help me (I do not want to creat official available packages). AppImage sounds like a cool thing, but I have not found any helpful information how to do this with a Lazarus/Freepascal executable ...

Thank you and greetings from Vienna,
Christian

Handoko

  • Hero Member
  • *****
  • Posts: 3909
  • My goal: build my own game engine using Lazarus
Re: Embed libraries into executable
« Reply #1 on: October 11, 2020, 05:36:00 am »
I successfully modified the source code using compiler directives [{$IFDEF WINDOWS}, {$IFDEF UNIX}] and the program runs successfully on Linux (Debian 10, 32 bit). If I copy the executable file to another Linux system (Ubuntu 20, 64 Bit), it does not start. Using ldd I determined that the program has a load of dependencies to "/lib/i386-linux-gnu/*" and I assume these external dependecies are the reason why the program start fails.

It's not your fault nor FPC. Some newer versions of Ubuntu do not include libraries to run 32-bit binaries. If you want to write programs to used by others, you should compile and provide your program in 32-bit and 64-bit versions. Or at least you should inform users how to enable 32-bit support on 64-bit Ubuntu:

https://www.unixmen.com/enable-32-bit-support-64-bit-ubuntu-13-10-greater/
« Last Edit: October 11, 2020, 07:46:03 am by Handoko »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Embed libraries into executable
« Reply #2 on: October 11, 2020, 01:23:23 pm »
Question 1: Are there compiler settings to integrate all the libraries into the executable file like on Windows? I am aware of the fact that even the Windows executable has external dependencies but they are compatible for each Windows version since XP.

FPC binaries use libraries on Windows as well. Mainly Kernel32.dll, User32.dll and others. However on Windows these are always available. On a Linux however this might not be the case. E.g. if you have a GUI-less Linux system then there won't be any GUI related libraries like X11 or GTK, thus your program needs to be compiled without any GUI code to work there.

Question 2: The reason for the error message mentioned above might be, that on Linux 32 bit the library is located in ...
/lib/i386-linux-gnu/libgdk-x11-2.0.so.0
... whereas the library on Linux 64 bit is located in ...
/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0
But I have not hard coded the path to the library, so why isn't it found, although it's the same name and version?

The path is irrelavant. The executable itself only contains the filename (in this case libgdk-x11-2.0.so.0) and the path is then found by the runtime linker (just like it's done on Windows essentially).

What is important however is that you try to run a 32-bit application on a 64-bit only Linux system. Unlike Windows a Linux might not be set up to run 32-bit applications. As Handoko said you'd need to get your 64-bit Linux to install the necessary 32-bit libraries or instead you could compile your Linux application as 64-bit.

cgaertner

  • Newbie
  • Posts: 4
Re: Embed libraries into executable
« Reply #3 on: October 14, 2020, 07:41:59 pm »
What is important however is that you try to run a 32-bit application on a 64-bit only Linux system. Unlike Windows a Linux might not be set up to run 32-bit applications. As Handoko said you'd need to get your 64-bit Linux to install the necessary 32-bit libraries or instead you could compile your Linux application as 64-bit.

Thank you for pointing this out - I was not aware of the fact, that a 64 bit Linux is not able to run 32 bit applications by default!

Greetings,
Christian

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Embed libraries into executable
« Reply #4 on: October 17, 2020, 12:06:52 pm »
What is important however is that you try to run a 32-bit application on a 64-bit only Linux system. Unlike Windows a Linux might not be set up to run 32-bit applications. As Handoko said you'd need to get your 64-bit Linux to install the necessary 32-bit libraries or instead you could compile your Linux application as 64-bit.

Thank you for pointing this out - I was not aware of the fact, that a 64 bit Linux is not able to run 32 bit applications by default!

As long as the Linux kernel does not have support for 32-bit applications disabled running a statically linked executable (like the FPC compiler which does not depend on any libraries on Linux) would work. However most other libraries are not used in a static way by FPC (just as an example: the unit for SQLite dynamically imports the library to allow support for various versions).

 

TinyPortal © 2005-2018