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 # Directories should come first. test_files.unshift executable_directory, expectation_directory, init 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