Recent

Author Topic: How to make an executable shared library with lazarus on linux ?  (Read 4895 times)

njlgg

  • Newbie
  • Posts: 6
How to make an executable shared library with lazarus on linux ?
« on: December 19, 2017, 02:11:02 am »
      On linux,some special shared libraries can be dynamically loaded by other applications, and they can also be executed . There are some ways of creating such kind of "Executable Library" with C or C++.
      Now the question is:Is it possible and how to make an "Executable Library" with Lazarus on linux?

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: How to make an executable shared library with lazarus on linux ?
« Reply #1 on: December 19, 2017, 02:14:50 am »
      On linux,some special shared libraries can be dynamically loaded by other applications, and they can also be executed . There are some ways of creating such kind of "Executable Library" with C or C++.
      Now the question is:Is it possible and how to make an "Executable Library" with Lazarus on linux?

https://macpgmr.github.io/MacXPlatform/PascalDynLibs.html


njlgg

  • Newbie
  • Posts: 6
Re: How to make an executable shared library with lazarus on linux ?
« Reply #2 on: December 19, 2017, 03:02:03 am »
This article is mainly about compiling a shared library and how to inter-act with other languages.It does not get the key point of the question.
Let me introduce the key point  by some pieces of source code on windows.
*************project source begin**********
program libTest;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, main
  { you can add units after this };

{$R *.res}

exports
  sayHello;

begin
  RequireDerivedFormResource:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
*************project source end**********

*************unit source begin**********
....
function sayHello(msg:String):String;export;stdcall;
begin
   result:='this is from libTest';
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
type
  sayHello = function(msg:String): String;stdcall;
var
  MyLib: TLibHandle = dynlibs.NilHandle;
  FsayHello:sayHello;
begin
   //Please note here that we use Loadlibrary to load the program itself as a library
    MyLib := LoadLibrary(forms.Application.ExeName);
    FsayHello:=sayHello( GetProcedureAddress(MyLib,'sayHello') );
    ShowMessage( FsayHello('njlgg'));
end;
......
*************unit source end**********

NOTE the project type is "program",not "library",the program exports a function "sayHello",and we  use Loadlibrary to load the program itself as a library in the unit code.

On windows,it works as expected,but on linux,if we define the project type as "program",we get an executable file,we can't load an executable as library ,or on the other hand ,if we define the project type as "library",we get a shared library,it can inter-act with other languages correctly ,but we can't run the library seperately like an executable program.

So the key point is How to make an "Executable Library" on linux.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: How to make an executable shared library with lazarus on linux ?
« Reply #3 on: December 19, 2017, 04:05:30 am »
NOTE the project type is "program",not "library",the program exports a function "sayHello",and we  use Loadlibrary to load the program itself as a library in the unit code.

On windows,it works as expected,but on linux,if we define the project type as "program",we get an executable file,we can't load an executable as library ,or on the other hand ,if we define the project type as "library",we get a shared library,it can inter-act with other languages correctly ,but we can't run the library seperately like an executable program.

So the key point is How to make an "Executable Library" on linux.

That works fine here on both Windows and Linux (Ubuntu). On Mac I get a compile error, so it's not a universal thing:

/Users/phil/Tools/laztests/testexeclib/project1.lpr(15,1) Warning: (3186) Use of unsupported feature!
/Users/phil/Tools/laztests/testexeclib/project1.lpr(15,1) Fatal: (2003) Syntax error, "BEGIN" expected but "EXPORTS" found

Not sure why you would want a program executable that could also be loaded as a dynamic library. I would separate out the non-UI code and put it in a dynamic library and leave the UI code in the program.


njlgg

  • Newbie
  • Posts: 6
Re: How to make an executable shared library with lazarus on linux ?
« Reply #4 on: December 19, 2017, 05:58:44 am »

That works fine here on both Windows and Linux (Ubuntu). On Mac I get a compile error, so it's not a universal thing:


    MyLib := LoadLibrary(forms.Application.ExeName);
    FsayHello:=sayHello( GetProcedureAddress(MyLib,'sayHello') );
    ShowMessage( FsayHello('njlgg'));

    The above code does work fine on Linux(Ubuntu),but it's a special occasion.

    Mylib:=LoadLibrary(forms.Application.ExeName) will always get a value "0",that means the executable program not really been loaded as library .So if you try to load the executable program as library in another program,not within itself , error occurs while processing GetProcedureAddress(MyLib,'sayHello').
    if we try to load the executable program as library from java code like this:

     static {
         System.load("/home/njlgg/MyDevelop/SoLibraryTest/libTest");
    }
   
   We will get an error:cannot dynamically load executable. The problem is not solved yet.

   

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: How to make an executable shared library with lazarus on linux ?
« Reply #5 on: December 19, 2017, 09:17:14 am »
If you do not specify PIC there is no chance that is works on Linux. Library code *must* be relocatable.
Specialize a type, not a var.

njlgg

  • Newbie
  • Posts: 6
Re: How to make an executable shared library with lazarus on linux ?
« Reply #6 on: December 19, 2017, 10:07:30 am »
If you do not specify PIC there is no chance that is works on Linux. Library code *must* be relocatable.

I specify -fpic in Project options->compiler options->custom options,but it doesn't work.Besides, another opition -cd (create also dynamic library is displayed "not supported").Is that the reason a program can't be also compiled into a dynamic library?

Чебурашка

  • Hero Member
  • *****
  • Posts: 568
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: How to make an executable shared library with lazarus on linux ?
« Reply #7 on: August 24, 2022, 04:39:56 pm »
Hello,
for what I understand, the OP question has not been answered yet.

Is is possible with fpc to get a linux shared library that is also executable?

gcc allows this with the options "-fPIC" "-pie" according to this post
https://unix.stackexchange.com/questions/223385/why-and-how-are-some-shared-libraries-runnable-as-though-they-are-executables

Thanks
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Fred vS

  • Hero Member
  • *****
  • Posts: 3158
    • StrumPract is the musicians best friend
Re: How to make an executable shared library with lazarus on linux ?
« Reply #8 on: August 24, 2022, 05:01:34 pm »
Hello,
for what I understand, the OP question has not been answered yet.

Is is possible with fpc to get a linux shared library that is also executable?

gcc allows this with the options "-fPIC" "-pie" according to this post
https://unix.stackexchange.com/questions/223385/why-and-how-are-some-shared-libraries-runnable-as-though-they-are-executables

Thanks

Hello.

You may "hardening" your executable that will be transformed into a library runnable.
Just add those parameters for compilation:
Code: Pascal  [Select][+][-]
  1. -Cg -k-pie -znow
https://wiki.freepascal.org/hardening
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018