www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

Makefile (21282B)


      1 MAKEFLAGS = --warn-undefined-variables
      2 SHELL = bash -euET -o pipefail -c
      3 .SECONDEXPANSION:
      4 
      5 os_filename = os.bat
      6 tests_emu = test/qemu-system-i386-floppy test/qemu-system-i386-cdrom test/qemu-system-arm test/virtualbox test/bochs test/gui-sh test/dosbox
      7 tests_requiring_sudo = test/fat12_mount test/iso_mount
      8 tests_noemu = test/zip test/os.reasm test/sizes test/fat12_contents
      9 
     10 offset_names = bytes_os_size \
     11                bytes_mbr_start \
     12                bytes_mbr_end \
     13                bytes_header_32k_start \
     14                bytes_header_32k_end \
     15                bytes_iso_start \
     16                bytes_iso_end \
     17                bytes_fat12_start \
     18                bytes_fat12_end \
     19                bytes_gpt_mirror_start \
     20                bytes_gpt_mirror_end \
     21                bytes_zip_start \
     22                bytes_zip_end
     23 
     24 more_offset_names = ${offset_names} \
     25                     bytes_fat12_size \
     26                     bytes_gpt_mirror_size \
     27                     bytes_header_32k_size \
     28                     bytes_iso_size \
     29                     bytes_zip_size \
     30                     sectors_fat12_size \
     31                     sectors_fat12_start \
     32                     sectors_gpt_mirror_size \
     33                     sectors_iso_size \
     34                     sectors_os_size \
     35                     sectors_zip_size \
     36                     tracks_fat12_size \
     37                     tracks_gpt_mirror_size \
     38                     tracks_iso_size \
     39                     tracks_os_size \
     40                     tracks_zip_size
     41 
     42 more_offset_dec = ${more_offset_names:%=build/offsets/%.dec}
     43 more_offset_hex = ${more_offset_names:%=build/offsets/%.hex}
     44 
     45 # + os.arm.disasm
     46 # + os.reasm.disasm
     47 built_files = ${os_filename} \
     48               build/check_makefile \
     49               build/check_makefile_targets \
     50               build/check_makefile_w_arnings \
     51               build/checkerboard_800x600.xbm \
     52               build/checkerboard_1024x768.png \
     53               build/makefile_built_directories \
     54               build/makefile_built_files \
     55               build/makefile_database \
     56               build/makefile_database_files \
     57               build/makefile_file_targets \
     58               build/makefile_non_file_targets \
     59               build/makefile_phony \
     60               build/makefile_targets \
     61               build/makefile_w_arnings \
     62               build/os.ndisasm.disasm \
     63               build/os.reasm.asm \
     64               build/os.reasm \
     65               build/os.file \
     66               build/os.gdisk \
     67               build/os.zip \
     68               build/os.zip.adjusted \
     69               build/os.iso \
     70               build/os.32k \
     71               build/os.fat12 \
     72               build/os.offsets.hex \
     73               build/os.offsets.dec \
     74               build/os.hex_with_offsets \
     75               build/iso_files/os.zip \
     76               build/iso_files/boot/iso_boot.sys \
     77               build/bochsrc \
     78               build/bochscontinue \
     79               build/twm_cfg \
     80               build/virtualbox.img \
     81               ${more_offset_dec} \
     82               ${more_offset_hex} \
     83               ${tests_emu:test/%=build/test_pass/emu_%} \
     84               ${tests_noemu:test/%=build/test_pass/noemu_%} \
     85               ${tests_requiring_sudo:test/%=build/test_pass/sudo_%} \
     86               ${tests_emu:test/%=deploy-screenshots/%.png} \
     87               ${tests_emu:test/%=deploy-screenshots/%-anim.gif}
     88 
     89 built_directories = build/iso_files/boot build/iso_files build/offsets build/mnt_fat12 build/mnt_iso build/test_pass deploy-screenshots
     90 more_built_directories = ${built_directories} build
     91 
     92 os_image_size_kb = 1440
     93 os_partition_start_sectors = 3
     94 os_partition_size_sectors = 717 # 720 - start
     95 # CHS parameters for 1.44 MB floppy disk
     96 os_floppy_chs_h = 2
     97 os_floppy_chs_s = 9
     98 
     99 .PHONY: all
    100 # all: os.arm.disasm
    101 all: ${os_filename} build/os.ndisasm.disasm build/os.reasm.asm build/os.file build/os.gdisk build/os.offsets.hex build/os.offsets.dec build/os.hex_with_offsets .gitignore build/check_makefile ${more_offset_dec} ${more_offset_hex}
    102 
    103 build/makefile_w_arnings: | $${@D}
    104 ${built_files}: | $${@D}
    105 
    106 build/makefile_w_arnings: Makefile
    107 	@unset MAKEFLAGS MAKELEVEL MAKE_TERMERR MFLAGS; make -n --warn-undefined-variables test 2>$@ 1>/dev/null || make -n --warn-undefined-variables test
    108 
    109 # Check that the file build/makefile_w_arnings is present, and that it does not contain the string "warn".
    110 build/check_makefile_w_arnings: build/makefile_w_arnings
    111 	@cat build/makefile_w_arnings > /dev/null && (! grep -i warn $<) && touch $@
    112 
    113 # Check that the declared list of built files matches the list of targets extracted from the Makefile.
    114 build/check_makefile_targets: build/makefile_built_files build/makefile_file_targets build/check_makefile_w_arnings
    115 	@diff build/makefile_built_files build/makefile_file_targets && touch $@
    116 
    117 build/check_makefile: build/check_makefile_w_arnings build/check_makefile_targets
    118 	@touch $@
    119 
    120 build/makefile_database: Makefile build/check_makefile_w_arnings
    121 	@unset MAKEFLAGS MAKELEVEL MAKE_TERMERR MFLAGS; make -rpn | sed -n -e '/^# Make data base,/,$$p' > $@
    122 
    123 build/makefile_database_files: build/makefile_database build/check_makefile_w_arnings
    124 	@sed -n -e '/^# Files$$/,/^# files hash-table stats:$$/p' $< > $@
    125 
    126 build/makefile_built_directories: build/check_makefile_w_arnings
    127 	@echo ${more_built_directories} | tr ' ' '\n' | grep -v '^[[:space:]]*$$' | sort > $@
    128 
    129 build/makefile_built_files: build/check_makefile_w_arnings
    130 	@echo ${built_files} | tr ' ' '\n' | grep -v '^[[:space:]]*$$' | sort > $@
    131 
    132 build/makefile_phony: build/makefile_database_files build/check_makefile_w_arnings
    133 	@sed -n -e 's/^\.PHONY: \(.*\)$$/\1/p' $< | tr ' ' '\n' | grep -v '^[[:space:]]*$$' | sort > $@
    134 
    135 build/makefile_targets: build/makefile_database_files build/check_makefile_w_arnings
    136 	@grep -E -v '^([[:space:]]|#|\.|$$|^[^:]*:$$)' $< | grep '^[^ :]*:' | sed -e 's|^\([^:]*\):.*$$|\1|' | sort > $@
    137 
    138 build/makefile_non_file_targets: build/makefile_phony build/makefile_built_directories build/check_makefile_w_arnings
    139 	@cat build/makefile_phony build/makefile_built_directories | sort > $@
    140 
    141 build/makefile_file_targets: build/makefile_non_file_targets build/makefile_targets build/check_makefile_w_arnings
    142 	@comm -23 build/makefile_targets build/makefile_non_file_targets > $@
    143 
    144 ${built_directories}: build/check_makefile
    145 ${more_built_directories}: Makefile
    146 	mkdir -p $@ && touch $@
    147 
    148 # 32k header of the ISO9660 image
    149 build/os.32k: example-os/os.asm build/check_makefile
    150 	nasm -w+macro-params -w+macro-selfref -w+orphan-labels -w+gnu-elf-extensions -o $@ $<
    151 
    152 build/os.iso: build/iso_files/os.zip build/iso_files/boot/iso_boot.sys build/check_makefile
    153 	mkisofs \
    154 	 --input-charset utf-8 \
    155 	 -rock \
    156 	 -joliet \
    157 	 -eltorito-catalog boot/boot.cat \
    158 	 -eltorito-boot boot/iso_boot.sys \
    159 	 -no-emul-boot \
    160 	 -boot-load-size 4 \
    161 	 -pad \
    162 	 -output $@ \
    163 	 ./build/iso_files/
    164 
    165 # Layout:
    166 # MBR; GPT; UNIX sh & MS-DOS batch scripts; ISO9660; FAT12; GPT mirror; ZIP
    167 
    168 define offset
    169 tmp_${1} = ${3}
    170 build/offsets/${1}.dec: $${tmp_${1}:%=build/offsets/%.dec} ${4} build/check_makefile
    171 	echo $$$$(( ${2} )) | tee $$@
    172 ${1} = $$$$(cat build/offsets/${1}.dec)
    173 dep_${1} = build/offsets/${1}.dec
    174 endef
    175 
    176 define div_round_up
    177 ( ( ( ${1} ) + ( ${2} ) - 1 ) / ( ${2} ) )
    178 endef
    179 
    180 sector_size = 512
    181 # should be exact (TODO: make a check)
    182 ${eval ${call offset,bytes_os_size,     $${os_image_size_kb} * 1024,,                                  }}
    183 ${eval ${call offset,sectors_os_size,   $${bytes_os_size}    / $${sector_size},                        bytes_os_size,}}
    184 ${eval ${call offset,tracks_os_size,    $${sectors_os_size}  / $${os_floppy_chs_s},                    sectors_os_size,}}
    185 
    186 # round up
    187 ${eval ${call offset,bytes_iso_size,    $$$$(utils/file-length.sh -c build/os.iso),                       ,build/os.iso}}
    188 ${eval ${call offset,sectors_iso_size,  ${call div_round_up,$${bytes_iso_size},$${sector_size}},       bytes_iso_size,}}
    189 ${eval ${call offset,tracks_iso_size,   ${call div_round_up,$${sectors_iso_size},$${os_floppy_chs_s}}, sectors_iso_size,}}
    190 
    191 # round up
    192 ${eval ${call offset,bytes_zip_size,    $$$$(utils/file-length.sh -c build/os.zip),                       ,build/os.zip}}
    193 ${eval ${call offset,sectors_zip_size,  ${call div_round_up,$${bytes_zip_size},$${sector_size}},       bytes_zip_size,}}
    194 ${eval ${call offset,tracks_zip_size,   ${call div_round_up,$${sectors_zip_size},$${os_floppy_chs_s}}, sectors_zip_size,}}
    195 
    196 # round up
    197 ${eval ${call offset,sectors_gpt_mirror_size, 33,,                                                   }}
    198 ${eval ${call offset,tracks_gpt_mirror_size,  ${call div_round_up,$${sectors_gpt_mirror_size},$${os_floppy_chs_s}}, sectors_gpt_mirror_size,}}
    199 
    200 # allocate the remaining sectors to the FAT, aligned on tracks
    201 ${eval ${call offset,tracks_fat12_size, $${tracks_os_size} - $${tracks_iso_size} - $${tracks_gpt_mirror_size} - $${tracks_zip_size}, tracks_os_size tracks_iso_size tracks_gpt_mirror_size tracks_zip_size,}}
    202 ${eval ${call offset,sectors_fat12_size,$${tracks_fat12_size} * $${os_floppy_chs_s},                   tracks_fat12_size,}}
    203 
    204 # zip should probably have its end aligned, not its start
    205 ${eval ${call offset,bytes_zip_start,   $${bytes_os_size} - $${bytes_zip_size},                        bytes_os_size bytes_zip_size,}}
    206 
    207 ${eval ${call offset,bytes_mbr_start,        0,,}}
    208 ${eval ${call offset,bytes_mbr_end,          512,,}}
    209 ${eval ${call offset,bytes_header_32k_start, 0,,}}
    210 ${eval ${call offset,bytes_header_32k_end,   32 * 1024,,}}
    211 ${eval ${call offset,bytes_header_32k_size,  $${bytes_header_32k_end} - $${bytes_header_32k_start},      bytes_header_32k_end bytes_header_32k_start,}}
    212 ${eval ${call offset,bytes_iso_start,        32 * 1024,,}}
    213 ${eval ${call offset,bytes_iso_end,          $${sectors_iso_size} * $${sector_size},                     sectors_iso_size,}}
    214 ${eval ${call offset,bytes_fat12_start,      $${tracks_iso_size} * $${os_floppy_chs_s} * $${sector_size}, tracks_iso_size,}}
    215 ${eval ${call offset,sectors_fat12_start,    $${bytes_fat12_start} / $${sector_size},                    bytes_fat12_start,}}
    216 ${eval ${call offset,bytes_fat12_size,       $${sectors_fat12_size} * $${sector_size},                   sectors_fat12_size,}}
    217 ${eval ${call offset,bytes_fat12_end,        $${bytes_fat12_start} + $${bytes_fat12_size},               bytes_fat12_start bytes_fat12_size,}}
    218 # It is probably not necessary to align the GPT mirror end on a track boundary.
    219 ${eval ${call offset,bytes_gpt_mirror_size,  $${sectors_gpt_mirror_size} + $${sector_size},              sectors_gpt_mirror_size,}}
    220 ${eval ${call offset,bytes_gpt_mirror_end,   $${bytes_fat12_end} + $${bytes_gpt_mirror_size},            bytes_fat12_end bytes_gpt_mirror_size,}}
    221 ${eval ${call offset,bytes_gpt_mirror_start, $${bytes_gpt_mirror_end} - $${bytes_gpt_mirror_size},       bytes_gpt_mirror_end bytes_gpt_mirror_size,}}
    222 ${eval ${call offset,bytes_zip_end,          $${bytes_os_size},,                                         }}
    223 
    224 os_fat12_partition = "$@@@${bytes_fat12_start}"
    225 build/os.fat12: build/os.zip ${dep_bytes_fat12_size} ${dep_bytes_fat12_start} ${dep_sectors_os_size} build/check_makefile
    226 	set -x; dd if=/dev/zero bs=${sector_size} count=${sectors_os_size} of=$@
    227 	set -x; mformat -v "Example OS" \
    228 	 -T ${sectors_fat12_size} \
    229 	 -h ${os_floppy_chs_h} \
    230 	 -s ${os_floppy_chs_s} \
    231 	 -i ${os_fat12_partition}
    232 	set -x; mcopy -i ${os_fat12_partition} build/os.zip "::os.zip"
    233 
    234 build/iso_files/os.zip: build/os.zip build/check_makefile
    235 # TODO: make it so that the various file formats are mutual quines:
    236 # * the ISO should contain the original file
    237 # * the ZIP should contain the original file
    238 # * the FAT12 should contain the original file
    239 	cp $< $@
    240 
    241 # 4 sectors loaded when booting from optical media (CD-ROM, …):
    242 build/iso_files/boot/iso_boot.sys: build/os.32k build/check_makefile
    243 # TODO: this copy of the (or alternate) bootsector should contain a Boot Information Table,
    244 #       see https://wiki.osdev.org/El-Torito#A_BareBones_Boot_Image_with_Boot_Information_Table
    245 	dd if=$< bs=512 count=4 of=$@
    246 
    247 build/os.zip: build/os.32k build/check_makefile
    248 	zip $@ $<
    249 
    250 build/os.zip.adjusted: build/os.zip ${dep_bytes_zip_start} build/check_makefile
    251 # TODO: the ZIP file can end with a variable-length comment, this would allow us to hide the GPT mirrors.
    252 	set -x; dd if=/dev/zero bs=1 count=${bytes_zip_start} of=$@
    253 	cat $< >> $@
    254 	zip --adjust-sfx $@
    255 
    256 ${os_filename}: build/os.32k build/os.iso build/os.fat12 build/os.zip.adjusted \
    257                 ${dep_bytes_header_32k_start} \
    258                 ${dep_bytes_header_32k_size} \
    259                 ${dep_bytes_fat12_start} \
    260                 ${dep_bytes_fat12_size} \
    261                 ${dep_bytes_gpt_mirror_start} \
    262                 ${dep_bytes_gpt_mirror_end} \
    263                 ${dep_sectors_fat12_start} \
    264                 ${dep_sectors_fat12_size} \
    265                 ${dep_bytes_zip_start} \
    266                 build/check_makefile
    267 	rm -f $@
    268 # start with the .iso
    269 	cp build/os.iso $@
    270 # splice in the first 32k (bootsector and partition table)
    271 	set -x; dd skip=${bytes_header_32k_start} seek=${bytes_header_32k_start} bs=1 count=${bytes_header_32k_size} conv=notrunc if=build/os.32k of=$@
    272 # splice in fat12
    273 	set -x; dd skip=${bytes_fat12_start} seek=${bytes_fat12_start} bs=1 count=${bytes_fat12_size} conv=notrunc if=build/os.fat12 of=$@
    274 # pad with zeroes to prepare for GPT table
    275 	set -x; dd if=/dev/zero seek=$$((${bytes_gpt_mirror_end} - 1 )) bs=1 count=1 conv=notrunc of=$@
    276 # patch the partition table
    277 # Thanks to https://wiki.gentoo.org/wiki/Hybrid_partition_table for showing that gdisk can be used to make a hybrid MBR / GPT.
    278 #       gdisk commands:
    279 #         * Delete (the only) partition, eXpert mode, sector aLignment = 1, back to Main menu,
    280 #         * New partition (number = 1, start sector, end sector, type 0700)
    281 #         * Recovery and transformation options, make Hybrid,
    282 #           * add GPT partition #1 to the hybrid MBR, do Not put the EFI partition first,
    283 #           * MBR partition type=0x01, bootable=Yes, do Not add extra partitions,
    284 #         * Print GPT, print MBR, Write, Proceed.
    285 	(if test "$$(uname -o)" = "Cygwin"; then printf "Y\n"; fi; \
    286 	 printf "d\nx\nl\n1\nm\nn\n1\n${sectors_fat12_start}\n${sectors_fat12_size}\n0700\n"; \
    287 	 printf "r\nh\n"; \
    288 	 printf "1\nN\n"; \
    289 	 printf "01\nY\nN\n"; \
    290 	 printf "p\no\nw\nY\n") | while read str; do echo "$$str"; printf "\033[1;33m%s\033[m\n" "$$str" >&2; sleep 0.01; done | gdisk $@
    291 # Inject MS-DOS newlines (CR+LF) and comments (":: ") in the GUID field of unused partition table entries,
    292 # so that the part that is to be skipped by MS-DOS does not form a line longer than the MS-DOS maximum
    293 # line length (8192 excluding CR+LF). $i below is the partition entry number, starting from 1
    294 # The numbers 55 and 118 are arbitrarily chosen so that the space between two CR+LF is less than 8192.
    295 	for i in 55 118; do \
    296 	  printf "\r\n:: %02x" $$i | dd bs=1 seek=$$(( 1024 + ( ($$i) - 1) * 128 + 16)) count=7 conv=notrunc of=$@; \
    297 	  printf "\r\n:: %02x" $$i | dd bs=1 seek=$$(( ${bytes_gpt_mirror_start} + ( ($$i) - 1) * 128 + 16)) count=7 conv=notrunc of=$@; \
    298 	done
    299 # splice in zip at the end
    300 	set -x; dd skip=${bytes_zip_start} seek=${bytes_zip_start} bs=1 conv=notrunc if=build/os.zip.adjusted of=$@
    301 	chmod a+x-w $@
    302 
    303 build/os.file: ${os_filename} build/check_makefile
    304 	file -kr $< > $@
    305 
    306 build/os.gdisk: ${os_filename} build/check_makefile
    307 #       gdisk commands:
    308 #         * Print partition table
    309 #         * Recovery and transformation options
    310 #         * print prOtective MBR table
    311 #         * Quit
    312 	printf 'p\nr\no\nq\n' | gdisk $< | tee $@
    313 
    314 build/os.offsets.hex: ${offset_names:%=build/offsets/%.hex} build/check_makefile
    315 	grep '^' ${offset_names:%=build/offsets/%.hex} | sed -e 's/:/: 0x/' | column -t > $@
    316 
    317 build/os.offsets.dec: ${offset_names:%=build/offsets/%.dec} build/check_makefile
    318 	grep '^' ${offset_names:%=build/offsets/%.dec} | sed -e 's/:/: /' | column -t > $@
    319 
    320 build/offsets/%.hex: build/offsets/%.dec
    321 	printf '%x\n' $$(cat $<) > $@
    322 
    323 build/os.hex_with_offsets: ${os_filename} build/os.offsets.hex
    324 	hexdump -C $< \
    325 	 | grep -E -e "($$(cat build/os.offsets.hex | cut -d '=' -f 2 | sed -e 's/^[[:space:]]*0x\(.*\).$$/^\10/' | tr '\n' '|')^)" --color=yes > $@
    326 
    327 build/os.ndisasm.disasm: ${os_filename} utils/compact-ndisasm.sh build/check_makefile
    328 	./utils/compact-ndisasm.sh $< $@
    329 
    330 build/os.reasm.asm: build/os.ndisasm.disasm build/check_makefile
    331 	sed -e 's/^[^ ]\+ \+[^ ]\+ \+//' $< > $@
    332 
    333 build/test_pass/noemu_%.reasm build/%.reasm: build/%.reasm.asm ${os_filename} utils/compact-ndisasm.sh build/check_makefile
    334 # For now ignore this test, since we cannot have a reliable re-assembly of arbitrary data.
    335 	touch build/test_pass/noemu_$*.reasm build/$*.reasm
    336 #	nasm $< -o $@
    337 #	@echo "diff $@ ${os_filename}"
    338 #	@diff $@ ${os_filename} \
    339 #         && echo "Re-assembled file is identical to ${os_filename}" \
    340 #         || (./utils/compact-ndisasm.sh $@ build/os.reasm.disasm; \
    341 #	     echo "Re-assembled file is different from ${os_filename}. Use meld build/os.ndisasm.disasm build/os.reasm.disasm to see differences."; \
    342 #	     exit 0)
    343 
    344 #os.arm.disasm: ${os_filename} build/check_makefile
    345 #	arm-none-eabi-objdump --endian=little -marm -b binary -D --adjust-vma=0x8000 $< > $@
    346 
    347 .PHONY: clean
    348 clean: build/check_makefile
    349 	rm -f ${built_files}
    350 	for d in $$(echo ${more_built_directories} | tr ' ' '\n' | sort --reverse); do \
    351           if test -e "$$d"; then \
    352             rmdir "$$d"; \
    353           fi; \
    354         done
    355 
    356 .gitignore: build/check_makefile
    357 	for f in ${built_files}; do echo "/$$f"; done | sort > $@
    358 
    359 .PHONY: test
    360 test: ${tests_emu:test/%=build/test_pass/emu_%} \
    361       ${tests_noemu:test/%=build/test_pass/noemu_%} \
    362       ${tests_requiring_sudo:test/%=build/test_pass/sudo_%} \
    363       all \
    364       build/check_makefile
    365 
    366 .PHONY: ${tests_emu}
    367 ${tests_emu}: build/test_pass/emu_$$(@F)
    368 
    369 build/test_pass/emu_% deploy-screenshots/%.png deploy-screenshots/%-anim.gif: \
    370  ${os_filename} \
    371  build/checkerboard_800x600.xbm \
    372  utils/gui-wrapper.sh utils/ansi-screenshots/ansi_screenshot.sh utils/ansi-screenshots/to_ansi.sh \
    373  test/%.sh \
    374  build/check_makefile \
    375  | build/test_pass deploy-screenshots
    376 	./utils/gui-wrapper.sh 800x600x24 ./test/$*.sh $<
    377 	touch build/test_pass/emu_$*
    378 
    379 .PHONY: test/noemu
    380 test/noemu: ${tests_noemu:test/%=build/test_pass/noemu_%} build/check_makefile
    381 
    382 build/test_pass/noemu_zip: ${os_filename} build/check_makefile
    383 	unzip -t ${os_filename}
    384 	touch $@
    385 
    386 build/test_pass/noemu_sizes: build/os.32k ${os_filename} build/check_makefile
    387 	test "$$(utils/file-length.sh -c build/os.32k)" = "$$((32*1024))"
    388 	test "$$(utils/file-length.sh -c ${os_filename})" = "$$((1440*1024))"
    389 	touch $@
    390 
    391 # check that the fat filesystem has the correct contents
    392 build/test_pass/noemu_fat12_contents: ${os_filename} ${dep_bytes_fat12_start} build/check_makefile
    393 	mdir -i "$<@@${bytes_fat12_start}" :: | grep -E "^os[[:space:]]+zip[[:space:]]+"
    394 	touch $@
    395 
    396 .PHONY: test/requiring_sudo
    397 test/requiring_sudo: ${tests_requiring_sudo:test/%=build/test_pass/sudo_%} build/check_makefile
    398 
    399 # check that the fat filesystem can be mounted and has the correct contents
    400 build/test_pass/sudo_fat12_mount: ${os_filename} ${dep_bytes_fat12_start} build/check_makefile | build/mnt_fat12
    401 	sudo umount build/mnt_fat12 || true
    402 	sudo mount -o loop,ro,offset=${bytes_fat12_start} $< build/mnt_fat12
    403 	ls -l build/mnt_fat12 | grep os.zip
    404 	sudo umount build/mnt_fat12
    405 	touch $@
    406 
    407 build/test_pass/sudo_iso_mount: ${os_filename} build/check_makefile | build/mnt_iso
    408 	sudo umount build/mnt_iso || true
    409 	grep '^' build/offsets/* # debug failure to mount the ISO9660 filesystem
    410 	(sudo mount -o loop,ro $< build/mnt_iso) || true
    411 	dmesg | tail # debug failure to mount the ISO9660 filesystem
    412 	hexdump -C os.bat
    413 	ls -l build/mnt_iso | grep os.zip
    414 	sudo umount build/mnt_iso
    415 	sudo mount -o loop,ro $< build/mnt_iso
    416 	sudo umount build/mnt_iso
    417 	touch $@
    418 
    419 .PHONY: test/macos
    420 test/macos: all test/noemu test/macos-sh test/macos-sh-x11
    421 
    422 .PHONY: test/macos-sh-x11
    423 test/macos-sh-x11:
    424 	sudo mkdir -p /tmp/.X11-unix
    425 	sudo chmod a+rwxt /tmp/.X11-unix
    426 	xvfb :42 & \
    427 	sleep 5; \
    428 	DISPLAY=:42 xterm -e ./os.bat & \
    429 	sleep 5; \
    430 #	DISPLAY=:42 import -window root deploy-screenshots/macos-sh-x11.png
    431 	screencapture deploy-screenshots/macos-sh-x11-screencapture.png
    432 
    433 .PHONY: test/macos-sh
    434 test/macos-sh: build/check_makefile \
    435                build/checkerboard_1024x768.png \
    436                | deploy-screenshots
    437 	osascript -e 'tell app "Terminal" to do script "'"$$PWD"'/os.bat"'
    438 	sleep 2
    439 	osascript -e 'tell app "Terminal" to activate'
    440 	sleep 5
    441 	(date +%n && sleep 0.2 && date +%n) || true
    442 	screencapture deploy-screenshots/screencapture-os-bat.png
    443 	./utils/gui-wrapper-mac.sh 1024x768x24 ./test/gui-sh-mac.sh ${os_filename}
    444 
    445 # See https://wiki.osdev.org/EFI#Emulation to emulate an UEFI system with qemu, to test the EFI boot from hdd / cd / fd (?).
    446 
    447 # Create checkerboard background
    448 build/checkerboard_%.png: build/check_makefile
    449 	convert -size "$*" \
    450 	        tile:pattern:checkerboard \
    451 	        -auto-level +level-colors 'gray(192),gray(128)' \
    452 	        $@
    453 
    454 build/checkerboard_%.xbm: build/check_makefile
    455 	convert -size "$*" \
    456 	        tile:pattern:checkerboard \
    457 	        -auto-level \
    458 	        $@
    459 
    460 # Temporary files
    461 build/bochsrc build/bochscontinue build/twm_cfg build/virtualbox.img:
    462 	touch $@