Как создать статическую библиотеку?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Как создать статическую библиотеку?

Сообщение Maxizar » 14.04.2012 15:08:14

Собственно сабж, как в FP создать статическую библиотеку.
В Линухе и на Си, собираем обьектные файлы и отдаем архиватору:
Код: Выделить всё
$ ar r libfoo.a fool.о foo2.o


А в FP как?

Есть проект ДЛЛ, она собирается и прекрасно работает, хочу сделать статику, и через
Код: Выделить всё
{$LINKLIB mylib}

Собрать приложение и тем самым избавить пользователя от "лишней" DLL.
При этом нужно это дело под WindowsLinux, тобишь получить .lib и .a

Добавлено спустя 6 часов 17 минут 12 секунд:
Нашел вот это:7.2.3 Compiling libraries
Написано:
You can do this as follows, for a dynamic library:
ppc386 -CD myunit

If you want a static library, you can do
ppc386 -CS myunit


динамическую библиотеку он создал, а статическую нет, говорит нет такого параметра как -CS....
-h вообще говорит, что ключ -CD не поддерживается, а -CS просто нету, есть -Cs но это установка стека...
Lazarus 0.9.30.4
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Как создать статическую библиотеку?

Сообщение Sergei I. Gorelkin » 15.04.2012 01:30:13

Точно так же можно собрать с помощью ar. Объектные файлы FPC ничем не отличаются от объектных файлов C.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Как создать статическую библиотеку?

Сообщение Maxizar » 15.04.2012 11:56:54

Я что-то делаю не так...
1. Код библиотеки:
Код: Выделить всё
library project1;

{$mode objfpc}{$H+}

uses
  Classes
  { you can add units after this };


{$R simple.res}
{$R *.res}


function Add(a:Integer):Integer;cdecl;
begin

  Result:=1+a;
end;


Exports

Add    index 1 name 'Add';


begin
end.


Как создовали ресурс:
Код: Выделить всё
C:\lazarus\fpc\2.6.0\bin\i386-win32>windres.exe -i C:\s.rc -o C:\simple.res

Где C:\s.rc:
Код: Выделить всё
B  BITMAP   "C:/1.bmp"


2. Динамическая загрузка:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface


uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls,windows;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;


implementation


  function Add (a : Integer) : Integer; cdecl;  External 'project1.dll';

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:=IntToStr(Add(1));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  h : THandle;

begin
  h := LoadLibrary('project1.DLL');
  try
    if h <> 0 then
    begin
      Image1.Picture.Bitmap.LoadFromResourceName(h, 'B');
    end
    else
    begin
      ShowMessage('Load Resource DLL FAILED!');
    end;
  finally
    FreeLibrary(h);
  end;

end;

end.


Все работает.

Статическая загрузка:
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface
  {$LINKLIB my}

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

  function Add (a : Integer) : Integer; cdecl;

implementation


  function Add (a : Integer) : Integer; cdecl;  External;

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:=IntToStr(Add(1));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin

  Image1.Picture.Bitmap.LoadFromResourceName(HInstance, 'B');

end;

end.


Как делал статическую библиотеку:
1. Компилим при помощи Lazarus-a длл, он создает объектные файлы в папке C:\LoadLib\Lib\lib\i386-win32\.
2. Собираем при помощи ar:
Код: Выделить всё
c:\lazarus\fpc\2.6.0\bin\i386-win32>ar.exe -r  C:\LoadLib\Lib\libmy.a C:\LoadLib\Lib\lib\i386-win32\project1.o C:\LoadLib\Lib\lib\i386-win32\project1.or C:\LoadLib\Lib\link.res

При компиляции программы, вываливается мол не определен _Add, задал в лоб:
Код: Выделить всё
function Add (a : Integer) : Integer; cdecl;  External name 'Add';

не помогло.

Исходники
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Как создать статическую библиотеку?

Сообщение Sergei I. Gorelkin » 15.04.2012 12:57:36

У dll и статических библиотек совершенно разные процедуры инициализации, поэтому просто так взять и прилинковать к exe объектный файл от dll (project1.o) не получится. "Экспортируемые" функции нужно определять в модулях как-то так: procedure foo; [public,alias: 'FOO'];

Учитывая, что конечный результат будет (должен быть) точно таким же, как и при обычном добавлении модулей из состава dll в секцию uses, непонятно зачем вообще нужен этот геморрой.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Как создать статическую библиотеку?

Сообщение Maxizar » 15.04.2012 14:05:02

Да вы правы, гемор еще тот, просто хотелось разобраться в этом вопросе.. Зачем? да просто для себя... но вышла полная фигня :(...

PS. у меня такое бывает, зацикливание... Иногда я побеждаю (решив вопрос, и узнав что-то новое), сегодня я сдулся.
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru