summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-01-04 17:14:00 +0100
committerEugen Wissner <belka@caraus.de>2026-01-04 21:04:43 +0100
commit955161b36e9525d7b5ab5fa053c9caf16746a354 (patch)
treee6a83a99260df196fe25f67d17952fc5ba348709
parentf86d06236cefe3de17965f641586c14a9ccb9f82 (diff)
downloadelna-955161b36e9525d7b5ab5fa053c9caf16746a354.tar.gz
Use ninja for build
-rw-r--r--Rakefile121
1 files changed, 58 insertions, 63 deletions
diff --git a/Rakefile b/Rakefile
index 4e8cbbc..1f175f8 100644
--- a/Rakefile
+++ b/Rakefile
@@ -17,10 +17,6 @@ CLEAN.include 'build/boot', 'build/valid'
CLEAN.include 'doc/*.pdf'
CLOBBER.include 'build'
-def compile(*arguments)
- sh(ENV.fetch('CC', 'gcc'), '-fpie', '-g', *arguments)
-end
-
def run(exe)
ENV.fetch('QEMU', '').split << exe
end
@@ -50,77 +46,76 @@ task :convert do
end
end
-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
+file 'build/build.ninja' => ['build'] do |t|
+ File.open t.name, 'w' do |f|
+ f << <<~NINJA
+ builddir = build
+ cflags = -fpie -g
-rule /^build\/[[:alpha:]]+\/stage[[:digit:]]+\/cl.o$/ => ->(match) {
- match.ext('.s')
-} do |t|
- compile('-c', '-o', t.name, *t.prerequisites)
-end
+ rule cc
+ command = gcc $cflags -nostdlib -o $out $in
-STAGES.each do |stage|
- previous = stage.delete_prefix('stage').to_i.pred
+ rule as
+ command = gcc $cflags -c -o $out $in
- directory "build/valid/#{stage}"
- directory "build/boot/#{stage}"
+ rule link1
+ command = ld -o $out $in
- file "build/valid/#{stage}/cl.s" => ["build/boot/#{stage}/cl", "boot/#{stage}/cl.elna", "build/valid/#{stage}"] do |t|
- exe, source = t.prerequisites
+ rule link2
+ command = ld -o $out --dynamic-linker /lib32/ld-linux-riscv32-ilp32d.so.1 /usr/lib/crt1.o /usr/lib/crti.o -lc $in /usr/lib/crtn.o
- cat_arguments = ['cat', source]
- last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, run(exe))
+ rule boot1
+ command = build/boot/stage1/cl < \$in > \$out
- IO.copy_stream last_stdout, t.name
- end
+ rule valid1
+ command = build/valid/stage1/cl < \$in > \$out
+ NINJA
+ STAGES.each do |stage|
+ stage_number = stage.delete_prefix('stage').to_i
- file "build/boot/#{stage}/cl.s" => ["build/valid/stage#{previous}/cl", "boot/#{stage}/cl.elna", "build/boot/#{stage}"] do |t|
- exe, source = t.prerequisites
+ f << <<~NINJA
- cat_arguments = ['cat', source]
- last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, run(exe))
+ rule valid#{stage_number}
+ command = build/valid/stage#{stage_number}/cl < \$in > \$out
- IO.copy_stream last_stdout, t.name
+ rule boot#{stage_number}
+ command = build/boot/stage#{stage_number}/cl < \$in > \$out
+ NINJA
+ end
+ f << <<~NINJA
+
+ build build/boot/stage1/cl: cc boot/stage1.s
+
+ build build/valid/stage1/cl.s: boot1 boot/stage1.s | build/boot/stage1/cl
+ build build/valid/stage1/cl.o: as build/valid/stage1/cl.s
+ build build/valid/stage1/cl: link1 build/valid/stage1/cl.o
+ NINJA
+ STAGES.each do |stage|
+ stage_number = stage.delete_prefix('stage').to_i
+
+ arguments_path = Pathname.new('boot') + stage + 'linker.arg'
+ if arguments_path.exist?
+ link = 'link2'
+ else
+ link = 'link1'
+ end
+ boot_stage = "build/boot/stage#{stage_number}"
+ valid_stage = "build/valid/stage#{stage_number}"
+ f << <<~NINJA
+
+ build #{boot_stage}/cl.s: valid#{stage_number.pred} boot/stage#{stage_number}/cl.elna | build/valid/stage#{stage_number.pred}/cl
+ build #{boot_stage}/cl.o: as #{boot_stage}/cl.s
+ build #{boot_stage}/cl: #{link} #{boot_stage}/cl.o
+
+ build #{valid_stage}/cl.s: boot#{stage_number} boot/stage#{stage_number}/cl.elna | #{boot_stage}/cl
+ build #{valid_stage}/cl.o: as #{valid_stage}/cl.s
+ build #{valid_stage}/cl: #{link} #{valid_stage}/cl.o
+ NINJA
+ end
+ f << "\ndefault build/valid/stage18/cl\n"
end
end
-#
-# Stage 1.
-#
-
-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]
- last_stdout, wait_threads = Open3.pipeline_r(cat_arguments, run(exe.first))
-
- IO.copy_stream last_stdout, t.name
-end
-
-file 'build/boot/stage1/cl' => ['build/boot/stage1', 'boot/stage1.s'] do |t|
- source = t.prerequisites.select { |prerequisite| prerequisite.end_with? '.s' }
-
- compile('-nostdlib', '-o', t.name, *source)
-end
-
rule '.pdf' => '.adoc' do |t|
Asciidoctor.convert_file t.source, backend: 'pdf', safe: :safe
end