{"id":107,"date":"2025-02-27T06:49:00","date_gmt":"2025-02-27T06:49:00","guid":{"rendered":"https:\/\/haco.club\/?p=107"},"modified":"2025-02-27T06:49:00","modified_gmt":"2025-02-27T06:49:00","slug":"everything-i-know-about-gnu-toolchain","status":"publish","type":"post","link":"https:\/\/haco.club\/?p=107","title":{"rendered":"Everything I know about GNU toolchain"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><a href=\"https:\/\/maskray.me\/blog\/2021-01-24-gnu-toolchain#:~:text=Main%20tools:%20as%20(%20gas\/,make%20%2DC%20out\/debug%20all\">https:\/\/maskray.me\/blog\/2021-01-24-gnu-toolchain#:~:text=Main%20tools:%20as%20(%20gas\/,make%20%2DC%20out\/debug%20all<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>As mainly an LLVM person, I occasionally contribute to GNU toolchain projects. This is sometimes for fun, sometimes for investigating why an (usually ancient) feature works in a particular way, sometimes for pushing forward a toolchain feature with the mind of both communities, or sometimes just for getting sense of how things work with mailing list+GNU make.<\/p>\n\n\n\n<p>For a debug build, I normally place my build directory&nbsp;<code>out\/debug<\/code>&nbsp;directly under the project root.<\/p>\n\n\n\n<p>Dependency chain of a port: GCC needs binutils. Linux kernel needs GCC. glibc needs Linux kernel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"binutils\">binutils<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Repository:\u00a0<a href=\"https:\/\/sourceware.org\/git\/gitweb.cgi?p=binutils-gdb.git\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/git\/gitweb.cgi?p=binutils-gdb.git<\/a>\u00a0(write access:\u00a0<code>ssh:\/\/sourceware.org\/git\/binutils-gdb.git<\/code>)<\/li>\n\n\n\n<li>Repository for documentation:\u00a0<a href=\"https:\/\/sourceware.org\/cgit\/binutils-htdocs\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/cgit\/binutils-htdocs\/<\/a><\/li>\n\n\n\n<li>Wiki:\u00a0<a href=\"https:\/\/sourceware.org\/binutils\/wiki\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/binutils\/wiki\/<\/a><\/li>\n\n\n\n<li>Mailing list:\u00a0<a href=\"https:\/\/sourceware.org\/pipermail\/binutils\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/pipermail\/binutils<\/a><\/li>\n\n\n\n<li>Bugzilla:\u00a0<a href=\"https:\/\/sourceware.org\/bugzilla\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/bugzilla\/<\/a>\u00a0(notifications:\u00a0<a href=\"https:\/\/lists.gnu.org\/archive\/html\/bug-binutils\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/lists.gnu.org\/archive\/html\/bug-binutils\/<\/a>)<\/li>\n\n\n\n<li>Main tools: as (<code>gas\/<\/code>, GNU assembler), ld (<code>ld\/<\/code>, GNU ld), gold (<code>gold\/<\/code>, GNU gold)<\/li>\n\n\n\n<li>Branches:\u00a0<code>binutils-2_35-branch<\/code>,\u00a0<code>binutils-2_36-branch<\/code><\/li>\n<\/ul>\n\n\n\n<p>Target&nbsp;<code>all<\/code>&nbsp;builds targets&nbsp;<code>all-host<\/code>&nbsp;and&nbsp;<code>all-target<\/code>. When running configure, by default most top-level directories&nbsp;<code>binutils gas gdb gdbserver ld libctf<\/code>&nbsp;are all enabled. You can disable some components via&nbsp;<code>--disable-*<\/code>.&nbsp;<code>--enable-gold<\/code>&nbsp;is needed to enable gold.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p out\/debug; cd out\/debug\n..\/..\/configure --target=x86_64-linux-gnu --prefix=\/tmp\/opt\/binutils-debug --disable-gdb --disable-gdbserver<\/code><\/pre>\n\n\n\n<p>For cross compiling, make sure your have&nbsp;<code>$target-{gcc,as,ld}<\/code>.<\/p>\n\n\n\n<p>For many tools (binutils, gdb, ld),&nbsp;<code>--enable-targets=all<\/code>&nbsp;will build every supported architectures and binary formats. However, one gas build can only support one architecture. ld has a default emulation and needs&nbsp;<code>-m<\/code>&nbsp;to support other architectures (<code>aarch64 architecture of input file `a.o' is incompatible with i386:x86-64 output<\/code>). Many tests are generic and can be run on many targets, but a&nbsp;<code>--enable-targets=all<\/code>&nbsp;build only tests its default target.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># binutils (binutils\/*)\nmake -C out\/debug all-binutils\n# gas (gas\/as-new)\nmake -C out\/debug all-gas\n# ld (ld\/ld-new)\nmake -C out\/debug all-ld\n\n# Build all enabled tools.\nmake -C out\/debug all<\/code><\/pre>\n\n\n\n<p>Build with Clang:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p out\/clang-debug; cd out\/clang-debug\n..\/..\/configure CC=~\/Stable\/bin\/clang CXX=~\/Stable\/bin\/clang++ CFLAGS='-O0 -g' CXXFLAGS='-O0 -g'<\/code><\/pre>\n\n\n\n<p>About security aspect, &#8220;don&#8217;t run any of binutils as root&#8221; is sufficient advice (Alan Modra).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"test\">Test<\/h3>\n\n\n\n<p>GNU Test Framework DejaGnu is based on Expect, which is in turn based on Tcl.<\/p>\n\n\n\n<p>To run tests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -C out\/debug check-binutils\n# Find the result in (summary) out\/debug\/binutils\/binutils.sum and (details) out\/debug\/binutils\/binutils.log\n\nmake -C out\/debug check-gas\n# Find the result in (summary) out\/debug\/gas\/testsuite\/gas.sum and (details) out\/debug\/gas\/testsuite\/gas.log\n\nmake -C out\/debug check-ld\n\n# Test all enabled tools.\nmake -C out\/debug check-all<\/code><\/pre>\n\n\n\n<p>For ld, tests are listed in&nbsp;<code>.exp<\/code>&nbsp;files under&nbsp;<code>ld\/testsuite<\/code>. A single test normally consists of a&nbsp;<code>.d<\/code>&nbsp;file and several associated&nbsp;<code>.s<\/code>&nbsp;files.<\/p>\n\n\n\n<p>To run the tests in&nbsp;<code>ld\/testsuite\/ld-shared\/shared.exp<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -C out\/debug check-ld RUNTESTFLAGS=ld-shared\/shared.exp<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"misc\">Misc<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A bot updates\u00a0<code>bfd\/version.h<\/code>\u00a0(<code>BFD_VERSION_DATE<\/code>) daily.<\/li>\n\n\n\n<li>Test coverage is low.<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>cat > .dir-locals-2.el &lt;&lt;e\n((nil . ((indent-tabs-mode . t)\n         (tab-width . 8)))\n (c-mode . ((c-file-style . \"gnu\"))))\ne\necho 'BasedOnStyle: GNU' > .clang-format<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"gdb\">gdb<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mailing list:\u00a0<a href=\"https:\/\/sourceware.org\/pipermail\/gdb\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/pipermail\/gdb<\/a>\u00a0<a href=\"https:\/\/sourceware.org\/pipermail\/gdb-prs\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/pipermail\/gdb-prs<\/a><\/li>\n<\/ul>\n\n\n\n<p>gdb resides in the binutils-gdb repository. configure enables gdb and gdbserver by default. You just need to make sure&nbsp;<code>--disable-gdb --disable-gdbserver<\/code>&nbsp;is not on the configure line.<\/p>\n\n\n\n<p>Run gdb under the build directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gdb\/gdb -data-directory gdb\/data-directory<\/code><\/pre>\n\n\n\n<p>To run the tests in\u00a0<code>gdb\/testsuite\/gdb.dwarf2\/dw2-abs-hi-pc.exp<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make check-gdb RUNTESTFLAGS=gdb.dwarf2\/dw2-abs-hi-pc.exp\n\n# cd $build\/gdb\/testsuite\/outputs\/gdb.dwarf2\/dw2-abs-hi-pc<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"glibc\">glibc<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Repository:\u00a0<a href=\"https:\/\/sourceware.org\/git\/gitweb.cgi?p=glibc.git\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/git\/gitweb.cgi?p=glibc.git<\/a><\/li>\n\n\n\n<li>Wiki:\u00a0<a href=\"https:\/\/sourceware.org\/glibc\/wiki\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/glibc\/wiki\/<\/a><\/li>\n\n\n\n<li>Bugzilla:\u00a0<a href=\"https:\/\/sourceware.org\/bugzilla\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/sourceware.org\/bugzilla\/<\/a><\/li>\n\n\n\n<li>Mailing lists:\u00a0<code>{libc-announce,libc-alpha,libc-locale,libc-stable,libc-help}@sourceware.org<\/code><\/li>\n\n\n\n<li>Patchwork:\u00a0<a href=\"https:\/\/patchwork.sourceware.org\/project\/glibc\/list\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/patchwork.sourceware.org\/project\/glibc\/list\/<\/a>\u00a0<a href=\"https:\/\/sourceware.org\/glibc\/wiki\/Patch%20Review%20Workflow?highlight=%28git-pw%29\" target=\"_blank\" rel=\"noreferrer noopener\">Patch Review Workflow<\/a><\/li>\n<\/ul>\n\n\n\n<p>(Mostly) an implementation of the user-space side of standard C\/POSIX functions with Linux extensions.<\/p>\n\n\n\n<p>A very unfortunate fact: glibc can only be built with&nbsp;<code>-O2<\/code>, not&nbsp;<code>-O0<\/code>&nbsp;or&nbsp;<code>-O1<\/code>. If you want to have an un-optimized debug build, deleting an object file and recompiling it with&nbsp;<code>-g<\/code>&nbsp;usually works. Another workaround is&nbsp;<code>#pragma GCC optimize (\"O0\")<\/code>.<\/p>\n\n\n\n<p>The&nbsp;<code>-O2<\/code>&nbsp;issue is probably related to (1) expected inlining and (2) avoiding dynamic relocations.<\/p>\n\n\n\n<p>To cross compile for aarch64:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/glibc\/aarch64 --host=aarch64-linux-gnu<\/code><\/pre>\n\n\n\n<p>If you don&#8217;t have a C++ compiler. Specify&nbsp;<code>CXX=false<\/code>.<\/p>\n\n\n\n<p>To cross compile for i686:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/glibc\/i686 --host=i686-linux-gnu CC='gcc -m32' CXX='g++ -m32' &amp;&amp; make -j 50 &amp;&amp; make -j 50 install &amp;&amp; cp -f \/usr\/lib\/i386-linux-gnu\/{libgcc_s.so.1,libstdc++.so.6} \/tmp\/glibc\/i686\/<\/code><\/pre>\n\n\n\n<p>For cross compiling,&nbsp;<code>run-built-tests<\/code>&nbsp;is yes only if&nbsp;<code>test-wrapper<\/code>&nbsp;is set.<\/p>\n\n\n\n<p>To build a directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -r -C ~\/Dev\/glibc\/stdlib objdir=$PWD subdir=stdlib subdir_lib<\/code><\/pre>\n\n\n\n<p>The run a program with the built dynamic loader:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$build\/testrun.sh $program\n\n# Debug a test. --direct can avoid spawning a new process.\ncgdb -ex 'set exec-wrapper env LD_LIBRARY_PATH=.:.\/math:.\/elf:.\/dlfcn:.\/nss:.\/nis:.\/rt:.\/resolv:.\/mathvec:.\/support:.\/crypt:.\/nptl' elf\/tst-nodelete --direct<\/code><\/pre>\n\n\n\n<p>To test one directory (say,\u00a0<code>libio<\/code>), delete\u00a0<code>libio\/*.out<\/code>\u00a0files and run<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -r -C ~\/Dev\/glibc\/libio objdir=$PWD check -j 20<\/code><\/pre>\n\n\n\n<p>(<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/glibc\/lld &amp;&amp; make -j 50 &amp;&amp; make -j 50 install &amp;&amp; 'cp' -f \/usr\/lib\/x86_64-linux-gnu\/libgcc_s.so.1 \/tmp\/glibc\/lld\/lib\/<\/code><\/pre>\n\n\n\n<p>)<\/p>\n\n\n\n<p>Delete failed tests so that the next&nbsp;<code>make check<\/code>&nbsp;invocation will re-run them:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rg -lg '*.test-result' '^FAIL' | while read i; do rm -f ${i\/.test-result\/.out} $i; done<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"grte\">GRTE<\/h3>\n\n\n\n<p>In a llvm-project build directory, build clang, lld, and&nbsp;<code>clang_rt.crtbegin*.o<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ninja -C \/tmp\/out\/custom1 clang crt lld<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout origin\/google\/grte\/v5-2.27\/master\nmkdir -p out\/grte &amp;&amp; cd out\/grte\n..\/..\/configure --prefix=\/tmp\/grte\/play --disable-werror --disable-float128 --with-clang --with-lld --enable-static-pie CC=\/tmp\/out\/custom1\/bin\/clang CXX=\/tmp\/out\/custom1\/bin\/clang++\nmake -j 30\nmake -j 30 install<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"build-many-glibcs.py\">build-many-glibcs.py<\/h3>\n\n\n\n<p>Run the following commands to populate&nbsp;<code>\/tmp\/glibc-many<\/code>&nbsp;with toolchains. Caution: please make sure the target file system has tens of gigabytes.<\/p>\n\n\n\n<p>Preparation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>scripts\/build-many-glibcs.py \/tmp\/glibc-many checkout --shallow\nscripts\/build-many-glibcs.py \/tmp\/glibc-many host-libraries\n\n# Build a bootstrap GCC (static-only, C-only, --with-newlib).\n# \/tmp\/glibc-many\/src\/gcc\/gcc\/configure --srcdir=\/tmp\/glibc-many\/src\/gcc\/gcc --prefix=\/tmp\/glibc-many\/install\/compilers\/aarch64-linux-gnu --with-sysroot=\/tmp\/glibc-many\/install\/compilers\/aarch64-linux-gnu\/sysroot --with-gmp=\/tmp\/glibc-many\/install\/host-libraries --with-mpfr=\/tmp\/glibc-many\/install\/host-libraries --with-mpc=\/tmp\/glibc-many\/install\/host-libraries --enable-shared --enable-threads --enable-languages=c,c++,lto ... --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=aarch64-glibc-linux-gnu ...\nscripts\/build-many-glibcs.py \/tmp\/glibc-many compilers aarch64-linux-gnu\nscripts\/build-many-glibcs.py \/tmp\/glibc-many compilers powerpc64le-linux-gnu\nscripts\/build-many-glibcs.py \/tmp\/glibc-many compilers sparc64-linux-gnu<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--shallow<\/code>\u00a0passes\u00a0<code>--depth 1<\/code>\u00a0to the git clone command.<\/li>\n\n\n\n<li><code>--keep all<\/code>\u00a0keeps intermediary build directories intact. You may want this option to investigate build issues.<\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;<code>glibcs<\/code>&nbsp;command will delete the glibc build directory, build glibc, and run&nbsp;<code>make check<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Build glibc using bootstrap GCC in &lt;path>\/install\/compilers\/aarch64-linux-gnu\/bin\/aarch64-linux-gcc\n# Then build GCC using the built glibc.\n# \/tmp\/glibc-many\/src\/glibc\/configure --prefix=\/usr --enable-profile --build=x86_64-pc-linux-gnu --host=aarch64-glibc-linux-gnu CC=aarch64-glibc-linux-gnu-gcc CXX=aarch64-glibc-linux-gnu-g++ AR=aarch64-glibc-linux-gnu-ar AS=aarch64-glibc-linux-gnu-as LD=aarch64-glibc-linux-gnu-ld NM=aarch64-glibc-linux-gnu-nm OBJCOPY=aarch64-glibc-linux-gnu-objcopy OBJDUMP=aarch64-glibc-linux-gnu-objdump RANLIB=aarch64-glibc-linux-gnu-ranlib READELF=aarch64-glibc-linux-gnu-readelf STRIP=aarch64-glibc-linux-gnu-strip\n# Find built glibc in &lt;path>\/install\/glibcs\/aarch64-linux-gnu\nscripts\/build-many-glibcs.py \/tmp\/glibc-many glibcs aarch64-linux-gnu\n# Find the logs and test results under \/tmp\/glibc-many\/logs\/glibcs\/aarch64-linux-gnu\/\n\nscripts\/build-many-glibcs.py \/tmp\/glibc-many glibcs powerpc64le-linux-gnu\n\nscripts\/build-many-glibcs.py \/tmp\/glibc-many glibcs sparc64-linux-gnu<\/code><\/pre>\n\n\n\n<p>For the\u00a0<code>glibcs<\/code>\u00a0command, add\u00a0<code>--full-gcc<\/code>\u00a0to build C++.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>many=\/tmp\/glibc-many\n$many\/install\/compilers\/aarch64-linux-gnu\/bin\/aarch64-glibc-linux-gnu-g++ -Wl,--dynamic-linker=$many\/install\/glibcs\/aarch64-linux-gnu\/lib\/ld-linux-aarch64.so.1 -Wl,-rpath=$many\/install\/compilers\/aarch64-linux-gnu\/sysroot\/lib64:$many\/install\/compilers\/aarch64-linux-gnu\/aarch64-glibc-linux-gnu\/lib64 a.cc\n.\/a.out\n\n$many\/install\/compilers\/riscv64-linux-gnu\/bin\/riscv64-glibc-linux-gnu-g++ -Wl,--dynamic-linker=$many\/install\/glibcs\/riscv64-linux-gnu\/lib\/ld-linux-riscv64.so.1 -Wl,-rpath=$many\/install\/compilers\/riscv64-linux-gnu\/sysroot\/lib64:$many\/install\/compilers\/riscv64-linux-gnu\/riscv64-glibc-linux-gnu\/lib64 a.cc\n.\/a.out\n\n$many\/install\/compilers\/x86_64-linux-gnu\/bin\/x86_64-glibc-linux-gnu-gcc -Wl,--dynamic-linker=$many\/install\/glibcs\/x86_64-linux-gnu\/lib64\/ld-linux-x86-64.so.2 -Wl,-rpath=$many\/install\/compilers\/x86_64-linux-gnu\/sysroot\/lib64:$many\/install\/compilers\/x86_64-linux-gnu\/x86_64-glibc-linux-gnu\/lib64 a.c\n.\/a.out<\/code><\/pre>\n\n\n\n<p>&#8220;On build-many-glibcs.py and most stage1 compiler bootstrap, gcc is build statically against newlib. the static linked gcc (with a lot of disabled features) is then used to build glibc and then the stage2 gcc (which will then have all the features that rely on libc enabled) so the stage1 gcc&nbsp;<em>might<\/em>&nbsp;not have the require started files&#8221;<\/p>\n\n\n\n<p>During development, some interesting targets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -C out\/debug check-abi<\/code><\/pre>\n\n\n\n<p>Building with Clang is not an option.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Clang does not support GCC nested functions\u00a0<a href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=27220\" target=\"_blank\" rel=\"noreferrer noopener\">BZ #27220<\/a><\/li>\n\n\n\n<li>x86\u00a0<code>PRESERVE_BND_REGS_PREFIX<\/code>: integrated assembler does not support the\u00a0<code>bnd<\/code>\u00a0prefix.<\/li>\n\n\n\n<li><code>sysdeps\/powerpc\/powerpc64\/Makefile<\/code>: Clang does not support\u00a0<code>-ffixed-vrsave -ffixed-vscr<\/code><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"misc-1\">Misc<\/h3>\n\n\n\n<p>To regenerate&nbsp;<code>configure<\/code>&nbsp;from&nbsp;<code>configure.ac<\/code>:&nbsp;<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/sourceware.org\/glibc\/wiki\/Regeneration\">https:\/\/sourceware.org\/glibc\/wiki\/Regeneration<\/a>. Consider installing autoconf\/automake somewhere with the required version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>~\/projects\/autoconf-2.69\/bin\/autoconf\n\nPATH=~\/projects\/autoconf-2.69\/bin:$PATH ~\/projects\/automake-1.15.1\/bin\/automake<\/code><\/pre>\n\n\n\n<p>In\u00a0<code>elf\/<\/code>,\u00a0<code>.o<\/code>\u00a0objects use\u00a0<code>-fpie -DPIC -DMODULE_NAME=libc<\/code>, while\u00a0<code>.os<\/code>\u00a0objects use\u00a0<code>-fPIC -DPIC -DMODULE_NAME=rtld<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"gcc\">GCC<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Repository for documentation:\u00a0<a href=\"https:\/\/gcc.gnu.org\/cgit\/gcc-wwwdocs\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/gcc.gnu.org\/cgit\/gcc-wwwdocs\/<\/a><\/li>\n\n\n\n<li>Mailing lists:\u00a0<code>gcc-{patches,regression}@sourceware.org<\/code><\/li>\n\n\n\n<li>Branches:\u00a0<code>releases\/gcc-8<\/code>,\u00a0<code>releases\/gcc-9<\/code>,\u00a0<code>releases\/gcc-10<\/code><\/li>\n\n\n\n<li><a href=\"https:\/\/gcc.gnu.org\/gitwrite.html\" target=\"_blank\" rel=\"noreferrer noopener\">Read-write Git access<\/a><\/li>\n<\/ul>\n\n\n\n<p><code>--disable-bootstrap<\/code>&nbsp;is the most important, otherwise you will get a stage 2 build. It is not clear what&nbsp;<code>make<\/code>&nbsp;does when you touch a source file. It definitely rebuilds stage1, but it is not clear to me how well stage2 dependency is handled. Anyway, touching a source file causes a total build is not what you desire.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/gcc\/release --disable-bootstrap --enable-languages=c,c++ --disable-multilib\nmake -j 30\n\n# Incremental build\nmake -C gcc cc1 cc1plus xgcc\nmake -C x86_64-pc-linux-gnu\/libstdc++-v3\n\n..\/..\/configure --prefix=\/tmp\/gcc\/debug --disable-bootstrap --enable-languages=c,c++ --disable-multilib CFLAGS='-O0 -g' CXXFLAGS='-O0 -g'<\/code><\/pre>\n\n\n\n<p>To build a GCC targeting riscv64-linux-gnu, we can run\u00a0<code>scripts\/build-many-glibcs.py<\/code>\u00a0from glibc first, then invoke:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/gcc\/rv --target=riscv64-linux-gnu --with-sysroot=\/tmp\/glibc-many\/install\/compilers\/riscv64-linux-gnu-rv64imafdc-lp64d\/sysroot --with-arch=rv64imafdc --with-abi=lp64d --disable-multilib --disable-libsanitizer --enable-languages=c,c++ CFLAGS='-O0 -g3 -gsplit-dwarf' CXXFLAGS='-O0 -g3 -gsplit-dwarf' LDFLAGS='-fuse-ld=lld -Wl,--gdb-index<\/code><\/pre>\n\n\n\n<p>To build a GCC targeting other targets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>..\/..\/configure --prefix=\/tmp\/gcc\/aarch64 --target=aarch64-linux-gnu --with-sysroot=\/tmp\/glibc-many\/install\/compilers\/aarch64-linux-gnu\/sysroot --disable-libsanitizer --enable-languages=c,c++ CFLAGS='-O0 -g3 -gsplit-dwarf' CXXFLAGS='-O0 -g3 -gsplit-dwarf' LDFLAGS='-fuse-ld=lld -Wl,--gdb-index'\n..\/..\/configure --prefix=\/tmp\/gcc\/arm --target=arm-linux-gnueabi --with-sysroot=\/tmp\/glibc-many\/install\/compilers\/arm-linux-gnueabi\/sysroot --disable-libsanitizer --enable-languages=c,c++ CFLAGS='-O0 -g3 -gsplit-dwarf' CXXFLAGS='-O0 -g3 -gsplit-dwarf' LDFLAGS='-fuse-ld=lld -Wl,--gdb-index'<\/code><\/pre>\n\n\n\n<p>If you have a system cross compiler, the steps will be easier. However,\u00a0<code>dg-do run<\/code>\u00a0tests would fail as we don&#8217;t specify\u00a0<code>--sysroot=\/tmp\/gcc\/arm\/arm-linux-gnueabi -Wl,--sysroot=<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rsync -a \/usr\/arm-linux-gnueabi\/{include,lib} \/tmp\/gcc\/arm\/arm-linux-gnueabi\/\n..\/..\/configure --prefix=\/tmp\/gcc\/sh --target=arm-linux-gnueabi --disable-libsanitizer --enable-languages=c,c++ CFLAGS='-O0 -g3 -gsplit-dwarf' CXXFLAGS='-O0 -g3 -gsplit-dwarf' LDFLAGS='-fuse-ld=lld -Wl,--gdb-index'\n\nrsync -a \/usr\/sh4-linux-gnu\/{include,lib} \/tmp\/gcc\/sh\/sh4-linux-gnu\/\n..\/..\/configure --prefix=\/tmp\/gcc\/sh --target=sh4-linux-gnu --disable-libsanitizer --enable-languages=c,c++ CFLAGS='-O0 -g3 -gsplit-dwarf' CXXFLAGS='-O0 -g3 -gsplit-dwarf' LDFLAGS='-fuse-ld=lld -Wl,--gdb-index'<\/code><\/pre>\n\n\n\n<p>To run tests:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make -C out\/release check-gcc\n\n# Test just gcc\/testsuite\/gcc.target\/i386\/i386.exp and gcc\/testsuite\/g++.target\/i386\/i386.exp\nmake -C out\/release check-gcc RUNTESTFLAGS='i386.exp'\n\n# Test one file\nmake -C out\/release check-gcc RUNTESTFLAGS='i386.exp=large-data.c'<\/code><\/pre>\n\n\n\n<p>Some architectures support multilib (aarch64\/powerpc64\/x86\/etc). On x86 you can use&nbsp;<code>--with-multilib='m32;m64'<\/code>, but you need to make sure the needed headers\/libraries are available.<\/p>\n\n\n\n<p>Use built libstdc++ and libgcc.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$build\/gcc\/xg++ -B $build\/release\/gcc forced1.C -L $build\/x86_64-pc-linux-gnu\/libstdc++-v3\/src\/.libs -Wl,-rpath=$build\/x86_64-pc-linux-gnu\/libstdc++-v3\/src\/.libs,-rpath=$build\/x86_64-pc-linux-gnu\/libgcc\n\n$prefix\/bin\/g++ -Wl,-rpath=$prefix\/lib64 a.cc<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>gcc\/incpath.c include path<\/code><\/pre>\n\n\n\n<p>To build older GCC versions, pass&nbsp;<code>--disable-libsanitizer<\/code>&nbsp;to&nbsp;<code>configure<\/code>, as older sanitizers may be unbuildable due to&nbsp;<code>linux\/*<\/code>&nbsp;files.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"misc-2\">Misc<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A bot updates\u00a0<code>ChangeLog<\/code>\u00a0files daily.\u00a0<code>Daily bump.<\/code><\/li>\n<\/ul>\n\n\n\n<p><a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/sourceware.org\/git\/?p=builder.git;a=summary\">https:\/\/sourceware.org\/git\/?p=builder.git;a=summary<\/a>&nbsp;provides continuous integration for some projects.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>To debug a cc1 command,\u00a0<code>gcc -c a.c -wrapper gdb,--args<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"unlisted\">Unlisted<\/h2>\n\n\n\n<p>autotools, bison, m4, make, &#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"contributing\">Contributing<\/h2>\n\n\n\n<p><a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/www.gnu.org\/prep\/standards\/\">GNU Coding Standards<\/a>. Emacs has good built-in support. clang-format&#8217;s support is not as good.<\/p>\n\n\n\n<p>Legally significant changes need&nbsp;<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/www.gnu.org\/prep\/maintain\/html_node\/Copyright-Papers.html\">Copyright Papers<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>setlocal cin cino=>4,n-2,{2,^-2,:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 sw=2 ts=8 sts=2 noet tw=79 colorcolumn=80\nsetlocal fo-=ro fo+=cql<\/code><\/pre>\n\n\n\n<p>In GDB,\u00a0<code>source gcc\/gdbhooks.py<\/code><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/maskray.me\/blog\/2021-01-24-gnu-toolchain#:~:text=Main%20tools:%20as%20(%20gas\/,make%20%2DC%20out\/debug%20all As mainly an LLVM person, I occasionally contribute to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[10],"class_list":["post-107","post","type-post","status-publish","format-standard","hentry","category-tutotial","tag-toolchain"],"_links":{"self":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/107","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=107"}],"version-history":[{"count":1,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/107\/revisions"}],"predecessor-version":[{"id":108,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/107\/revisions\/108"}],"wp:attachment":[{"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=107"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}