remove sdl header reqs; better compile invalidation

This commit is contained in:
2025-12-05 19:31:56 -06:00
parent 7a6209df72
commit 744f64b83b
5 changed files with 120 additions and 37 deletions

View File

@@ -101,7 +101,7 @@ JSValue js_crypto_blake2(JSContext *js, JSValue self, int argc, JSValue *argv)
size_t data_bits;
uint8_t *data = get_blob_any(js, argv[0], &data_bits, "crypto.blake2 data");
if (data == -1) return JS_EXCEPTION;
if (!data) return JS_EXCEPTION;
int32_t hash_len = 32;
if (argc > 1) {

View File

@@ -466,7 +466,7 @@ JSC_CCALL(fd_is_file,
struct stat st;
if (stat(path, &st) != 0) {
JS_FreeCString(js, path);
return JS_NewBool(js, false);
return JS_NewBool(js, 0);
}
JS_FreeCString(js, path);
@@ -480,7 +480,7 @@ JSC_CCALL(fd_is_dir,
struct stat st;
if (stat(path, &st) != 0) {
JS_FreeCString(js, path);
return JS_NewBool(js, false);
return JS_NewBool(js, 0);
}
JS_FreeCString(js, path);

View File

@@ -1156,6 +1156,10 @@ Shop.build_package = function(package)
else use_prefix = 'js_' + package.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_') + '_'
var c_objects = []
function get_hash(str) {
return text(crypto.blake2(utf8.encode(str)), 'h')
}
for (var i=0; i<files.length; i++) {
var file = files[i]
@@ -1175,34 +1179,101 @@ Shop.build_package = function(package)
} else if (file.endsWith('.c') || file.endsWith('.cpp')) {
// Compile C
var obj_path = build_dir + '/' + file + '.o'
var meta_path = obj_path + '.meta'
ensure_dir(obj_path.substring(0, obj_path.lastIndexOf('/')))
var safe_path = file.substring(0, file.lastIndexOf('.')).replace(/\//g, '_').replace(/\\/g, '_').replace(/\./g, '_').replace(/-/g, '_')
var use_name = use_prefix + safe_path + '_use'
var comp_src = file
var comp_obj = file + '.o'
var base_cmd = 'cc -fPIC '
var compile_flags = '-c ' + comp_src + ' -O3 -DCELL_USE_NAME=' + use_name
if (cflags != '') compile_flags += ' ' + cflags
var full_compile_cmd = 'cd ' + module_dir + ' && ' + base_cmd + compile_flags + ' -o ' + comp_obj
var cmd_hash = get_hash(full_compile_cmd)
var needs_compile = true
if (fd.is_file(obj_path)) {
var st_src = fd.stat(src_path)
var st_obj = fd.stat(obj_path)
if (st_src && st_obj && st_src.mtime <= st_obj.mtime) {
needs_compile = false
var meta = null
if (fd.is_file(obj_path) && fd.is_file(meta_path)) {
try {
meta = json.decode(text(fd.slurp(meta_path)))
} catch(e) {}
if (meta && meta.cmd_hash == cmd_hash) {
var st_src = fd.stat(src_path)
var st_obj = fd.stat(obj_path)
if (st_src && st_obj && st_src.mtime <= st_obj.mtime) {
needs_compile = false
// Check headers
if (meta.headers) {
for (var h = 0; h < meta.headers.length; h++) {
var header_rel = meta.headers[h]
var header_full
if (header_rel.startsWith('/'))
header_full = header_rel
else
header_full = module_dir + '/' + header_rel
if (!fd.is_file(header_full)) {
log.console(`coulnd't find header ${header_full}`)
needs_compile = true; break;
}
var st_h = fd.stat(header_full)
if (st_h.mtime > st_obj.mtime) {
log.console(`${header_full} out of date`)
needs_compile = true; break;
}
}
}
}
}
}
if (needs_compile) {
log.console("Compiling " + src_path + " -> " + obj_path)
var comp_src = file
var comp_obj = file + '.o'
var cmd = 'cd ' + module_dir + ' && cc -fPIC -c ' + comp_src + ' -O3 -DCELL_USE_NAME=' + use_name + ' -o ' + comp_obj
if (cflags != '') cmd += ' ' + cflags
var ret = os.system(cmd)
// 1. Generate dependencies
var deps_file = comp_obj + '.d'
// Use same flags but with -M
var deps_cmd = 'cd ' + module_dir + ' && ' + base_cmd + '-MM ' + compile_flags + ' > ' + deps_file
os.system(deps_cmd)
var headers = []
var deps_full_path = module_dir + '/' + deps_file
if (fd.is_file(deps_full_path)) {
var deps_content = text(fd.slurp(deps_full_path))
deps_content = deps_content.replace(/\\\n/g, ' ').replace(/\\\r\n/g, ' ').replace(/\n/g, ' ')
var parts = deps_content.split(' ')
for (var p=0; p<parts.length; p++) {
var part = parts[p].trim()
if (part == '' || part.endsWith(':')) continue
if (part == comp_src) continue
headers.push(part)
}
fd.rm(deps_full_path)
}
// 2. Compile
var ret = os.system(full_compile_cmd)
if (ret != 0) {
log.error("Compilation failed for " + src_path)
return false
}
// now move it
// 3. Move object
os.system('mv ' + module_dir + '/' + comp_obj + ' ' + obj_path)
// 4. Write meta
var new_meta = {
cmd_hash: cmd_hash,
headers: headers
}
fd.slurpwrite(meta_path, utf8.encode(json.encode(new_meta)))
}
c_objects.push(obj_path)
}
@@ -1211,16 +1282,39 @@ Shop.build_package = function(package)
// Link if there are C objects
if (c_objects.length > 0) {
var lib_name = build_dir + '/cellmod' + dylib_ext
var lib_meta_path = lib_name + '.meta'
var link_flags = '-fPIC -shared'
var ldflags = get_flags(config, platform, 'LDFLAGS')
if (ldflags != '') link_flags += ' ' + ldflags
var temp_lib = 'cellmod' + dylib_ext
var objs_str = ''
for (var i=0; i<c_objects.length; i++) {
objs_str += '"$HERE/' + c_objects[i] + '" '
}
var link_cmd = 'HERE=$(pwd); cd ' + module_dir + ' && cc ' + link_flags + ' ' + objs_str + ' -lcell_runtime -lc -lc++ -o ' + temp_lib
var link_cmd_hash = get_hash(link_cmd)
// Check if we need to relink
var needs_link = true
if (fd.is_file(lib_name)) {
var lib_time = fd.stat(lib_name).mtime
needs_link = false
for (var i=0; i<c_objects.length; i++) {
if (fd.stat(c_objects[i]).mtime > lib_time) {
needs_link = true
break
if (fd.is_file(lib_name) && fd.is_file(lib_meta_path)) {
var meta = null
try {
meta = json.decode(text(fd.slurp(lib_meta_path)))
} catch(e) {}
if (meta && meta.cmd_hash == link_cmd_hash) {
var lib_time = fd.stat(lib_name).mtime
needs_link = false
for (var i=0; i<c_objects.length; i++) {
if (fd.stat(c_objects[i]).mtime > lib_time) {
needs_link = true
break
}
}
}
}
@@ -1228,24 +1322,14 @@ Shop.build_package = function(package)
if (needs_link) {
log.console("Linking " + lib_name)
var link_flags = '-fPIC -shared'
var ldflags = get_flags(config, platform, 'LDFLAGS')
if (ldflags != '') link_flags += ' ' + ldflags
var temp_lib = 'cellmod' + dylib_ext
var objs_str = ''
for (var i=0; i<c_objects.length; i++) {
objs_str += '"$HERE/' + c_objects[i] + '" '
}
var link_cmd = 'HERE=$(pwd); cd ' + module_dir + ' && cc ' + link_flags + ' ' + objs_str + ' -lcell_runtime -lc -lc++ -o ' + temp_lib
var ret = os.system(link_cmd)
if (ret != 0) {
log.error("Linking failed")
return false
}
os.system('mv ' + module_dir + '/' + temp_lib + ' ' + lib_name)
fd.slurpwrite(lib_meta_path, utf8.encode(json.encode({ cmd_hash: link_cmd_hash })))
}
log.console("Built " + lib_name)
}

View File

@@ -1,7 +1,6 @@
#ifndef CELL_H
#define CELL_H
#include <SDL3/SDL.h>
#include "quickjs.h"
#include "blob.h"
@@ -20,7 +19,7 @@ double cell_random();
uint64_t cell_random_fit();
int JS_ArrayLength(JSContext *js, JSValue a);
int js2bool(JSContext *js, JSValue v);
JSValue bool2js(JSContext *js, int b);
double js2number(JSContext *js, JSValue v);

View File

@@ -48,10 +48,10 @@ mi_heap_t *heap;
letter *letters;
/* CHANGED FOR EVENTS: a separate lock for the actor->events queue */
struct { Uint32 key; JSValue value; } *timers;
struct { uint32_t key; JSValue value; } *timers;
int state;
Uint32 ar; // timer for unneeded
uint32_t ar; // timer for unneeded
double ar_secs; // time for unneeded
JSValue unneeded; // fn to call before unneeded