From fa126b950ae3d19876276466e8b3f9e48230a722 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 25 Nov 2020 15:40:17 +0200 Subject: [PATCH] cgen: prevent `undefined symbol: tcc_backtrace` errors with tcc and `-shared -d no_backtrace` --- vlib/builtin/builtin_nix.c.v | 8 ++++---- vlib/v/builder/cc.v | 2 +- vlib/v/gen/cheaders.v | 18 ++++++++++++++++++ vlib/v/gen/fn.v | 6 +++--- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/vlib/builtin/builtin_nix.c.v b/vlib/builtin/builtin_nix.c.v index 9a75f4bf18..b305465b8a 100644 --- a/vlib/builtin/builtin_nix.c.v +++ b/vlib/builtin/builtin_nix.c.v @@ -83,13 +83,13 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { eprintln('Some libc implementations like musl simply do not provide it.') return false } - $if tinyc { - C.tcc_backtrace("Backtrace") - return false - } $if no_backtrace ? { return false } $else { + $if tinyc { + C.tcc_backtrace("Backtrace") + return false + } buffer := [100]byteptr{} nr_ptrs := C.backtrace(voidptr(buffer), 100) if nr_ptrs < 2 { diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 7cc2c6efe4..da2af815d9 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -497,7 +497,7 @@ fn (mut v Builder) cc() { } } } - if is_cc_tcc { + if is_cc_tcc && 'no_backtrace' !in v.pref.compile_defines { args << '-bt25' } // Without these libs compilation will fail on Linux diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index c572d75229..1fc60628ca 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -99,6 +99,24 @@ typedef int (*qsort_callback_func)(const void*, const void*); #include // TODO remove all these includes, define all function signatures and types manually #include +#if defined(_WIN32) || defined(__CYGWIN__) + #define VV_EXPORTED_SYMBOL extern __declspec(dllexport) + #define VV_LOCAL_SYMBOL static +#else + // 4 < gcc < 5 is used by some older Ubuntu LTS and Centos versions, + // and does not support __has_attribute(visibility) ... + #ifndef __has_attribute + #define __has_attribute(x) 0 // Compatibility with non-clang compilers. + #endif + #if (defined(__GNUC__) && (__GNUC__ >= 4)) || (defined(__clang__) && __has_attribute(visibility)) + #define VV_EXPORTED_SYMBOL extern __attribute__ ((visibility ("default"))) + #define VV_LOCAL_SYMBOL __attribute__ ((visibility ("hidden"))) + #else + #define VV_EXPORTED_SYMBOL extern + #define VV_LOCAL_SYMBOL static + #endif +#endif + #ifdef __cplusplus #include #define _MOV std::move diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 4d7486fce3..da56b0e8c1 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -100,8 +100,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { // if !(g.pref.build_mode == .build_module && g.is_builtin_mod) { // If we are building vlib/builtin, we need all private functions like array_get // to be public, so that all V programs can access them. - g.write('static ') - g.definitions.write('static ') + g.write('VV_LOCAL_SYMBOL ') + g.definitions.write('VV_LOCAL_SYMBOL ') } } fn_header := if msvc_attrs.len > 0 { '$type_name $msvc_attrs ${name}(' } else { '$type_name ${name}(' } @@ -170,7 +170,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) { if attr.name == 'export' { g.writeln('// export alias: $attr.arg -> $name') export_alias := '$type_name ${attr.arg}($arg_str)' - g.definitions.writeln('$export_alias;') + g.definitions.writeln('VV_EXPORTED_SYMBOL $export_alias; // exported fn $it.name') g.writeln('$export_alias {') g.write('\treturn ${name}(') g.write(fargs.join(', '))