1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#- modmake
# this is the master makefile that controls the building of each
# libk module. it is included from each k*/makefile.
# vim: ft=make
mod = $(notdir $(PWD))
src = $(wildcard *.c) $(wildcard *.s)
bare = $(mod:k%=%)
headers = $(wildcard *.h) $(gen-headers)
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
obj: $(cobjects:%.c=${OUT}/$(mod).%.o) \
$(sobjects:%.s=${OUT}/$(mod).%.o)
tool: $(tools:%.exe.c=${OUT}/$(mod).%) \
${OUT}/libk.a
def: $(headers:%=${OUT}/k/%)
dbg:
@echo tools = $(tools)
@echo TARGET = ${TARGET}
@echo cobjects = $(cobjects)
@echo sobjects = $(sobjects)
@echo headers = $(headers)
@echo mod = $(mod)
${OUT}/$(mod).%.o: %.c
$(CC) $(cflags) -c $< -o $@
${OUT}/k/%.h: %.h
cp $< $@
${OUT}/$(mod).%: %.exe.c
$(CC) $(cflags) $< -o $@
${TMP}:
mkdir -p ${TMP}
#- assembly
# compiling the assembly code will be faster but a lot more
# complex, given the nature of assembly and the large number of
................................................................................
# that requires ugly make rules, we're just going to use a
# function to generate these.
# ${OUT} = ultimate build directory
# $(mod) = module name
# % = function name
# $(1) = arch tuple
arch = ${OUT}/$(mod).%.$(1).o: %.$(1).s
# invoke with $(call arch,tuple). do not
# put spaces between either term though!
ifeq ($(debug),yes)
yasm-flags = -gdwarf2
endif
#-- 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 $@
#${OUT}/$(mod).%.x86.lin.64.o: %.x86.lin.64.s
$(call arch,x86.lin.64)
yasm $(yasm-flags) -felf64 -i${TMP} $< -o $@
#-- freebsd
# the freebsd ABI is different, so it will require different code
# (though there might be ways to minimize that). freebsd uses the
# same binary format as Linux (though it also supports a.out and
# 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 $@
brandelf -t FreeBSD $@
$(call arch,x86.fbsd.64)
yasm -felf64 $< -o $@
brandelf -t FreeBSD $@
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
<
>
|
|
|
>
>
>
>
>
|
<
>
|
|
|
|
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#- modmake
# this is the master makefile that controls the building of each
# libk module. it is included from each k*/makefile.
# vim: ft=make
mod = $(notdir $(PWD))
src = $(wildcard *.c) $(wildcard *.s) $(filter-out %.h,$(patsubst %.m,%,$(wildcard *.m)))
bare = $(mod:k%=%)
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))
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).%) \
${OUT}/libk.a
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}/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) $< ${OUT}/libk.a -o $@
${TMP}:
mkdir -p ${TMP}
#- assembly
# compiling the assembly code will be faster but a lot more
# complex, given the nature of assembly and the large number of
................................................................................
# that requires ugly make rules, we're just going to use a
# function to generate these.
# ${OUT} = ultimate build directory
# $(mod) = module name
# % = function name
# $(1) = arch tuple
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.
$(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)
$(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
# same binary format as Linux (though it also supports a.out and
# 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,)
$(call yasm,elf32)
brandelf -t FreeBSD $@
$(call arch,x86.fbsd.64,)
$(call yasm,elf64)
brandelf -t FreeBSD $@
$(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 $@
|