def test_llvm(self): LLVM_WARNING = 'LLVM version appears incorrect' restore_and_set_up() # Clang should report the version number we expect, and emcc should not warn assert shared.check_llvm_version() output = self.check_working(EMCC) self.assertNotContained(LLVM_WARNING, output) # Fake a different llvm version restore_and_set_up() with open(CONFIG_FILE, 'a') as f: f.write('LLVM_ROOT = "' + self.in_dir('fake') + '"') real_version_x, real_version_y = ( int(x) for x in expected_llvm_version().split('.')) if shared.get_llvm_target() == shared.WASM_TARGET: make_fake_llc(self.in_dir('fake', 'llc'), 'wasm32 - WebAssembly 32-bit') make_fake_lld(self.in_dir('fake', 'wasm-ld')) else: make_fake_llc(self.in_dir('fake', 'llc'), 'js - JavaScript (asm.js, emscripten)') with env_modify({'EM_IGNORE_SANITY': '1'}): for inc_x in range(-2, 3): for inc_y in range(-2, 3): expected_x = real_version_x + inc_x expected_y = real_version_y + inc_y if expected_x < 0 or expected_y < 0: continue # must be a valid llvm version print("mod LLVM version: %d %d -> %d %d" % (real_version_x, real_version_x, expected_x, expected_y)) make_fake_clang(self.in_dir('fake', 'clang'), '%s.%s' % (expected_x, expected_y)) did_modify = inc_x != 0 or inc_y != 0 if did_modify: output = self.check_working(EMCC, LLVM_WARNING) else: output = self.check_working(EMCC) self.assertNotContained(LLVM_WARNING, output)
return y->y; } ''', ['libcxxabi.bc']) elif what == 'gl': build(''' extern "C" { extern void* emscripten_GetProcAddress(const char *x); } int main() { return int(emscripten_GetProcAddress("waka waka")); } ''', ['gl.bc']) elif what == 'native_optimizer': build(''' int main() {} ''', ['optimizer.2.exe'], ['-O2']) elif what == 'wasm_compiler_rt': if shared.get_llvm_target() == shared.WASM_TARGET: build(''' int main() {} ''', ['wasm_compiler_rt.a'], ['-s', 'BINARYEN=1']) else: shared.logging.warning('wasm_compiler_rt not built when using JSBackend') elif what == 'zlib': build_port('zlib', 'libz.a', ['-s', 'USE_ZLIB=1']) elif what == 'bullet': build_port('bullet', 'libbullet.bc', ['-s', 'USE_BULLET=1']) elif what == 'vorbis': build_port('vorbis', 'libvorbis.bc', ['-s', 'USE_VORBIS=1']) elif what == 'ogg': build_port('ogg', 'libogg.bc', ['-s', 'USE_OGG=1']) elif what == 'libpng': build_port('libpng', 'libpng.bc', ['-s', 'USE_ZLIB=1', '-s', 'USE_LIBPNG=1'])
} ''', ['libcxxabi.bc']) elif what == 'gl': build( ''' extern "C" { extern void* emscripten_GetProcAddress(const char *x); } int main() { return int(emscripten_GetProcAddress("waka waka")); } ''', ['gl.bc']) elif what == 'native_optimizer': build(''' int main() {} ''', ['optimizer.2.exe'], ['-O2']) elif what == 'wasm_compiler_rt': if shared.get_llvm_target() == shared.WASM_TARGET: build(''' int main() {} ''', ['wasm_compiler_rt.a'], ['-s', 'BINARYEN=1']) else: shared.logging.warning( 'wasm_compiler_rt not built when using JSBackend') elif what == 'zlib': build_port('zlib', 'libz.a', ['-s', 'USE_ZLIB=1']) elif what == 'bullet': build_port('bullet', 'libbullet.bc', ['-s', 'USE_BULLET=1']) elif what == 'vorbis': build_port('vorbis', 'libvorbis.bc', ['-s', 'USE_VORBIS=1']) elif what == 'ogg': build_port('ogg', 'libogg.bc', ['-s', 'USE_OGG=1']) elif what == 'libpng':
def generate_object_file(data_files): embed_files = [f for f in data_files if f.mode == 'embed'] assert embed_files asm_file = shared.replace_suffix(options.obj_output, '.s') used = set() for f in embed_files: f.c_symbol_name = '__em_file_data_%s' % to_c_symbol(f.dstpath, used) with open(asm_file, 'w') as out: out.write( '# Emscripten embedded file data, generated by tools/file_packager.py\n' ) for f in embed_files: if DEBUG: err('embedding %s at %s' % (f.srcpath, f.dstpath)) size = os.path.getsize(f.srcpath) dstpath = to_asm_string(f.dstpath) srcpath = to_unix_path(f.srcpath) out.write( dedent(f''' .section .rodata.{f.c_symbol_name},"",@ # The name of file {f.c_symbol_name}_name: .asciz "{dstpath}" .size {f.c_symbol_name}_name, {len(dstpath)+1} # The size of the file followed by the content itself {f.c_symbol_name}: .incbin "{srcpath}" .size {f.c_symbol_name}, {size} ''')) out.write( dedent(''' # A list of triples of: # (file_name_ptr, file_data_size, file_data_ptr) # The list in null terminate with a single 0 .globl __emscripten_embedded_file_data .export_name __emscripten_embedded_file_data, __emscripten_embedded_file_data .section .rodata.__emscripten_embedded_file_data,"",@ __emscripten_embedded_file_data: .p2align 2 ''')) for f in embed_files: # The `.dc.a` directive gives us a pointer (address) sized entry. # See https://sourceware.org/binutils/docs/as/Dc.html out.write( dedent(f'''\ .dc.a {f.c_symbol_name}_name .int32 {os.path.getsize(f.srcpath)} .dc.a {f.c_symbol_name} ''')) ptr_size = 4 elem_size = (2 * ptr_size) + 4 total_size = len(embed_files) * elem_size + 4 out.write( dedent(f'''\ .dc.a 0 .size __emscripten_embedded_file_data, {total_size} ''')) shared.check_call([ shared.LLVM_MC, '-filetype=obj', '-triple=' + shared.get_llvm_target(), '-o', options.obj_output, asm_file ])