From 6fc654821fcc4072b3c102aefa934f9cb3032799 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Thu, 17 Feb 2022 22:17:07 +1100 Subject: [PATCH] cgen: get usecache working with clang (fix duplicate symbols) --- .github/workflows/ci.yml | 22 ++++++++-------------- vlib/v/gen/c/cgen.v | 34 +++++++++++++++++++++++++--------- vlib/v/gen/c/cheaders.v | 33 +++++---------------------------- vlib/v/gen/c/fn.v | 16 ++++++++++++++-- 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c12020567c..a1d7368af0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -188,13 +188,10 @@ jobs: echo $VFLAGS ./v cmd/tools/test_if_v_test_system_works.v ./cmd/tools/test_if_v_test_system_works - - name: Self tests run: VJOBS=1 ./v test-self - - name: Build examples run: ./v build-examples - - name: Build examples with -autofree run: | ./v -autofree -o tetris examples/tetris/tetris.v @@ -202,14 +199,12 @@ jobs: - name: v doctor run: | ./v doctor - - name: Test ved run: | git clone --depth 1 https://github.com/vlang/ved cd ved && ../v -o ved . ../v -autofree . cd .. - # - name: Test c2v # run: | # git clone --depth 1 https://github.com/vlang/c2v @@ -218,7 +213,6 @@ jobs: # ../v run tests/run_tests.vsh # ../v -experimental -w c2v_test.v # cd .. - - name: Build V UI examples run: | git clone --depth 1 https://github.com/vlang/ui @@ -227,6 +221,14 @@ jobs: ln -s $(pwd) ~/.vmodules/ui ../v examples/rectangles.v ## ../v run examples/build_examples.vsh + - name: V self compilation with -usecache + run: | + unset VFLAGS + ./v -usecache examples/hello_world.v && examples/hello_world + ./v -o v2 -usecache cmd/v + ./v2 -o v3 -usecache cmd/v + ./v3 version + ./v3 -o tetris -usecache examples/tetris/tetris.v ubuntu: runs-on: ubuntu-20.04 @@ -517,31 +519,23 @@ jobs: - name: v doctor run: | ./v doctor - - name: Verify `v test` works run: | .\v.exe cmd/tools/test_if_v_test_system_works.v .\cmd\tools\test_if_v_test_system_works.exe - - name: Verify `v vlib/v/gen/c/coutput_test.v` works run: | .\v.exe vlib/v/gen/c/coutput_test.v - - name: Make sure running TCC64 instead of TCC32 run: ./v test .github\workflows\make_sure_ci_run_with_64bit_compiler_test.v - - name: Test ./v doc -v clipboard *BEFORE building tools* run: ./v doc -v clipboard - - name: Test v build-tools run: ./v -W build-tools - - name: Test ./v doc clipboard run: ./v doc clipboard - - name: Self tests run: ./v test-self - - name: Test v->js run: ./v -o hi.js examples/hello_v_js.v && node hi.js - name: Test v binaries diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 50950281d1..a6345950e8 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -720,6 +720,12 @@ pub fn (mut g Gen) init() { if g.pref.prealloc { g.comptime_definitions.writeln('#define _VPREALLOC (1)') } + if g.pref.use_cache { + g.comptime_definitions.writeln('#define _VUSECACHE (1)') + } + if g.pref.build_mode == .build_module { + g.comptime_definitions.writeln('#define _VBUILDMODULE (1)') + } if g.pref.is_livemain || g.pref.is_liveshared { g.generate_hotcode_reloading_declarations() } @@ -812,7 +818,7 @@ pub fn (mut g Gen) write_typeof_functions() { } g.writeln('}') g.writeln('') - g.writeln('int v_typeof_sumtype_idx_${sym.cname}(int sidx) { /* $sym.name */ ') + g.writeln('static int v_typeof_sumtype_idx_${sym.cname}(int sidx) { /* $sym.name */ ') if g.pref.build_mode == .build_module { g.writeln('\t\tif( sidx == _v_type_idx_${sym.cname}() ) return ${int(ityp)};') for v in sum_info.variants { @@ -4295,7 +4301,17 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ } fn (mut g Gen) global_decl(node ast.GlobalDecl) { - mod := if g.pref.build_mode == .build_module && g.is_builtin_mod { 'static ' } else { '' } + // was static used here to to make code optimizable? it was removed when + // 'extern' was used to fix the duplicate symbols with usecache && clang + // visibility_kw := if g.pref.build_mode == .build_module && g.is_builtin_mod { 'static ' } + visibility_kw := if + (g.pref.use_cache || (g.pref.build_mode == .build_module && g.module_built != node.mod)) + && !util.should_bundle_module(node.mod) { + 'extern ' + } + else { + '' + } mut attributes := '' if node.attrs.contains('weak') { attributes += 'VWEAK ' @@ -4310,20 +4326,20 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) { } } styp := g.typ(field.typ) + should_init := (!g.pref.use_cache && g.pref.build_mode != .build_module) + || (g.pref.build_mode == .build_module && g.module_built == node.mod) + g.definitions.write_string('$visibility_kw$styp $attributes $field.name') if field.has_expr { - g.definitions.write_string('$mod$styp $attributes $field.name') - if field.expr.is_literal() { - g.definitions.writeln(' = ${g.expr_string(field.expr)}; // global') + if field.expr.is_literal() && should_init { + g.definitions.write_string(' = ${g.expr_string(field.expr)}; // global') } else { - g.definitions.writeln(';') g.global_init.writeln('\t$field.name = ${g.expr_string(field.expr)}; // global') } } else { default_initializer := g.type_default(field.typ) - if default_initializer == '{0}' { - g.definitions.writeln('$mod$styp $attributes $field.name = {0}; // global') + if default_initializer == '{0}' && should_init { + g.definitions.writeln(' = {0}; // global') } else { - g.definitions.writeln('$mod$styp $attributes $field.name; // global') if field.name !in ['as_cast_type_indexes', 'g_memory_block', 'global_allocator'] { g.global_init.writeln('\t$field.name = *($styp*)&(($styp[]){${g.type_default(field.typ)}}[0]); // global') } diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index bba7441d06..2bf49a243e 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -362,7 +362,11 @@ const c_common_macros = ' #else #define VV_EXPORTED_SYMBOL extern __attribute__((visibility("default"))) #endif - #define VV_LOCAL_SYMBOL __attribute__ ((visibility ("hidden"))) + #if defined(__clang__) && (defined(_VUSECACHE) || defined(_VBUILDMODULE)) + #define VV_LOCAL_SYMBOL static + #else + #define VV_LOCAL_SYMBOL __attribute__ ((visibility ("hidden"))) + #endif #else #define VV_EXPORTED_SYMBOL extern #define VV_LOCAL_SYMBOL static @@ -478,33 +482,6 @@ typedef int (*qsort_callback_func)(const void*, const void*); #include #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)) - #ifdef ARM - #define VV_EXPORTED_SYMBOL extern __attribute__((externally_visible,visibility("default"))) - #else - #define VV_EXPORTED_SYMBOL extern __attribute__((visibility("default"))) - #endif - #define VV_LOCAL_SYMBOL __attribute__ ((visibility ("hidden"))) - #else - #define VV_EXPORTED_SYMBOL extern - #define VV_LOCAL_SYMBOL static - #endif -#endif - -#if defined(__TINYC__) && defined(__has_include) -// tcc does not support has_include properly yet, turn it off completely -#undef __has_include -#endif - #ifndef _WIN32 #if defined __has_include #if __has_include () diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 863fe8c21f..7e59bedd95 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -61,7 +61,10 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { // TODO true for not just "builtin" // TODO: clean this up mod := if g.is_builtin_mod { 'builtin' } else { node.name.all_before_last('.') } - if (mod != g.module_built && node.mod != g.module_built.after('/')) || should_bundle_module { + // for now dont skip generic functions as they are being marked as static + // when -usecache is enabled, until a better solution is implemented. + if ((mod != g.module_built && node.mod != g.module_built.after('/')) + || should_bundle_module) && node.generic_names.len == 0 { // Skip functions that don't have to be generated for this module. // println('skip bm $node.name mod=$node.mod module_built=$g.module_built') skip = true @@ -269,7 +272,16 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) { g.definitions.write_string('VV_LOCAL_SYMBOL ') } } - fn_header := '$type_name $fn_attrs${name}(' + // as a temp solution generic functions are marked static + // when -usecache is enabled to fix duplicate symbols with clang + // TODO: implement a better sulution + visibility_kw := if g.cur_concrete_types.len > 0 + && (g.pref.build_mode == .build_module || g.pref.use_cache) { + 'static ' + } else { + '' + } + fn_header := '$visibility_kw$type_name $fn_attrs${name}(' g.definitions.write_string(fn_header) g.write(fn_header) }