Статическое связывание - работа с приложением GTKmm? - пересмотрено - PullRequest
0 голосов
/ 22 ноября 2011

Можно ли сделать статическую компоновку (компиляцию) в программе Gtk (mm)?Мне нужно, чтобы программа меньше передавала зависимости в пользовательской системе.

Я пытаюсь:

g++ -static data/Area.h data/Picture.cpp data/GLScene.cpp data/KBDialog.cpp data/Dialogs.h data/FilePreview.cpp data/MainWindow.cpp prog.cpp -o prog `pkg-config --cflags --libs  gtkmm-2.4 gtkglextmm-1.2 exiv2`

, но не получается:

/usr/bin/ld: cannot find -lgtkmm-2.4
/usr/bin/ld: cannot find -lGL
/usr/bin/ld: cannot find -latkmm-1.6
/usr/bin/ld: cannot find -lgdkmm-2.4
/usr/bin/ld: cannot find -lpangomm-1.4
/usr/bin/ld: cannot find -lgdk_pixbuf-2.0
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libgio-2.0.a(glocalfileinfo.o): In function `lookup_gid_name':
(.text+0x207a): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libgio-2.0.a(glocalvfs.o): In function `g_local_vfs_parse_name':
(.text+0x26c): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libglib-2.0.a(gutils.o): In function `g_get_any_init_do':
(.text+0x1244): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libglib-2.0.a(gutils.o): In function `g_get_any_init_do':
(.text+0x1237): warning: Using 'setpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libglib-2.0.a(gutils.o): In function `g_get_any_init_do':
(.text+0x124f): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libglib-2.0.a(gutils.o): In function `g_get_any_init_do':
(.text+0xf6e): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libgio-2.0.a(glocalfileinfo.o): In function `lookup_uid_data':
(.text+0x1eea): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libX11.a(xim_trans.o): In function `_XimXTransSocketUNIXConnect':
(.text+0xe23): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libgio-2.0.a(gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xe3c): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/libgio-2.0.a(gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xe4c): warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
collect2: ld returned 1 exit status

Ответы [ 2 ]

10 голосов
/ 24 ноября 2011

(Ваш вопрос, заданный дважды, меня бесит, поэтому вот более подробный ответ, который я мог бы отредактировать и дополнить в дальнейшем)


Почему полезны динамически связанные общие библиотеки?

Во-первых, почти каждый двоичный файл динамически связан в современных системах Linux.В моей системе Debian / Sid у меня есть только статически связанные исполняемые файлы /sbin/ldconfig /bin/sash и /usr/bin/rar, но около семи тысяч других динамически связанных исполняемых файлов (под /bin & /usr/bin).Даже такие важные программы, как /sbin/init, на сегодняшний день динамически связаны.

Существует несколько преимуществ использования динамически связанных исполняемых файлов ELF с использованием общих библиотек

  1. Избегайте траты дискового пространства .Когда динамически связанные исполняемые файлы не существовали (эра 1986 года, SunOS3.5, поскольку ядро ​​не было в состоянии mmap файловых сегментов), люди занимали много времени, смешивая несколько двоичных файлов в одном (я помню *)1028 * и cmdtool - это один и тот же двоичный файл, представляющий собой смесь нескольких программ на SunOS3.5) для освобождения дискового пространства.Хорошо, сегодня дисковое пространство дешевле, но если бы каждая из моих семи тысяч программ имела статическую ссылку libc, это заняло бы несколько гигабайт дискового пространства (а это означало бы дополнительный DVD или несколько часов сетевой загрузки при установке дистрибутива Linux).

  2. Включение более простого обновления .Когда система упаковки (apt-get, dpkg и друзья в Debian) обновляет общую разделяемую библиотеку (например, GLibC или Gtk), она заменяет динамически связанные разделяемые библиотеки (*.so файлы, называемые ELF * 1041).* разделяемые объекты) и все последующие исполнения двоичного кода с их использованием получают прибыль.Поэтому, если /usr/lib/libgtk-3.so обновляется, нет необходимости обновлять /usr/bin/gedit, чтобы воспользоваться исправлениями ошибок внутри libgtk-3.so;просто перезапуск gedit принесет прибыль от улучшений в libgtk-3.so

  3. Более эффективное общее использование оперативной памяти .Файл типа libc.so используется почти каждым процессом, и даже libgtk-3.so используется десятками процессов.В основном это mmap -сегментированный только для чтения «текстовый» сегмент (в частности, содержащий исполняемый двоичный машинный код и постоянные только для чтения, такие как строка);это отображение использует одни и те же ячейки ОЗУ для каждого процесса, использующего его.Таким образом, память используется совместно

  4. Юридическое соответствие лицензии LGPL Лицензия LGPL-2.1 библиотек GTK - единственная причина, по которой вы на законных основанияхразрешено использовать GTK (т.е. запускать программы GTK и связывать собственную программу с GTK).Эта лицензия дает вам, в частности, права на улучшение GTK или использование улучшений GTK, но вы не должны запрещать пользователям вашей (например, проприетарной) программы, связывающей /usr/lib/gtk-3.so, использовать преимущества улучшений внутри самого GTK.В разделе 6 LGPL2.1 упоминается явно динамическое связывание. Вы не можете распространять статически связанные двоичные файлы GTK без предоставления пользователю возможности обновить свою библиотеку GTK.Наиболее удобный способ - динамически связать вашу программу GTK с libgtk-3.so.Менее простой альтернативой будет распространение статически связанного исполняемого файла с его объектными *.o файлами и инструкциями о том, как статически связать его с гипотетически улучшенным libgtk.a (которого не существует).

  5. Возможность плагина для динамической загрузки других библиотечных модулей Программа может загрузить некоторый общий объект во время выполнения, используя функцию dlopen (на основе системного вызова mmap через библиотеку -ldl).Вот как плагины возможны в Linux.GTK очень активно использует эту способность: темы, стили и, возможно, шрифты используют dlopen и реализованы с помощью dlopen -подобных вещей.Поскольку dlopen является открытым интерфейсом для динамического загрузчика /lib64/ld-linux-x86-64.so.2, библиотека -ldl представляет собой динамически совместно используемый объект libdl.so.2, делящийся функциональностью и кодом с динамическим загрузчиком (на который в каждом динамически связанном исполняемом файле ссылается как "ELF-интерпретатор"«).Редко и неразумно связывать -ldl статически.Даже библиотека libc.so может загружать другие модули (возможно, для поддержки DNS и т. Д.);некоторые функции ограничены в статически связанных исполняемых файлах (см. файл /etc/nsswitch.conf и т. д.).

  6. динамическое связывание немного медленнее во время запуска, поскольку программа должна запускаться и динамически загружаться (этоэто роль ld-linux-x86-64.so.2) при запуске всех динамических библиотек, в которых она нуждается.Код внутри динамической библиотеки должен быть позиционно-независимым кодом , в противном случае часть перемещения динамически загружаемых библиотек будет слишком большой (и усилия по перемещению при запуске слишком длинные), что может стоить дополнительного регистра (иэто в основном верно для 32-битных процессоров x86, а в 64-битных x64- или AMD64-битных процессорах - намного меньше, поэтому составляет чуть больший машинный код (на 32-битных x86-машинах мы говорим об увеличении размера на несколько процентов и замедлении времени выполнения;на 64-битных машинах это ничтожно мало).Конечно, перемещение сотен тысяч внешних вызовов может занять некоторое время (и происходит больше с кодом C ++, чем с кодом C, возможно, из-за проблем с отображением имен).


Почему вы (Марко) не должны статически связывать свой двоичный файл GTK ?

Пять первых пунктов выше должны убедить вас в том, что статическое связывание GTK является злым делом.В частности, обратите внимание на юридические аспекты (LGPL): совершать заведомо нарушение LGPL - это огромная профессиональная ошибка, не делайте этого.

Если вы действительно этого хотите, потратив несколько недель, вы, вероятно, сможететехнически способен (путем перекомпиляции и взлома исходного кода GTK) статически связать ваш двоичный файл с GTK (с некоторыми сокращенными функциональными возможностями, например, без темы), но это, вероятно, неэтично и бесполезно.Если ваш босс достаточно глуп, чтобы потребовать от вас этого, попытайтесь убедить его (или найдите другую работу).И тот факт, что вы спросили на открытом форуме, как статически связать GTK (что я понимаю как « как нарушить лицензию LGPL »), подвергает вас риску.Есть организации, подобные gpl-нарушения , которые обращают на это внимание.

Я не вижу никакой полезной причины для статической привязки программы GTK.Даже проприетарные программы, использующие библиотеку GUI, динамически связаны (хорошим примером является драйвер AMD FGLRX и его сопутствующие программы, такие как amdccle, обеспечивающие графический интерфейс на основе Qt для установки).

Конечно, вы можете иметь дело сс зависимостями.Оставьте это менеджеру пакетов вашего дистрибутива Linux.

Если вам нужна дополнительная помощь, пожалуйста, объясните гораздо больше, что вы действительно хотите сделать, и убедите нас, что вы не просите помощи в нарушении лицензии.А еще лучше попробуйте распространять свое программное обеспечение с бесплатной лицензией, например, GPLv3

6 голосов
/ 22 ноября 2011

Я бы предпочел не делать этого, потому что GTK зависит от хитрых низкоуровневых библиотек, которые действительно очень специфичны для системы (возможно, libfontconfig.so и т. Д.) И содержат специфическую для системы информацию (например, встроенные пути для шрифтов ...).

Я также думаю, что GTK нужны динамические разделяемые библиотеки для реализации их оформления или стилизации (поэтому сам GTK вызывает dlopen, а наличие статически связанной libdl нецелесообразно).

Я предлагаю хотя бы динамически связать gtk и все его зависимости.

...