fix build regression
This commit is contained in:
76
build.cm
76
build.cm
@@ -127,7 +127,8 @@ var SALT_MACH = 'mach' // mach bytecode blob
|
||||
var SALT_MCODE = 'mcode' // mcode IR (JSON)
|
||||
var SALT_DEPS = 'deps' // cached cc -MM dependency list
|
||||
var SALT_FAIL = 'fail' // cached compilation failure
|
||||
var SALT_BMFST = 'bmfst' // stat-based build manifest
|
||||
var SALT_BMFST = 'bmfst' // stat-based build manifest (object level)
|
||||
var SALT_BMFST_DL = 'bmfst_dl' // stat-based build manifest (dylib level)
|
||||
|
||||
function cache_path(content, salt) {
|
||||
return get_build_dir() + '/' + content_hash(content + '\n' + salt)
|
||||
@@ -185,6 +186,54 @@ function bmfst_save(cmd_str, src_path, deps, obj_path) {
|
||||
fd.slurpwrite(mf_path, stone(blob(json.encode(mf))))
|
||||
}
|
||||
|
||||
// Dylib-level stat manifest — keyed on compile cmd + link info + src path.
|
||||
// All key inputs are available without reading any files.
|
||||
|
||||
function bmfst_dl_key(setup, link_info) {
|
||||
var parts = [setup.cmd_str, setup.src_path]
|
||||
push(parts, 'target:' + text(link_info.target))
|
||||
push(parts, 'cc:' + text(link_info.cc))
|
||||
arrfor(link_info.extra_objects, function(obj) {
|
||||
if (obj != null) push(parts, 'extra:' + text(obj))
|
||||
})
|
||||
arrfor(link_info.ldflags, function(flag) {
|
||||
push(parts, 'ldflag:' + text(flag))
|
||||
})
|
||||
arrfor(link_info.target_ldflags, function(flag) {
|
||||
push(parts, 'target_ldflag:' + text(flag))
|
||||
})
|
||||
return text(parts, '\n')
|
||||
}
|
||||
|
||||
function bmfst_dl_probe(setup, link_info) {
|
||||
var mf_path = cache_path(bmfst_dl_key(setup, link_info), SALT_BMFST_DL)
|
||||
if (!fd.is_file(mf_path)) return null
|
||||
var mf = json.decode(text(fd.slurp(mf_path)))
|
||||
if (!mf || !mf.d || !mf.dylib) return null
|
||||
if (!fd.is_file(mf.dylib)) return null
|
||||
var ok = true
|
||||
arrfor(mf.d, function(entry) {
|
||||
if (!ok) return
|
||||
var st = memo_stat(entry.p)
|
||||
if (!st || st.m != entry.m || st.s != entry.s)
|
||||
ok = false
|
||||
})
|
||||
if (!ok) return null
|
||||
return mf.dylib
|
||||
}
|
||||
|
||||
function bmfst_dl_save(setup, link_info, deps, dylib_path) {
|
||||
var entries = []
|
||||
arrfor(deps, function(dep_path) {
|
||||
var st = memo_stat(dep_path)
|
||||
if (st)
|
||||
push(entries, {p: dep_path, m: st.m, s: st.s})
|
||||
})
|
||||
var mf = {dylib: dylib_path, d: entries}
|
||||
var mf_path = cache_path(bmfst_dl_key(setup, link_info), SALT_BMFST_DL)
|
||||
fd.slurpwrite(mf_path, stone(blob(json.encode(mf))))
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Dependency scanning helpers
|
||||
// ============================================================================
|
||||
@@ -525,6 +574,17 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
||||
|
||||
var link_info = {extra_objects: _extra, ldflags: resolved_ldflags, target_ldflags: target_ldflags, target: _target, cc: cc}
|
||||
|
||||
// Stat-based dylib manifest — zero file reads on warm cache
|
||||
var mf_dylib = null
|
||||
if (!_opts.force) {
|
||||
mf_dylib = bmfst_dl_probe(setup, link_info)
|
||||
if (mf_dylib) {
|
||||
if (_opts.verbose) log.build('[verbose] manifest hit: ' + file)
|
||||
log.shop('manifest hit ' + file)
|
||||
return mf_dylib
|
||||
}
|
||||
}
|
||||
|
||||
// Probe source key — check dylib cache before compiling
|
||||
var probe = probe_source_key(setup, file)
|
||||
var dylib_path = null
|
||||
@@ -547,6 +607,7 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
||||
dylib_path = cache_path(dylib_content, SALT_DYLIB)
|
||||
if (!_opts.force && fd.is_file(dylib_path)) {
|
||||
log.shop('cache hit ' + file)
|
||||
bmfst_dl_save(setup, link_info, probe.deps, dylib_path)
|
||||
return dylib_path
|
||||
}
|
||||
|
||||
@@ -568,7 +629,10 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
||||
if (post_probe && post_probe.full_content) {
|
||||
dylib_content = compute_dylib_content(post_probe.full_content, link_info)
|
||||
dylib_path = cache_path(dylib_content, SALT_DYLIB)
|
||||
if (fd.is_file(dylib_path)) return dylib_path
|
||||
if (fd.is_file(dylib_path)) {
|
||||
bmfst_dl_save(setup, link_info, post_probe.deps, dylib_path)
|
||||
return dylib_path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -631,6 +695,13 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Save dylib manifest for future stat-based probes
|
||||
var mf_deps = null
|
||||
if (fallback_probe && fallback_probe.deps) mf_deps = fallback_probe.deps
|
||||
if (post_probe && post_probe.deps) mf_deps = post_probe.deps
|
||||
if (probe && probe.deps) mf_deps = probe.deps
|
||||
if (mf_deps) bmfst_dl_save(setup, link_info, mf_deps, dylib_path)
|
||||
|
||||
return dylib_path
|
||||
}
|
||||
|
||||
@@ -1093,6 +1164,7 @@ Build.SALT_MCODE = SALT_MCODE
|
||||
Build.SALT_DEPS = SALT_DEPS
|
||||
Build.SALT_FAIL = SALT_FAIL
|
||||
Build.SALT_BMFST = SALT_BMFST
|
||||
Build.SALT_BMFST_DL = SALT_BMFST_DL
|
||||
Build.cache_path = cache_path
|
||||
Build.manifest_path = manifest_path
|
||||
Build.native_sanitize_flags = native_sanitize_flags
|
||||
|
||||
Reference in New Issue
Block a user