8.29.1. Installation of GCC
        
        
          If building on x86_64, change the default directory name for 64-bit
          libraries to “lib”:
        
        case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac
        
          The GCC documentation recommends building GCC in a dedicated build
          directory:
        
        mkdir -v build
cd       build
        
          Prepare GCC for compilation:
        
        ../configure --prefix=/usr            \
             LD=ld                    \
             --enable-languages=c,c++ \
             --enable-default-pie     \
             --enable-default-ssp     \
             --enable-host-pie        \
             --disable-multilib       \
             --disable-bootstrap      \
             --disable-fixincludes    \
             --with-system-zlib
        
          GCC supports seven different computer languages, but the
          prerequisites for most of them have not yet been installed. See the
          
          BLFS Book GCC page for instructions on how to build all of
          GCC's supported languages.
        
        
          
            The meaning of the new configure parameters:
          
          
            - 
              LD=ld
- 
              
                This parameter makes the configure script use the ld program
                installed by the Binutils package built earlier in this
                chapter, rather than the cross-built version which would
                otherwise be used.
               
- 
              --disable-fixincludes
- 
              
                By default, during the installation of GCC some system
                headers would be “fixed” to be used with GCC. This is not
                necessary for a modern Linux system, and potentially harmful
                if a package is reinstalled after installing GCC. This switch
                prevents GCC from “fixing” the headers.
               
- 
              --with-system-zlib
- 
              
                This switch tells GCC to link to the system installed copy of
                the Zlib library, rather than its own internal copy.
               
 
        
          ![[Note]](../images/note.png) 
          
            Note
          
          
            PIE (position-independent executables) are binary programs that
            can be loaded anywhere in memory. Without PIE, the security
            feature named ASLR (Address Space Layout Randomization) can be
            applied for the shared libraries, but not for the executables
            themselves. Enabling PIE allows ASLR for the executables in
            addition to the shared libraries, and mitigates some attacks
            based on fixed addresses of sensitive code or data in the
            executables.
          
          
            SSP (Stack Smashing Protection) is a technique to ensure that the
            parameter stack is not corrupted. Stack corruption can, for
            example, alter the return address of a subroutine, thus
            transferring control to some dangerous code (existing in the
            program or shared libraries, or injected by the attacker
            somehow).
          
         
        
          Compile the package:
        
        make
        
          ![[Important]](../images/important.png) 
          
            Important
          
          
            In this section, the test suite for GCC is considered important,
            but it takes a long time. First-time builders are encouraged to
            run the test suite. The time to run the tests can be reduced
            significantly by adding -jx to the make -k check command below,
            where x is the number of CPU cores on your system.
          
         
        
          GCC may need more stack space compiling some extremely complex code
          patterns. As a precaution for the host distros with a tight stack
          limit, explicitly set the stack size hard limit to infinite. On
          most host distros (and the final LFS system) the hard limit is
          infinite by default, but there is no harm done by setting it
          explicitly. It's not necessary to change the stack size soft limit
          because GCC will automatically set it to an appropriate value, as
          long as the value does not exceed the hard limit:
        
        ulimit -s -H unlimited
        
          Now remove/fix several known test failures:
        
        sed -e '/cpython/d'               -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
sed -e 's/no-pic /&-no-pie /'     -i ../gcc/testsuite/gcc.target/i386/pr113689-1.c
sed -e 's/300000/(1|300000)/'     -i ../libgomp/testsuite/libgomp.c-c++-common/pr109062.c
sed -e 's/{ target nonpic } //' \
    -e '/GOTPCREL/d'              -i ../gcc/testsuite/gcc.target/i386/fentryname3.c
        
          Test the results as a non-privileged user, but do not stop at
          errors:
        
        chown -R tester .
su tester -c "PATH=$PATH make -k check"
        
          To extract a summary of the test suite results, run:
        
        ../contrib/test_summary
        
          To filter out only the summaries, pipe the output through
          grep -A7 Summ.
        
        
          Results can be compared with those located at https://www.linuxfromscratch.org/lfs/build-logs/12.3-rc2/
          and https://gcc.gnu.org/ml/gcc-testresults/.
        
        
          The tsan tests are known to fail on some host distros.
        
        
          A few unexpected failures cannot always be avoided. In some cases
          test failures depend on the specific hardware of the system. Unless
          the test results are vastly different from those at the above URL,
          it is safe to continue.
        
        
          Install the package:
        
        make install
        
          The GCC build directory is owned by tester now, and the ownership of the installed
          header directory (and its content) is incorrect. Change the
          ownership to the root user and
          group:
        
        chown -v -R root:root \
    /usr/lib/gcc/$(gcc -dumpmachine)/14.2.0/include{,-fixed}
        
          Create a symlink required by the FHS
          for "historical" reasons.
        
        ln -svr /usr/bin/cpp /usr/lib
        
          Many packages use the name cc to call the C compiler. We've
          already created cc as
          a symlink in gcc-pass2, create its
          man page as a symlink as well:
        
        ln -sv gcc.1 /usr/share/man/man1/cc.1
        
          Add a compatibility symlink to enable building programs with Link
          Time Optimization (LTO):
        
        ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/14.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/
        
          Now that our final toolchain is in place, it is important to again
          ensure that compiling and linking will work as expected. We do this
          by performing some sanity checks:
        
        echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
        
          There should be no errors, and the output of the last command will
          be (allowing for platform-specific differences in the dynamic
          linker name):
        
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
        
          Now make sure that we're set up to use the correct start files:
        
        grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
        
          The output of the last command should be:
        
        /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crtn.o succeeded
        
          Depending on your machine architecture, the above may differ
          slightly. The difference will be the name of the directory after
          /usr/lib/gcc. The important thing to
          look for here is that gcc has found all three
          crt*.o files under the /usr/lib directory.
        
        
          Verify that the compiler is searching for the correct header files:
        
        grep -B4 '^ /usr/include' dummy.log
        
          This command should return the following output:
        
        #include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/include-fixed
 /usr/include
        
          Again, the directory named after your target triplet may be
          different than the above, depending on your system architecture.
        
        
          Next, verify that the new linker is being used with the correct
          search paths:
        
        grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
        
          References to paths that have components with '-linux-gnu' should
          be ignored, but otherwise the output of the last command should be:
        
        SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          A 32-bit system may use a few other directories. For example, here
          is the output from an i686 machine:
        
        SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          Next make sure that we're using the correct libc:
        
        grep "/lib.*/libc.so.6 " dummy.log
        
          The output of the last command should be:
        
        attempt to open /usr/lib/libc.so.6 succeeded
        
          Make sure GCC is using the correct dynamic linker:
        
        grep found dummy.log
        
          The output of the last command should be (allowing for
          platform-specific differences in dynamic linker name):
        
        found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
        
          If the output does not appear as shown above or is not received at
          all, then something is seriously wrong. Investigate and retrace the
          steps to find out where the problem is and correct it. Any issues
          should be resolved before continuing with the process.
        
        
          Once everything is working correctly, clean up the test files:
        
        rm -v dummy.c a.out dummy.log
        
          Finally, move a misplaced file:
        
        mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib