# This Source Code Form is subject to the terms of the Mozilla Public License, # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. # frozen_string_literal: true require 'open3' require 'rake/clean' CROSS_GCC = '../eugenios/build/rootfs/bin/riscv32-unknown-linux-gnu-gcc' SYSROOT = '../eugenios/build/sysroot' QEMU = 'qemu-riscv32' STAGES = Dir.glob('boot/stage*.elna').collect { |stage| File.basename stage, '.elna' }.sort CLEAN.include 'build/boot', 'build/valid' directory 'build/boot' directory 'build/valid' task default: :boot desc 'Final stage' task boot: "build/valid/#{STAGES.last}" task boot: "build/valid/#{STAGES.last}.s" task boot: "boot/#{STAGES.last}.elna" do |t| groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first) exe = groupped[''] expected = groupped['.s'] source = groupped['.elna'] cat_arguments = ['cat', source] compiler_arguments = [QEMU, '-L', SYSROOT, exe] diff_arguments = ['diff', '-Nur', '--text', expected, '-'] Open3.pipeline(cat_arguments, compiler_arguments, diff_arguments) end desc 'Convert previous stage language into the current stage language' task :convert do File.open('boot/stage4.elna', 'w') do |current_stage| li_value = nil File.readlines('boot/stage3.elna').each do |line| current_stage << line end end end rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+$/ => ->(match) { "#{match}.s" } do |t| sh CROSS_GCC, '-nostdlib', '-o', t.name, *t.prerequisites end STAGES.each do |stage| previous = stage.delete_prefix('stage').to_i.pred file "build/valid/#{stage}.s" => ["build/boot/#{stage}", "boot/#{stage}.elna"] do |t| exe, source = t.prerequisites cat_arguments = ['cat', source] compiler_arguments = [QEMU, '-L', SYSROOT, exe] last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, compiler_arguments) IO.copy_stream last_stdout, t.name end file "build/boot/#{stage}.s" => ["build/valid/stage#{previous}", "boot/#{stage}.elna"] do |t| exe, source = t.prerequisites cat_arguments = ['cat', source] compiler_arguments = [QEMU, '-L', SYSROOT, exe] last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, compiler_arguments) IO.copy_stream last_stdout, t.name end end # # Stage 1. # file 'build/valid/stage1.s' => ['build/boot/stage1', 'boot/stage1.s', 'build/valid'] do |t| source, exe, = t.prerequisites.partition { |prerequisite| prerequisite.end_with? '.s' } cat_arguments = ['cat', *source] compiler_arguments = [QEMU, '-L', SYSROOT, *exe] last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, compiler_arguments) IO.copy_stream last_stdout, t.name end file 'build/boot/stage1' => ['build/boot', 'boot/stage1.s'] do |t| source = t.prerequisites.select { |prerequisite| prerequisite.end_with? '.s' } sh CROSS_GCC, '-nostdlib', '-o', t.name, *source end