【问题标题】:How to edit and re-build the GCC libstdc++ C++ standard library source?如何编辑和重新构建 GCC libstdc++ C++ 标准库源?
【发布时间】:2014-03-19 07:06:16
【问题描述】:

我正在进行一些研究,并想编辑 libstdc++ 库中的一些源代码以进行实验。具体来说,我对尝试并行排序算法很感兴趣。有没有地方可以找到文档来轻松编辑和构建源代码?

我尝试构建各种版本的 libstdc++ 库,但未成功。似乎大多数新版本都需要构建整个 gcc 包,这是一个更加漫长的过程,特别是如果我要在 libstdc++ 中编辑和试验一些文件。

我也无法找到包含并行排序算法的源文件。我似乎只能找到定义函数的头文件,而不是源代码本身。任何建议或文档链接将不胜感激。

【问题讨论】:

    标签: c++ gcc parallel-processing stl libstdc++


    【解决方案1】:

    简单的分步示例

    Compile GCC from source。精简命令:

    sudo apt-get build-dep gcc
    git clone git://gcc.gnu.org/git/gcc.git
    cd gcc
    git checkout gcc-6_4_0-release
    ./contrib/download_prerequisites
    mkdir build
    cd build
    ../configure --enable-languages=c,c++ --prefix="$(pwd)/install"
    make -j`nproc`
    

    等待 30 分钟到两个小时。现在让我们使用这个测试程序a.cpp

    #include <cassert>
    #include <queue>
    
    int main() {
        std::priority_queue<int> q;
        q.emplace(2);
        q.emplace(1);
        q.emplace(3);
        assert(q.top() == 3);
        q.pop();
        assert(q.top() == 2);
        q.pop();
        assert(q.top() == 1);
        q.pop();
    }
    

    首先编译并运行它以确保初始编译工作:

    gcc/build/install/bin/g++ -g -std=c++11 -O0 -o a.out ./a.cpp
    ./a.out
    

    现在让我们破解 priority_queue 构造函数。

    首先,您可以使用 GDB 轻松找到实际的构造函数,如下所述:When should I use make_heap vs. Priority Queue?

    所以我们用这个补丁破解它:

    diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
    index 5d255e7300b..deec7bc4d99 100644
    --- a/libstdc++-v3/include/bits/stl_queue.h
    +++ b/libstdc++-v3/include/bits/stl_queue.h
    @@ -61,6 +61,7 @@
     #if __cplusplus >= 201103L
     # include <bits/uses_allocator.h>
     #endif
    +#include <iostream>
    
     namespace std _GLIBCXX_VISIBILITY(default)
     {
    @@ -444,7 +445,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
           priority_queue(const _Compare& __x = _Compare(),
                 _Sequence&& __s = _Sequence())
           : c(std::move(__s)), comp(__x)
    -      { std::make_heap(c.begin(), c.end(), comp); }
    +      {
    +        std::cout << "hacked" << std::endl;
    +        std::make_heap(c.begin(), c.end(), comp);
    +      }
    
           template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
        explicit
    

    然后重建并重新安装 libstdc++ 以节省大量时间:

    cd gcc/build/x86_64-pc-linux-gnu/libstdc++-v3
    make -j`nproc`
    make install
    

    现在是下一个构建和运行:

    gcc/build/install/bin/g++ -g -std=c++11 -O0 -o a.out ./a.cpp
    ./a.out
    

    输出:

    hacked
    

    在 Ubuntu 16.04 上测试。

    glibc

    作为奖励,如果您也对 C 感兴趣:Multiple glibc libraries on a single host

    【讨论】:

      【解决方案2】:

      是的,您必须构建整个 GCC,但一旦完成,您只需要重新构建 libstdc++ 部分。

      http://gcc.gnu.org/wiki/InstallingGCC 中描述了构建 GCC

      libstdc++ 源代码位于libstdc++-v3 目录中。并行算法在libstdc++-v3/include/parallel 中,它们是模板,所以所有代码都在标头中。少量非头代码在libstdc++-v3/src/c++98/parallel-settings.cc

      在正常配置和构建整个 GCC 之后,您可以通过在 $TARGET/libstdc++-v3 目录中运行 make 来重建 libstdc++(其中 $TARGET 类似于 x86_64-pc-linux-gnu)。

      默认情况下,makefile 没有适当的依赖关系,导致在标头更改后重新构建对象,因此您可能需要再次执行 make clean 然后 make 以获取您的更改。

      【讨论】:

      • 这不再有效(至少对于 Make 4.2 和 gcc 10.2 源)
      • @automorphic 它适用于我,使用 Make 4.3 但我怀疑它有什么不同。我每天做几次,一周中的每一天。什么失败了?可能你没有注意到我说的是 like x86_64-unknown-linux-gnu(具体目标取决于你的主机和 gcc 版本)。
      • @automorphic makefile 由configure 步骤创建,您仍需要运行该步骤。请参阅我的答案中的链接,不要只跳到最后,只做我提到的最后一件事。那是关于重建它,所以只有在你已经构建过一次之后才有意义,这是正常的方式。看链接!我已经编辑了答案以使其更清楚。
      • 另外,bits/libc-header-start.h 属于 glibc,而不是 GCC。如果找不到,则根本无法构建 GCC。听起来您的问题只是首先构建 GCC,而不是仅重建 libstdc++ 部分。那你需要解决这个问题,这不是 libstdc++ 问题。
      • @automorphic 该文件是 glibc 的一部分,没有它,您将无法编译任何东西。这不是 GCC 问题。
      猜你喜欢
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      相关资源
      最近更新 更多