@@ -3,18 +3,30 @@ # libk module. it is included from each k*/makefile. # vim: ft=make mod = $(notdir $(PWD)) -src = $(wildcard *.c) $(wildcard *.s) +src = $(wildcard *.c) $(wildcard *.s) $(filter-out %.h,$(patsubst %.m,%,$(wildcard *.m))) bare = $(mod:k%=%) -headers = $(wildcard *.h) $(gen-headers) +headers = $(wildcard *.h) $(gen-headers) $(patsubst %.m,%,$(wildcard *.h.m)) tools = $(filter %.exe.c, $(src)) nontools = $(filter-out %.exe.c, $(src)) cobjects = $(filter %.c, $(nontools)) sobjects = $(filter %.${TARGET}.s, $(nontools)) -cflags = -isystem ${OUT} -fPIC -nostdlib ${COMPLIB} -L${OUT} -lk +gpp = gpp +cflags = -std=c11 -isystem ${OUT} -fPIC -nostdlib ${COMPLIB} -L${OUT} + +m-env = atom_target_arch=${ARCH} +m-env += atom_target_os=${OS} +ifneq (${BITS},) #!!! ifdef does NOT work with environment variables + m-env += atom_target_bits=${BITS} +endif +m-env += target_posix=${POSIX} +m-env += target_unix=${UNIX} + +m-grammar = $(file < ${TMP}/precomp.g) +m-comp = $(gpp) $(m-grammar) $(m-env:%=-D%) obj: $(cobjects:%.c=${OUT}/$(mod).%.o) \ $(sobjects:%.s=${OUT}/$(mod).%.o) tool: $(tools:%.exe.c=${OUT}/$(mod).%) \ @@ -22,23 +34,37 @@ def: $(headers:%=${OUT}/k/%) dbg: + @echo src = $(src) @echo tools = $(tools) @echo TARGET = ${TARGET} @echo cobjects = $(cobjects) @echo sobjects = $(sobjects) @echo headers = $(headers) + @echo m-comp = $(m-comp) + @echo m-grammar = $(m-grammar) + @echo m-env = $(m-env) "$(m-env:%=-D%)" @echo mod = $(mod) -${OUT}/$(mod).%.o: %.c +${OUT}/k/%.h: %.h.m + $(m-comp) $< > $@ + +.PRECIOUS: ${TMP}/$(mod).% +${TMP}/$(mod).%: %.m ${TMP} + $(m-comp) $< > $@ + +${OUT}/$(mod).%.o: ${TMP}/$(mod).%.c + $(CC) $(cflags) -c $< -o $@ + +${OUT}/$(mod).%.o: %.c $(bare).h $(CC) $(cflags) -c $< -o $@ ${OUT}/k/%.h: %.h cp $< $@ ${OUT}/$(mod).%: %.exe.c - $(CC) $(cflags) $< -o $@ + $(CC) $(cflags) $< ${OUT}/libk.a -o $@ ${TMP}: mkdir -p ${TMP} @@ -53,28 +79,35 @@ # ${OUT} = ultimate build directory # $(mod) = module name # % = function name # $(1) = arch tuple -arch = ${OUT}/$(mod).%.$(1).o: %.$(1).s +arch = ${OUT}/$(mod).%.$(1).o: $2%.$(1).s # invoke with $(call arch,tuple). do not # put spaces between either term though! ifeq ($(debug),yes) yasm-flags = -gdwarf2 endif +yasm = yasm $(yasm-flags) -f$1 -i${TMP} $< -o $@ + #-- linux # linux uses the ELF{32,64} binary format, and generating these # from yasm is trivial. linux only supports one ABI per format, # at least with ELF, so that's all we need to do. -#${OUT}/$(mod).%.x86.lin.32.o: %.x86.lin.32.s -$(call arch,x86.lin.32) - yasm $(yasm-flags) -felf32 -i${TMP} $< -o $@ + +$(call arch,x86.lin.32,) + $(call yasm,elf32) + +$(call arch,x86.lin.64,) + $(call yasm,elf64) + +$(call arch,x86.lin.32,${TMP}/$(mod).) + $(call yasm,elf32) -#${OUT}/$(mod).%.x86.lin.64.o: %.x86.lin.64.s -$(call arch,x86.lin.64) - yasm $(yasm-flags) -felf64 -i${TMP} $< -o $@ +$(call arch,x86.lin.64,${TMP}/$(mod).) + $(call yasm,elf64) #-- freebsd # the freebsd ABI is different, so it will require different code # (though there might be ways to minimize that). freebsd uses the @@ -82,12 +115,19 @@ # COFF) but because freebsd can interpret multiple different ABIs # the object files need to be "branded" with the correct one # using the tool brandelf (`brandelf -t [ABI]`) -$(call arch,x86.fbsd.32) - yasm -felf32 $< -o $@ +$(call arch,x86.fbsd.32,) + $(call yasm,elf32) + brandelf -t FreeBSD $@ + +$(call arch,x86.fbsd.64,) + $(call yasm,elf64) brandelf -t FreeBSD $@ -$(call arch,x86.fbsd.64) - yasm -felf64 $< -o $@ +$(call arch,x86.fbsd.32,${TMP}/$(mod).) + $(call yasm,elf32) brandelf -t FreeBSD $@ +$(call arch,x86.fbsd.64,${TMP}/$(mod).) + $(call yasm,elf64) + brandelf -t FreeBSD $@