97 lines
3.1 KiB
Ruby
97 lines
3.1 KiB
Ruby
require 'open3'
|
|
require 'rake/clean'
|
|
require_relative 'shared'
|
|
|
|
CLEAN.include(TMP + 'riscv')
|
|
|
|
LINKER = 'build/rootfs/riscv32-unknown-linux-gnu/bin/ld'
|
|
AS = 'build/rootfs/riscv32-unknown-linux-gnu/bin/as'
|
|
|
|
namespace :test do
|
|
test_sources = FileList['tests/vm/*.elna', 'tests/vm/*.s']
|
|
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'
|
|
builtin = TMP + 'riscv/builtin.o'
|
|
|
|
directory root_directory
|
|
directory object_directory
|
|
directory executable_directory
|
|
directory expectation_directory
|
|
|
|
file builtin => ['tools/builtin.s', object_directory] do |task|
|
|
sh AS, '-o', task.name, task.prerequisites.first
|
|
end
|
|
|
|
test_files = test_sources.flat_map do |test_source|
|
|
test_basename = File.basename(test_source, '.*')
|
|
test_object = object_directory + test_basename.ext('.o')
|
|
|
|
file test_object => [test_source, object_directory] do |task|
|
|
case File.extname(task.prerequisites.first)
|
|
when '.s'
|
|
sh AS, '-mno-relax', '-o', task.name, task.prerequisites.first
|
|
when '.elna'
|
|
sh compiler, '--output', task.name, task.prerequisites.first
|
|
else
|
|
raise "Unknown source file extension #{task.prerequisites.first}"
|
|
end
|
|
end
|
|
test_executable = executable_directory + test_basename
|
|
|
|
file test_executable => [test_object, executable_directory, builtin] do |task|
|
|
objects = task.prerequisites.filter { |prerequisite| File.file? prerequisite }
|
|
|
|
sh LINKER, '-o', test_executable.to_path, *objects
|
|
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
|