C++ -静态libstdc++;在g+上工作+;但不是在纯gcc上?

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++程序

作为参考,我使用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++程序时,它通常自动链接 针对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
    :在另行通知之前,请勿链接动态库
  • -lstdc++
    :Link
    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++