%define target_arch aarch64 %define target_kernel arm64 %define target_qemu_arch aarch64 %define target %target_arch-linux-gnu %define gcc_branch 8 %define gcc_version 8.4.1 %define gcc_source_version_timestamp 20200305 %define orig_gcc_release alt0.p9.1 Name: cross-gcc%gcc_branch-%target Release: alt1 Version: %gcc_version ExclusiveArch: x86_64 %define binutils_version 2.31.1 %define binutils_evr 1:%binutils_version-alt4 %define glibc_version 2.27 %define glibc_release alt13 %define glibc_evr %glibc_version-%glibc_release %define kernel_version 5.4 %define sysroot %prefix/lib/%target/sys-root %define target_ld_linux /lib64/ld-linux-aarch64.so.1 Summary: aarch64-targeted GCC cross-toolchain License: LGPL-2.1-or-later and LGPL-3.0-or-later and GPL-2.0-or-later and GPL-3.0-or-later and GPL-3.0-or-later with GCC-exception-3.1 Group: Development/C BuildPreReq: gcc-c++ BuildPreReq: libmpc-devel libmpfr-devel libgmp-devel zlib-devel BuildPreReq: coreutils flex bison makeinfo findutils # Linux' headers_install uses rsync BuildPreReq: rsync BuildRequires: gcc-source = %gcc_version-%orig_gcc_release BuildRequires: binutils-source = %binutils_evr BuildRequires: glibc-source = %glibc_evr BuildRequires: kernel-source-%kernel_version BuildRequires: qemu-user-static-%target_qemu_arch Requires: cross-binutils-%target = %binutils_version Requires: cross-glibc-%target = %glibc_version %define _libexecdir /usr/libexec %description %target_arch-targeted GCC cross-compiler %package -n cross-binutils-%target Version: %binutils_version Summary: %target_arch-targeted binutils (linker, assembler, etc) Group: Development/C %description -n cross-binutils-%target %target_arch-targeted binutils (linker, assembler, objdump, etc) %package -n cross-glibc-%target Version: %glibc_version Summary: %target_arch-targeted cross-glibc Group: Development/C %description -n cross-glibc-%target glibc for %target_arch. Should be used for cross-compilation only %prep %setup -cT tar -xf /usr/src/gcc-source/gcc-%gcc_version-%gcc_source_version_timestamp.tar tar -xf /usr/src/binutils-source/binutils-%binutils_version.tar tar -xf /usr/src/kernel/sources/kernel-source-%kernel_version.tar tar -xf /usr/src/glibc-source/glibc-%glibc_evr.tar rm -rf stage %build mkdir -p obj_binutils mkdir -p obj_gcc mkdir -p obj_kheaders mkdir -p obj_glibc mkdir -p -m755 stage%prefix/bin export PATH=`pwd`/stage%prefix/bin:$PATH stagedir=`pwd`/stage # kernel headers %_make_bin -j%__nprocs \ -C kernel-source-%kernel_version \ O=`pwd`/obj_kheaders \ ARCH=%target_kernel \ INSTALL_HDR_PATH=${stagedir}%sysroot/usr \ headers_install # XXX: avoid %%configure for it puts $target libraries into /usr/lib64 cd obj_binutils ../binutils-%binutils_version/configure \ --target=%target \ --host=%{_configure_platform} \ --build=%{_configure_platform} \ --prefix=%prefix \ --disable-bootstrap \ --disable-multiarch \ --disable-multilib \ --disable-werror \ --disable-shared \ --disable-nls \ --with-sysroot=%sysroot \ --with-build-sysroot=${stagedir}%sysroot \ --with-system-zlib \ --enable-plugins \ --enable-gold=yes \ --enable-ld=default \ --enable-64-bit-bfd \ --enable-relro \ --enable-textrel-check=warning %make_build # XXX: avoid makeinstall for it puts $target libraries into /usr/lib64 %make_install install DESTDIR=${stagedir} # N.B.: this builds GCC in a single stage (but not all target at once) cd ../obj_gcc # XXX: avoid %%configure puts $target libraries in /usr/lib64 ../gcc-%gcc_version-%gcc_source_version_timestamp/configure \ --target=%target \ --host=%{_configure_platform} \ --build=%{_configure_platform} \ --prefix=%prefix \ --disable-bootstrap \ --disable-multiarch \ --disable-multilib \ --disable-werror \ --with-sysroot=%sysroot \ --with-build-sysroot=${stagedir}%sysroot \ --with-gcc-major-version-only \ --enable-languages=c,c++ \ --enable-version-specific-runtime-libs \ --disable-nls \ --with-system-zlib %make_build all-gcc # XXX: avoid makeinstall for it puts $target libraries into /usr/lib64 %make_install install-gcc DESTDIR=${stagedir} cd ../obj_glibc # XXX: avoid %%configure since it puts target libraries/binaries into /usr/lib64 # Note: glibc's is a library, so $host must be the same as $target ../glibc-%glibc_evr/configure \ --host=%target \ --target=%target \ --build=%{_configure_platform} \ --prefix=%prefix \ --with-sysroot=%sysroot \ --with-build-sysroot=${stagedir}%sysroot \ --with-headers=${stagedir}%sysroot/usr/include \ --with-lib=${stagedir}%sysroot/usr/lib \ --disable-multilib \ --disable-crypt \ libc_cv_forced_unwind=yes # glibc: headers, C runtime %_make_bin -j%__nprocs install-bootstrap-headers=yes install-headers DESTDIR=${stagedir}%sysroot %_make_bin -j%__nprocs csu/subdir_lib install -d -m755 ${stagedir}%sysroot/usr/lib install csu/crt1.o csu/crti.o csu/crtn.o ${stagedir}%sysroot/usr/lib %target-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o "${stagedir}%sysroot/usr/lib/libc.so" touch ${stagedir}/%sysroot/usr/include/gnu/stubs.h touch ${stagedir}/%sysroot/usr/include/bits/stdio_lim.h # libgcc cd ../obj_gcc %make_build all-target-libgcc # XXX: avoid makeinstall since it puts target libs into /usr/lib64 %make_install install-target-libgcc DESTDIR=${stagedir} # finish off glibc cd ../obj_glibc %make_build # XXX: avoid makeinstall since it puts target libs into /usr/lib64 # Note: target glibc **must** be installed into sysroot to prevent # native compilers from using it by default %make_install install DESTDIR=${stagedir}%sysroot # finish off gcc (g++, libstdc++, libssp, whatever) cd ../obj_gcc %make_build # XXX: avoid makeinstall since it puts target libs into /usr/lib64 %make_install install DESTDIR=${stagedir} %install export PATH=`pwd`/stage%prefix/bin:$PATH %_make_bin -j%__nprocs \ -C kernel-source-%kernel_version \ O=`pwd`/obj_kheaders \ ARCH=%target_kernel \ INSTALL_HDR_PATH=%buildroot%sysroot/usr \ headers_install cd obj_binutils %make_install install DESTDIR=%buildroot tooldir=%prefix/libexec/gcc/%target cd ../obj_glibc %make_install install DESTDIR=%buildroot%sysroot cd ../obj_gcc %make_install install DESTDIR=%buildroot # relocate target libgcc_s mv %buildroot%prefix/lib/gcc/%target/lib64/libgcc_s.so* %buildroot%prefix/lib/gcc/%target/%gcc_branch/ rmdir %buildroot%prefix/lib/gcc/%target/lib64 # XXX: native compiler sets /lib64/ld-linux-aarch64.so.1 as an ELF interpreter. # Make sure cross-toolchain we build does the same thing. %buildroot%prefix/bin/%target-gcc -dumpspecs > specs sed -e "s;/lib/ld-linux-aarch64;/lib64/ld-linux-aarch64;g" -i specs # Assembler: %%target-as. # Path is relative to %%prefix/lib/gcc/%%target/%%gcc_branch sed -e '/^[*]invoke_as:/,/^[*]cpp:/ s; as ; ../../../../bin/%target-as ;' -i specs # objcopy: %%target-objcopy sed -e 's; objcopy ; ../../../../bin/%target-objcopy ;' -i specs install -m 644 specs %buildroot%prefix/lib/gcc/%target/%gcc_branch/specs # Note: collect2 (GCCs linker wrapper) searches for %%target-ld on its own. # Alas it does not use relative paths and is not adjustable via the specs file # XXX: apparently invoke_as: spec directive applies only to running assembler # on compiler (cc1) output. The spec which describes compiling of `assembler` # and `assembler-with-cpp` pseudo-languages seems to be hard-coded into GCC. # As a result GCC still runs /usr/bin/as (instead of target assembler) when # compiling .S files. Therefore install `as` symlinks in GCC libsubdir # (%%prefix/lib/gcc/%%target/%%gcc_branch). # Just in a case make symlins to other tools. for tool in ar as ld ld.bfd ld.gold nm objcopy objdump ranlib readelf strip; do ln -s ../../../../bin/%target-$tool %buildroot%prefix/lib/gcc/%target/%gcc_branch/$tool # just in a case add a symlink into libexec too ln -s ../../../../bin/%target-$tool %buildroot%prefix/libexec/gcc/%target/%gcc_branch/$tool done # XXX: ABI: which is correct location of ELF interpreter for aarch64? # Native glibc provides ld-linux-aarch64.so.1 in both /lib64 and /lib. # Do the same thing in cross-glibc install -d -m 755 %buildroot%sysroot/lib ln -s ../lib64/`basename %target_ld_linux` %buildroot%sysroot/lib/`basename %target_ld_linux` rm -rf %buildroot%sysroot/etc rm -rf %buildroot%sysroot/var rm -rf %buildroot%sysroot/sbin rm -rf %buildroot%sysroot/usr/share rm -rf %buildroot%sysroot/usr/bin rm -rf %buildroot%sysroot/usr/sbin rm -rf %buildroot%sysroot/usr/libexec rm -rf %buildroot%sysroot/usr/lib64/audit rm -rf %buildroot%sysroot/usr/lib64/gconv rm -rf %buildroot%prefix/share/info rm -rf %buildroot%prefix/share/man/man7 # python pretty-printers conflict with native compiler rm -rf %buildroot%prefix/share/gcc-%gcc_branch/python # conficts with the native compiler and is not particularly useful rm -f %buildroot%prefix/%_lib/libcc1.so* # Useless for Linux targets rm -f %buildroot%prefix/share/man/man1/%target-windmc* rm -f %buildroot%prefix/share/man/man1/%target-windres* # libtool junk find %buildroot%prefix/lib/gcc/%target/%gcc_branch -type f -name '*.la' -delete find %buildroot%prefix/libexec/gcc -type f -name '*.la' -delete # Target C++ runtime is used for linking only find %buildroot%prefix/lib/gcc/%target/%gcc_branch -type f -name 'lib*-gdb.py' -delete # XXX: gcc needs this to locate crt1.o install -d -m 755 %buildroot%sysroot/usr/lib # Leave alone $target libraries %add_verify_elf_skiplist %sysroot/* %prefix/lib/gcc/%target/%gcc_branch/* %add_findreq_skiplist %sysroot/* %prefix/lib/gcc/%target/%gcc_branch/* %add_findprov_skiplist %sysroot/* %prefix/lib/gcc/%target/%gcc_branch/* %add_debuginfo_skiplist %sysroot/* %prefix/lib/gcc/%target/%gcc_branch/* %check cat > hello.c < int main(int argc, char** argv) { printf("Hello, %%s!\n", argc > 1 ? argv[1] : "world"); return 0; } EOF cat > hello.cpp < int main(int argc, char** argv) { std::cout << "Hello, " << (argc > 1 ? argv[1] : "world") << "!" << std::endl; return 0; } EOF gcc_runtime_libdir=`dirname $(%buildroot%prefix/bin/%target-gcc --print-libgcc-file-name)` # XXX: PATH= is necessary for collect2 to find %%target-ld env PATH=%buildroot%prefix/bin:$PATH \ %buildroot%prefix/bin/%target-gcc -o hello_c hello.c || exit 2 env PATH=%buildroot%prefix/bin:$PATH \ %buildroot%prefix/bin/%target-g++ -o hello_cpp hello.cpp || exit 3 # Note: LD_LIBRARY_PATH is for **target** ld.so. # Use qemu-user-static so qemu-user is not affected by LD_LIBRARY_PATH env LD_LIBRARY_PATH=%buildroot%sysroot/lib64:${gcc_runtime_libdir} \ qemu-%target_qemu_arch-static -L %buildroot%sysroot ./hello_c || exit 5 env LD_LIBRARY_PATH=%buildroot%sysroot/lib64:${gcc_runtime_libdir} \ qemu-%target_qemu_arch-static -L %buildroot%sysroot ./hello_cpp || exit 7 cat > bye.S < .arch armv8-a .text .align 2 .global _start _start: mov x8, __NR_exit mov x0, 0 svc #0 .section .note.GNU-stack,"",@progbits EOF env PATH=%buildroot%prefix/bin:$PATH \ %buildroot%prefix/bin/%target-gcc -static -nostdlib -o bye_asm bye.S || exit 11 qemu-%target_qemu_arch-static ./bye_asm || exit 13 %files %_bindir/%target-gcc* %_bindir/%target-cpp %_bindir/%target-g++ %_bindir/%target-c++ %_bindir/%target-gcov* %prefix/lib/gcc/%target/%gcc_branch/* %prefix/libexec/gcc/%target/* %exclude %prefix/libexec/gcc/%target/bin/* %exclude %prefix/libexec/gcc/%target/lib/* %prefix/share/man/man1/aarch64-linux-gnu-cpp* %prefix/share/man/man1/aarch64-linux-gnu-g++* %prefix/share/man/man1/aarch64-linux-gnu-gcc* %prefix/share/man/man1/aarch64-linux-gnu-gcov-dump* %prefix/share/man/man1/aarch64-linux-gnu-gcov-tool* %prefix/share/man/man1/aarch64-linux-gnu-gcov* %files -n cross-glibc-%target %sysroot/usr/include/* # XXX: gcc needs %%sysroot/usr/lib to locate C runtime (crt1.o) %sysroot/usr/lib %sysroot/lib64/* %sysroot/usr/lib64/* # Compatibility symlink to ld.so %sysroot/lib/* %files -n cross-binutils-%target %_bindir/%target-addr2line %_bindir/%target-ar %_bindir/%target-as %_bindir/%target-c++filt %_bindir/%target-dwp %_bindir/%target-elfedit %_bindir/%target-gprof %_bindir/%target-ld %_bindir/%target-ld.bfd %_bindir/%target-ld.gold %_bindir/%target-nm %_bindir/%target-objcopy %_bindir/%target-objdump %_bindir/%target-ranlib %_bindir/%target-readelf %_bindir/%target-size %_bindir/%target-strings %_bindir/%target-strip # gcc_tooldir %prefix/libexec/gcc/%target/bin/* %prefix/libexec/gcc/%target/lib/* %changelog * Fri Jun 11 2021 Alexey Sheplyakov 8.4.1-alt1 - Initial build