C++ 静态链接-使用GTKmm应用程序?-修订过的
是否可以在Gtk(mm)程序上进行静态链接(编译)?我需要的程序是较少的中继依赖于用户的系统 我尝试:C++ 静态链接-使用GTKmm应用程序?-修订过的,c++,linux,gtk,static-linking,gtkmm,C++,Linux,Gtk,Static Linking,Gtkmm,是否可以在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
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
我宁愿避免这样做,因为GTK依赖于复杂的低级库,这些库实际上非常特定于系统(可能是
libfontconfig.so
等),并且包含特定于系统的信息(例如字体的内置路径…)
我还认为GTK需要动态共享库来实现主题化或样式化(因此GTK本身正在调用dlopen
,而使用静态链接的libdl
是不合理的)
我建议至少动态链接gtk及其所有依赖项。(你的问题问了两次,我很生气,所以这里有一个更详细的答案,我可能会进一步编辑和完成)
为什么动态链接的共享库很有用? 首先,在今天的Linux系统上,几乎每个二进制文件都是动态链接的。在我的Debian/Sid系统上,我只有
/sbin/ldconfig
/bin/sash
和/usr/bin/rar
静态链接的可执行文件,但还有大约七千个其他动态链接的可执行文件(在/bin
和/usr/bin
下)。即使是像/sbin/init
这样的基本程序,现在也可以动态链接
使用动态链接的ELF可执行文件有几个好处
textedit
和cmdtool
是同一个二进制文件,是SunOS3.5上几个程序的混合)来赢得磁盘空间。好吧,现在的磁盘空间比较便宜,但是如果我的7000个程序都必须静态链接到libc,那将消耗数GB的磁盘空间(这意味着安装Linux发行版时需要额外的DVD或数小时的网络上传)apt get
、dpkg
和Debian上的friends)升级一个公共共享库(如GLibC或Gtk)时,它将替换动态链接的共享库(*.so
文件,称为共享对象),所有使用它们的二进制文件的未来执行都将获利。因此,如果更新了/usr/lib/libgtk-3.So
,则无需更新/usr/bin/gedit
来利用libgtk-3.So中的错误修复;只要重新启动gedit
就可以从libgtk-3的改进中获益。因此
libc.so
这样的文件几乎被每个进程使用,甚至libgtk-3.so
被几十个进程使用。大部分是mmap
-ed只读“text”段(特别是包含可执行的二进制机器码和字符串等只读常量);此映射对使用它的每个进程使用相同的RAM单元。所以内存是共享的/usr/lib/GTK-3。因此
利用GTK本身的改进。LGPL2.1的第6节明确提到了动态链接如果不允许用户升级其GTK库,则不允许分发静态链接的GTK二进制文件。最方便的方法是将GTK程序动态链接到libgtk-3.so
。一个不太容易的替代方法是分发静态链接的可执行文件及其对象*.o
文件,以及关于如何根据假设的改进libgtk.A
(不存在)对其进行静态链接的说明mmap
系统调用,通过-ldl
库)。这就是插件在Linux上的实现方式。GTK非常积极地利用了这一能力:主题、样式和字体都使用dlopen
,并通过dlopen
-ing适当的东西来实现。由于dlopen
是动态加载程序/lib64/ld-linux-x86-64.so.2
的公共接口,-ldl
库是一个动态共享对象libdl.so.2
与动态加载程序共享功能和代码(在每个动态链接的可执行文件中,它本身被称为“ELF解释器”)。静态链接-ldl
是不常见和不明智的。甚至libc.so
库也可能加载其他模块(可能是为了DNS支持等);某些功能在静态链接的可执行文件中受到限制(请参阅文件/etc/nsswitch.conf
etc)