C++ 如何避免系统标准C/C++;linux上的库?

C++ 如何避免系统标准C/C++;linux上的库?,c++,c,linux,gcc,C++,C,Linux,Gcc,我安装了一个新版本的GCC,这对我的linux系统来说是一种污染。我计划以更好的方式处理多个版本的GCC。我计划在/opt/tools目录下安装所有不同的版本。然后我的项目makefile明确指定要使用的版本。它包括所有二进制可执行文件,如g++、gcc等,以及头文件、库 这种方法的好处是显而易见的。该构建更具可复制性。它不假定版本,而是选择非常具体的版本。不同编译器版本之间的切换都发生在makefile内部 为了实现这一点,我使用“-nosdinc”,并将所有include路径显式地放入编译命

我安装了一个新版本的
GCC
,这对我的linux系统来说是一种污染。我计划以更好的方式处理多个版本的
GCC
。我计划在/opt/tools目录下安装所有不同的版本。然后我的项目makefile明确指定要使用的版本。它包括所有二进制可执行文件,如g++、gcc等,以及头文件、库

这种方法的好处是显而易见的。该构建更具可复制性。它不假定版本,而是选择非常具体的版本。不同编译器版本之间的切换都发生在makefile内部

为了实现这一点,我使用“-nosdinc”,并将所有include路径显式地放入编译命令行中。我的代码包括
limits.h
,它会导致奇怪的构建错误

limits.h
是安装在我的debian中的libc6 dev的一部分。但它不在gcc的include目录中。一些在线材料说标准
C
lib是操作系统的一部分。我的问题是,构建独立于系统头文件和库的代码是否可行?我怀疑gcc中可能缺少其他标题。起初,我认为gcc是随一切而来的。不是这样吗


换句话说,系统库和头是否取决于debian发行版附带的特定GCC版本?我有点不舒服,系统头和lib来自gcc4.7,而我使用的是gcc5.3。

GCC不提供任何C头文件。GNUC库(简称GNUC库)是一个单独的项目。有一个libc不可知的工具链是没有意义的,因为GCC需要一个C库,而且它与GCC编译器的版本无关。不,您不需要VM或“从头开始的Linux”,这是不合适的,因为它告诉您从源代码编译整个工具链。将不同版本的GCC安装到它们自己的前缀(目标文件夹)中非常简单。它甚至允许您在可执行文件的名称中添加前缀,以简化操作

我郑重地建议你深入研究。它是由一个实际的GCC维护人员编写的,它直接指向了重点。不要让事情变得更难

要编译GCC,请执行以下操作:

tar xzf gcc-VERSION.tar.gz
cd gcc-VERSION
./contrib/download_prerequisites
cd ..
mkdir objdir
cd objdir
$PWD/../gcc-VERSION/configure --prefix=$HOME/gcc-VERSION --enable-languages=c,c++
make
make install
我所说的选择是:

--程序前缀=前缀
-GCC支持在安装程序时对其程序名进行一些转换。此选项在程序名称前加前缀 安装在bindir中(见上文)。例如,指定
--程序前缀=foo-
将导致将
gcc
安装为
/usr/local/bin/foo gcc


这里的
/usr/local
只是自动工具的默认前缀。我强烈建议您不要在那里安装GCC。对每个版本执行此操作,您可以拥有
gcc-4.8
gcc-5.3
,等等。

在典型的Linux/“免费unix”系统中,有几个层与程序编译相关

  • 内核。用户级程序很少直接与内核交互,尽管它们可以
  • 特定于内核的头文件,由内核模块使用,并绑定到特定的Linux内核版本。在
    Debian
    中,这些头出现在
    linux头-
    中。可能有多个专用于相应内核版本的包。除非您的程序是内核模块或类似模块,否则您不需要它们
  • libc的内核特定部分。在Debian系统中,这在包
    linux libc dev
    中提供。通常,这个包不是特定于某个特定的内核版本,而是“一代版本”(它发展缓慢,反映了新内核用户级工具、常量等的出现)。您确实需要这个包来编译一个典型的复杂用户land程序,因为它包含重要的系统范围常量和类型定义
  • libc
    。此库提供所有常用的“C库”函数、工具等,有时它包装相应的内核工具(想想
    open()
    send()
    brk()
    函数),有时它提供自己的高级功能(例如
    qsort()
    实现)。您确实需要这个库来构建几乎所有的程序。在debian系统中,它有几个包,头在
    libc6 dev
    中。可能有多个不同的
    libc
    实例同时在单个Linux内核上运行(例如在
    chroot
    s中),但是由于库依赖于特定的文件层次结构,因此通常只有一个

  • 编译器。编译器有自己的头集,但是对于C编译器来说,编译器特定的头比C++编译器要少得多,因为C++编译器通常有自己的STL实现,这是语言设计的头库。C编译器中的大多数
    .h
    头负责各种特定于编译器的技巧,如varargs处理(
    stdarg.h
    )或其他东西。例如,在Debian 7中的
    gcc-4.7
    包中,只有47个
    .h
    文件,其中大部分是

  • 实际上,在Debian中,您可以安装任意数量的编译器,它们不会相互干扰。例如,现在在我的
    Ubuntu-16.04
    中有4个gcc版本可以立即安装:
    4.7.4
    4.8.5
    4.9.3
    5.3.1
    ,-4
    clang
    版本:
    3.5
    3.6
    3.7
    3.8
    。所有这些不同版本的编译器都可以通过
    apt get install
    安装。我猜现代的Debian或多或少都有相同的集合。使用相对简单的规则,您可以为任何给定的编译器和任何给定的版本构建包

    在编译过程中,可以使用
    CC
    环境变量选择所需的C编译器,而不需要这样做