From 85973b9ccadba7f2380bbd0be3ac3d2c3d47d1ad Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 12 Mar 2025 21:57:56 +0200 Subject: [PATCH] v.builder,v.cflags: improve the cross compilation support for programs using libraries like raylib, that have specific linking order needs, by supporting -lraylib@START_LIBS --- vlib/v/builder/cc.v | 6 ++++-- vlib/v/cflag/cflags.v | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 5376c28482..ec40be14b6 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -1130,6 +1130,7 @@ fn (mut c Builder) cc_windows_cross() { } else { args << cflags.c_options_after_target() } + if current_os !in ['macos', 'linux', 'termux'] { println(current_os) panic('your platform is not supported yet') @@ -1144,8 +1145,9 @@ fn (mut c Builder) cc_windows_cross() { all_args << args all_args << c.get_subsystem_flag() - all_args << c.ccoptions.linker_flags - all_args << '${c.pref.ldflags}' + // Note: c.ccoptions.linker_flags was already in cflags.c_options_after_target(), which is in args, so no need to add it again here + all_args << c.pref.ldflags + c.dump_c_options(all_args) mut cmd := cross_compiler_name_path + ' ' + all_args.join(' ') // cmd := 'clang -o $obj_name -w $include -m32 -c -target x86_64-win32 ${pref.default_module_path}/$c.out_name_c' diff --git a/vlib/v/cflag/cflags.v b/vlib/v/cflag/cflags.v index 14c380c9ad..cfd9b750b8 100644 --- a/vlib/v/cflag/cflags.v +++ b/vlib/v/cflag/cflags.v @@ -100,7 +100,7 @@ pub fn (cflags []CFlag) c_options_before_target() []string { mut args := []string{cap: defines.len + others.len} args << defines args << others - return args + return uniq_non_empty(args) } pub fn (cflags []CFlag) c_options_after_target() []string { @@ -116,7 +116,7 @@ pub fn (cflags []CFlag) c_options_without_object_files() []string { } args << flag.format() or { continue } } - return args + return uniq_non_empty(args) } pub fn (cflags []CFlag) c_options_only_object_files() []string { @@ -128,7 +128,7 @@ pub fn (cflags []CFlag) c_options_only_object_files() []string { args << flag.format() or { continue } } } - return args.filter(it != '') + return uniq_non_empty(args) } pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) { @@ -137,6 +137,10 @@ pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) { mut others := []string{} mut libs := []string{} for copt in copts_without_obj_files { + if copt.ends_with('@START_LIBS') { + libs.insert(0, copt.all_before('@START_LIBS')) + continue + } if copt.starts_with('-l') { libs << copt continue @@ -145,11 +149,34 @@ pub fn (cflags []CFlag) defines_others_libs() ([]string, []string, []string) { libs << '"${copt}"' continue } + + if copt.ends_with('@START_DEFINES') { + defines.insert(0, copt.all_before('@START_DEFINES')) + continue + } if copt.starts_with('-D') { defines << copt continue } + + if copt.ends_with('@START_OTHERS') { + others.insert(0, copt.all_before('@START_OTHERS')) + continue + } others << copt } - return defines, others, libs + return uniq_non_empty(defines), uniq_non_empty(others), uniq_non_empty(libs) +} + +fn uniq_non_empty(args []string) []string { + mut uniq_args := []string{} + for a in args { + if a == '' { + continue + } + if a !in uniq_args { + uniq_args << a + } + } + return uniq_args }