diff options
Diffstat (limited to 'rakelib')
| -rw-r--r-- | rakelib/cross.rake | 34 | ||||
| -rw-r--r-- | rakelib/shared.rb | 1 | ||||
| -rw-r--r-- | rakelib/tester.rake | 80 |
3 files changed, 110 insertions, 5 deletions
diff --git a/rakelib/cross.rake b/rakelib/cross.rake index 3de7d79..700a8dd 100644 --- a/rakelib/cross.rake +++ b/rakelib/cross.rake @@ -4,15 +4,14 @@ require 'net/http' require 'rake/clean' require 'open3' require 'etc' +require_relative 'shared' GCC_VERSION = "14.2.0" BINUTILS_VERSION = '2.43.1' GLIBC_VERSION = '2.40' KERNEL_VERSION = '5.15.166' -TMP = Pathname.new('./build') - -CLEAN.include TMP +CLOBBER.include TMP class BuildTarget attr_accessor(:build, :gcc, :target, :tmp) @@ -87,11 +86,16 @@ def download_and_unarchive(url, target) download_and_unarchive URI.parse(response['location']) when Net::HTTPSuccess Open3.popen2 'tar', '-C', target.to_path, archive_type, '-xv' do |stdin, stdout, wait_thread| - stdout.close + Thread.new do + stdout.each { |line| puts line } + end response.read_body do |chunk| stdin.write chunk end + stdin.close + + wait_thread.value end else response.error! @@ -301,7 +305,27 @@ namespace :cross do sh env, 'make', '-j', Etc.nprocessors.to_s, chdir: cwd.to_path sh env, 'make', 'install', chdir: cwd.to_path end + + task :init, [:target] do |_, args| + options = find_build_target GCC_VERSION, args + env = { + 'PATH' => "#{options.rootfs.realpath + 'bin'}:#{ENV['PATH']}" + } + sh env, 'riscv32-unknown-linux-gnu-gcc', + '-ffreestanding', '-static', + '-o', (options.tools + 'init').to_path, + 'tools/init.c' + end end -task cross: ['cross:binutils', 'cross:gcc1', 'cross:headers', 'cross:kernel', 'cross:glibc', 'cross:gcc2'] do +desc 'Build cross toolchain' +task cross: [ + 'cross:binutils', + 'cross:gcc1', + 'cross:headers', + 'cross:kernel', + 'cross:glibc', + 'cross:gcc2', + 'cross:init' +] do end diff --git a/rakelib/shared.rb b/rakelib/shared.rb new file mode 100644 index 0000000..8ecd8cb --- /dev/null +++ b/rakelib/shared.rb @@ -0,0 +1 @@ +TMP = Pathname.new('./build') diff --git a/rakelib/tester.rake b/rakelib/tester.rake new file mode 100644 index 0000000..ef05556 --- /dev/null +++ b/rakelib/tester.rake @@ -0,0 +1,80 @@ +require 'open3' +require 'rake/clean' +require_relative 'shared' + +CLEAN.include(TMP + 'riscv') + +LINKER = 'build/rootfs/riscv32-unknown-linux-gnu/bin/ld' + +namespace :test do + test_sources = FileList['tests/vm/*.elna'] + compiler = `cabal list-bin elna`.strip + object_directory = TMP + 'riscv/tests' + root_directory = TMP + 'riscv/root' + executable_directory = root_directory + 'tests' + expectation_directory = root_directory + 'expectations' + init = TMP + 'riscv/root/init' + + directory root_directory + directory object_directory + directory executable_directory + directory expectation_directory + + test_files = test_sources.flat_map do |test_source| + test_basename = File.basename(test_source, '.elna') + test_object = object_directory + test_basename.ext('.o') + + file test_object => [test_source, object_directory] do + sh compiler, '--output', test_object.to_path, test_source + end + test_executable = executable_directory + test_basename + + file test_executable => [test_object, executable_directory] do + sh LINKER, '-o', test_executable.to_path, test_object.to_path + end + expectation_name = test_basename.ext '.txt' + source_expectation = "tests/expectations/#{expectation_name}" + target_expectation = expectation_directory + expectation_name + + file target_expectation => [source_expectation, expectation_directory] do + cp source_expectation, target_expectation + end + + [test_executable, target_expectation] + end + + file init => [root_directory] do |task| + cp (TMP + 'tools/init'), task.name + end + test_files << init << executable_directory << expectation_directory + + file (TMP + 'riscv/root.cpio') => test_files do |task| + root_files = task.prerequisites + .map { |prerequisite| Pathname.new(prerequisite).relative_path_from(root_directory).to_path } + + File.open task.name, 'wb' do |cpio_file| + cpio_options = { + chdir: root_directory.to_path + } + cpio_stream = Open3.popen2 'cpio', '-o', '--format=newc', cpio_options do |stdin, stdout, wait_thread| + stdin.write root_files.join("\n") + stdin.close + stdout.each { |chunk| cpio_file.write chunk } + wait_thread.value + end + end + end + + task :vm => (TMP + 'riscv/root.cpio') do |task| + kernels = FileList.glob(TMP + 'tools/linux-*/arch/riscv/boot/Image') + + sh 'qemu-system-riscv32', + '-nographic', + '-M', 'virt', + '-bios', 'default', + '-kernel', kernels.first, + '-append', 'quiet panic=1', + '-initrd', task.prerequisites.first, + '-no-reboot' + end +end |
