2019-04-30 11:43:40 +02:00
const std = @import ( " std " ) ;
2019-09-03 20:13:26 +02:00
const builtin = @import ( " builtin " ) ;
2020-06-23 13:43:52 +02:00
const rt = @import ( " test/runtime_test.zig " ) ;
const RuntimeStep = rt . RuntimeStep ;
2019-09-03 20:13:26 +02:00
const Builder = std . build . Builder ;
2019-09-16 23:19:21 +02:00
const LibExeObjStep = std . build . LibExeObjStep ;
2019-09-03 20:13:26 +02:00
const Step = std . build . Step ;
2020-04-12 23:26:34 +02:00
const Target = std . Target ;
const CrossTarget = std . zig . CrossTarget ;
2019-09-03 20:13:26 +02:00
const fs = std . fs ;
2019-09-08 21:48:23 +02:00
const Mode = builtin . Mode ;
2020-06-23 13:43:52 +02:00
const TestMode = rt . TestMode ;
const ArrayList = std . ArrayList ;
2019-09-03 20:13:26 +02:00
2020-06-02 19:54:41 +02:00
const x86_i686 = CrossTarget {
. cpu_arch = . i386 ,
. os_tag = . freestanding ,
. cpu_model = . { . explicit = & Target . x86 . cpu . _i686 } ,
} ;
2019-09-08 21:48:23 +02:00
2020-06-02 19:54:41 +02:00
pub fn build ( b : * Builder ) ! void {
2020-06-22 21:18:19 +02:00
const target = b . standardTargetOptions ( . { . whitelist = & [ _ ] CrossTarget { x86_i686 } , . default_target = x86_i686 } ) ;
const arch = switch ( target . getCpuArch ( ) ) {
. i386 = > " x86 " ,
else = > unreachable ,
2019-09-08 21:48:23 +02:00
} ;
2019-09-16 23:19:21 +02:00
2020-01-15 17:30:30 +01:00
const fmt_step = b . addFmt ( & [ _ ] [ ] const u8 {
" build.zig " ,
" src " ,
" test " ,
} ) ;
b . default_step . dependOn ( & fmt_step . step ) ;
2020-01-09 14:08:00 +01:00
const main_src = " src/kernel/kmain.zig " ;
2020-06-02 19:41:54 +02:00
const arch_root = " src/kernel/arch " ;
const constants_path = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { arch_root , arch , " constants.zig " } ) ;
2020-06-23 13:43:52 +02:00
const linker_script_path = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { arch_root , arch , " link.ld " } ) ;
const output_iso = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { b . exe_dir , " pluto.iso " } ) ;
const iso_dir_path = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { b . exe_dir , " iso " } ) ;
const boot_path = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { b . exe_dir , " iso " , " boot " } ) ;
const modules_path = try fs . path . join ( b . allocator , & [ _ ] [ ] const u8 { b . exe_dir , " iso " , " modules " } ) ;
2020-01-09 14:08:00 +01:00
2019-09-17 20:00:33 +02:00
const build_mode = b . standardReleaseOptions ( ) ;
2020-06-23 13:43:52 +02:00
comptime var test_mode_desc : [ ] const u8 = " \n " ;
inline for ( @typeInfo ( TestMode ) . Enum . fields ) | field | {
const tm = @field ( TestMode , field . name ) ;
test_mode_desc = test_mode_desc + + field . name + + " ( " + + TestMode . getDescription ( tm ) + + " ) " ;
test_mode_desc = test_mode_desc + + " \n " ;
}
const test_mode = b . option ( TestMode , " test-mode " , " Run a specific runtime test. This option is for the rt-test step. Available options: " + + test_mode_desc ) orelse . None ;
const disable_display = b . option ( bool , " disable-display " , " Disable the qemu window " ) orelse false ;
2019-04-17 18:40:26 +02:00
2020-06-02 19:54:41 +02:00
const exec = b . addExecutable ( " pluto.elf " , main_src ) ;
2019-09-16 23:19:21 +02:00
exec . addPackagePath ( " constants " , constants_path ) ;
2020-01-09 14:08:00 +01:00
exec . setOutputDir ( b . cache_root ) ;
2020-06-23 13:43:52 +02:00
exec . addBuildOption ( TestMode , " test_mode " , test_mode ) ;
2020-01-09 14:08:00 +01:00
exec . setBuildMode ( build_mode ) ;
2020-06-02 19:41:54 +02:00
exec . setLinkerScriptPath ( linker_script_path ) ;
2020-04-12 23:26:34 +02:00
exec . setTarget ( target ) ;
2019-05-31 08:41:28 +02:00
2020-06-02 19:54:41 +02:00
const make_iso = switch ( target . getCpuArch ( ) ) {
. i386 = > b . addSystemCommand ( & [ _ ] [ ] const u8 { " ./makeiso.sh " , boot_path , modules_path , iso_dir_path , exec . getOutputPath ( ) , output_iso } ) ,
else = > unreachable ,
} ;
2020-01-09 14:08:00 +01:00
make_iso . step . dependOn ( & exec . step ) ;
2020-06-23 13:43:52 +02:00
2020-01-09 14:08:00 +01:00
b . default_step . dependOn ( & make_iso . step ) ;
2019-04-17 18:40:26 +02:00
2020-01-09 14:08:00 +01:00
const test_step = b . step ( " test " , " Run tests " ) ;
2020-06-23 13:43:52 +02:00
const mock_path = " \" ../../test/mock/kernel/ \" " ;
const arch_mock_path = " \" ../../../../test/mock/kernel/ \" " ;
const unit_tests = b . addTest ( main_src ) ;
unit_tests . setBuildMode ( build_mode ) ;
unit_tests . setMainPkgPath ( " . " ) ;
unit_tests . addPackagePath ( " constants " , constants_path ) ;
unit_tests . addBuildOption ( TestMode , " test_mode " , test_mode ) ;
unit_tests . addBuildOption ( [ ] const u8 , " mock_path " , mock_path ) ;
unit_tests . addBuildOption ( [ ] const u8 , " arch_mock_path " , arch_mock_path ) ;
if ( builtin . os . tag ! = . windows ) {
unit_tests . enable_qemu = true ;
2020-01-09 14:08:00 +01:00
}
2019-04-17 18:40:26 +02:00
2020-06-23 13:43:52 +02:00
unit_tests . setTarget ( . { . cpu_arch = target . cpu_arch } ) ;
test_step . dependOn ( & unit_tests . step ) ;
2019-10-01 18:35:15 +02:00
2020-06-23 13:43:52 +02:00
const rt_test_step = b . step ( " rt-test " , " Run runtime tests " ) ;
const build_mode_str = switch ( build_mode ) {
. Debug = > " " ,
. ReleaseSafe = > " -Drelease-safe " ,
. ReleaseFast = > " -Drelease-fast " ,
. ReleaseSmall = > " -Drelease-small " ,
2019-09-16 23:19:21 +02:00
} ;
2020-06-23 13:43:52 +02:00
var qemu_args_al = ArrayList ( [ ] const u8 ) . init ( b . allocator ) ;
defer qemu_args_al . deinit ( ) ;
switch ( target . getCpuArch ( ) ) {
. i386 = > try qemu_args_al . append ( " qemu-system-i386 " ) ,
else = > unreachable ,
}
try qemu_args_al . append ( " -serial " ) ;
try qemu_args_al . append ( " stdio " ) ;
switch ( target . getCpuArch ( ) ) {
. i386 = > {
try qemu_args_al . append ( " -boot " ) ;
try qemu_args_al . append ( " d " ) ;
try qemu_args_al . append ( " -cdrom " ) ;
try qemu_args_al . append ( output_iso ) ;
2020-06-02 19:54:41 +02:00
} ,
2020-06-23 13:43:52 +02:00
else = > unreachable ,
}
if ( disable_display ) {
try qemu_args_al . append ( " -display " ) ;
try qemu_args_al . append ( " none " ) ;
}
var qemu_args = qemu_args_al . toOwnedSlice ( ) ;
const rt_step = RuntimeStep . create ( b , test_mode , qemu_args ) ;
rt_step . step . dependOn ( & make_iso . step ) ;
rt_test_step . dependOn ( & rt_step . step ) ;
const run_step = b . step ( " run " , " Run with qemu " ) ;
const run_debug_step = b . step ( " debug-run " , " Run with qemu and wait for a gdb connection " ) ;
2019-10-01 18:35:15 +02:00
const qemu_cmd = b . addSystemCommand ( qemu_args ) ;
const qemu_debug_cmd = b . addSystemCommand ( qemu_args ) ;
2020-01-01 20:12:36 +01:00
qemu_debug_cmd . addArgs ( & [ _ ] [ ] const u8 { " -s " , " -S " } ) ;
2019-09-16 23:19:21 +02:00
2020-01-09 14:08:00 +01:00
qemu_cmd . step . dependOn ( & make_iso . step ) ;
qemu_debug_cmd . step . dependOn ( & make_iso . step ) ;
2019-10-01 18:35:15 +02:00
run_step . dependOn ( & qemu_cmd . step ) ;
run_debug_step . dependOn ( & qemu_debug_cmd . step ) ;
2019-04-30 11:43:40 +02:00
2019-10-01 18:35:15 +02:00
const debug_step = b . step ( " debug " , " Debug with gdb and connect to a running qemu instance " ) ;
2020-01-09 14:08:00 +01:00
const symbol_file_arg = try std . mem . join ( b . allocator , " " , & [ _ ] [ ] const u8 { " symbol-file " , exec . getOutputPath ( ) } ) ;
2020-01-01 20:12:36 +01:00
const debug_cmd = b . addSystemCommand ( & [ _ ] [ ] const u8 {
2020-06-02 19:54:41 +02:00
" gdb-multiarch " ,
2019-09-03 20:13:26 +02:00
" -ex " ,
2019-09-12 00:25:34 +02:00
symbol_file_arg ,
2020-06-02 19:54:41 +02:00
" -ex " ,
" set architecture auto " ,
2019-09-03 20:13:26 +02:00
} ) ;
2020-01-01 20:12:36 +01:00
debug_cmd . addArgs ( & [ _ ] [ ] const u8 {
2019-09-03 20:13:26 +02:00
" -ex " ,
" target remote localhost:1234 " ,
} ) ;
debug_step . dependOn ( & debug_cmd . step ) ;
2019-04-30 11:43:40 +02:00
}