Makefile 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. ifeq ($(TOOLCHAIN),)
  2. ifeq ($(shell util/check.sh),y)
  3. export PATH := $(shell util/activate.sh)
  4. else
  5. FOO := $(shell util/prompt.sh)
  6. ifeq ($(shell util/check.sh),y)
  7. export PATH := $(shell util/activate.sh)
  8. else
  9. $(error "No toolchain, and you did not ask to build it.")
  10. endif
  11. endif
  12. endif
  13. # Prevents Make from removing intermediary files on failure
  14. .SECONDARY:
  15. # Disable built-in rules
  16. .SUFFIXES:
  17. all: image.iso
  18. TARGET_TRIPLET=i686-pc-toaru
  19. # Userspace flags
  20. CC=$(TARGET_TRIPLET)-gcc
  21. AR=$(TARGET_TRIPLET)-ar
  22. AS=$(TARGET_TRIPLET)-as
  23. CFLAGS= -O3 -g -std=gnu99 -I. -Iapps -pipe -mmmx -msse -msse2 -fplan9-extensions -Wall -Wextra -Wno-unused-parameter
  24. ##
  25. # C library objects from libc/ C sources (and setjmp, which is assembly)
  26. LIBC_OBJS = $(patsubst %.c,%.o,$(wildcard libc/*.c))
  27. LIBC_OBJS += $(patsubst %.c,%.o,$(wildcard libc/*/*.c))
  28. LIBC_OBJS += libc/setjmp.o
  29. LC=base/lib/libc.so
  30. ##
  31. # APPS = C sources from apps/
  32. # APPS_X = binaries
  33. # APPS_Y = generated makefiles for binaries (except init)
  34. # APPS_SH = shell scripts to copy to base/bin/ and mark executable
  35. # APPS_SH_X = destinations for shell scripts
  36. APPS=$(patsubst apps/%.c,%,$(wildcard apps/*.c))
  37. APPS_X=$(foreach app,$(APPS),base/bin/$(app))
  38. APPS_Y=$(foreach app,$(filter-out init,$(APPS)),.make/$(app).mak)
  39. APPS_SH=$(patsubst apps/%.sh,%.sh,$(wildcard apps/*.sh))
  40. APPS_SH_X=$(foreach app,$(APPS_SH),base/bin/$(app))
  41. ##
  42. # LIBS = C sources from lib/
  43. # LIBS_X = Shared libraries (.so)
  44. # LIBS_Y = Generated makefiles for libraries
  45. LIBS=$(patsubst lib/%.c,%,$(wildcard lib/*.c))
  46. LIBS_X=$(foreach lib,$(LIBS),base/lib/libtoaru_$(lib).so)
  47. LIBS_Y=$(foreach lib,$(LIBS),.make/$(lib).lmak)
  48. SOURCE_FILES = $(wildcard kernel/*.c kernel/*/*.c kernel/*/*/*.c modules/*.c)
  49. SOURCE_FILES += $(wildcard apps/*.c linker/*.c libc/*.c libc/*/*.c lib/*.c)
  50. tags: $(SOURCE_FILES)
  51. ctags -f tags $(SOURCE_FILES)
  52. ##
  53. # Files that must be present in the ramdisk (apps, libraries)
  54. RAMDISK_FILES= ${APPS_X} ${APPS_SH_X} ${LIBS_X} base/lib/ld.so base/lib/libm.so
  55. # Kernel / module flags
  56. ifeq (,${USE_CLANG})
  57. KCC = $(TARGET_TRIPLET)-gcc
  58. LGCC = -lgcc
  59. EXTRALIB =
  60. else
  61. KCC = clang --target=i686-elf -static -Ibase/usr/include -nostdinc -mno-sse
  62. LGCC = util/compiler-rt.o
  63. EXTRALIB = util/compiler-rt.o
  64. util/compiler-rt.o: util/compiler-rt.S
  65. ${KAS} ${ASFLAGS} $< -o $@
  66. endif
  67. KAS = $(TARGET_TRIPLET)-as
  68. KLD = $(TARGET_TRIPLET)-ld
  69. KNM = $(TARGET_TRIPLET)-nm
  70. KCFLAGS = -O2 -std=c99
  71. KCFLAGS += -finline-functions -ffreestanding
  72. KCFLAGS += -Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-format
  73. KCFLAGS += -pedantic -fno-omit-frame-pointer
  74. KCFLAGS += -D_KERNEL_
  75. KCFLAGS += -DKERNEL_GIT_TAG=$(shell util/make-version)
  76. KASFLAGS = --32
  77. ##
  78. # Kernel objects from kernel/ C sources
  79. KERNEL_OBJS = $(patsubst %.c,%.o,$(wildcard kernel/*.c))
  80. KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*.c))
  81. KERNEL_OBJS += $(patsubst %.c,%.o,$(wildcard kernel/*/*/*.c))
  82. ##
  83. # Kernel objects from kernel/ assembly sources
  84. KERNEL_ASMOBJS = $(filter-out kernel/symbols.o,$(patsubst %.S,%.o,$(wildcard kernel/*.S)))
  85. # Kernel
  86. fatbase/kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${EXTRALIB}
  87. ${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o $@ ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${LGCC}
  88. ##
  89. # Symbol table for the kernel. Instead of relying on getting
  90. # the symbol table from our bootloader (eg. through ELF
  91. # headers provided via multiboot structure), we have a dedicated
  92. # object that build with all the symbols. This allows us to
  93. # build the kernel as a flat binary or load it with less-capable
  94. # multiboot loaders and still get symbols, which we need to
  95. # load kernel modules and link them properly.
  96. kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/generate_symbols.py ${EXTRALIB}
  97. -rm -f kernel/symbols.o
  98. ${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o .toaruos-kernel ${KERNEL_ASMOBJS} ${KERNEL_OBJS} ${LGCC}
  99. ${KNM} .toaruos-kernel -g | util/generate_symbols.py > kernel/symbols.S
  100. ${KAS} ${KASFLAGS} kernel/symbols.S -o $@
  101. -rm -f .toaruos-kernel
  102. ##
  103. # version.o should be rebuilt whenever the kernel changes
  104. # in order to get fresh git commit hash information.
  105. kernel/sys/version.o: kernel/*/*.c kernel/*.c
  106. kernel/%.o: kernel/%.S
  107. ${KAS} ${ASFLAGS} $< -o $@
  108. kernel/%.o: kernel/%.c ${HEADERS}
  109. ${KCC} ${KCFLAGS} -nostdlib -g -c -o $@ $<
  110. # Modules
  111. fatbase/mod:
  112. @mkdir -p $@
  113. ##
  114. # Modules need to be installed on the boot image
  115. MODULES = $(patsubst modules/%.c,fatbase/mod/%.ko,$(wildcard modules/*.c))
  116. HEADERS = $(wildcard base/usr/include/kernel/*.h base/usr/include/kernel/*/*.h)
  117. fatbase/mod/%.ko: modules/%.c ${HEADERS} | fatbase/mod
  118. ${KCC} -nostdlib ${KCFLAGS} -c -o $@ $<
  119. modules: ${MODULES}
  120. # Root Filesystem
  121. base/dev:
  122. mkdir -p $@
  123. base/tmp:
  124. mkdir -p $@
  125. base/proc:
  126. mkdir -p $@
  127. base/bin:
  128. mkdir -p $@
  129. base/lib:
  130. mkdir -p $@
  131. base/cdrom:
  132. mkdir -p $@
  133. base/var:
  134. mkdir -p $@
  135. fatbase/efi/boot:
  136. mkdir -p $@
  137. cdrom:
  138. mkdir -p $@
  139. .make:
  140. mkdir -p .make
  141. dirs: base/dev base/tmp base/proc base/bin base/lib base/cdrom cdrom base/var fatbase/efi/boot .make
  142. # C Library
  143. crts: base/lib/crt0.o base/lib/crti.o base/lib/crtn.o | dirs
  144. base/lib/crt%.o: libc/crt%.S
  145. $(AS) -o $@ $<
  146. libc/setjmp.o: libc/setjmp.S
  147. $(AS) -o $@ $<
  148. libc/%.o: libc/%.c
  149. $(CC) $(CFLAGS) -fPIC -c -o $@ $<
  150. base/lib/libc.a: ${LIBC_OBJS} | dirs crts
  151. $(AR) cr $@ $^
  152. base/lib/libc.so: ${LIBC_OBJS} | dirs crts
  153. $(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc
  154. base/lib/libm.so: util/lm.c | dirs crts
  155. $(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc
  156. # Userspace Linker/Loader
  157. base/lib/ld.so: linker/linker.c base/lib/libc.a | dirs
  158. $(CC) -static -Wl,-static $(CFLAGS) -o $@ -Os -T linker/link.ld $<
  159. # Shared Libraries
  160. .make/%.lmak: lib/%.c util/auto-dep.py | dirs crts
  161. util/auto-dep.py --makelib $< > $@
  162. ifeq (,$(findstring clean,$(MAKECMDGOALS)))
  163. -include ${LIBS_Y}
  164. endif
  165. # Init (static)
  166. base/bin/init: apps/init.c base/lib/libc.a | dirs
  167. $(CC) -static -Wl,-static $(CFLAGS) -o $@ $<
  168. fatbase/netinit: util/netinit.c base/lib/libc.a | dirs
  169. $(CC) -static -Wl,-static $(CFLAGS) -o $@ $<
  170. # Userspace applications
  171. .make/%.mak: apps/%.c util/auto-dep.py | dirs crts
  172. util/auto-dep.py --make $< > $@
  173. ifeq (,$(findstring clean,$(MAKECMDGOALS)))
  174. -include ${APPS_Y}
  175. endif
  176. base/bin/%.sh: apps/%.sh
  177. cp $< $@
  178. chmod +x $@
  179. # Ramdisk
  180. fatbase/ramdisk.img: ${RAMDISK_FILES} $(shell find base) Makefile util/createramdisk.py | dirs
  181. python3 util/createramdisk.py
  182. # CD image
  183. ifeq (,$(wildcard /usr/lib32/crt0-efi-ia32.o))
  184. $(error Missing GNU-EFI.)
  185. endif
  186. EFI_XORRISO=-eltorito-alt-boot -e fat.img -no-emul-boot -isohybrid-gpt-basdat
  187. EFI_BOOT=cdrom/fat.img
  188. EFI_UPDATE=util/update-extents.py
  189. image.iso: ${EFI_BOOT} cdrom/boot.sys fatbase/netinit ${MODULES} util/update-extents.py
  190. xorriso -as mkisofs -R -J -c bootcat \
  191. -b boot.sys -no-emul-boot -boot-load-size 24 \
  192. ${EFI_XORRISO} \
  193. -o image.iso cdrom
  194. ${EFI_UPDATE}
  195. # Boot loader
  196. ##
  197. # FAT EFI payload
  198. # This is the filesystem the EFI loaders see, so it must contain
  199. # the kernel, modules, and ramdisk, plus anything else we want
  200. # available to the bootloader (eg., netinit).
  201. cdrom/fat.img: fatbase/ramdisk.img ${MODULES} fatbase/kernel fatbase/netinit fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi util/mkdisk.sh | dirs
  202. util/mkdisk.sh $@ fatbase
  203. ##
  204. # For EFI, we build two laoders: ia32 and x64
  205. # We build them as ELF shared objects and the use objcopy to convert
  206. # them to PE executables / DLLs (as expected by EFI).
  207. EFI_CFLAGS=-fno-stack-protector -fpic -DEFI_PLATFORM -ffreestanding -fshort-wchar -I /usr/include/efi -mno-red-zone
  208. EFI_SECTIONS=-j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc
  209. # ia32
  210. boot/efi.so: boot/cstuff.c boot/*.h
  211. $(CC) ${EFI_CFLAGS} -I /usr/include/efi/ia32 -c -o boot/efi.o $<
  212. $(LD) boot/efi.o /usr/lib32/crt0-efi-ia32.o -nostdlib -znocombreloc -T /usr/lib32/elf_ia32_efi.lds -shared -Bsymbolic -L /usr/lib32 -lefi -lgnuefi -o boot/efi.so
  213. fatbase/efi/boot/bootia32.efi: boot/efi.so
  214. objcopy ${EFI_SECTIONS} --target=efi-app-ia32 $< $@
  215. # x64
  216. boot/efi64.so: boot/cstuff.c boot/*.h
  217. gcc ${EFI_CFLAGS} -I /usr/include/efi/x86_64 -DEFI_FUNCTION_WRAPPER -c -o boot/efi64.o $<
  218. $(LD) boot/efi64.o /usr/lib/crt0-efi-x86_64.o -nostdlib -znocombreloc -T /usr/lib/elf_x86_64_efi.lds -shared -Bsymbolic -L /usr/lib -lefi -lgnuefi -o boot/efi64.so
  219. fatbase/efi/boot/bootx64.efi: boot/efi64.so
  220. objcopy ${EFI_SECTIONS} --target=efi-app-x86_64 $< $@
  221. # BIOS loader
  222. cdrom/boot.sys: boot/boot.o boot/cstuff.o boot/link.ld | dirs
  223. ${KLD} -T boot/link.ld -o $@ boot/boot.o boot/cstuff.o
  224. boot/cstuff.o: boot/cstuff.c boot/*.h
  225. ${CC} -c -Os -o $@ $<
  226. boot/boot.o: boot/boot.S
  227. ${AS} -o $@ $<
  228. .PHONY: clean
  229. clean:
  230. rm -f base/lib/*.so
  231. rm -f base/lib/libc.a
  232. rm -f ${APPS_X} ${APPS_SH_X}
  233. rm -f libc/*.o libc/*/*.o
  234. rm -f image.iso
  235. rm -f fatbase/ramdisk.img
  236. rm -f cdrom/boot.sys
  237. rm -f boot/*.o
  238. rm -f boot/*.efi
  239. rm -f boot/*.so
  240. rm -f cdrom/fat.img cdrom/kernel cdrom/mod/* cdrom/ramdisk.img
  241. rm -f fatbase/kernel fatbase/efi/boot/bootia32.efi fatbase/efi/boot/bootx64.efi
  242. rm -f cdrom/netinit fatbase/netinit
  243. rm -f ${KERNEL_OBJS} ${KERNEL_ASMOBJS} kernel/symbols.o kernel/symbols.S
  244. rm -f base/lib/crt*.o
  245. rm -f ${MODULES}
  246. rm -f ${APPS_Y} ${LIBS_Y} ${EXT_LIBS_Y}
  247. ifneq (,$(findstring Microsoft,$(shell uname -r)))
  248. QEMU_ARGS=-serial mon:stdio -m 1G -rtc base=localtime -vnc :0
  249. else
  250. ifeq (,${NO_KVM})
  251. KVM=-enable-kvm
  252. else
  253. KVM=
  254. endif
  255. QEMU_ARGS=-serial mon:stdio -m 1G -soundhw ac97,pcspk ${KVM} -rtc base=localtime ${QEMU_EXTRA}
  256. endif
  257. .PHONY: run
  258. run: image.iso
  259. qemu-system-i386 -cdrom $< ${QEMU_ARGS}
  260. .PHONY: fast
  261. fast: image.iso
  262. qemu-system-i386 -cdrom $< ${QEMU_ARGS} \
  263. -fw_cfg name=opt/org.toaruos.bootmode,string=normal
  264. .PHONY: headless
  265. headless: image.iso
  266. @qemu-system-i386 -cdrom $< ${QEMU_ARGS} \
  267. -nographic -no-reboot \
  268. -fw_cfg name=opt/org.toaruos.bootmode,string=headless
  269. .PHONY: shell
  270. shell: image.iso
  271. @qemu-system-i386 -cdrom $< ${QEMU_ARGS} \
  272. -nographic -no-reboot \
  273. -fw_cfg name=opt/org.toaruos.bootmode,string=headless \
  274. -fw_cfg name=opt/org.toaruos.forceuser,string=local \
  275. -fw_cfg name=opt/org.toaruos.term,string=${TERM} </dev/null >/dev/null & \
  276. stty raw -echo && nc -l 127.0.0.1 8090 && stty sane && wait
  277. .PHONY: efi64
  278. efi64: image.iso
  279. qemu-system-x86_64 -cdrom $< ${QEMU_ARGS} \
  280. -bios /usr/share/qemu/OVMF.fd
  281. VMNAME=ToaruOS CD
  282. define virtualbox-runner =
  283. .PHONY: $1
  284. $1: image.iso
  285. -VBoxManage unregistervm "$(VMNAME)" --delete
  286. VBoxManage createvm --name "$(VMNAME)" --ostype $2 --register
  287. VBoxManage modifyvm "$(VMNAME)" --memory 1024 --vram 32 --audio pulse --audiocontroller ac97 --bioslogodisplaytime 1 --bioslogofadeout off --bioslogofadein off --biosbootmenu disabled $3
  288. VBoxManage storagectl "$(VMNAME)" --add ide --name "IDE"
  289. VBoxManage storageattach "$(VMNAME)" --storagectl "IDE" --port 0 --device 0 --medium $$(shell pwd)/image.iso --type dvddrive
  290. VBoxManage setextradata "$(VMNAME)" GUI/DefaultCloseAction PowerOff
  291. VBoxManage startvm "$(VMNAME)" --type separate
  292. endef
  293. $(eval $(call virtualbox-runner,virtualbox,"Other",))
  294. $(eval $(call virtualbox-runner,virtualbox-efi,"Other",--firmware efi))
  295. $(eval $(call virtualbox-runner,virtualbox-efi64,"Other_64",--firmware efi))
  296. ##
  297. # Optional Extensions
  298. #
  299. # These optional extension libraries require third-party components to build,
  300. # but allow the native applications to make use of functionality such as
  301. # TrueType fonts or PNG images. You must have the necessary elements to build
  302. # these already installed into your sysroot for this to work.
  303. EXT_LIBS=$(patsubst ext/%.c,%,$(wildcard ext/*.c))
  304. EXT_LIBS_X=$(foreach lib,$(EXT_LIBS),base/lib/libtoaru_$(lib).so)
  305. EXT_LIBS_Y=$(foreach lib,$(EXT_LIBS),.make/$(lib).elmak)
  306. .make/%.elmak: ext/%.c util/auto-dep.py | dirs
  307. util/auto-dep.py --makelib $< > $@
  308. ifeq (,$(findstring clean,$(MAKECMDGOALS)))
  309. -include ${EXT_LIBS_Y}
  310. endif
  311. # Freetype: Terminal text rendering backend
  312. ext-freetype: base/lib/libtoaru_ext_freetype_fonts.so
  313. # Cairo: Compositor rendering backend
  314. ext-cairo: base/lib/libtoaru_ext_cairo_renderer.so
  315. # Other extra stuff
  316. util/ungz: util/ungz.c
  317. $(CC) -o $@ $< -lz