cross_toolchain.rb: Use GNU mirrors
This commit is contained in:
@@ -13,41 +13,50 @@ require 'fileutils'
|
|||||||
require 'pathname'
|
require 'pathname'
|
||||||
require 'term/ansicolor'
|
require 'term/ansicolor'
|
||||||
|
|
||||||
BINUTILS_VERSION = '2.44'
|
BINUTILS_VERSION = '2.45'
|
||||||
GLIBC_VERSION = '2.41'
|
GLIBC_VERSION = '2.42'
|
||||||
KERNEL_VERSION = '5.15.185'
|
KERNEL_VERSION = '6.1.150'
|
||||||
GCC_VERSION = "15.1.0"
|
GCC_VERSION = "15.2.0"
|
||||||
|
|
||||||
TMP = Pathname.new('./tmp')
|
TMP = Pathname.new('./tmp')
|
||||||
|
|
||||||
class BuildTarget
|
class BuildTarget
|
||||||
attr_accessor(:build, :gcc, :target, :tmp)
|
def initialize(architecture)
|
||||||
|
case architecture
|
||||||
def gxx
|
when /^r(isc)?v32$/
|
||||||
@gcc.gsub 'c', '+'
|
@architecture = :rv32
|
||||||
|
else
|
||||||
|
raise "Unsupported architecture '#{architecture}'."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def sysroot
|
def sysroot
|
||||||
tmp + 'sysroot'
|
TMP + 'sysroot'
|
||||||
end
|
end
|
||||||
|
|
||||||
def rootfs
|
def rootfs
|
||||||
tmp + 'rootfs'
|
TMP + 'rootfs'
|
||||||
end
|
end
|
||||||
|
|
||||||
def tools
|
def target
|
||||||
tmp + 'tools'
|
case @architecture
|
||||||
|
when :rv32
|
||||||
|
'riscv32-unknown-linux-gnu'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def configuration
|
def build
|
||||||
case target
|
@build ||= gcc_verbose(ENV['CC']).lines
|
||||||
when /^riscv[[:digit:]]+-/
|
.find { |line| line.start_with? 'Target: ' }
|
||||||
[
|
.split(' ').last.strip
|
||||||
'--with-arch=rv32imafdc',
|
end
|
||||||
'--with-abi=ilp32d',
|
|
||||||
'--with-tune=rocket',
|
def configuration(prefix)
|
||||||
'--with-isa-spec=20191213'
|
case @architecture
|
||||||
]
|
when :rv32
|
||||||
|
['arch=rv32imafdc', 'abi=ilp32d', 'tune=rocket', 'isa-spec=20191213'].map do |option|
|
||||||
|
"-#{prefix}#{option}"
|
||||||
|
end
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
@@ -63,29 +72,7 @@ def gcc_verbose(gcc_binary)
|
|||||||
output
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_build_target(gcc_version, target)
|
def download_and_unarchive(url)
|
||||||
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)
|
|
||||||
puts Term::ANSIColor.green "Downloading #{url}."
|
puts Term::ANSIColor.green "Downloading #{url}."
|
||||||
|
|
||||||
case File.extname url.path
|
case File.extname url.path
|
||||||
@@ -98,7 +85,7 @@ def download_and_unarchive(url, target)
|
|||||||
else
|
else
|
||||||
raise "Unsupported archive type #{url.path}."
|
raise "Unsupported archive type #{url.path}."
|
||||||
end
|
end
|
||||||
|
target = TMP + 'tools'
|
||||||
Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http|
|
Net::HTTP.start(url.host, url.port, use_ssl: url.scheme == 'https') do |http|
|
||||||
request = Net::HTTP::Get.new url.request_uri
|
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
|
system env, 'make', 'install', chdir: cwd.to_path, exception: true
|
||||||
end
|
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.
|
# Build cross binutils.
|
||||||
def binutils(options)
|
def binutils(options)
|
||||||
source_directory = download_and_unarchive(
|
source_directory = download_and_unarchive(
|
||||||
URI.parse("https://ftp.gnu.org/gnu/binutils/binutils-#{BINUTILS_VERSION}.tar.xz"),
|
URI.parse("https://ftpmirror.gnu.org/gnu/binutils/binutils-#{BINUTILS_VERSION}.tar.xz"))
|
||||||
options.tools)
|
|
||||||
|
|
||||||
cwd = source_directory.dirname + 'build-binutils'
|
cwd = source_directory.dirname + 'build-binutils'
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
options.rootfs.mkpath
|
options.rootfs.mkpath
|
||||||
|
options.sysroot.mkpath
|
||||||
|
|
||||||
env = {
|
env = ENV.slice 'CC', 'CXX'
|
||||||
'CC' => options.gcc,
|
|
||||||
'CXX' => options.gxx
|
|
||||||
}
|
|
||||||
configure_options = [
|
configure_options = [
|
||||||
"--prefix=#{options.rootfs.realpath}",
|
"--prefix=#{options.rootfs.realpath}",
|
||||||
"--target=#{options.target}",
|
"--target=#{options.target}",
|
||||||
|
"--with-sysroot=#{options.sysroot.realpath}",
|
||||||
'--disable-nls',
|
'--disable-nls',
|
||||||
'--enable-gprofng=no',
|
'--enable-gprofng=no',
|
||||||
'--disable-werror',
|
'--disable-werror',
|
||||||
@@ -163,16 +164,14 @@ end
|
|||||||
# Build stage 1 GCC.
|
# Build stage 1 GCC.
|
||||||
def gcc1(options)
|
def gcc1(options)
|
||||||
source_directory = download_and_unarchive(
|
source_directory = download_and_unarchive(
|
||||||
URI.parse("https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz"),
|
URI.parse("https://gcc.gnu.org/pub/gcc/releases/gcc-#{GCC_VERSION}/gcc-#{GCC_VERSION}.tar.xz"))
|
||||||
options.tools)
|
|
||||||
|
|
||||||
cwd = source_directory.dirname + 'build-gcc'
|
cwd = source_directory.dirname + 'build-gcc'
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
options.rootfs.mkpath
|
options.rootfs.mkpath
|
||||||
options.sysroot.mkpath
|
|
||||||
|
|
||||||
system 'contrib/download_prerequisites', chdir: source_directory.to_path, exception: true
|
system 'contrib/download_prerequisites', chdir: source_directory.to_path, exception: true
|
||||||
configure_options = options.configuration + [
|
configure_options = options.configuration('-with-') + [
|
||||||
"--prefix=#{options.rootfs.realpath}",
|
"--prefix=#{options.rootfs.realpath}",
|
||||||
"--with-sysroot=#{options.sysroot.realpath}",
|
"--with-sysroot=#{options.sysroot.realpath}",
|
||||||
'--enable-languages=c,c++',
|
'--enable-languages=c,c++',
|
||||||
@@ -197,8 +196,8 @@ def gcc1(options)
|
|||||||
]
|
]
|
||||||
flags = '-O2 -fPIC'
|
flags = '-O2 -fPIC'
|
||||||
env = {
|
env = {
|
||||||
'CC' => options.gcc,
|
'CC' => ENV['CC'],
|
||||||
'CXX' => options.gxx,
|
'CXX' => ENV['CXX'],
|
||||||
'CFLAGS' => flags,
|
'CFLAGS' => flags,
|
||||||
'CXXFLAGS' => flags,
|
'CXXFLAGS' => flags,
|
||||||
'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}"
|
'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}"
|
||||||
@@ -209,9 +208,8 @@ end
|
|||||||
# Copy glibc headers.
|
# Copy glibc headers.
|
||||||
def headers(options)
|
def headers(options)
|
||||||
source_directory = download_and_unarchive(
|
source_directory = download_and_unarchive(
|
||||||
URI.parse("https://ftp.gnu.org/gnu/glibc/glibc-#{GLIBC_VERSION}.tar.xz"),
|
URI.parse("https://ftpmirror.gnu.org/gnu/glibc/glibc-#{GLIBC_VERSION}.tar.xz"))
|
||||||
options.tools)
|
include_directory = TMP + 'tools/include'
|
||||||
include_directory = options.tools + 'include'
|
|
||||||
|
|
||||||
include_directory.mkpath
|
include_directory.mkpath
|
||||||
FileUtils.cp (source_directory + 'elf/elf.h'), (include_directory + 'elf.h')
|
FileUtils.cp (source_directory + 'elf/elf.h'), (include_directory + 'elf.h')
|
||||||
@@ -220,17 +218,16 @@ end
|
|||||||
# Build linux kernel.
|
# Build linux kernel.
|
||||||
def kernel(options)
|
def kernel(options)
|
||||||
cwd = download_and_unarchive(
|
cwd = download_and_unarchive(
|
||||||
URI.parse("https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-#{KERNEL_VERSION}.tar.xz"),
|
URI.parse("https://cdn.kernel.org/pub/linux/kernel/v#{major(KERNEL_VERSION)}.x/linux-#{KERNEL_VERSION}.tar.xz"))
|
||||||
options.tools)
|
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
'CROSS_COMPILE' => "#{options.target}-",
|
'CROSS_COMPILE' => "#{options.target}-",
|
||||||
'ARCH' => 'riscv',
|
'ARCH' => 'riscv',
|
||||||
'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}",
|
'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', '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
|
system env, 'make', 'headers', chdir: cwd.to_path, exception: true
|
||||||
|
|
||||||
user_directory = options.sysroot + 'usr'
|
user_directory = options.sysroot + 'usr'
|
||||||
@@ -241,7 +238,7 @@ end
|
|||||||
|
|
||||||
# Build glibc.
|
# Build glibc.
|
||||||
def glibc(options)
|
def glibc(options)
|
||||||
source_directory = options.tools + "glibc-#{GLIBC_VERSION}"
|
source_directory = TMP + "tools/glibc-#{GLIBC_VERSION}"
|
||||||
configure_options = [
|
configure_options = [
|
||||||
'--prefix=/usr',
|
'--prefix=/usr',
|
||||||
"--host=#{options.target}",
|
"--host=#{options.target}",
|
||||||
@@ -258,7 +255,9 @@ def glibc(options)
|
|||||||
bin = options.rootfs.realpath + 'bin'
|
bin = options.rootfs.realpath + 'bin'
|
||||||
env = {
|
env = {
|
||||||
'PATH' => "#{bin}:#{ENV['PATH']}",
|
'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 = source_directory.dirname + 'build-glibc'
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
@@ -271,13 +270,13 @@ end
|
|||||||
|
|
||||||
# Build stage 2 GCC.
|
# Build stage 2 GCC.
|
||||||
def gcc2(options)
|
def gcc2(options)
|
||||||
source_directory = options.tools + "gcc-#{GCC_VERSION}"
|
source_directory = TMP + "tools/gcc-#{GCC_VERSION}"
|
||||||
cwd = options.tools + 'build-gcc'
|
cwd = TMP + 'tools/build-gcc'
|
||||||
|
|
||||||
FileUtils.rm_rf cwd
|
FileUtils.rm_rf cwd
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
|
|
||||||
configure_options = options.configuration + [
|
configure_options = options.configuration('-with-') + [
|
||||||
"--prefix=#{options.rootfs.realpath}",
|
"--prefix=#{options.rootfs.realpath}",
|
||||||
"--with-sysroot=#{options.sysroot.realpath}",
|
"--with-sysroot=#{options.sysroot.realpath}",
|
||||||
'--enable-languages=c,c++,lto',
|
'--enable-languages=c,c++,lto',
|
||||||
@@ -294,9 +293,8 @@ def gcc2(options)
|
|||||||
"--target=#{options.target}",
|
"--target=#{options.target}",
|
||||||
"--build=#{options.build}",
|
"--build=#{options.build}",
|
||||||
"--host=#{options.build}"
|
"--host=#{options.build}"
|
||||||
|
|
||||||
]
|
]
|
||||||
flags = '-O2 -fPIC'
|
flags = '-O2 -fPIC -I/opt/homebrew/opt/flex/include'
|
||||||
env = {
|
env = {
|
||||||
'CFLAGS' => flags,
|
'CFLAGS' => flags,
|
||||||
'CXXFLAGS' => flags,
|
'CXXFLAGS' => flags,
|
||||||
@@ -305,10 +303,12 @@ def gcc2(options)
|
|||||||
configure_make_install source_directory, configure_options, env, cwd
|
configure_make_install source_directory, configure_options, env, cwd
|
||||||
end
|
end
|
||||||
|
|
||||||
target = ARGV.fetch 0, 'riscv32-unknown-linux-gnu'
|
target = ARGV.fetch 0, 'riscv32'
|
||||||
options = find_build_target GCC_VERSION, target
|
options = BuildTarget.new target
|
||||||
|
|
||||||
|
(TMP + 'tools').mkpath
|
||||||
|
environment
|
||||||
|
|
||||||
options.tools.mkpath
|
|
||||||
binutils options
|
binutils options
|
||||||
gcc1 options
|
gcc1 options
|
||||||
headers options
|
headers options
|
||||||
|
Reference in New Issue
Block a user