From 42732138c68563f45c20a8128579287ff2644e93 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Mon, 13 Mar 2023 21:38:48 +0200 Subject: [PATCH] v: support `-ldflags` in addition to `-cflags` (allow adding C options *after* other C option, similar to `LDFLAGS`) (#17630) --- doc/docs.md | 6 ++++-- vlib/v/builder/cc.v | 7 +++++++ vlib/v/builder/msvc_windows.v | 5 +++-- vlib/v/help/build/build-c.txt | 9 +++++++-- vlib/v/pref/pref.v | 12 +++++++++--- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/doc/docs.md b/doc/docs.md index 33555feaec..b8f14d2adb 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -6213,8 +6213,9 @@ Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported. In the console build command, you can use: -* `-cflags` to pass custom flags to the backend C compiler. * `-cc` to change the default C backend compiler. +* `-cflags` to pass custom flags to the backend C compiler (passed before other C options). +* `-ldflags` to pass custom flags to the backend C linker (passed after every other C option). * For example: `-cc gcc-9 -cflags -fsanitize=thread`. You can define a `VFLAGS` environment variable in your terminal to store your `-cc` @@ -6229,7 +6230,8 @@ As long as backticks can't be used in `#flag` and spawning processes is not desi and portability reasons, V uses its own pkgconfig library that is compatible with the standard freedesktop one. -If no flags are passed it will add `--cflags` and `--libs`, both lines below do the same: +If no flags are passed it will add `--cflags` and `--libs` to pkgconfig (not to V). +In other words, both lines below do the same: ```v oksyntax #pkgconfig r_core diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 4b6ec3fe14..99145415d8 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -120,6 +120,7 @@ mut: source_args []string // for `x.tmp.c` post_args []string // options that should go after .o_args linker_flags []string // `-lm` + ldflags []string // `-labcd' from `v -ldflags "-labcd"` } fn (mut v Builder) setup_ccompiler_options(ccompiler string) { @@ -129,6 +130,7 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) { mut optimization_options := ['-O2'] // arguments for the C compiler ccoptions.args = [v.pref.cflags] + ccoptions.ldflags = [v.pref.ldflags] if !v.pref.no_std { if v.pref.os == .linux { ccoptions.args << '-std=gnu99 -D_DEFAULT_SOURCE' @@ -430,6 +432,7 @@ fn (v &Builder) all_args(ccoptions CcompilerOptions) []string { if v.pref.build_mode != .build_module { all << ccoptions.linker_flags all << ccoptions.env_ldflags + all << ccoptions.ldflags } return all } @@ -442,6 +445,7 @@ fn (v &Builder) thirdparty_object_args(ccoptions CcompilerOptions, middle []stri // NOTE do not append linker flags in .o build process, // compilers are inconsistent about how they handle: // all << ccoptions.env_ldflags + // all << ccoptions.ldflags return all } @@ -854,12 +858,15 @@ fn (mut c Builder) cc_windows_cross() { println(os.user_os()) panic('your platform is not supported yet') } + // mut all_args := []string{} all_args << optimization_options all_args << debug_options all_args << '-std=gnu11' + // all_args << args all_args << '-municode' + 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/builder/msvc_windows.v b/vlib/v/builder/msvc_windows.v index 76e5d3564c..933d4eda49 100644 --- a/vlib/v/builder/msvc_windows.v +++ b/vlib/v/builder/msvc_windows.v @@ -430,8 +430,9 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(mod string, path string, oargs << '/c "${cfile}"' oargs << '/Fo"${obj_path}"' env_ldflags := os.getenv('LDFLAGS') - if env_ldflags != '' { - oargs << env_ldflags + mut all_ldflags := '${env_ldflags} ${v.pref.ldflags}' + if all_ldflags != '' { + oargs << all_ldflags } v.dump_c_options(oargs) str_oargs := oargs.join(' ') diff --git a/vlib/v/help/build/build-c.txt b/vlib/v/help/build/build-c.txt index c50d392b2c..9da5f1b928 100644 --- a/vlib/v/help/build/build-c.txt +++ b/vlib/v/help/build/build-c.txt @@ -16,9 +16,14 @@ see also `v help build`. -cflags Pass the provided flag as is to the C compiler. Can be specified multiple times to provide multiple flags. - Use quotes to wrap the flag argument if it contains spaces. + Use quotes to wrap the flag argument, if it contains spaces. - V also supports the environment variables CFLAGS and LDFLAGS. + -ldflags + Pass the provided flag as is to the C compiler *after every other C option*. + Can be specified multiple times to provide multiple flags. + Use quotes to wrap the flag argument, if it contains spaces. + + Note: V also supports the environment variables CFLAGS and LDFLAGS. The contents of the CFLAGS variable will be prepended as is, at the start of the C backend command, right after the name of the compiler. The contents of the LDFLAGS variable will be appended as is, at the end diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index b045c88b82..87a7a24f0e 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -88,8 +88,8 @@ pub enum Arch { _max } -pub const list_of_flags_with_param = ['o', 'd', 'define', 'b', 'backend', 'cc', 'os', 'cf', 'cflags', - 'path', 'arch'] +pub const list_of_flags_with_param = ['b', 'd', 'e', 'o', 'define', 'backend', 'cc', 'os', 'cflags', + 'ldflags', 'path', 'arch'] pub const supported_test_runners = ['normal', 'simple', 'tap', 'dump', 'teamcity'] @@ -154,7 +154,8 @@ pub mut: use_cache bool // when set, use cached modules to speed up subsequent compilations, at the cost of slower initial ones (while the modules are cached) retry_compilation bool = true // retry the compilation with another C compiler, if tcc fails. // TODO Convert this into a []string - cflags string // Additional options which will be passed to the C compiler. + cflags string // Additional options which will be passed to the C compiler *before* other options. + ldflags string // Additional options which will be passed to the C compiler *after* everything else. // For example, passing -cflags -Os will cause the C compiler to optimize the generated binaries for size. // You could pass several -cflags XXX arguments. They will be merged with each other. // You can also quote several options at the same time: -cflags '-Os -fno-inline-small-functions'. @@ -693,6 +694,11 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin res.build_options << '${arg} "${res.cflags.trim_space()}"' i++ } + '-ldflags' { + res.ldflags += ' ' + cmdline.option(current_args, '-ldflags', '') + res.build_options << '${arg} "${res.ldflags.trim_space()}"' + i++ + } '-d', '-define' { if current_args.len > 1 { define := current_args[1]