Port kernel to Jmk2
diff --git a/share/jmk/jmk.tcl b/share/jmk/jmk.tcl
index d1de805..b3b860c 100644
--- a/share/jmk/jmk.tcl
+++ b/share/jmk/jmk.tcl
@@ -2,11 +2,20 @@
 
 variable jmk_name {}
 variable jmk_target {}
+variable jmk_clean_libs {}
+variable jmk_phony_libs {}
+variable jmk_lib_paths
+variable jmk_lib_targets
+
 variable cflags {}
 variable asmflags {}
+variable ldflags {}
 
 variable asm as
-variable cc cc
+variable cc gcc
+variable ld ld
+
+variable objs {}
 
 # variable options
 
@@ -28,6 +37,11 @@
 	puts {MAKEFILE_DEPTH ?= 1}
 
 	rule all $target {}
+
+	rule Makefile Jmk2 {
+		log JMK2 ""
+		shell "cd $::jmk_build_dir && $::jmk_build_cmd"
+	}
 }
 
 proc preset {p} {
@@ -62,6 +76,17 @@
 	}
 }
 
+proc ldflag {arg} {
+	global ldflags
+	set ldflags "$ldflags $arg"
+}
+
+proc ldflags {args} {
+	foreach arg $args {
+		ldflag $arg
+	}
+}
+
 proc option {name val} {
 	global options
 	if {![info exists options($name)]} {
@@ -70,7 +95,7 @@
 }
 
 proc log {category message} {
-	puts "\t@printf '\\e\[1;34m%8s\\e\[m  %s\\n' '$category' '$message' > /dev/stderr"
+	puts "\t@printf ' \\e\[1;34m%8s\\e\[m  %s\\n' '$category' '$message' > /dev/stderr"
 }
 
 proc cc {command} {
@@ -85,33 +110,62 @@
 	puts "\t@$command"
 }
 
+proc make {command} {
+	shell "\$(MAKE) --no-print-directory MAKEFILE_DEPTH=\$\$((\$(MAKEFILE_DEPTH)+1)) $command"
+}
+
 proc rule {target deps does} {
 	puts ""
 	puts "$target: $deps"
-	eval $does
+	uplevel 1 $does
 }
 
 proc type {type} {
 	::type::$type
 }
 
+proc objs {args} {
+	foreach obj $args {
+		set ::objs "$::objs $obj"
+	}
+}
+
 proc srcs {args} {
 	puts ""
 	variable objs ""
 
 	foreach src $args {
 		variable obj [regsub -- {(.+)\.\w+} $src {\1.o}]
-		variable objs "$objs $obj"
+		set ::objs "$::objs $obj"
+	}
+}
+
+proc depends {name path {target DEFAULT_TARGET}} {
+	if {$target eq {DEFAULT_TARGET}} {
+		variable target "lib${name}.a"
 	}
 
-	puts "OBJECTS += $objs"
+	set ::jmk_clean_libs "$::jmk_clean_libs $path"
+	set ::jmk_lib_paths($name) $path
+	set ::jmk_lib_target($name) $target
+	set ::jmk_phony_libs "$::jmk_phony_libs $path"
+
+	rule "$path/$target" {} {
+		log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Entering $name"
+		make "-C $path $target"
+		log "MAKE\[\$(MAKEFILE_DEPTH)\]" "Leaving $name"
+	}
+}
+
+proc lib {name} {
+	return "$::jmk_lib_paths($name)/$::jmk_lib_target($name)"
 }
 
 namespace eval type {
 	proc executable {} {
 		global jmk_target
 
-		rule $jmk_target "\$(OBJECTS)" {
+		rule $jmk_target $::objs {
 			log LD $::target
 			cc "-o $::target $::src"
 		}
@@ -119,6 +173,17 @@
 		helpers
 	}
 
+proc custom_link {} {
+	global jmk_target
+
+	rule $jmk_target $::objs {
+		log LD $::target
+		shell "$::ld $::ldflags -o $::target $::src"
+	}
+
+	helpers
+}
+
 proc helpers {} {
 	rule .c.o {} {
 		log CC $::first_src
@@ -131,9 +196,13 @@
 	}
 
 	rule clean {} {
-		shell "rm -f **/*.o **/*.a *.so $::target \$(OBJECTS)"
+		shell "rm -f **/*.o **/*.a *.so $::jmk_target $::objs"
+
+		foreach lib $::jmk_clean_libs {
+			make "-C $lib clean"
+		}
 	}
-}	
+}
 }
 
 namespace eval preset {
@@ -156,7 +225,7 @@
 	}
 
 	proc warn {} {
-		cflags -Wall -Wextra -Wno-unused-function -Wno-unused-variable -Wno-incompatible-pointer-types -Werror
+		cflags -Wall -Wno-unused-function -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-sign-compare
 	}
 
 	proc nasm {} {