blob: 1a82ffbb26b3b4a0090a1451a02c7672df2dd9aa [file] [log] [blame]
swissChili0fc3f262021-08-09 22:05:17 -07001# Rewrite of JMK in TCL
2
3variable jmk_name {}
4variable jmk_target {}
swissChilif3d65762022-07-03 22:34:54 -07005variable jmk_clean_libs {}
6variable jmk_phony_libs {}
7variable jmk_lib_paths
8variable jmk_lib_targets
9
swissChili9b46c902022-07-10 15:48:46 -070010variable jmk_sourced
11
swissChili0fc3f262021-08-09 22:05:17 -070012variable cflags {}
13variable asmflags {}
swissChilif3d65762022-07-03 22:34:54 -070014variable ldflags {}
swissChili0fc3f262021-08-09 22:05:17 -070015
16variable asm as
swissChilif3d65762022-07-03 22:34:54 -070017variable cc gcc
18variable ld ld
19
20variable objs {}
swissChili0fc3f262021-08-09 22:05:17 -070021
swissChili35558852022-07-02 18:15:45 -070022# variable options
23
24variable src \$^
25variable first_src \$<
26variable target \$@
swissChili0fc3f262021-08-09 22:05:17 -070027
28proc 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
swissChili35558852022-07-02 18:15:45 -070038
39 puts {MAKEFILE_DEPTH ?= 1}
40
41 rule all $target {}
swissChilif3d65762022-07-03 22:34:54 -070042
43 rule Makefile Jmk2 {
44 log JMK2 ""
45 shell "cd $::jmk_build_dir && $::jmk_build_cmd"
46 }
swissChili0fc3f262021-08-09 22:05:17 -070047}
48
49proc preset {p} {
50 ::preset::$p
51}
52
53proc presets {args} {
54 foreach arg $args {
55 preset $arg
56 }
57}
58
59proc cflag {arg} {
60 global cflags
61 set cflags "$cflags $arg"
62}
63
64proc cflags {args} {
65 foreach arg $args {
66 cflag $arg
67 }
68}
69
70proc asmflag {arg} {
71 global asmflags
72 set asmflags "$asmflags $arg"
73}
74
75proc asmflags {args} {
76 foreach arg $args {
77 asmflag $arg
78 }
79}
80
swissChilif3d65762022-07-03 22:34:54 -070081proc ldflag {arg} {
82 global ldflags
83 set ldflags "$ldflags $arg"
84}
85
86proc ldflags {args} {
87 foreach arg $args {
88 ldflag $arg
89 }
90}
91
swissChili0fc3f262021-08-09 22:05:17 -070092proc option {name val} {
93 global options
94 if {![info exists options($name)]} {
95 set options($name) $val
96 }
97}
98
swissChili35558852022-07-02 18:15:45 -070099proc log {category message} {
swissChilif3d65762022-07-03 22:34:54 -0700100 puts "\t@printf ' \\e\[1;34m%8s\\e\[m %s\\n' '$category' '$message' > /dev/stderr"
swissChili35558852022-07-02 18:15:45 -0700101}
102
swissChili9b46c902022-07-10 15:48:46 -0700103proc jmk_log {message} {
104 puts stderr $message
105}
106
107proc jmk_error {message} {
108 puts stderr "\e[31mError\e[0m $message"
109 exit 1
110}
111
swissChili35558852022-07-02 18:15:45 -0700112proc cc {command} {
113 puts "\t@$::cc $command $::cflags"
114}
115
116proc asm {command} {
117 puts "\t@$::asm $command $::asmflags"
118}
119
120proc shell {command} {
121 puts "\t@$command"
122}
123
swissChilif3d65762022-07-03 22:34:54 -0700124proc make {command} {
125 shell "\$(MAKE) --no-print-directory MAKEFILE_DEPTH=\$\$((\$(MAKEFILE_DEPTH)+1)) $command"
126}
127
swissChili35558852022-07-02 18:15:45 -0700128proc rule {target deps does} {
129 puts ""
130 puts "$target: $deps"
swissChilif3d65762022-07-03 22:34:54 -0700131 uplevel 1 $does
swissChili35558852022-07-02 18:15:45 -0700132}
133
134proc type {type} {
135 ::type::$type
136}
137
swissChilif3d65762022-07-03 22:34:54 -0700138proc objs {args} {
139 foreach obj $args {
140 set ::objs "$::objs $obj"
141 }
142}
143
swissChili35558852022-07-02 18:15:45 -0700144proc srcs {args} {
145 puts ""
swissChili35558852022-07-02 18:15:45 -0700146
147 foreach src $args {
swissChili9b46c902022-07-10 15:48:46 -0700148 set src [file join [pwd] $src]
swissChili35558852022-07-02 18:15:45 -0700149 variable obj [regsub -- {(.+)\.\w+} $src {\1.o}]
swissChilif3d65762022-07-03 22:34:54 -0700150 set ::objs "$::objs $obj"
swissChili0db97752022-07-29 21:09:16 -0700151
152 if {[string match *.c $src]} {
153 variable cc $::cc
154 if {[string match *distcc* $cc]} {
155 variable cc [regsub -- {.*distcc +(.+)$} $cc {\1}]
156 }
157
158 if {[file exists $src]} {
159 puts [exec sh -c "$cc $src -MM -MT $obj $::cflags"]
160 } else {
161 rule $obj $src {}
162 }
163
swissChilia890aed2022-07-30 17:13:07 -0700164 log CC $src
swissChili0db97752022-07-29 21:09:16 -0700165 cc "-c $::first_src -o $::target"
166 puts ""
167 }
swissChilif3d65762022-07-03 22:34:54 -0700168 }
169}
170
171proc depends {name path {target DEFAULT_TARGET}} {
172 if {$target eq {DEFAULT_TARGET}} {
173 variable target "lib${name}.a"
swissChili35558852022-07-02 18:15:45 -0700174 }
175
swissChilif3d65762022-07-03 22:34:54 -0700176 set ::jmk_clean_libs "$::jmk_clean_libs $path"
177 set ::jmk_lib_paths($name) $path
178 set ::jmk_lib_target($name) $target
179 set ::jmk_phony_libs "$::jmk_phony_libs $path"
180
181 rule "$path/$target" {} {
182 log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Entering $name"
183 make "-C $path $target"
184 log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Leaving $name"
185 }
186}
187
188proc lib {name} {
189 return "$::jmk_lib_paths($name)/$::jmk_lib_target($name)"
swissChili35558852022-07-02 18:15:45 -0700190}
191
192namespace eval type {
193 proc executable {} {
194 global jmk_target
195
swissChilif3d65762022-07-03 22:34:54 -0700196 rule $jmk_target $::objs {
swissChili35558852022-07-02 18:15:45 -0700197 log LD $::target
198 cc "-o $::target $::src"
199 }
200
201 helpers
202 }
203
swissChilif3d65762022-07-03 22:34:54 -0700204proc custom_link {} {
205 global jmk_target
206
207 rule $jmk_target $::objs {
208 log LD $::target
209 shell "$::ld $::ldflags -o $::target $::src"
210 }
211
212 helpers
213}
214
swissChili35558852022-07-02 18:15:45 -0700215proc helpers {} {
swissChili0db97752022-07-29 21:09:16 -0700216 # rule .c.o {} {
217 # log CC $::first_src
218 # cc "-c $::first_src -o $::target"
219 # }
swissChili35558852022-07-02 18:15:45 -0700220
221 rule .s.o {} {
222 log ASM $::first_src
swissChili56cf8172022-07-30 18:47:48 -0700223 asm "$::asmflags $::first_src -o $::target"
swissChili35558852022-07-02 18:15:45 -0700224 }
225
226 rule clean {} {
swissChilif3d65762022-07-03 22:34:54 -0700227 shell "rm -f **/*.o **/*.a *.so $::jmk_target $::objs"
228
229 foreach lib $::jmk_clean_libs {
230 make "-C $lib clean"
231 }
swissChili35558852022-07-02 18:15:45 -0700232 }
swissChilif3d65762022-07-03 22:34:54 -0700233}
swissChili35558852022-07-02 18:15:45 -0700234}
235
swissChili0fc3f262021-08-09 22:05:17 -0700236namespace eval preset {
swissChili35558852022-07-02 18:15:45 -0700237 proc freestanding {} {
238 cflags -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding
239 }
240
241 proc optimize {} {
242 cflags -O2
243 }
244
swissChili0fc3f262021-08-09 22:05:17 -0700245 proc debug {} {
246 cflag -g
swissChili0fc3f262021-08-09 22:05:17 -0700247 }
248
249 proc warn {} {
swissChilif3d65762022-07-03 22:34:54 -0700250 cflags -Wall -Wno-unused-function -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-sign-compare
swissChili0fc3f262021-08-09 22:05:17 -0700251 }
252
swissChili56cf8172022-07-30 18:47:48 -0700253 proc 32 {} {
254 cflag -m32
255 asmflag -felf32
256 }
257
swissChili0fc3f262021-08-09 22:05:17 -0700258 proc nasm {} {
swissChili56cf8172022-07-30 18:47:48 -0700259 set ::asm nasm
260 asmflag -Fdwarf
swissChili0fc3f262021-08-09 22:05:17 -0700261 }
262}
swissChili9b46c902022-07-10 15:48:46 -0700263
264proc jmk_source {path} {
265 variable dir [pwd]
266
267 if {![file exists $path]} {
268 jmk_error "jmk_source: $dir/$path doesn't exist"
269 }
270
271 lappend ::jmk_sourced "$dir/$path"
272
273 cd [file dirname $path]
274 uplevel 1 source [file tail $path]
275 cd $dir
276}
277
278proc jmk_finalize {} {
279 puts "Jmk2: $::jmk_sourced"
280}