From fac77c3ff04c2f228389fd3697239db263f62ab6 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 24 Jun 2013 16:00:24 -0700 Subject: [PATCH] initial setup --- emcc | 10 ++++++++++ emlink.py | 27 +++++++++++++++++++++++++++ src/settings.js | 4 ++++ tests/runner.py | 19 +++++++++++++++++++ tools/shared.py | 1 + 5 files changed, 61 insertions(+) create mode 100644 emlink.py diff --git a/emcc b/emcc index 75750e1e0..c6b0893b7 100755 --- a/emcc +++ b/emcc @@ -1066,6 +1066,16 @@ try: logging.warning('disabling LLVM optimizations, need typed arrays mode 2 for them') llvm_opts = 0 + if shared.Settings.MAIN_MODULE: + assert not shared.Settings.SIDE_MODULE + shared.Settings.INCLUDE_FULL_LIBRARY = 1 + shared.Settings.LINKABLE = 1 # TODO: add FORCE_DCE option for the brave people that do want to dce here and in side modules + debug_level = max(debug_level, 2) # preserve function names + elif shared.Settings.SIDE_MODULE: + assert not shared.Settings.MAIN_MODULE + shared.Settings.LINKABLE = 1 + debug_level = max(debug_level, 2) + ## Compile source code to bitcode logging.debug('compiling to bitcode') diff --git a/emlink.py b/emlink.py new file mode 100644 index 000000000..30fa675a0 --- /dev/null +++ b/emlink.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python2 + +''' +Fast static linker for emscripten outputs. Specifically this links asm.js modules. + +Usage: emlink.py [main module] [side module] [output name] + + Main module should be built with -s MAIN_MODULE=1 + Side module should be built with -s SIDE_MODULE=1 + +Note that the output file can be used as a main module, so you can link multiple +side modules into a main module that way. +''' + +import os, subprocess, sys +from tools import shared + +try: + me, main, side, out = sys.argv[:4] +except: + print >> sys.stderr, 'usage: emlink.py [main module] [side module] [output name]' + sys.exit(1) + +print 'Main module:', main +print 'Side module:', side +print 'Output:', out + diff --git a/src/settings.js b/src/settings.js index dff52adf1..37a118cbc 100644 --- a/src/settings.js +++ b/src/settings.js @@ -296,6 +296,10 @@ var SHOW_LABELS = 0; // Show labels in the generated code var PRINT_SPLIT_FILE_MARKER = 0; // Prints markers in Javascript generation to split the file later on. See emcc --split option. +var MAIN_MODULE = 0; // A main module is a file compiled in a way that allows us to link it to + // a side module using emlink.py. +var SIDE_MODULE = 0; // Corresponds to MAIN_MODULE + var BUILD_AS_SHARED_LIB = 0; // Whether to build the code as a shared library // 0 here means this is not a shared lib: It is a main file. // All shared library options (1 and 2) are currently deprecated XXX diff --git a/tests/runner.py b/tests/runner.py index 3566ed854..15de7756b 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -10606,6 +10606,25 @@ f.close() self.assertContained('hello from lib', run_js(os.path.join(self.get_dir(), 'a.out.js'))) assert not os.path.exists('a.out') and not os.path.exists('a.exe'), 'Must not leave unneeded linker stubs' + def zzztest_static_link(self): + open(os.path.join(self.get_dir(), 'main.cpp'), 'w').write(''' + extern void printey(); + int main() { + printey(); + return 0; + } + ''') + open(os.path.join(self.get_dir(), 'lib.cpp'), 'w').write(''' + #include + void printey() { + printf("hello from lib\\n"); + } + ''') + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'lib.cpp'), '-o', 'lib.js', '-s', 'SIDE_MODULE=1', '-O2']).communicate() + Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'main.cpp'), '-o', 'main.js', '-s', 'MAIN_MODULE=1', '-O2']).communicate() + Popen([PYTHON, EMLINK, 'main.js', 'lib.js', 'together.js']) + self.assertContained('hello from lib', run_js('together.js')) + def test_symlink(self): if os.name == 'nt': return self.skip('Windows FS does not need to be tested for symlinks support, since it does not have them.') diff --git a/tools/shared.py b/tools/shared.py index 2c352f1cb..fc6950d5e 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -400,6 +400,7 @@ EMAR = path_from_root('emar') EMRANLIB = path_from_root('emranlib') EMLIBTOOL = path_from_root('emlibtool') EMCONFIG = path_from_root('em-config') +EMLINK = path_from_root('emlink.py') EMMAKEN = path_from_root('tools', 'emmaken.py') AUTODEBUGGER = path_from_root('tools', 'autodebugger.py') BINDINGS_GENERATOR = path_from_root('tools', 'bindings_generator.py')