swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 1 | # Rewrite of JMK in TCL |
2 | |||||
3 | variable jmk_name {} | ||||
4 | variable jmk_target {} | ||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 5 | variable jmk_clean_libs {} |
6 | variable jmk_phony_libs {} | ||||
7 | variable jmk_lib_paths | ||||
8 | variable jmk_lib_targets | ||||
9 | |||||
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 10 | variable jmk_sourced |
11 | |||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 12 | variable cflags {} |
13 | variable asmflags {} | ||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 14 | variable ldflags {} |
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 15 | |
swissChili | 14d0b84 | 2023-01-01 02:22:44 -0500 | [diff] [blame] | 16 | variable asm nasm |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 17 | variable cc gcc |
18 | variable ld ld | ||||
19 | |||||
20 | variable objs {} | ||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 21 | |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 22 | # variable options |
23 | |||||
24 | variable src \$^ | ||||
25 | variable first_src \$< | ||||
26 | variable target \$@ | ||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 27 | |
28 | proc init {name {target {DEFAULT_TARGET}}} { | ||||
29 | if {$target eq {DEFAULT_TARGET}} { | ||||
30 | set target $name | ||||
31 | } | ||||
32 | |||||
33 | global jmk_name | ||||
34 | global jmk_target | ||||
35 | |||||
36 | set jmk_name $name | ||||
37 | set jmk_target $target | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 38 | |
39 | puts {MAKEFILE_DEPTH ?= 1} | ||||
40 | |||||
41 | rule all $target {} | ||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 42 | |
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 43 | } |
44 | |||||
45 | proc preset {p} { | ||||
46 | ::preset::$p | ||||
47 | } | ||||
48 | |||||
49 | proc presets {args} { | ||||
50 | foreach arg $args { | ||||
51 | preset $arg | ||||
52 | } | ||||
53 | } | ||||
54 | |||||
55 | proc cflag {arg} { | ||||
56 | global cflags | ||||
57 | set cflags "$cflags $arg" | ||||
58 | } | ||||
59 | |||||
60 | proc cflags {args} { | ||||
61 | foreach arg $args { | ||||
62 | cflag $arg | ||||
63 | } | ||||
64 | } | ||||
65 | |||||
66 | proc asmflag {arg} { | ||||
67 | global asmflags | ||||
68 | set asmflags "$asmflags $arg" | ||||
69 | } | ||||
70 | |||||
71 | proc asmflags {args} { | ||||
72 | foreach arg $args { | ||||
73 | asmflag $arg | ||||
74 | } | ||||
75 | } | ||||
76 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 77 | proc ldflag {arg} { |
78 | global ldflags | ||||
79 | set ldflags "$ldflags $arg" | ||||
80 | } | ||||
81 | |||||
82 | proc ldflags {args} { | ||||
83 | foreach arg $args { | ||||
84 | ldflag $arg | ||||
85 | } | ||||
86 | } | ||||
87 | |||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 88 | proc option {name val} { |
89 | global options | ||||
90 | if {![info exists options($name)]} { | ||||
91 | set options($name) $val | ||||
92 | } | ||||
93 | } | ||||
94 | |||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 95 | proc log {category message} { |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 96 | puts "\t@printf ' \\e\[1;34m%8s\\e\[m %s\\n' '$category' '$message' > /dev/stderr" |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 97 | } |
98 | |||||
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 99 | proc jmk_log {message} { |
100 | puts stderr $message | ||||
101 | } | ||||
102 | |||||
103 | proc jmk_error {message} { | ||||
104 | puts stderr "\e[31mError\e[0m $message" | ||||
105 | exit 1 | ||||
106 | } | ||||
107 | |||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 108 | proc cc {command} { |
109 | puts "\t@$::cc $command $::cflags" | ||||
110 | } | ||||
111 | |||||
112 | proc asm {command} { | ||||
113 | puts "\t@$::asm $command $::asmflags" | ||||
114 | } | ||||
115 | |||||
116 | proc shell {command} { | ||||
117 | puts "\t@$command" | ||||
118 | } | ||||
119 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 120 | proc make {command} { |
121 | shell "\$(MAKE) --no-print-directory MAKEFILE_DEPTH=\$\$((\$(MAKEFILE_DEPTH)+1)) $command" | ||||
122 | } | ||||
123 | |||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 124 | proc rule {target deps does} { |
125 | puts "" | ||||
126 | puts "$target: $deps" | ||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 127 | uplevel 1 $does |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 128 | } |
129 | |||||
130 | proc type {type} { | ||||
131 | ::type::$type | ||||
132 | } | ||||
133 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 134 | proc objs {args} { |
135 | foreach obj $args { | ||||
136 | set ::objs "$::objs $obj" | ||||
137 | } | ||||
138 | } | ||||
139 | |||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 140 | proc srcs {args} { |
141 | puts "" | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 142 | |
143 | foreach src $args { | ||||
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 144 | set src [file join [pwd] $src] |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 145 | variable obj [regsub -- {(.+)\.\w+} $src {\1.o}] |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 146 | set ::objs "$::objs $obj" |
swissChili | 0db9775 | 2022-07-29 21:09:16 -0700 | [diff] [blame] | 147 | |
swissChili | e4229a2 | 2023-01-01 15:59:53 -0500 | [diff] [blame^] | 148 | set relpath [exec sh -c "realpath --relative-to '$::jmk_makefile_dir' '$src'"] |
149 | |||||
swissChili | 0db9775 | 2022-07-29 21:09:16 -0700 | [diff] [blame] | 150 | if {[string match *.c $src]} { |
151 | variable cc $::cc | ||||
152 | if {[string match *distcc* $cc]} { | ||||
153 | variable cc [regsub -- {.*distcc +(.+)$} $cc {\1}] | ||||
154 | } | ||||
155 | |||||
156 | if {[file exists $src]} { | ||||
157 | puts [exec sh -c "$cc $src -MM -MT $obj $::cflags"] | ||||
158 | } else { | ||||
159 | rule $obj $src {} | ||||
160 | } | ||||
161 | |||||
swissChili | e4229a2 | 2023-01-01 15:59:53 -0500 | [diff] [blame^] | 162 | log CC $relpath |
swissChili | 0db9775 | 2022-07-29 21:09:16 -0700 | [diff] [blame] | 163 | cc "-c $::first_src -o $::target" |
164 | puts "" | ||||
swissChili | e4229a2 | 2023-01-01 15:59:53 -0500 | [diff] [blame^] | 165 | } elseif {[string match *.s $src]} { |
166 | log ASM $relpath | ||||
167 | rule $obj $src { | ||||
168 | asm "$::asmflags $::first_src -o $::target" | ||||
169 | } | ||||
swissChili | 0db9775 | 2022-07-29 21:09:16 -0700 | [diff] [blame] | 170 | } |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 171 | } |
172 | } | ||||
173 | |||||
174 | proc depends {name path {target DEFAULT_TARGET}} { | ||||
175 | if {$target eq {DEFAULT_TARGET}} { | ||||
176 | variable target "lib${name}.a" | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 177 | } |
178 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 179 | set ::jmk_clean_libs "$::jmk_clean_libs $path" |
180 | set ::jmk_lib_paths($name) $path | ||||
181 | set ::jmk_lib_target($name) $target | ||||
182 | set ::jmk_phony_libs "$::jmk_phony_libs $path" | ||||
183 | |||||
184 | rule "$path/$target" {} { | ||||
185 | log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Entering $name" | ||||
186 | make "-C $path $target" | ||||
187 | log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Leaving $name" | ||||
188 | } | ||||
189 | } | ||||
190 | |||||
191 | proc lib {name} { | ||||
192 | return "$::jmk_lib_paths($name)/$::jmk_lib_target($name)" | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 193 | } |
194 | |||||
195 | namespace eval type { | ||||
196 | proc executable {} { | ||||
197 | global jmk_target | ||||
198 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 199 | rule $jmk_target $::objs { |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 200 | log LD $::target |
201 | cc "-o $::target $::src" | ||||
202 | } | ||||
203 | |||||
204 | helpers | ||||
205 | } | ||||
206 | |||||
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 207 | proc custom_link {} { |
208 | global jmk_target | ||||
209 | |||||
210 | rule $jmk_target $::objs { | ||||
211 | log LD $::target | ||||
212 | shell "$::ld $::ldflags -o $::target $::src" | ||||
213 | } | ||||
214 | |||||
215 | helpers | ||||
216 | } | ||||
217 | |||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 218 | proc helpers {} { |
swissChili | 0db9775 | 2022-07-29 21:09:16 -0700 | [diff] [blame] | 219 | # rule .c.o {} { |
220 | # log CC $::first_src | ||||
221 | # cc "-c $::first_src -o $::target" | ||||
222 | # } | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 223 | |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 224 | rule clean {} { |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 225 | shell "rm -f **/*.o **/*.a *.so $::jmk_target $::objs" |
226 | |||||
227 | foreach lib $::jmk_clean_libs { | ||||
228 | make "-C $lib clean" | ||||
229 | } | ||||
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 230 | } |
swissChili | f3d6576 | 2022-07-03 22:34:54 -0700 | [diff] [blame] | 231 | } |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 232 | } |
233 | |||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 234 | namespace eval preset { |
swissChili | 3555885 | 2022-07-02 18:15:45 -0700 | [diff] [blame] | 235 | proc freestanding {} { |
236 | cflags -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding | ||||
237 | } | ||||
238 | |||||
239 | proc optimize {} { | ||||
240 | cflags -O2 | ||||
241 | } | ||||
242 | |||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 243 | proc debug {} { |
244 | cflag -g | ||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 245 | } |
246 | |||||
247 | proc warn {} { | ||||
swissChili | e4229a2 | 2023-01-01 15:59:53 -0500 | [diff] [blame^] | 248 | cflags -Wall |
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 249 | } |
250 | |||||
swissChili | 56cf817 | 2022-07-30 18:47:48 -0700 | [diff] [blame] | 251 | proc 32 {} { |
252 | cflag -m32 | ||||
253 | asmflag -felf32 | ||||
254 | } | ||||
255 | |||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 256 | proc nasm {} { |
swissChili | 56cf817 | 2022-07-30 18:47:48 -0700 | [diff] [blame] | 257 | set ::asm nasm |
258 | asmflag -Fdwarf | ||||
swissChili | 0fc3f26 | 2021-08-09 22:05:17 -0700 | [diff] [blame] | 259 | } |
260 | } | ||||
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 261 | |
262 | proc jmk_source {path} { | ||||
263 | variable dir [pwd] | ||||
264 | |||||
265 | if {![file exists $path]} { | ||||
swissChili | 14d0b84 | 2023-01-01 02:22:44 -0500 | [diff] [blame] | 266 | jmk_error "jmk_source: $path doesn't exist" |
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 267 | } |
268 | |||||
swissChili | 14d0b84 | 2023-01-01 02:22:44 -0500 | [diff] [blame] | 269 | lappend ::jmk_sourced "$path" |
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 270 | |
271 | cd [file dirname $path] | ||||
272 | uplevel 1 source [file tail $path] | ||||
273 | cd $dir | ||||
274 | } | ||||
275 | |||||
276 | proc jmk_finalize {} { | ||||
swissChili | 14d0b84 | 2023-01-01 02:22:44 -0500 | [diff] [blame] | 277 | rule Makefile "Jmk2 $::jmk_sourced" { |
278 | log JMK2 "" | ||||
279 | shell "cd $::jmk_build_dir && $::jmk_build_cmd" | ||||
280 | } | ||||
swissChili | 9b46c90 | 2022-07-10 15:48:46 -0700 | [diff] [blame] | 281 | } |