Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态链接-使用GTKmm应用程序?-修订过的_C++_Linux_Gtk_Static Linking_Gtkmm - Fatal编程技术网

C++ 静态链接-使用GTKmm应用程序?-修订过的

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

是否可以在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

我宁愿避免这样做,因为GTK依赖于复杂的低级库,这些库实际上非常特定于系统(可能是
libfontconfig.so
等),并且包含特定于系统的信息(例如字体的内置路径…)

我还认为GTK需要动态共享库来实现主题化或样式化(因此GTK本身正在调用
dlopen
,而使用静态链接的
libdl
是不合理的)

我建议至少动态链接gtk及其所有依赖项。

(你的问题问了两次,我很生气,所以这里有一个更详细的答案,我可能会进一步编辑和完成)


为什么动态链接的共享库很有用?

首先,在今天的Linux系统上,几乎每个二进制文件都是动态链接的。在我的Debian/Sid系统上,我只有
/sbin/ldconfig
/bin/sash
/usr/bin/rar
静态链接的可执行文件,但还有大约七千个其他动态链接的可执行文件(在
/bin
/usr/bin
下)。即使是像
/sbin/init
这样的基本程序,现在也可以动态链接

使用动态链接的ELF可执行文件有几个好处

  • 避免浪费磁盘空间。当动态链接的可执行文件不存在时(1986年,SunOS3.5,因为内核无法文件段),人们花了很多时间在一个二进制文件中混合几个二进制文件(我记得
    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的改进中获益。因此

  • 整体RAM使用效率更高。像
    libc.so
    这样的文件几乎被每个进程使用,甚至
    libgtk-3.so
    被几十个进程使用。大部分是
    mmap
    -ed只读“text”段(特别是包含可执行的二进制机器码和字符串等只读常量);此映射对使用它的每个进程使用相同的RAM单元。所以内存是共享的

  • LGPL许可证的法律合规性 GTK库的许可证是合法允许您使用GTK的唯一原因(即运行GTK程序,并将您自己的程序与GTK链接)。本许可证授予您权利,特别是改进GTK或利用GTK改进的权利,但您不应禁止您(例如专有)程序的用户链接
    /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)

  • 动态链接在启动时稍微慢一点,因为程序必须在启动时启动并动态加载它所需的所有动态库(这是ld-linux-x86-64.so.2的角色)。动态库中的代码需要重新加载,否则动态加载库的重新定位部分会太大(并且启动时的重新定位工作太长),这可能需要额外的寄存器(这在32位x86处理器上最为常见,在x86-64或AMD64 64位处理器上更为少见),因此会造成稍大的机器代码(在32位x86机器上,我们说的是