Refactor build process to integrate toolchain support in compilation and linking functions
parent
d66b83c06d
commit
d89a53de94
|
|
@ -166,7 +166,7 @@ fn topo_sort_nodes(nodes []BuildNode, node_index map[string]int) ![]int {
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_compile_tasks(tasks []CompileTask, build_config config.BuildConfig) ![]string {
|
fn run_compile_tasks(tasks []CompileTask, build_config config.BuildConfig, toolchain config.Toolchain) ![]string {
|
||||||
mut object_files := []string{}
|
mut object_files := []string{}
|
||||||
if tasks.len == 0 {
|
if tasks.len == 0 {
|
||||||
return object_files
|
return object_files
|
||||||
|
|
@ -175,7 +175,7 @@ fn run_compile_tasks(tasks []CompileTask, build_config config.BuildConfig) ![]st
|
||||||
// If parallel compilation disabled, compile sequentially
|
// If parallel compilation disabled, compile sequentially
|
||||||
if !build_config.parallel_compilation {
|
if !build_config.parallel_compilation {
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
object := compile_file(task.source, task.obj, build_config, task.target_config) or {
|
object := compile_file(task.source, task.obj, build_config, toolchain, task.target_config) or {
|
||||||
return error('Failed to compile ${task.source}: ${err}')
|
return error('Failed to compile ${task.source}: ${err}')
|
||||||
}
|
}
|
||||||
object_files << object
|
object_files << object
|
||||||
|
|
@ -197,20 +197,20 @@ fn run_compile_tasks(tasks []CompileTask, build_config config.BuildConfig) ![]st
|
||||||
|
|
||||||
// Worker goroutines
|
// Worker goroutines
|
||||||
for _ in 0 .. workers {
|
for _ in 0 .. workers {
|
||||||
go fn (ch chan CompileTask, res chan CompileResult, bc config.BuildConfig) {
|
go fn (ch chan CompileTask, res chan CompileResult, bc config.BuildConfig, tc config.Toolchain) {
|
||||||
for {
|
for {
|
||||||
t := <-ch
|
t := <-ch
|
||||||
// sentinel task: empty source signals worker to exit
|
// sentinel task: empty source signals worker to exit
|
||||||
if t.source == '' {
|
if t.source == '' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
object := compile_file(t.source, t.obj, bc, t.target_config) or {
|
object := compile_file(t.source, t.obj, bc, tc, t.target_config) or {
|
||||||
res <- CompileResult{obj: '', err: err.msg()}
|
res <- CompileResult{obj: '', err: err.msg()}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res <- CompileResult{obj: object, err: ''}
|
res <- CompileResult{obj: object, err: ''}
|
||||||
}
|
}
|
||||||
}(tasks_ch, res_ch, build_config)
|
}(tasks_ch, res_ch, build_config, toolchain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send tasks
|
// Send tasks
|
||||||
|
|
@ -345,7 +345,7 @@ fn plan_build_graph(build_config &config.BuildConfig) !BuildGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph) ! {
|
fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph, toolchain config.Toolchain) ! {
|
||||||
for node_idx in graph.order {
|
for node_idx in graph.order {
|
||||||
node := graph.nodes[node_idx]
|
node := graph.nodes[node_idx]
|
||||||
if node.id in graph.unresolved && build_config.verbose {
|
if node.id in graph.unresolved && build_config.verbose {
|
||||||
|
|
@ -360,7 +360,7 @@ fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph) !
|
||||||
match node.target {
|
match node.target {
|
||||||
.shared_lib {
|
.shared_lib {
|
||||||
if node.is_directive {
|
if node.is_directive {
|
||||||
build_directive_shared(node.directive, build_config) or {
|
build_directive_shared(node.directive, build_config, toolchain) or {
|
||||||
return error('Failed to build shared directive ${node.name}: ${err}')
|
return error('Failed to build shared directive ${node.name}: ${err}')
|
||||||
}
|
}
|
||||||
} else if node.shared_lib_idx >= 0 {
|
} else if node.shared_lib_idx >= 0 {
|
||||||
|
|
@ -368,7 +368,7 @@ fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph) !
|
||||||
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
||||||
println('Building shared library: ${lib_config.name}')
|
println('Building shared library: ${lib_config.name}')
|
||||||
}
|
}
|
||||||
build_shared_library(mut lib_config, build_config) or {
|
build_shared_library(mut lib_config, build_config, toolchain) or {
|
||||||
return error('Failed to build shared library ${lib_config.name}: ${err}')
|
return error('Failed to build shared library ${lib_config.name}: ${err}')
|
||||||
}
|
}
|
||||||
if build_config.verbose {
|
if build_config.verbose {
|
||||||
|
|
@ -378,7 +378,7 @@ fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph) !
|
||||||
}
|
}
|
||||||
.tool {
|
.tool {
|
||||||
if node.is_directive {
|
if node.is_directive {
|
||||||
build_directive_tool(node.directive, build_config) or {
|
build_directive_tool(node.directive, build_config, toolchain) or {
|
||||||
return error('Failed to build tool directive ${node.name}: ${err}')
|
return error('Failed to build tool directive ${node.name}: ${err}')
|
||||||
}
|
}
|
||||||
} else if node.tool_idx >= 0 {
|
} else if node.tool_idx >= 0 {
|
||||||
|
|
@ -386,7 +386,7 @@ fn execute_build_graph(mut build_config config.BuildConfig, graph BuildGraph) !
|
||||||
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
||||||
println('Building tool: ${tool_config.name}')
|
println('Building tool: ${tool_config.name}')
|
||||||
}
|
}
|
||||||
build_tool(mut tool_config, build_config) or {
|
build_tool(mut tool_config, build_config, toolchain) or {
|
||||||
return error('Failed to build tool ${tool_config.name}: ${err}')
|
return error('Failed to build tool ${tool_config.name}: ${err}')
|
||||||
}
|
}
|
||||||
if build_config.verbose {
|
if build_config.verbose {
|
||||||
|
|
@ -470,7 +470,7 @@ fn prepare_directive_build(directive config.BuildDirective, build_config config.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_directive_shared(directive config.BuildDirective, build_config config.BuildConfig) ! {
|
fn build_directive_shared(directive config.BuildDirective, build_config config.BuildConfig, toolchain config.Toolchain) ! {
|
||||||
ctx := prepare_directive_build(directive, build_config) or {
|
ctx := prepare_directive_build(directive, build_config) or {
|
||||||
if err.msg() == skip_directive_err {
|
if err.msg() == skip_directive_err {
|
||||||
return
|
return
|
||||||
|
|
@ -482,7 +482,7 @@ fn build_directive_shared(directive config.BuildDirective, build_config config.B
|
||||||
if build_config.debug || build_config.verbose {
|
if build_config.debug || build_config.verbose {
|
||||||
println('Compiling ${directive.unit_name}: ${ctx.source}...')
|
println('Compiling ${directive.unit_name}: ${ctx.source}...')
|
||||||
}
|
}
|
||||||
compile_file(ctx.source, ctx.object, build_config, ctx.target_config) or {
|
compile_file(ctx.source, ctx.object, build_config, toolchain, ctx.target_config) or {
|
||||||
return error('Failed to compile ${ctx.source} for ${directive.unit_name}')
|
return error('Failed to compile ${ctx.source} for ${directive.unit_name}')
|
||||||
}
|
}
|
||||||
} else if build_config.verbose {
|
} else if build_config.verbose {
|
||||||
|
|
@ -500,7 +500,7 @@ fn build_directive_shared(directive config.BuildDirective, build_config config.B
|
||||||
println('Linking shared library: ${lib_output_dir}/${base}.so')
|
println('Linking shared library: ${lib_output_dir}/${base}.so')
|
||||||
}
|
}
|
||||||
|
|
||||||
link_shared_library([ctx.object], directive.unit_name, lib_output_dir, build_config, config.SharedLibConfig{
|
link_shared_library([ctx.object], directive.unit_name, lib_output_dir, build_config, toolchain, config.SharedLibConfig{
|
||||||
name: directive.unit_name
|
name: directive.unit_name
|
||||||
libraries: directive.link_libs
|
libraries: directive.link_libs
|
||||||
debug: build_config.debug
|
debug: build_config.debug
|
||||||
|
|
@ -516,7 +516,7 @@ fn build_directive_shared(directive config.BuildDirective, build_config config.B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_directive_tool(directive config.BuildDirective, build_config config.BuildConfig) ! {
|
fn build_directive_tool(directive config.BuildDirective, build_config config.BuildConfig, toolchain config.Toolchain) ! {
|
||||||
ctx := prepare_directive_build(directive, build_config) or {
|
ctx := prepare_directive_build(directive, build_config) or {
|
||||||
if err.msg() == skip_directive_err {
|
if err.msg() == skip_directive_err {
|
||||||
return
|
return
|
||||||
|
|
@ -528,7 +528,7 @@ fn build_directive_tool(directive config.BuildDirective, build_config config.Bui
|
||||||
if build_config.debug || build_config.verbose {
|
if build_config.debug || build_config.verbose {
|
||||||
println('Compiling ${directive.unit_name}: ${ctx.source}...')
|
println('Compiling ${directive.unit_name}: ${ctx.source}...')
|
||||||
}
|
}
|
||||||
compile_file(ctx.source, ctx.object, build_config, ctx.target_config) or {
|
compile_file(ctx.source, ctx.object, build_config, toolchain, ctx.target_config) or {
|
||||||
return error('Failed to compile ${ctx.source} for ${directive.unit_name}')
|
return error('Failed to compile ${ctx.source} for ${directive.unit_name}')
|
||||||
}
|
}
|
||||||
} else if build_config.verbose {
|
} else if build_config.verbose {
|
||||||
|
|
@ -540,7 +540,7 @@ fn build_directive_tool(directive config.BuildDirective, build_config config.Bui
|
||||||
println('Linking executable: ${executable}')
|
println('Linking executable: ${executable}')
|
||||||
}
|
}
|
||||||
|
|
||||||
link_tool([ctx.object], executable, build_config, config.ToolConfig{
|
link_tool([ctx.object], executable, build_config, toolchain, config.ToolConfig{
|
||||||
name: directive.unit_name
|
name: directive.unit_name
|
||||||
libraries: directive.link_libs
|
libraries: directive.link_libs
|
||||||
debug: build_config.debug
|
debug: build_config.debug
|
||||||
|
|
@ -570,8 +570,12 @@ pub fn build(mut build_config config.BuildConfig) ! {
|
||||||
|
|
||||||
// Auto-discover sources if not specified
|
// Auto-discover sources if not specified
|
||||||
auto_discover_sources(mut build_config)
|
auto_discover_sources(mut build_config)
|
||||||
|
toolchain := config.get_toolchain(build_config)
|
||||||
graph := plan_build_graph(&build_config)!
|
graph := plan_build_graph(&build_config)!
|
||||||
execute_build_graph(mut build_config, graph)!
|
if build_config.verbose {
|
||||||
|
println('Using toolchain: ${toolchain.description()} (${build_config.compiler})')
|
||||||
|
}
|
||||||
|
execute_build_graph(mut build_config, graph, toolchain)!
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -686,7 +690,7 @@ pub fn clean(build_config config.BuildConfig) {
|
||||||
println('Clean completed!')
|
println('Clean completed!')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_shared_library(mut lib_config config.SharedLibConfig, build_config config.BuildConfig) ! {
|
fn build_shared_library(mut lib_config config.SharedLibConfig, build_config config.BuildConfig, toolchain config.Toolchain) ! {
|
||||||
if lib_config.sources.len == 0 {
|
if lib_config.sources.len == 0 {
|
||||||
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
||||||
println('No sources specified for shared library ${lib_config.name}, skipping')
|
println('No sources specified for shared library ${lib_config.name}, skipping')
|
||||||
|
|
@ -724,7 +728,7 @@ fn build_shared_library(mut lib_config config.SharedLibConfig, build_config conf
|
||||||
lib_target_config := config.TargetConfig(lib_config)
|
lib_target_config := config.TargetConfig(lib_config)
|
||||||
// show compile command if verbose
|
// show compile command if verbose
|
||||||
if lib_config.verbose || build_config.verbose {
|
if lib_config.verbose || build_config.verbose {
|
||||||
cmd_preview := config.build_shared_compiler_command(src_file, obj_file, build_config, lib_target_config)
|
cmd_preview := toolchain.compile_command(src_file, obj_file, &build_config, lib_target_config)
|
||||||
println('Compile command (preview): ${cmd_preview}')
|
println('Compile command (preview): ${cmd_preview}')
|
||||||
}
|
}
|
||||||
compile_tasks << CompileTask{source: src_file, obj: obj_file, target_config: lib_target_config}
|
compile_tasks << CompileTask{source: src_file, obj: obj_file, target_config: lib_target_config}
|
||||||
|
|
@ -738,7 +742,7 @@ fn build_shared_library(mut lib_config config.SharedLibConfig, build_config conf
|
||||||
|
|
||||||
// Run compile tasks (parallel if enabled)
|
// Run compile tasks (parallel if enabled)
|
||||||
if compile_tasks.len > 0 {
|
if compile_tasks.len > 0 {
|
||||||
compiled := run_compile_tasks(compile_tasks, build_config) or { return err }
|
compiled := run_compile_tasks(compile_tasks, build_config, toolchain) or { return err }
|
||||||
object_files << compiled
|
object_files << compiled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,7 +758,7 @@ fn build_shared_library(mut lib_config config.SharedLibConfig, build_config conf
|
||||||
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
if build_config.debug || build_config.verbose || lib_config.debug || lib_config.verbose {
|
||||||
println('Linking shared library: ${lib_output_dir}/${lib_config.name.split('/').last()}.so')
|
println('Linking shared library: ${lib_output_dir}/${lib_config.name.split('/').last()}.so')
|
||||||
}
|
}
|
||||||
link_shared_library(object_files, lib_config.name, lib_output_dir, build_config, lib_config) or {
|
link_shared_library(object_files, lib_config.name, lib_output_dir, build_config, toolchain, lib_config) or {
|
||||||
return error('Failed to link shared library ${lib_config.name}')
|
return error('Failed to link shared library ${lib_config.name}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -763,7 +767,7 @@ fn build_shared_library(mut lib_config config.SharedLibConfig, build_config conf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_tool(mut tool_config config.ToolConfig, build_config config.BuildConfig) ! {
|
fn build_tool(mut tool_config config.ToolConfig, build_config config.BuildConfig, toolchain config.Toolchain) ! {
|
||||||
if tool_config.sources.len == 0 {
|
if tool_config.sources.len == 0 {
|
||||||
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
||||||
println('No sources specified for tool ${tool_config.name}, skipping')
|
println('No sources specified for tool ${tool_config.name}, skipping')
|
||||||
|
|
@ -801,7 +805,7 @@ fn build_tool(mut tool_config config.ToolConfig, build_config config.BuildConfig
|
||||||
tool_target_config := config.TargetConfig(tool_config)
|
tool_target_config := config.TargetConfig(tool_config)
|
||||||
// show compile command if verbose
|
// show compile command if verbose
|
||||||
if tool_config.verbose || build_config.verbose {
|
if tool_config.verbose || build_config.verbose {
|
||||||
cmd_preview := config.build_shared_compiler_command(src_file, obj_file, build_config, tool_target_config)
|
cmd_preview := toolchain.compile_command(src_file, obj_file, &build_config, tool_target_config)
|
||||||
println('Compile command (preview): ${cmd_preview}')
|
println('Compile command (preview): ${cmd_preview}')
|
||||||
}
|
}
|
||||||
compile_tasks << CompileTask{source: src_file, obj: obj_file, target_config: tool_target_config}
|
compile_tasks << CompileTask{source: src_file, obj: obj_file, target_config: tool_target_config}
|
||||||
|
|
@ -815,7 +819,7 @@ fn build_tool(mut tool_config config.ToolConfig, build_config config.BuildConfig
|
||||||
|
|
||||||
// Run compile tasks (parallel if enabled)
|
// Run compile tasks (parallel if enabled)
|
||||||
if compile_tasks.len > 0 {
|
if compile_tasks.len > 0 {
|
||||||
compiled := run_compile_tasks(compile_tasks, build_config) or { return err }
|
compiled := run_compile_tasks(compile_tasks, build_config, toolchain) or { return err }
|
||||||
object_files << compiled
|
object_files << compiled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -828,7 +832,7 @@ fn build_tool(mut tool_config config.ToolConfig, build_config config.BuildConfig
|
||||||
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
if build_config.debug || build_config.verbose || tool_config.debug || tool_config.verbose {
|
||||||
println('Linking tool: ${executable}')
|
println('Linking tool: ${executable}')
|
||||||
}
|
}
|
||||||
link_tool(object_files, executable, build_config, tool_config) or {
|
link_tool(object_files, executable, build_config, toolchain, tool_config) or {
|
||||||
return error('Failed to link tool ${tool_config.name}')
|
return error('Failed to link tool ${tool_config.name}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -851,8 +855,8 @@ fn get_target_verbose(target_config config.TargetConfig) bool {
|
||||||
return verbose
|
return verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_file(source_file string, object_file string, build_config config.BuildConfig, target_config config.TargetConfig) !string {
|
fn compile_file(source_file string, object_file string, build_config config.BuildConfig, toolchain config.Toolchain, target_config config.TargetConfig) !string {
|
||||||
cmd := config.build_shared_compiler_command(source_file, object_file, build_config, target_config)
|
cmd := toolchain.compile_command(source_file, object_file, &build_config, target_config)
|
||||||
|
|
||||||
target_verbose := get_target_verbose(target_config)
|
target_verbose := get_target_verbose(target_config)
|
||||||
|
|
||||||
|
|
@ -876,8 +880,8 @@ fn compile_file(source_file string, object_file string, build_config config.Buil
|
||||||
return object_file
|
return object_file
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_shared_library(object_files []string, library_name string, output_path string, build_config config.BuildConfig, lib_config config.SharedLibConfig) ! {
|
fn link_shared_library(object_files []string, library_name string, output_path string, build_config config.BuildConfig, toolchain config.Toolchain, lib_config config.SharedLibConfig) ! {
|
||||||
cmd := config.build_shared_linker_command(object_files, library_name, output_path, build_config, lib_config)
|
cmd := toolchain.shared_link_command(object_files, library_name, output_path, &build_config, lib_config)
|
||||||
|
|
||||||
if lib_config.verbose {
|
if lib_config.verbose {
|
||||||
println('Shared lib link command: ${cmd}')
|
println('Shared lib link command: ${cmd}')
|
||||||
|
|
@ -893,8 +897,8 @@ fn link_shared_library(object_files []string, library_name string, output_path s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_tool(object_files []string, executable string, build_config config.BuildConfig, tool_config config.ToolConfig) ! {
|
fn link_tool(object_files []string, executable string, build_config config.BuildConfig, toolchain config.Toolchain, tool_config config.ToolConfig) ! {
|
||||||
cmd := config.build_tool_linker_command(object_files, executable, build_config, tool_config)
|
cmd := toolchain.tool_link_command(object_files, executable, &build_config, tool_config)
|
||||||
|
|
||||||
if tool_config.verbose {
|
if tool_config.verbose {
|
||||||
println('Tool link command: ${cmd}')
|
println('Tool link command: ${cmd}')
|
||||||
|
|
|
||||||
179
config/config.v
179
config/config.v
|
|
@ -1034,185 +1034,6 @@ pub fn get_toolchain(build_config BuildConfig) Toolchain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to build compiler command for shared libraries and tools
|
|
||||||
pub fn build_shared_compiler_command(source_file string, object_file string, build_config BuildConfig, target_config TargetConfig) string {
|
|
||||||
mut cmd := '${build_config.compiler} -c'
|
|
||||||
|
|
||||||
// Add include directories (project + target specific)
|
|
||||||
for include_dir in build_config.include_dirs {
|
|
||||||
cmd += ' -I${include_dir}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add library search paths
|
|
||||||
for lib_path in build_config.lib_search_paths {
|
|
||||||
cmd += ' -L${lib_path}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get target-specific values
|
|
||||||
_, _, _, _, target_includes, target_cflags := get_target_config_values(target_config)
|
|
||||||
|
|
||||||
// Add target-specific include dirs
|
|
||||||
for include_dir in target_includes {
|
|
||||||
if include_dir != '' {
|
|
||||||
cmd += ' -I${include_dir}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add debug/optimization flags
|
|
||||||
_, use_debug, use_optimize, _, _, _ := get_target_config_values(target_config)
|
|
||||||
|
|
||||||
if use_debug {
|
|
||||||
cmd += ' -g -O0'
|
|
||||||
} else if use_optimize {
|
|
||||||
cmd += ' -O3'
|
|
||||||
} else {
|
|
||||||
cmd += ' -O2'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add PIC flag for shared libraries
|
|
||||||
is_shared_lib, _, _, _, _, _ := get_target_config_values(target_config)
|
|
||||||
if is_shared_lib {
|
|
||||||
cmd += ' -fPIC'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add standard flags
|
|
||||||
cmd += ' -Wall -Wextra'
|
|
||||||
|
|
||||||
// Add global CFLAGS
|
|
||||||
for flag in build_config.cflags {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add target-specific CFLAGS
|
|
||||||
for flag in target_cflags {
|
|
||||||
if flag != '' {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd += ' ${source_file} -o ${object_file}'
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to build shared library linker command
|
|
||||||
pub fn build_shared_linker_command(object_files []string, library_name string, output_path string, build_config BuildConfig, lib_config SharedLibConfig) string {
|
|
||||||
mut cmd := '${build_config.compiler} -shared'
|
|
||||||
|
|
||||||
// Add library search paths
|
|
||||||
cmd += ' -L${build_config.bin_dir}/lib'
|
|
||||||
for lib_path in build_config.lib_search_paths {
|
|
||||||
cmd += ' -L${lib_path}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add debug flags for linking
|
|
||||||
if lib_config.debug {
|
|
||||||
cmd += ' -g'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add object files
|
|
||||||
for obj_file in object_files {
|
|
||||||
cmd += ' ${obj_file}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add project libraries
|
|
||||||
for library in build_config.libraries {
|
|
||||||
if library != '' {
|
|
||||||
cmd += ' -l${library}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this library's dependencies (hardcode to filename form: -l:<name>.so)
|
|
||||||
for library in lib_config.libraries {
|
|
||||||
if library != '' {
|
|
||||||
// strip any existing .so or lib/ prefix and ensure we request the explicit filename
|
|
||||||
mut libfile := library
|
|
||||||
if libfile.starts_with('lib/') {
|
|
||||||
parts := libfile.split('/')
|
|
||||||
libfile = parts[parts.len - 1]
|
|
||||||
}
|
|
||||||
if libfile.ends_with('.so') {
|
|
||||||
libfile = libfile.replace('.so', '')
|
|
||||||
}
|
|
||||||
cmd += ' -l:${libfile}.so'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add custom LDFLAGS
|
|
||||||
for flag in build_config.ldflags {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
for flag in lib_config.ldflags {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set output name (with platform-specific extension)
|
|
||||||
// Use only the basename of the library to avoid duplicating path segments
|
|
||||||
parts := library_name.split('/')
|
|
||||||
base_name := if parts.len > 0 { parts[parts.len - 1] } else { library_name }
|
|
||||||
mut lib_name := base_name
|
|
||||||
$if windows {
|
|
||||||
lib_name += '.dll'
|
|
||||||
} $else {
|
|
||||||
lib_name += '.so'
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd += ' -o ${output_path}/${lib_name}'
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to build linker command for tools/executables
|
|
||||||
pub fn build_tool_linker_command(object_files []string, executable string, build_config BuildConfig, tool_config ToolConfig) string {
|
|
||||||
mut cmd := '${build_config.compiler}'
|
|
||||||
|
|
||||||
// Add library search paths
|
|
||||||
cmd += ' -L${build_config.bin_dir}/lib'
|
|
||||||
for lib_path in build_config.lib_search_paths {
|
|
||||||
cmd += ' -L${lib_path}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add debug flags for linking
|
|
||||||
if tool_config.debug {
|
|
||||||
cmd += ' -g'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add object files
|
|
||||||
for obj_file in object_files {
|
|
||||||
cmd += ' ${obj_file}'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add project libraries
|
|
||||||
for library in build_config.libraries {
|
|
||||||
if library != '' {
|
|
||||||
cmd += ' -l${library}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this tool's dependencies (shared libs) — hardcode to explicit .so filenames
|
|
||||||
for library in tool_config.libraries {
|
|
||||||
if library != '' {
|
|
||||||
mut libfile := library
|
|
||||||
if libfile.starts_with('lib/') {
|
|
||||||
parts := libfile.split('/')
|
|
||||||
libfile = parts[parts.len - 1]
|
|
||||||
}
|
|
||||||
if libfile.ends_with('.so') {
|
|
||||||
libfile = libfile.replace('.so', '')
|
|
||||||
}
|
|
||||||
cmd += ' -l:${libfile}.so'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add custom LDFLAGS
|
|
||||||
for flag in build_config.ldflags {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
for flag in tool_config.ldflags {
|
|
||||||
cmd += ' ${flag}'
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd += ' -o ${executable}'
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to build compiler command (existing - for backward compatibility)
|
// Utility function to build compiler command (existing - for backward compatibility)
|
||||||
pub fn build_compiler_command(source_file string, object_file string, build_config BuildConfig) string {
|
pub fn build_compiler_command(source_file string, object_file string, build_config BuildConfig) string {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue