From 241b2e28d7c248d5098a3dcee0dcf2a3bf2d6355 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 8 Sep 2025 10:56:54 +0200 Subject: [PATCH] cross_toolchain.rb: Use GNU mirrors --- bin/cross_toolchain.rb | 148 ++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/bin/cross_toolchain.rb b/bin/cross_toolchain.rb index cae2d7d..42b1865 100755 --- a/bin/cross_toolchain.rb +++ b/bin/cross_toolchain.rb @@ -13,41 +13,50 @@ require 'fileutils' require 'pathname' require 'term/ansicolor' -BINUTILS_VERSION = '2.44' -GLIBC_VERSION = '2.41' -KERNEL_VERSION = '5.15.185' -GCC_VERSION = "15.1.0" +BINUTILS_VERSION = '2.45' +GLIBC_VERSION = '2.42' +KERNEL_VERSION = '6.1.150' +GCC_VERSION = "15.2.0" TMP = Pathname.new('./tmp') class BuildTarget - attr_accessor(:build, :gcc, :target, :tmp) - - def gxx - @gcc.gsub 'c', '+' + def initialize(architecture) + case architecture + when /^r(isc)?v32$/ + @architecture = :rv32 + else + raise "Unsupported architecture '#{architecture}'." + end end def sysroot - tmp + 'sysroot' + TMP + 'sysroot' end def rootfs - tmp + 'rootfs' + TMP + 'rootfs' end - def tools - tmp + 'tools' + def target + case @architecture + when :rv32 + 'riscv32-unknown-linux-gnu' + end end - def configuration - case target - when /^riscv[[:digit:]]+-/ - [ - '--with-arch=rv32imafdc', - '--with-abi=ilp32d', - '--with-tune=rocket', - '--with-isa-spec=20191213' - ] + def build + @build ||= gcc_verbose(ENV['CC']).lines + .find { |line| line.start_with? 'Target: ' } + .split(' ').last.strip + end + + def configuration(prefix) + case @architecture + when :rv32 + ['arch=rv32imafdc', 'abi=ilp32d', 'tune=rocket', 'isa-spec=20191213'].map do |option| + "-#{prefix}#{option}" + end else [] end @@ -63,29 +72,7 @@ def gcc_verbose(gcc_binary) output end -def find_build_target(gcc_version, target) - gcc_binary = 'gcc' - output = gcc_verbose gcc_binary - - if output.start_with? 'Apple clang' - gcc_binary = "gcc-#{gcc_version.split('.').first}" - output = gcc_verbose gcc_binary - end - result = output - .lines - .each_with_object(BuildTarget.new) do |line, accumulator| - if line.start_with? 'Target: ' - accumulator.build = line.split(' ').last.strip - elsif line.start_with? 'COLLECT_GCC' - accumulator.gcc = line.split('=').last.strip - end - end - result.tmp = TMP - result.target = target - result -end - -def download_and_unarchive(url, target) +def download_and_unarchive(url) puts Term::ANSIColor.green "Downloading #{url}." case File.extname url.path @@ -98,7 +85,7 @@ def download_and_unarchive(url, target) else raise "Unsupported archive type #{url.path}." end - + target = TMP + 'tools' Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http| request = Net::HTTP::Get.new url.request_uri @@ -134,23 +121,37 @@ def configure_make_install(source_directory, configure_options, env, cwd) system env, 'make', 'install', chdir: cwd.to_path, exception: true end +def major(version) + version.split('.').first +end + +def environment + binary_suffix = '' + output = gcc_verbose 'gcc' + + if output.start_with? 'Apple clang' + binary_suffix = "-#{major(GCC_VERSION)}" + end + + ENV['CC'] = "gcc#{binary_suffix}" + ENV['CXX'] = "g++#{binary_suffix}" +end + # Build cross binutils. def binutils(options) source_directory = download_and_unarchive( - URI.parse("https://ftp.gnu.org/gnu/binutils/binutils-#{BINUTILS_VERSION}.tar.xz"), - options.tools) + URI.parse("https://ftpmirror.gnu.org/gnu/binutils/binutils-#{BINUTILS_VERSION}.tar.xz")) cwd = source_directory.dirname + 'build-binutils' cwd.mkpath options.rootfs.mkpath + options.sysroot.mkpath - env = { - 'CC' => options.gcc, - 'CXX' => options.gxx - } + env = ENV.slice 'CC', 'CXX' configure_options = [ "--prefix=#{options.rootfs.realpath}", "--target=#{options.target}", + "--with-sysroot=#{options.sysroot.realpath}", '--disable-nls', '--enable-gprofng=no', '--disable-werror', @@ -163,16 +164,14 @@ end # Build stage 1 GCC. def gcc1(options) source_directory = download_and_unarchive( - URI.parse("https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz"), - options.tools) + URI.parse("https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz")) cwd = source_directory.dirname + 'build-gcc' cwd.mkpath options.rootfs.mkpath - options.sysroot.mkpath system 'contrib/download_prerequisites', chdir: source_directory.to_path, exception: true - configure_options = options.configuration + [ + configure_options = options.configuration('-with-') + [ "--prefix=#{options.rootfs.realpath}", "--with-sysroot=#{options.sysroot.realpath}", '--enable-languages=c,c++', @@ -197,8 +196,8 @@ def gcc1(options) ] flags = '-O2 -fPIC' env = { - 'CC' => options.gcc, - 'CXX' => options.gxx, + 'CC' => ENV['CC'], + 'CXX' => ENV['CXX'], 'CFLAGS' => flags, 'CXXFLAGS' => flags, 'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}" @@ -209,9 +208,8 @@ end # Copy glibc headers. def headers(options) source_directory = download_and_unarchive( - URI.parse("https://ftp.gnu.org/gnu/glibc/glibc-#{GLIBC_VERSION}.tar.xz"), - options.tools) - include_directory = options.tools + 'include' + URI.parse("https://ftpmirror.gnu.org/gnu/glibc/glibc-#{GLIBC_VERSION}.tar.xz")) + include_directory = TMP + 'tools/include' include_directory.mkpath FileUtils.cp (source_directory + 'elf/elf.h'), (include_directory + 'elf.h') @@ -220,17 +218,16 @@ end # Build linux kernel. def kernel(options) cwd = download_and_unarchive( - URI.parse("https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-#{KERNEL_VERSION}.tar.xz"), - options.tools) + URI.parse("https://cdn.kernel.org/pub/linux/kernel/v#{major(KERNEL_VERSION)}.x/linux-#{KERNEL_VERSION}.tar.xz")) env = { 'CROSS_COMPILE' => "#{options.target}-", 'ARCH' => 'riscv', 'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}", - 'HOSTCFLAGS' => "-D_UUID_T -D__GETHOSTUUID_H -I#{options.tools.realpath + 'include'}" + 'HOSTCFLAGS' => "-D_UUID_T -D__GETHOSTUUID_H -I#{TMP + 'tools/include'}" } system env, 'make', 'rv32_defconfig', chdir: cwd.to_path, exception: true - system env, 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path, exception: true + # system env, 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path, exception: true system env, 'make', 'headers', chdir: cwd.to_path, exception: true user_directory = options.sysroot + 'usr' @@ -241,7 +238,7 @@ end # Build glibc. def glibc(options) - source_directory = options.tools + "glibc-#{GLIBC_VERSION}" + source_directory = TMP + "tools/glibc-#{GLIBC_VERSION}" configure_options = [ '--prefix=/usr', "--host=#{options.target}", @@ -258,7 +255,9 @@ def glibc(options) bin = options.rootfs.realpath + 'bin' env = { 'PATH' => "#{bin}:#{ENV['PATH']}", - 'MAKE' => 'make' # Otherwise it uses gnumake which can be different and too old. + 'MAKE' => 'make', # Otherwise it uses gnumake which can be different and too old. + 'CC' => "#{options.target}-gcc", + 'CXX' => "#{options.target}-g++" } cwd = source_directory.dirname + 'build-glibc' cwd.mkpath @@ -271,13 +270,13 @@ end # Build stage 2 GCC. def gcc2(options) - source_directory = options.tools + "gcc-#{GCC_VERSION}" - cwd = options.tools + 'build-gcc' + source_directory = TMP + "tools/gcc-#{GCC_VERSION}" + cwd = TMP + 'tools/build-gcc' FileUtils.rm_rf cwd cwd.mkpath - configure_options = options.configuration + [ + configure_options = options.configuration('-with-') + [ "--prefix=#{options.rootfs.realpath}", "--with-sysroot=#{options.sysroot.realpath}", '--enable-languages=c,c++,lto', @@ -294,9 +293,8 @@ def gcc2(options) "--target=#{options.target}", "--build=#{options.build}", "--host=#{options.build}" - ] - flags = '-O2 -fPIC' + flags = '-O2 -fPIC -I/opt/homebrew/opt/flex/include' env = { 'CFLAGS' => flags, 'CXXFLAGS' => flags, @@ -305,10 +303,12 @@ def gcc2(options) configure_make_install source_directory, configure_options, env, cwd end -target = ARGV.fetch 0, 'riscv32-unknown-linux-gnu' -options = find_build_target GCC_VERSION, target +target = ARGV.fetch 0, 'riscv32' +options = BuildTarget.new target + +(TMP + 'tools').mkpath +environment -options.tools.mkpath binutils options gcc1 options headers options