diff options
Diffstat (limited to 'Rakefile')
| -rw-r--r-- | Rakefile | 59 |
1 files changed, 41 insertions, 18 deletions
@@ -4,19 +4,18 @@ # frozen_string_literal: true require 'open3' +require 'pathname' require 'rake/clean' -STAGES = Dir.glob('boot/stage*.elna') - .collect { |stage| File.basename stage, '.elna' } +STAGES = Dir.glob('boot/stage*') + .collect { |stage| File.basename stage } .sort { |a, b| a.delete_prefix('stage').to_i <=> b.delete_prefix('stage').to_i } + .drop(1) # First assembly stage does not count. CLEAN.include 'build/boot', 'build/valid' -directory 'build/boot' -directory 'build/valid' - -def compile(input, output) - sh ENV.fetch('CC', 'gcc'), '-nostdlib', '-fpie', '-g', '-o', output, input +def compile(*arguments) + sh(ENV.fetch('CC', 'gcc'), '-fpie', '-g', *arguments) end def run(exe) @@ -26,9 +25,9 @@ end 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| +task boot: "build/valid/#{STAGES.last}/cl" +task boot: "build/valid/#{STAGES.last}/cl.s" +task boot: "boot/#{STAGES.last}/cl.elna" do |t| groupped = t.prerequisites.group_by { |stage| File.extname stage }.transform_values(&:first) exe = groupped[''] expected = groupped['.s'] @@ -81,16 +80,33 @@ task :convert do end end -rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+$/ => ->(match) { - "#{match}.s" +rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+\/cl$/ => ->(match) { + "#{match}.o" +} do |t| + arguments_path = Pathname.new('boot') + Pathname.new(t.name).dirname.basename + 'linker.arg' + if arguments_path.exist? + arguments1 = ['--dynamic-linker', '/lib32/ld-linux-riscv32-ilp32d.so.1', '/usr/lib/crt1.o', '/usr/lib/crti.o', '-lc'] + arguments2 = ['/usr/lib/crtn.o'] + else + arguments1 = arguments2 = [] + end + + sh(ENV.fetch('LD', 'ld'), '-o', t.name, *arguments1, *t.prerequisites, *arguments2) +end + +rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+\/cl.o$/ => ->(match) { + match.ext('.s') } do |t| - compile(*t.prerequisites, t.name) + compile('-c', '-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| + directory "build/valid/#{stage}" + directory "build/boot/#{stage}" + + file "build/valid/#{stage}/cl.s" => ["build/boot/#{stage}/cl", "boot/#{stage}/cl.elna", "build/valid/#{stage}"] do |t| exe, source = t.prerequisites cat_arguments = ['cat', source] @@ -99,7 +115,7 @@ STAGES.each do |stage| IO.copy_stream last_stdout, t.name end - file "build/boot/#{stage}.s" => ["build/valid/stage#{previous}", "boot/#{stage}.elna"] do |t| + file "build/boot/#{stage}/cl.s" => ["build/valid/stage#{previous}/cl", "boot/#{stage}/cl.elna", "build/boot/#{stage}"] do |t| exe, source = t.prerequisites cat_arguments = ['cat', source] @@ -113,7 +129,14 @@ end # Stage 1. # -file 'build/valid/stage1.s' => ['build/boot/stage1', 'boot/stage1.s', 'build/valid'] do |t| +directory 'build/valid/stage1' +directory 'build/boot/stage1' + +file 'build/valid/stage1/cl' => ['build/valid/stage1.s'] do |t| + compile('-nostdlib', '-o', t.name, *t.prerequisites) +end + +file 'build/valid/stage1.s' => ['build/boot/stage1/cl', 'boot/stage1.s', 'build/valid/stage1'] do |t| source, exe, = t.prerequisites.partition { |prerequisite| prerequisite.end_with? '.s' } cat_arguments = ['cat', *source] @@ -122,8 +145,8 @@ file 'build/valid/stage1.s' => ['build/boot/stage1', 'boot/stage1.s', 'build/val IO.copy_stream last_stdout, t.name end -file 'build/boot/stage1' => ['build/boot', 'boot/stage1.s'] do |t| +file 'build/boot/stage1/cl' => ['build/boot/stage1', 'boot/stage1.s'] do |t| source = t.prerequisites.select { |prerequisite| prerequisite.end_with? '.s' } - compile(*source, t.name) + compile('-nostdlib', '-o', t.name, *source) end |
