Merge branch 'cell_lsp'

This commit is contained in:
2026-02-17 09:01:28 -06:00
7 changed files with 487 additions and 157 deletions

View File

@@ -26,16 +26,18 @@ function get_local_dir() {
}
// Replace sigils in a string
// Currently supports: $LOCAL -> .cell/local full path
function replace_sigils(str) {
return replace(str, '$LOCAL', get_local_dir())
// Supports: $LOCAL -> .cell/local, $PACKAGE -> package dir (if provided)
function replace_sigils(str, pkg_dir) {
var r = replace(str, '$LOCAL', get_local_dir())
if (pkg_dir) r = replace(r, '$PACKAGE', pkg_dir)
return r
}
// Replace sigils in an array of flags
function replace_sigils_array(flags) {
function replace_sigils_array(flags, pkg_dir) {
var result = []
arrfor(flags, function(flag) {
push(result, replace_sigils(flag))
push(result, replace_sigils(flag, pkg_dir))
})
return result
}
@@ -101,8 +103,9 @@ Build.ensure_dir = ensure_dir
// Compile a single C file for a package
// Returns the object file path (content-addressed in .cell/build)
Build.compile_file = function(pkg, file, target, buildtype) {
var _buildtype = buildtype || 'release'
Build.compile_file = function(pkg, file, target, opts) {
var _opts = opts || {}
var _buildtype = _opts.buildtype || 'release'
var pkg_dir = shop.get_package_dir(pkg)
var src_path = pkg_dir + '/' + file
var core_dir = null
@@ -112,8 +115,8 @@ Build.compile_file = function(pkg, file, target, buildtype) {
return null
}
// Get flags (with sigil replacement)
var cflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'CFLAGS', target))
// Use pre-fetched cflags if provided, otherwise fetch them
var cflags = _opts.cflags || replace_sigils_array(pkg_tools.get_flags(pkg, 'CFLAGS', target), pkg_dir)
var target_cflags = toolchains[target].c_args || []
var cc = toolchains[target].c
@@ -144,8 +147,12 @@ Build.compile_file = function(pkg, file, target, buildtype) {
// Add package CFLAGS (resolve relative -I paths)
arrfor(cflags, function(flag) {
var f = flag
var ipath = null
if (starts_with(f, '-I') && !starts_with(f, '-I/')) {
f = '-I"' + pkg_dir + '/' + text(f, 2) + '"'
ipath = text(f, 2)
if (!starts_with(ipath, pkg_dir)) {
f = '-I"' + pkg_dir + '/' + ipath + '"'
}
}
push(cmd_parts, f)
})
@@ -179,6 +186,7 @@ Build.compile_file = function(pkg, file, target, buildtype) {
var ret = os.system(full_cmd)
if (ret != 0) {
print('Compilation failed: ' + file)
print('Command: ' + full_cmd)
return null
}
@@ -193,8 +201,12 @@ Build.build_package = function(pkg, target, exclude_main, buildtype) {
var c_files = pkg_tools.get_c_files(pkg, _target, exclude_main)
var objects = []
// Pre-fetch cflags once
var pkg_dir = shop.get_package_dir(pkg)
var cached_cflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'CFLAGS', _target), pkg_dir)
arrfor(c_files, function(file) {
var obj = Build.compile_file(pkg, file, _target, _buildtype)
var obj = Build.compile_file(pkg, file, _target, {buildtype: _buildtype, cflags: cached_cflags})
push(objects, obj)
})
@@ -235,7 +247,7 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
var _target = target || Build.detect_host_target()
var _buildtype = _opts.buildtype || 'release'
var _extra = _opts.extra_objects || []
var obj = Build.compile_file(pkg, file, _target, _buildtype)
var obj = Build.compile_file(pkg, file, _target, {buildtype: _buildtype, cflags: _opts.cflags})
if (!obj) return null
var tc = toolchains[_target]
@@ -245,13 +257,17 @@ Build.build_module_dylib = function(pkg, file, target, opts) {
var pkg_dir = shop.get_package_dir(pkg)
// Get link flags
var ldflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'LDFLAGS', _target))
var ldflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'LDFLAGS', _target), pkg_dir)
var target_ldflags = tc.c_link_args || []
var resolved_ldflags = []
arrfor(ldflags, function(flag) {
var f = flag
var lpath = null
if (starts_with(f, '-L') && !starts_with(f, '-L/')) {
f = '-L"' + pkg_dir + '/' + text(f, 2) + '"'
lpath = text(f, 2)
if (!starts_with(lpath, pkg_dir)) {
f = '-L"' + pkg_dir + '/' + lpath + '"'
}
}
push(resolved_ldflags, f)
})
@@ -333,17 +349,23 @@ Build.build_dynamic = function(pkg, target, buildtype) {
var c_files = pkg_tools.get_c_files(pkg, _target, true)
var results = []
// Pre-fetch cflags once to avoid repeated TOML reads
var pkg_dir = shop.get_package_dir(pkg)
var cached_cflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'CFLAGS', _target), pkg_dir)
log.console(`CFLAGS ${pkg}: ${text(cached_cflags, '|')}`)
// Compile support sources to cached objects
var sources = pkg_tools.get_sources(pkg)
var support_objects = []
arrfor(sources, function(src_file) {
var obj = Build.compile_file(pkg, src_file, _target, _buildtype)
var obj = Build.compile_file(pkg, src_file, _target, {buildtype: _buildtype, cflags: cached_cflags})
push(support_objects, obj)
})
arrfor(c_files, function(file) {
var sym_name = shop.c_symbol_for_file(pkg, file)
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects})
var dylib = Build.build_module_dylib(pkg, file, _target, {buildtype: _buildtype, extra_objects: support_objects, cflags: cached_cflags})
if (dylib) {
push(results, {file: file, symbol: sym_name, dylib: dylib})
}
@@ -378,8 +400,8 @@ Build.build_static = function(packages, target, output, buildtype) {
})
// Collect LDFLAGS (with sigil replacement)
var ldflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'LDFLAGS', _target))
var pkg_dir = shop.get_package_dir(pkg)
var ldflags = replace_sigils_array(pkg_tools.get_flags(pkg, 'LDFLAGS', _target), pkg_dir)
// Deduplicate based on the entire LDFLAGS string for this package
var ldflags_key = pkg + ':' + text(ldflags, ' ')
@@ -387,8 +409,12 @@ Build.build_static = function(packages, target, output, buildtype) {
seen_flags[ldflags_key] = true
arrfor(ldflags, function(flag) {
var f = flag
var lpath = null
if (starts_with(f, '-L') && !starts_with(f, '-L/')) {
f = '-L"' + pkg_dir + '/' + text(f, 2) + '"'
lpath = text(f, 2)
if (!starts_with(lpath, pkg_dir)) {
f = '-L"' + pkg_dir + '/' + lpath + '"'
}
}
push(all_ldflags, f)
})