Итак, думаю, весьма очевидна главная проблема FreePascal: он не может поместить часть сгенерированного кода в динамическую библиотеку. Как следствие, он генерирует каждый файл огромного размера, помещая весь свой код в каждый файл. Свои плюсы в подходе "Всё своё ношу с собой", конечно же, есть, но если попробовать создать целую систему с десятком паскалевских файлов (о формах lazarus я вообще молчу), то мы получим огромный перерасход и дискового пространства, и, как следствие, места на сервере и расхода трафика у качающих. Короче, всё плохо.
Но ведь в linux же есть такой хороший механизм - gcc --shared, который может всё общее свести в одну библиотеку!
Как-то года 3-4 назад я этим уже баловался, но тогда не сильно преуспел, да и язык фактически был другим, сейчас решил повторить.
Итак, на чём я тестировал. Компилятор стандартный 3.0.0 (а для trunk и не стоит делать библиотек). Lazarus, забегая вперёд, взял 1.6RC1.
Система - ubuntu wily amd64. Проект для начала сделал простейший (tst.pas):
- Код: Выделить всё
program tst;
uses Classes,SysUtils,x;
begin
Writeln(Trim('Привет, мир!'));
end.
Модули Classes и SysUtils нужны чтобы было что загонять в библиотеку (затем же и функция Trim), а модуль x - чтобы FPC запустил динамическую компоновку (иначе будет создан скрипт для статической компоновки, и присоединить к файлу нему библиотеку окажется непросто).
Итак, fpc tst.pas - и передо мной файл tst. Я его переименовал в tst.nolib - размер 706 624 байт. Так себе, но для такой ерунды хотелось бы меньше. Сюда вложил сжатым в gz - .
Следующее действие - разбить на две части: библиотеку и сам файл. Ключ -Cn заставит FPC опустить стадию компоновки, получив link.res.
Итак, у нас появился link.res - внимательно смотрим. Ищем секции INPUT - их три.
Первая самая интересная - сначала там идут всякие служебные файлы prt, cpt. Их трогать не надо. Потом идут файлы проекта вперемешку с стандартными паскалевскими файлами. Вот последние и перемещаем в отдельный файл (секций не надо). В начало дописываем gcc -o <Название библиотеки> --shared
а все остальные строки заканчиваем обратным слешем. Туда же бросаем на всякий случай всё из второй секции INPUT.
Результат:
- Код: Выделить всё
gcc --shared -o libfpc-3.0.so
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/system.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/classes.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/sysutils.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/x11/x.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/objpas.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/types.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/typinfo.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/rtlconsts.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/linux.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/unix.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/errors.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/sysconst.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/unixtype.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/baseunix.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/unixutil.o
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/ctypes.o
-lX11
Этот файл можно запустить - и у нас в каталоге появилась библиотека. Ничего так весит, после strip 1,5 Мб (точнее 1 549 192 байта) - но она же может использоваться для нескольких проектов! Там у нас всё для паскаля.
Вот ссылка на библиотеку: http://daesher.narod.ru/nolib/libfpc-3.0.so
Теперь правим подрезанный link.res - во вторую секцию INPUT надо добавить -l<краткое название библиотеки>. Третью секцию трогать не надо. Привожу кусок link.res без начала и конца после третьей секции INPUT (он всё равно собирается!)
- Код: Выделить всё
INPUT(
/usr/lib/fpc/3.0.0/units/x86_64-linux/rtl/cprt0.o
/usr/lib/x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
tst.o
)
INPUT(
-lX11
-lfpc-3.0
)
GROUP(
-lc
)
INPUT(
/usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
/usr/lib/x86_64-linux-gnu/crtn.o
)
Запускаем ppas.sh - и - о чудо - у нас файл в 8 Кб.
http://daesher.narod.ru/nolib/tst.noext
Запускать так
LD_LIBRARY_PATH=. ./tst
Или скопировать библиотеку куда-нибудь в стандартное место.
Под Windows не проверял.
Добавлено спустя 14 минут 17 секунд:
Часть вторая - графическое приложение Lazarus.
Взял за основу мой кластерный анализ - возможно, сделан коряво, где-то когда-то публиковал, но не помню. По GPL выкладываю исходники .
Теперь запускаем Lazarus и правим параметры проекта: вырубаем отладку вообще (иначе будут проблемы), ставим в дополнительные параметры -Cn и "собираем".
Получаем нужный нам link.res, делим его на части.
Честно скажу: проверил я на другом проекте, вырезав всё паскалевское и лазарусное в liblcl.so "весом" в 13 мегабайт:
http://daesher.narod.ru/nolib/liblcl.so.xz (я её, конечно, сжал xz).
Скрипт к ней вот: http://daesher.narod.ru/nolib/laz.sh (толку от него уже мало - пути относительно моего компьютера).
После этого подрезал link.res (он есть в исходном архиве). В итоге сам файл с интерфейсом вполне скромный, на "дельфевском" уровне:
http://daesher.narod.ru/nolib/ClAnalysis.noext
Чуть больше 250 Кб (по сравнению с исходным, без библиотеки - 5,5 Мб) . И ведь работает!!!
Выигрыш, таким образом, начинается только с 3-4 файлов с GUI.
Вывод: над этим надо работать. Думаю, есть смысл автоматизировать процесс если не создания библиотек, то хотя бы их подключения - создать надстройку над FPC.