GCC/G++选项 -Wl,--as-needed

    GCC/G++提供了 -Wl,--as-needed 和 -Wl,--no-as-needed 两个选项,这两个选项一个是开启特性,一个是取消该特性。

    在生成可执行文件的时候,通过 -lxxx 选项指定需要链接的库文件。以动态库为例,如果我们指定了一个需要链接的库,则连接器会在可执行文件的文件头中会记录下该库的信息。而后,在可执行文件运行的时候,动态加载器会读取文件头信息,并加载所有的链接库。在这个过程中,如果用户指定链接了一个毫不相关的库,则这个库在最终的可执行程序运行时也会被加载,如果类似这样的不相关库很多,会明显拖慢程序启动过程。

    这时,通过指定 -Wl,--as-needed 选项,链接过程中,链接器会检查所有的依赖库,没有实际被引用的库,不再写入可执行文件头。最终生成的可执行文件头中包含的都是必要的链接库信息。-Wl,--no-as-needed 选项不会做这样的检查,会把用户指定的链接库完全写入可执行文件中。

    举例如下:

    main.cc

#include <iostream>

int main() {
    std::cout << "Hello, World" << std::endl;
}

    1,使用 -Wl,--no-as-needed 选项,且编译时指定加载不相关的 pthread库。

            g++ -Wl,--no-as-needed -o main main.cc -lpthread

        (1)查看可执行文件main的文件头中是否包含pthread库:               

                    $ ldd main
                        linux-vdso.so.1 =>  (0x00007fff0fbb0000)
                        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe9452d4000)
                        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe944f52000)
                        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe944c49000)
                        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe944a33000)
                        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe944669000)
                        /lib64/ld-linux-x86-64.so.2 (0x00007fe9454f1000)

                可见可执行文件main中包含了不相关的pthread库。

       (2)查看运行时是否加载pthread库。

                $ strace ./main

                    ...

                    open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3                    

                    ...

                可见,在程序运行时也加载了pthread库。

    2,使用 -Wl,--as-needed 选项,且编译时指定加载不相关的 pthread库。

            g++ -Wl,--as-needed -o main main.cc -lpthread

        (1)查看可执行文件main的文件头中是否包含pthread库:               

                    $ ldd main
                        linux-vdso.so.1 =>  (0x00007ffecb5b6000)
                        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff99f7ca000)
                        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff99f400000)
                        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff99f0f7000)
                        /lib64/ld-linux-x86-64.so.2 (0x00007ff99fb4c000)
                        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff99eee1000)

                可见即使在命令行中指定了 -lpthread,一旦指定了 -Wl,--as-needed 选项,由于pthread库不是必须的,所以不会在可执行文件中记录 pthread 库。

       (2)通过执行 strace ./main 命令,运行结果显示也不会去加载pthread库。

    总结:-Wl,--as-needed 选项指示最终的可执行文件中只包含必要的链接库信息,-Wl,--no-as-needed 选项指示在命令行中指定加载的所有库都记录到可执行文件头中,并最终由动态加载器去加载。

                

   

转载于:https://my.oschina.net/yepanl/blog/2222870

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/usr/bin/g++编译选项中的大多数选项都是链接器选项,用于指定链接器的行为和规则。这些选项一般会影响可执行文件的生成、模块的链接以及共享库的链接等。 根据你提供的编译选项,可以看出你是在使用g++编译器来编译一个名为analogclock的可执行文件,使用了以下链接器选项: - -Wl,--enable-new-dtags:启用新的DTags,用于指定可执行文件依赖的共享库。 - -Wl,-z,origin:指定可执行文件的运行路径为可执行文件所在的目录。 - -Wl,-rpath,$ORIGIN/../../../../../5.14.1/gcc_64/lib:指定运行时动态链接器查找共享库的路径。 - -s:生成一个无符号的可执行文件。 - -L/home/qt/openssl-1.1.1d/lib:指定共享库搜索路径。 - /home/farsight/farsight/feng/buildroot-2021.02.1/output/build/qt5base-5.15.2/lib/libQt5Widgets.so:指定需要链接的共享库,这里是Qt5Widgets库。 - /home/farsight/farsight/feng/buildroot-2021.02.1/output/build/qt5base-5.15.2/lib/libQt5Gui.so:指定需要链接的共享库,这里是Qt5Gui库。 - /home/farsight/farsight/feng/buildroot-2021.02.1/output/build/qt5base-5.15.2/lib/libQt5Core.so:指定需要链接的共享库,这里是Qt5Core库。 - -lGL:指定需要链接的静态库,这里是OpenGL库。 - -lpthread:指定需要链接的静态库,这里是pthread库。 根据这些编译选项,可以初步判断编译选项是否正确。但具体是否正确还需要根据实际情况来判断,比如是否需要链接其他库等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值