How to edit and re-build the GCC libstdc++ C++ standard library source?
Asked Answered
F

2

13

I am working on some research and would like to edit some of the source code in the libstdc++ library for experimentation. I am, specifically, interested in experimenting with the parallel sorting algorithms. Is there a place I can find documentation to easily edit and build the source code?

I have tried, unsuccessfully, to build various versions of the libstdc++ library. It seems like most new versions require building the entire gcc package, which is a much more lengthy process, especially if I am going to be editing and experimenting with a few files in libstdc++.

I have also been unable to find the source files that contain the parallel sorting algorithms. I can only seem to find the header files that define the functions, and not the source code itself. Any advice or links to documentation would be greatly appreciated.

Fascista answered 19/2, 2014 at 5:54 Comment(0)
F
11

Yes, you have to build the whole of GCC, but once you've done that you only need to rebuild the libstdc++ part.

Building GCC is described at http://gcc.gnu.org/wiki/InstallingGCC

The libstdc++ sources are in the libstdc++-v3 directory. The parallel algorithms are in libstdc++-v3/include/parallel, they are templates so all the code is in headers. The small amount of non-header code is in libstdc++-v3/src/c++98/parallel-settings.cc

After configuring and building the whole of GCC as normal, you can rebuild libstdc++ by running make in the $TARGET/libstdc++-v3 directory (where $TARGET is something like x86_64-pc-linux-gnu).

By default the makefiles don't have proper dependencies that cause objects to be rebuilt after headers change, so you might need to do make clean then make again to get your changes to be picked up.

Flosser answered 10/3, 2014 at 13:32 Comment(8)
This no longer works (at least with Make 4.2 and gcc 10.2 source)Pumpkin
@Pumpkin it works fine for me, with Make 4.3 but I doubt it makes any difference. I do it several times a day, every day of the week. What fails? Maybe you didn't notice I said something like x86_64-unknown-linux-gnu (the exact target depends on your host, and the gcc version).Flosser
Thanks - I must be missing something. I downloaded the source again (this time, GCC 11.02) and still see no Makefile in the libstdc++-v3 subdir, at least on the ARM7 (raspi4). Maybe because the build didn't complete? (bits/libc-header-start.h wasn't found at some point).Pumpkin
@Pumpkin the makefile is created by the configure step, which you still need to run. See the link in my answer, don't just skip to the end and only do the last thing I mentioned. That is about rebuilding it, so only relevant after you've already built it once, the normal way. See the link! I've edited the answer to make that clearer.Flosser
Also, bits/libc-header-start.h belongs to glibc, not GCC. If that isn't found, you can't build GCC, at all. Sounds like your problem is just building GCC in the first place, not rebuilding just the libstdc++ part. You need to fix that then, it's not a libstdc++ problem.Flosser
Thanks @Jonathan for the clarification. Building GCC from scratch fails at the same point: In file included from ../../../gcc-11.2.0/libgcc/../gcc/tsystem.h:87, from ../../../gcc-11.2.0/libgcc/libgcc2.c:27: /usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory 27 | #include <bits/libc-header-start.h>Pumpkin
@Pumpkin that file is part of glibc, without it you can't compile anything. This is not a GCC problem.Flosser
Thanks, @Jonathan - it insists on using the wrong one. Apparently not easy to fix.Pumpkin
C
10

Minimal step-by-step example

Compile GCC from source. Condensed commands:

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`
make install

Wait from 30-minutes to two hours. Now let's use this test program 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();
}

First compile and run it to ensure that the initial compilation worked:

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

Now let's hack up the priority_queue constructor.

First, you can find the actual constructor easily with GDB as explained at: When should I use make_heap vs. Priority Queue?

So we hack it up with this patch:

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

Then rebuild and re-install just libstdc++ to save a lot of time:

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

and now the next build and run:

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

outputs:

hacked

Tested on Ubuntu 16.04.

Ubuntu 22.04, GCC 12.1

We need to either:

or else it fails with:

configure: WARNING: using in-tree isl, disabling version check          
*** This configuration is not supported in the following subdirectories:                                                                                                                                           
     gnattools gotools target-libada target-libphobos target-zlib target-libbacktrace target-libgfortran target-libgo target-libffi target-libobjc target-liboffloadmic
    (Any other directories should still work fine.) 
checking for default BUILD_CONFIG... bootstrap-debug
checking for --enable-vtable-verify... no
/usr/bin/ld: cannot find Scrt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/11/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/11/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc: No such file or directory
collect2: error: ld returned 1 exit status                                                               
configure: error: I suspect your system does not have 32-bit development libraries (libc and headers). If you have them, rerun configure with --enable-multilib. If you do not have them, and want to build a 64-bi
t-only compiler, rerun configure with --disable-multilib. 

glibc

As a bonus, if you are also interested in C: Multiple glibc libraries on a single host

Related:

Cerous answered 21/8, 2018 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.