cgen: prevent `undefined symbol: tcc_backtrace` errors with tcc and `-shared -d no_backtrace`

pull/6947/head
Delyan Angelov 2020-11-25 15:40:17 +02:00
parent 4e9967a5f1
commit fa126b950a
4 changed files with 26 additions and 8 deletions

View File

@ -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.') eprintln('Some libc implementations like musl simply do not provide it.')
return false return false
} }
$if no_backtrace ? {
return false
} $else {
$if tinyc { $if tinyc {
C.tcc_backtrace("Backtrace") C.tcc_backtrace("Backtrace")
return false return false
} }
$if no_backtrace ? {
return false
} $else {
buffer := [100]byteptr{} buffer := [100]byteptr{}
nr_ptrs := C.backtrace(voidptr(buffer), 100) nr_ptrs := C.backtrace(voidptr(buffer), 100)
if nr_ptrs < 2 { if nr_ptrs < 2 {

View File

@ -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' args << '-bt25'
} }
// Without these libs compilation will fail on Linux // Without these libs compilation will fail on Linux

View File

@ -99,6 +99,24 @@ typedef int (*qsort_callback_func)(const void*, const void*);
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually #include <stdio.h> // TODO remove all these includes, define all function signatures and types manually
#include <stdlib.h> #include <stdlib.h>
#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 #ifdef __cplusplus
#include <utility> #include <utility>
#define _MOV std::move #define _MOV std::move

View File

@ -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 !(g.pref.build_mode == .build_module && g.is_builtin_mod) {
// If we are building vlib/builtin, we need all private functions like array_get // 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. // to be public, so that all V programs can access them.
g.write('static ') g.write('VV_LOCAL_SYMBOL ')
g.definitions.write('static ') g.definitions.write('VV_LOCAL_SYMBOL ')
} }
} }
fn_header := if msvc_attrs.len > 0 { '$type_name $msvc_attrs ${name}(' } else { '$type_name ${name}(' } 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' { if attr.name == 'export' {
g.writeln('// export alias: $attr.arg -> $name') g.writeln('// export alias: $attr.arg -> $name')
export_alias := '$type_name ${attr.arg}($arg_str)' 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.writeln('$export_alias {')
g.write('\treturn ${name}(') g.write('\treturn ${name}(')
g.write(fargs.join(', ')) g.write(fargs.join(', '))