Reputation: 335
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.
Upvotes: 16
Views: 19124
Reputation: 383698
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:
--disable-multilib
to ./configure
sudo apt install gcc-multilib g++-multilib
, these are linked to support for 32-bit executables: How to Compile 32-bit Apps on 64-bit Ubuntu?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:
Upvotes: 11
Reputation: 171373
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.
Upvotes: 12