blob: 13f3fca0cc98327e9c7d8f59717673d26c29f9d5 [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
swissChili14d0b842023-01-01 02:22:44 -050016variable asm nasm
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
swissChili0fc3f262021-08-09 22:05:17 -070043}
44
45proc preset {p} {
46 ::preset::$p
47}
48
49proc presets {args} {
50 foreach arg $args {
51 preset $arg
52 }
53}
54
55proc cflag {arg} {
56 global cflags
57 set cflags "$cflags $arg"
58}
59
60proc cflags {args} {
61 foreach arg $args {
62 cflag $arg
63 }
64}
65
66proc asmflag {arg} {
67 global asmflags
68 set asmflags "$asmflags $arg"
69}
70
71proc asmflags {args} {
72 foreach arg $args {
73 asmflag $arg
74 }
75}
76
swissChilif3d65762022-07-03 22:34:54 -070077proc ldflag {arg} {
78 global ldflags
79 set ldflags "$ldflags $arg"
80}
81
82proc ldflags {args} {
83 foreach arg $args {
84 ldflag $arg
85 }
86}
87
swissChili0fc3f262021-08-09 22:05:17 -070088proc option {name val} {
89 global options
90 if {![info exists options($name)]} {
91 set options($name) $val
92 }
93}
94
swissChili35558852022-07-02 18:15:45 -070095proc log {category message} {
swissChilif3d65762022-07-03 22:34:54 -070096 puts "\t@printf ' \\e\[1;34m%8s\\e\[m %s\\n' '$category' '$message' > /dev/stderr"
swissChili35558852022-07-02 18:15:45 -070097}
98
swissChili9b46c902022-07-10 15:48:46 -070099proc jmk_log {message} {
100 puts stderr $message
101}
102
103proc jmk_error {message} {
104 puts stderr "\e[31mError\e[0m $message"
105 exit 1
106}
107
swissChili35558852022-07-02 18:15:45 -0700108proc cc {command} {
109 puts "\t@$::cc $command $::cflags"
110}
111
112proc asm {command} {
113 puts "\t@$::asm $command $::asmflags"
114}
115
116proc shell {command} {
117 puts "\t@$command"
118}
119
swissChilif3d65762022-07-03 22:34:54 -0700120proc make {command} {
121 shell "\$(MAKE) --no-print-directory MAKEFILE_DEPTH=\$\$((\$(MAKEFILE_DEPTH)+1)) $command"
122}
123
swissChili35558852022-07-02 18:15:45 -0700124proc rule {target deps does} {
125 puts ""
126 puts "$target: $deps"
swissChilif3d65762022-07-03 22:34:54 -0700127 uplevel 1 $does
swissChili35558852022-07-02 18:15:45 -0700128}
129
130proc type {type} {
131 ::type::$type
132}
133
swissChilif3d65762022-07-03 22:34:54 -0700134proc objs {args} {
135 foreach obj $args {
136 set ::objs "$::objs $obj"
137 }
138}
139
swissChili35558852022-07-02 18:15:45 -0700140proc srcs {args} {
141 puts ""
swissChili35558852022-07-02 18:15:45 -0700142
143 foreach src $args {
swissChili9b46c902022-07-10 15:48:46 -0700144 set src [file join [pwd] $src]
swissChili35558852022-07-02 18:15:45 -0700145 variable obj [regsub -- {(.+)\.\w+} $src {\1.o}]
swissChilif3d65762022-07-03 22:34:54 -0700146 set ::objs "$::objs $obj"
swissChili0db97752022-07-29 21:09:16 -0700147
148 if {[string match *.c $src]} {
149 variable cc $::cc
150 if {[string match *distcc* $cc]} {
151 variable cc [regsub -- {.*distcc +(.+)$} $cc {\1}]
152 }
153
154 if {[file exists $src]} {
155 puts [exec sh -c "$cc $src -MM -MT $obj $::cflags"]
156 } else {
157 rule $obj $src {}
158 }
159
swissChilia890aed2022-07-30 17:13:07 -0700160 log CC $src
swissChili0db97752022-07-29 21:09:16 -0700161 cc "-c $::first_src -o $::target"
162 puts ""
163 }
swissChilif3d65762022-07-03 22:34:54 -0700164 }
165}
166
167proc depends {name path {target DEFAULT_TARGET}} {
168 if {$target eq {DEFAULT_TARGET}} {
169 variable target "lib${name}.a"
swissChili35558852022-07-02 18:15:45 -0700170 }
171
swissChilif3d65762022-07-03 22:34:54 -0700172 set ::jmk_clean_libs "$::jmk_clean_libs $path"
173 set ::jmk_lib_paths($name) $path
174 set ::jmk_lib_target($name) $target
175 set ::jmk_phony_libs "$::jmk_phony_libs $path"
176
177 rule "$path/$target" {} {
178 log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Entering $name"
179 make "-C $path $target"
180 log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Leaving $name"
181 }
182}
183
184proc lib {name} {
185 return "$::jmk_lib_paths($name)/$::jmk_lib_target($name)"
swissChili35558852022-07-02 18:15:45 -0700186}
187
188namespace eval type {
189 proc executable {} {
190 global jmk_target
191
swissChilif3d65762022-07-03 22:34:54 -0700192 rule $jmk_target $::objs {
swissChili35558852022-07-02 18:15:45 -0700193 log LD $::target
194 cc "-o $::target $::src"
195 }
196
197 helpers
198 }
199
swissChilif3d65762022-07-03 22:34:54 -0700200proc custom_link {} {
201 global jmk_target
202
203 rule $jmk_target $::objs {
204 log LD $::target
205 shell "$::ld $::ldflags -o $::target $::src"
206 }
207
208 helpers
209}
210
swissChili35558852022-07-02 18:15:45 -0700211proc helpers {} {
swissChili0db97752022-07-29 21:09:16 -0700212 # rule .c.o {} {
213 # log CC $::first_src
214 # cc "-c $::first_src -o $::target"
215 # }
swissChili35558852022-07-02 18:15:45 -0700216
217 rule .s.o {} {
218 log ASM $::first_src
swissChili56cf8172022-07-30 18:47:48 -0700219 asm "$::asmflags $::first_src -o $::target"
swissChili35558852022-07-02 18:15:45 -0700220 }
221
222 rule clean {} {
swissChilif3d65762022-07-03 22:34:54 -0700223 shell "rm -f **/*.o **/*.a *.so $::jmk_target $::objs"
224
225 foreach lib $::jmk_clean_libs {
226 make "-C $lib clean"
227 }
swissChili35558852022-07-02 18:15:45 -0700228 }
swissChilif3d65762022-07-03 22:34:54 -0700229}
swissChili35558852022-07-02 18:15:45 -0700230}
231
swissChili0fc3f262021-08-09 22:05:17 -0700232namespace eval preset {
swissChili35558852022-07-02 18:15:45 -0700233 proc freestanding {} {
234 cflags -nostdlib -nostdinc -fno-builtin -fno-stack-protector -ffreestanding
235 }
236
237 proc optimize {} {
238 cflags -O2
239 }
240
swissChili0fc3f262021-08-09 22:05:17 -0700241 proc debug {} {
242 cflag -g
swissChili0fc3f262021-08-09 22:05:17 -0700243 }
244
245 proc warn {} {
swissChilif3d65762022-07-03 22:34:54 -0700246 cflags -Wall -Wno-unused-function -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-sign-compare
swissChili0fc3f262021-08-09 22:05:17 -0700247 }
248
swissChili56cf8172022-07-30 18:47:48 -0700249 proc 32 {} {
250 cflag -m32
251 asmflag -felf32
252 }
253
swissChili0fc3f262021-08-09 22:05:17 -0700254 proc nasm {} {
swissChili56cf8172022-07-30 18:47:48 -0700255 set ::asm nasm
256 asmflag -Fdwarf
swissChili0fc3f262021-08-09 22:05:17 -0700257 }
258}
swissChili9b46c902022-07-10 15:48:46 -0700259
260proc jmk_source {path} {
261 variable dir [pwd]
262
263 if {![file exists $path]} {
swissChili14d0b842023-01-01 02:22:44 -0500264 jmk_error "jmk_source: $path doesn't exist"
swissChili9b46c902022-07-10 15:48:46 -0700265 }
266
swissChili14d0b842023-01-01 02:22:44 -0500267 lappend ::jmk_sourced "$path"
swissChili9b46c902022-07-10 15:48:46 -0700268
269 cd [file dirname $path]
270 uplevel 1 source [file tail $path]
271 cd $dir
272}
273
274proc jmk_finalize {} {
swissChili14d0b842023-01-01 02:22:44 -0500275 rule Makefile "Jmk2 $::jmk_sourced" {
276 log JMK2 ""
277 shell "cd $::jmk_build_dir && $::jmk_build_cmd"
278 }
swissChili9b46c902022-07-10 15:48:46 -0700279}