@needs_dlfcn
@no_wasm_backend('wasm backend resolves symbols greedily on startup')
def test_dylink_hyper_dupe(self):
    self.set_setting('INITIAL_MEMORY', ((64 * 1024) * 1024))
    if (not self.has_changed_setting('ASSERTIONS')):
        self.set_setting('ASSERTIONS', 2)
    create_test_file('third.cpp', '\n      #include <stdio.h>\n      int sidef() { return 36; }\n      int sideg = 49;\n      int bsidef() { return 536; }\n      extern void only_in_second_1(int x);\n      extern int second_to_third;\n      int third_to_second = 1337;\n      void only_in_third_0() {\n        // note we access our own globals directly, so\n        // it doesn\'t matter that overriding failed\n        printf("only_in_third_0: %d, %d, %d\\n", sidef(), sideg, second_to_third);\n        only_in_second_1(2112);\n      }\n      void only_in_third_1(int x) {\n        printf("only_in_third_1: %d, %d, %d, %d\\n", sidef(), sideg, second_to_third, x);\n      }\n    ')
    if self.is_wasm():
        libname = 'third.wasm'
    else:
        libname = 'third.js'
    run_process(([EMCC, 'third.cpp', '-o', libname, '-s', 'SIDE_MODULE', '-s', 'EXPORT_ALL'] + self.get_emcc_args()))
    self.dylink_test(main=('\n      #include <stdio.h>\n      #include <emscripten.h>\n      extern int sidef();\n      extern int sideg;\n      extern int bsidef();\n      extern int bsideg;\n      extern void only_in_second_0();\n      extern void only_in_third_0();\n      int main() {\n        EM_ASM({\n          loadDynamicLibrary(\'%s\'); // hyper-dynamic! works at least for functions (and consts not used in same block)\n        });\n        printf("sidef: %%d, sideg: %%d.\\n", sidef(), sideg);\n        printf("bsidef: %%d.\\n", bsidef());\n        only_in_second_0();\n        only_in_third_0();\n      }\n    ' % libname), side='\n      #include <stdio.h>\n      int sidef() { return 10; } // third will try to override these, but fail!\n      int sideg = 20;\n      extern void only_in_third_1(int x);\n      int second_to_third = 500;\n      extern int third_to_second;\n      void only_in_second_0() {\n        printf("only_in_second_0: %d, %d, %d\\n", sidef(), sideg, third_to_second);\n        only_in_third_1(1221);\n      }\n      void only_in_second_1(int x) {\n        printf("only_in_second_1: %d, %d, %d, %d\\n", sidef(), sideg, third_to_second, x);\n      }\n    ', expected=['sidef: 10, sideg: 20.\nbsidef: 536.\nonly_in_second_0: 10, 20, 1337\nonly_in_third_1: 36, 49, 500, 1221\nonly_in_third_0: 36, 49, 500\nonly_in_second_1: 10, 20, 1337, 2112\n'], need_reverse=(not self.is_wasm()))
    if (not self.has_changed_setting('ASSERTIONS')):
        print('check warnings')
        full = run_js('src.cpp.o.js', engine=JS_ENGINES[0], full_output=True, stderr=STDOUT)
        self.assertContained(("warning: symbol '_sideg' from '%s' already exists" % libname), full)
@needs_dlfcn
@no_wasm_backend('wasm backend resolves symbols greedily on startup')
def test_dylink_hyper_dupe(self):
    self.set_setting('INITIAL_MEMORY', ((64 * 1024) * 1024))
    if (not self.has_changed_setting('ASSERTIONS')):
        self.set_setting('ASSERTIONS', 2)
    create_test_file('third.cpp', '\n      #include <stdio.h>\n      int sidef() { return 36; }\n      int sideg = 49;\n      int bsidef() { return 536; }\n      extern void only_in_second_1(int x);\n      extern int second_to_third;\n      int third_to_second = 1337;\n      void only_in_third_0() {\n        // note we access our own globals directly, so\n        // it doesn\'t matter that overriding failed\n        printf("only_in_third_0: %d, %d, %d\\n", sidef(), sideg, second_to_third);\n        only_in_second_1(2112);\n      }\n      void only_in_third_1(int x) {\n        printf("only_in_third_1: %d, %d, %d, %d\\n", sidef(), sideg, second_to_third, x);\n      }\n    ')
    if self.is_wasm():
        libname = 'third.wasm'
    else:
        libname = 'third.js'
    run_process(([EMCC, 'third.cpp', '-o', libname, '-s', 'SIDE_MODULE', '-s', 'EXPORT_ALL'] + self.get_emcc_args()))
    self.dylink_test(main=('\n      #include <stdio.h>\n      #include <emscripten.h>\n      extern int sidef();\n      extern int sideg;\n      extern int bsidef();\n      extern int bsideg;\n      extern void only_in_second_0();\n      extern void only_in_third_0();\n      int main() {\n        EM_ASM({\n          loadDynamicLibrary(\'%s\'); // hyper-dynamic! works at least for functions (and consts not used in same block)\n        });\n        printf("sidef: %%d, sideg: %%d.\\n", sidef(), sideg);\n        printf("bsidef: %%d.\\n", bsidef());\n        only_in_second_0();\n        only_in_third_0();\n      }\n    ' % libname), side='\n      #include <stdio.h>\n      int sidef() { return 10; } // third will try to override these, but fail!\n      int sideg = 20;\n      extern void only_in_third_1(int x);\n      int second_to_third = 500;\n      extern int third_to_second;\n      void only_in_second_0() {\n        printf("only_in_second_0: %d, %d, %d\\n", sidef(), sideg, third_to_second);\n        only_in_third_1(1221);\n      }\n      void only_in_second_1(int x) {\n        printf("only_in_second_1: %d, %d, %d, %d\\n", sidef(), sideg, third_to_second, x);\n      }\n    ', expected=['sidef: 10, sideg: 20.\nbsidef: 536.\nonly_in_second_0: 10, 20, 1337\nonly_in_third_1: 36, 49, 500, 1221\nonly_in_third_0: 36, 49, 500\nonly_in_second_1: 10, 20, 1337, 2112\n'], need_reverse=(not self.is_wasm()))
    if (not self.has_changed_setting('ASSERTIONS')):
        print('check warnings')
        full = run_js('src.cpp.o.js', engine=JS_ENGINES[0], full_output=True, stderr=STDOUT)
        self.assertContained(("warning: symbol '_sideg' from '%s' already exists" % libname), full)