C++ -静态libstdc++;在g+上工作+;但不是在纯gcc上?
作为参考,我使用MinGW(GCC 5.3)。在使用编译文件时C++ -静态libstdc++;在g+上工作+;但不是在纯gcc上?,c++,gcc,mingw,mingw32,C++,Gcc,Mingw,Mingw32,作为参考,我使用MinGW(GCC 5.3)。在使用编译文件时 g++file.cc-静态libstdc++ 静态链接C++标准LIB( LBSTDC++< /COD>),并生成1.9MB可执行文件。p> 然而运行 gcc-lstdc++-static libstdc++file.cc 它仍然动态链接到libstdc++-6.dll,并生成一个34KB的可执行文件 为什么-static libstdc++只适用于g++,而不适用于纯gcc -静态libstdc++ 当C++程序用于链接C++程序
g++file.cc-静态libstdc++
静态链接C++标准LIB(<代码> LBSTDC++< /COD>),并生成1.9MB可执行文件。p> 然而运行
gcc-lstdc++-static libstdc++file.cc
它仍然动态链接到libstdc++-6.dll
,并生成一个34KB的可执行文件
为什么
-static libstdc++
只适用于g++
,而不适用于纯gcc
-静态libstdc++
当C++程序用于链接C++程序时,它通常自动链接 针对libstdc++。如果libstdc++作为共享库提供,则-static 如果未使用选项,则此选项将链接到libstdc++的共享版本。 那通常很好。但是,冻结的版本有时很有用 libstdc++由程序使用,无需一直到完全静态链接。 -static libstdc++选项指示g++驱动程序静态链接libstdc++, 无需静态链接其他库
这表明选项
-static libstdc++
仅对
g++
编译器驱动程序,而不是gcc
或任何其他驱动程序
另一方面,选项-l
是有意义的,意思相同
所有GCC编译器驱动程序。在此基础上,毫不奇怪:
gcc file.cc -lstdc++ -static-libstdc++
含义与:
gcc file.cc -lstdc++
然而,这一观察并不能真正说明为什么第一个
命令行动态链接libstdc++
:-
-静态libstdc++
仅对g++
有意义,因为只有g++
链接
libstdc++
自动执行。因此,只有g++
才会出现问题
自动链接的libstdc++
是否为动态版本
或者静态版本。动态版本是默认版本:
-static libstdc++
坚持静态版本
通过g++
自动链接libstdc++
意味着:g++
无提示
将-lstdc++
附加到您指定的任何链接选项(以及
相当多的其他锅炉板的C++链接。你可以揭露一切
通过请求详细链接(g++…-Wl,-v…
)创建样板文件
附加的-lstdc++
本身将导致链接器链接动态版本
根据其默认行为,使用libstdc++。唯一不同的是
-static libstdc++
是在-lstdc++
不使用的地方
要以静默方式传递给链接器,选项:
-Bstatic -lstdc++ -Bdynamic
而是默默地传递给它。这些信息告诉链接器:
:在另行通知之前,请勿链接动态库-Bstatic
:Link-lstdc++
libstdc++
:链接动态库,直至另行通知-b动态
libstdc++
的静态链接的
排除对任何其他库的链接的副作用
但是您也可以看到,libstdc++
的自动链接
动态或静态,对链接没有追溯作用
您自己指定的任何库的
因此,如果您的链接在任何锅炉板之前已经包含-lstdc++
编译器驱动程序以静默方式附加选项,然后将链接libstdc++
与悬挂机构中该位置的任何-l
相同
序列如果无提示地添加锅炉板选项,则会导致-lstdc++
随后在链接序列中重新出现,无论是通过自身还是通过
周围环境:
-Bstatic -lstdc++ -Bdynamic
然后,后面的外观将只是多余的,因为库
已被链接
因此,gcc
没有什么特别的地方会导致:
gcc file.cc -lstdc++ -static-libstdc++
生成一个动态链接libstdc++
的程序。我也是
g++ file.cc -lstdc++ -static-libstdc++
或者实际上:
g++ file.cc -static-libstdc++ -lstdc++
因为生成的链接器命令行的格式为:
... file.o -lstdc++ ... -Bstatic -lstdc++ -Bdynamic ...
其中-Bstatic-lstdc++-Bdynamic
为时已晚,无法发挥任何作用
请查看:
file.cc
#include <iostream>
int main()
{
std::cout << "Hello World" << std::endl;
return 0;
}
libstdc++。因此
存在
现在只需使用
-静态libstdc++
:
$ g++ -o prog file.cc -static-libstdc++
$ ldd prog
linux-vdso.so.1 => (0x00007fff448d7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe5f7c71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5f78aa000)
/lib64/ld-linux-x86-64.so.2 (0x0000556ebf272000)
$ g++ -o prog file.cc -static-libstdc++ -lstdc++
$ ldd prog
linux-vdso.so.1 => (0x00007ffd12de9000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd5a1823000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd5a145c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd5a1153000)
/lib64/ld-linux-x86-64.so.2 (0x000055bbe31c3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd5a0f3c000)
libstdc++。因此
不存在
最后使用-static libstdc++-lstdc++
:
$ g++ -o prog file.cc -static-libstdc++
$ ldd prog
linux-vdso.so.1 => (0x00007fff448d7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe5f7c71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5f78aa000)
/lib64/ld-linux-x86-64.so.2 (0x0000556ebf272000)
$ g++ -o prog file.cc -static-libstdc++ -lstdc++
$ ldd prog
linux-vdso.so.1 => (0x00007ffd12de9000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd5a1823000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd5a145c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd5a1153000)
/lib64/ld-linux-x86-64.so.2 (0x000055bbe31c3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd5a0f3c000)
libstdc++。所以
回来了
(当然,这是Linux,但在Windows上也可以找到同样的东西)
因此,无论您是使用g++
还是gcc
驱动您的链接
{gcc|g++} file.cc -lstdc++ ...
将导致动态链接libstdc++
,这很简单
{gcc|g++} file.cc -lfoo ...
将导致动态链接libfoo
,如果可以,不管
什么是
..
,前提是..
不包含选项-static
从技术上讲,这不是一个答案,而是一个解决坏的构建系统的方法
我正在使用一个构建系统,它有一些非常奇怪的原因,即使是C++对象,也使用GCC代替G++来驱动构建过程。我需要一个二进制文件,它不依赖于glibc库以外的任何东西。因此,我最终做了以下工作:
$ cat <<EOF > gcc
#!/bin/bash
if [[ \$@ == *"-lstdc++"* ]]; then
/full/path/to/g++ -static-libgcc -static-libstdc++ \$(echo \$@ | sed 's,-lstdc++,,g')
else
/full/path/to/gcc -static-libgcc \$@
fi
EOF
$ chmod +x gcc
$ export PATH=$PWD:$PATH
<代码> $CAT<代码>静态LBSTDC++<代码>是C++标志…通过编写
gcc
您指定了链接一个C程序,但是gcc
和g++
不是一回事吗?唯一的主要区别是g++
自动链接标准库,不像gcc
那样我必须通过-lstdc++
。我可以用C++代码编写代码> GCC < /COD>。我想这个问题说明它们不是…(说到链接)我不明白为什么这是个问题。只需使用g++