summaryrefslogtreecommitdiff
path: root/native_client_sdk
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2014-04-24 10:50:13 +0100
committerBen Murdoch <benm@google.com>2014-04-24 10:50:13 +0100
commit0529e5d033099cbfc42635f6f6183833b09dff6e (patch)
treebadea60062e611382d8a37e3b0bfda8d69760c2b /native_client_sdk
parent8346740f6fb555ccbb9b4148ab63402ae8f6e4ca (diff)
downloadchromium_org-0529e5d033099cbfc42635f6f6183833b09dff6e.tar.gz
Merge from Chromium at DEPS revision 265802
This commit was generated by merge_to_master.py. Change-Id: I6fac2dbbce472b18ca943b6e6f247835b0bd6281
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/doc_generated/devguide/tutorial/tutorial-part2.html12
-rw-r--r--native_client_sdk/doc_generated/redirects.json3
-rw-r--r--native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html4
-rwxr-xr-xnative_client_sdk/src/build_tools/build_sdk.py13
-rw-r--r--native_client_sdk/src/build_tools/buildbot_common.py5
-rwxr-xr-xnative_client_sdk/src/build_tools/buildbot_run.py9
-rw-r--r--native_client_sdk/src/build_tools/generate_make.py2
-rwxr-xr-xnative_client_sdk/src/build_tools/parse_dsc.py3
-rw-r--r--native_client_sdk/src/build_tools/sdk_files.list2
-rw-r--r--native_client_sdk/src/doc/devguide/tutorial/tutorial-part2.rst12
-rw-r--r--native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst4
-rw-r--r--native_client_sdk/src/examples/demo/nacl_io/handlers.c10
-rw-r--r--native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c2
-rw-r--r--native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h7
-rw-r--r--native_client_sdk/src/examples/tutorial/multi_platform/README22
-rw-r--r--native_client_sdk/src/examples/tutorial/multi_platform/example.dsc20
-rw-r--r--native_client_sdk/src/examples/tutorial/multi_platform/example.js16
-rw-r--r--native_client_sdk/src/examples/tutorial/multi_platform/index.html21
-rw-r--r--native_client_sdk/src/examples/tutorial/multi_platform/multi_platform.cc36
-rw-r--r--native_client_sdk/src/gonacl_appengine/src/bullet/Makefile4
-rw-r--r--native_client_sdk/src/gonacl_appengine/src/cube/Makefile4
-rw-r--r--native_client_sdk/src/gonacl_appengine/src/earth/Makefile4
-rw-r--r--native_client_sdk/src/gonacl_appengine/src/life/Makefile4
-rw-r--r--native_client_sdk/src/gonacl_appengine/src/voronoi/Makefile4
-rw-r--r--native_client_sdk/src/gonacl_appengine/static/bullet/fullscreen.html2
-rw-r--r--native_client_sdk/src/libraries/nacl_io/dbgprint.h16
-rw-r--r--native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc8
-rw-r--r--native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc4
-rw-r--r--native_client_sdk/src/libraries/nacl_io/library.dsc4
-rw-r--r--native_client_sdk/src/libraries/nacl_io/log.c (renamed from native_client_sdk/src/libraries/nacl_io/dbgprint.c)4
-rw-r--r--native_client_sdk/src/libraries/nacl_io/log.h35
-rw-r--r--native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h8
-rw-r--r--native_client_sdk/src/libraries/nacl_io/pepper_interface.h1
-rw-r--r--native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc4
-rw-r--r--native_client_sdk/src/libraries/sdk_util/macros.h16
-rw-r--r--native_client_sdk/src/resources/Makefile.example.template12
-rw-r--r--native_client_sdk/src/resources/manifest.json.template16
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/example.dsc2
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.cc7
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.h3
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_buffer_interface.h5
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_interface.h5
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.cc104
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.h34
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_interface.h2
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.cc24
-rw-r--r--native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.h6
-rwxr-xr-xnative_client_sdk/src/tools/fix_manifest.py132
-rw-r--r--native_client_sdk/src/tools/nacl_gcc.mk146
-rw-r--r--native_client_sdk/src/tools/nacl_llvm.mk12
50 files changed, 698 insertions, 137 deletions
diff --git a/native_client_sdk/doc_generated/devguide/tutorial/tutorial-part2.html b/native_client_sdk/doc_generated/devguide/tutorial/tutorial-part2.html
index 45fea11dfa..ab9550b916 100644
--- a/native_client_sdk/doc_generated/devguide/tutorial/tutorial-part2.html
+++ b/native_client_sdk/doc_generated/devguide/tutorial/tutorial-part2.html
@@ -76,7 +76,9 @@ SOURCES = hello_tutorial.cc
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
@@ -168,7 +170,7 @@ will use the variables we&#8217;ve defined above.</p>
<pre class="prettyprint">
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
@@ -189,9 +191,11 @@ there will be three executables generated, one for each architecture: in the
example above, <code>part2_arm.nexe</code>, <code>part2_x86_32.nexe</code> and
<code>part2_x86_64.nexe</code>.</p>
<p>When <code>CONFIG</code> is <code>Release</code>, each executable is also stripped to remove
-debug information and reduce the file size:</p>
+debug information and reduce the file size. Otherwise, when the <code>TOOLCHAIN</code>
+is <code>pnacl</code>, the workflow involves creating an unstripped binary for debugging
+and then finalizing it and stripping it for publishing.</p>
<pre class="prettyprint">
-ifeq ($(CONFIG),Release)
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/doc_generated/redirects.json b/native_client_sdk/doc_generated/redirects.json
deleted file mode 100644
index 2f16825253..0000000000
--- a/native_client_sdk/doc_generated/redirects.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "": "index"
-}
diff --git a/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html b/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
index 78ad20b9fe..ce1bfeadea 100644
--- a/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
+++ b/native_client_sdk/doc_generated/reference/pnacl-c-cpp-language-support.html
@@ -71,7 +71,7 @@ locations to each other as the C11/C++11 standards do.</p>
<p>Non-atomic memory accesses may be reordered, separated, elided or fused
according to C and C++&#8217;s memory model before the pexe is created as well
as after its creation. Accessing atomic memory location through
-non-atomic primitives is <cite>Undefined Behavior &lt;undefined_behavior&gt;</cite>.</p>
+non-atomic primitives is <a class="reference internal" href="/native-client/reference/pnacl-undefined-behavior.html#undefined-behavior"><em>Undefined Behavior</em></a>.</p>
<p>As in C11/C++11 some atomic accesses may be implemented with locks on
certain platforms. The <code>ATOMIC_*_LOCK_FREE</code> macros will always be
<code>1</code>, signifying that all types are sometimes lock-free. The
@@ -183,7 +183,7 @@ for the target architecture has to be respected.</p>
</section><section id="undefined-behavior">
<h2 id="undefined-behavior">Undefined Behavior</h2>
<p>The C and C++ languages expose some undefined behavior which is
-discussed in <cite>PNaCl Undefined Behavior &lt;undefined_behavior&gt;</cite>.</p>
+discussed in <a class="reference internal" href="/native-client/reference/pnacl-undefined-behavior.html#undefined-behavior"><em>PNaCl Undefined Behavior</em></a>.</p>
</section><section id="floating-point">
<h2 id="floating-point">Floating-Point</h2>
<p>PNaCl exposes 32-bit and 64-bit floating point operations which are
diff --git a/native_client_sdk/src/build_tools/build_sdk.py b/native_client_sdk/src/build_tools/build_sdk.py
index 3f0d1f1a52..e90a142708 100755
--- a/native_client_sdk/src/build_tools/build_sdk.py
+++ b/native_client_sdk/src/build_tools/build_sdk.py
@@ -358,7 +358,6 @@ TOOLCHAIN_LIBS = {
'libnacl_exception.a',
'libnacl_list_mappings.a',
'libppapi.a',
- 'libppapi_stub.a',
],
'newlib' : [
'crti.o',
@@ -942,8 +941,12 @@ def main(args):
options.tar = True
toolchains = ['newlib', 'glibc', 'arm', 'pnacl', 'host']
+
+ # Changes for experimental bionic builder
if options.bionic:
toolchains.append('bionic')
+ options.build_ports = False
+ options.build_app_engine = False
print 'Building: ' + ' '.join(toolchains)
@@ -957,7 +960,10 @@ def main(args):
pepper_old = str(chrome_version - 1)
pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver)
pepperdir_old = os.path.join(OUT_DIR, 'pepper_' + pepper_old)
- tarname = 'naclsdk_' + getos.GetPlatform() + '.tar.bz2'
+ if options.bionic:
+ tarname = 'naclsdk_bionic.tar.bz2'
+ else:
+ tarname = 'naclsdk_' + getos.GetPlatform() + '.tar.bz2'
tarfile = os.path.join(OUT_DIR, tarname)
if options.release:
@@ -987,7 +993,8 @@ def main(args):
GenerateNotice(pepperdir)
# Verify the SDK contains what we expect.
- BuildStepVerifyFilelist(pepperdir)
+ if not options.bionic:
+ BuildStepVerifyFilelist(pepperdir)
if options.tar:
BuildStepTarBundle(pepper_ver, tarfile)
diff --git a/native_client_sdk/src/build_tools/buildbot_common.py b/native_client_sdk/src/build_tools/buildbot_common.py
index 5a08e1fb92..dd10870dcb 100644
--- a/native_client_sdk/src/build_tools/buildbot_common.py
+++ b/native_client_sdk/src/build_tools/buildbot_common.py
@@ -28,8 +28,9 @@ def IsSDKBuilder():
(win|mac|linux)_nacl_sdk_build
Builder names:
- (windows|mac|linux)-sdk-multi(rel)?"""
- return '-sdk-multi' in os.getenv('BUILDBOT_BUILDERNAME', '')
+ (windows|mac|linux)-sdk-multi(bionic)(rel)?"""
+ bot = os.getenv('BUILDBOT_BUILDERNAME', '')
+ return '-sdk-multi' in bot or '-sdk-bionic-multi' in bot
def IsSDKTrybot():
diff --git a/native_client_sdk/src/build_tools/buildbot_run.py b/native_client_sdk/src/build_tools/buildbot_run.py
index 4a06b00ed3..c24c6df556 100755
--- a/native_client_sdk/src/build_tools/buildbot_run.py
+++ b/native_client_sdk/src/build_tools/buildbot_run.py
@@ -62,8 +62,12 @@ def StepBuildSDK():
else:
new_script_dir = SCRIPT_DIR
+ args = [sys.executable, 'build_sdk.py']
+ if 'bionic' in os.getenv('BUILDBOT_BUILDERNAME', ''):
+ args.append('--bionic')
+
try:
- Run([sys.executable, 'build_sdk.py'], cwd=new_script_dir)
+ Run(args, cwd=new_script_dir)
finally:
if is_win:
subprocess.check_call(['subst', '/D', subst_drive])
@@ -108,6 +112,9 @@ def main(args):
# to pass --build-only argument.
if os.getenv('BUILDBOT_BUILDERNAME', '').endswith('build'):
options.build_only = True
+ # TODO(noelallen): Enable testing on bionic when we have an ARM solution.
+ if 'bionic' in os.getenv('BUILDBOT_BUILDERNAME', ''):
+ options.build_only = True
StepArmRunHooks()
StepRunUnittests()
diff --git a/native_client_sdk/src/build_tools/generate_make.py b/native_client_sdk/src/build_tools/generate_make.py
index d44d2a5789..4188e7a0b0 100644
--- a/native_client_sdk/src/build_tools/generate_make.py
+++ b/native_client_sdk/src/build_tools/generate_make.py
@@ -159,6 +159,7 @@ def GenerateManifest(srcroot, dstroot, desc):
'key': True,
'channel': None,
'permissions': pretty_permissions,
+ 'multi_platform': desc.get('MULTI_PLATFORM', False),
'version': build_version.ChromeVersionNoTrunk()
}
RunTemplateFileIfChanged(srcpath, dstpath, replace)
@@ -262,6 +263,7 @@ def ProcessProject(pepperdir, srcroot, dstroot, desc, toolchains, configs=None,
'tools': tools,
'sel_ldr': desc.get('SEL_LDR'),
'targets': desc['TARGETS'],
+ 'multi_platform': desc.get('MULTI_PLATFORM', False),
}
RunTemplateFileIfChanged(template, make_path, template_dict)
diff --git a/native_client_sdk/src/build_tools/parse_dsc.py b/native_client_sdk/src/build_tools/parse_dsc.py
index 1088fef709..63e55d1456 100755
--- a/native_client_sdk/src/build_tools/parse_dsc.py
+++ b/native_client_sdk/src/build_tools/parse_dsc.py
@@ -65,7 +65,8 @@ DSC_FORMAT = {
'GROUP': (str, '', False),
'EXPERIMENTAL': (bool, [True, False], False),
'PERMISSIONS': (list, '', False),
- 'SOCKET_PERMISSIONS': (list, '', False)
+ 'SOCKET_PERMISSIONS': (list, '', False),
+ 'MULTI_PLATFORM': (bool, [True, False], False),
}
diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list
index 0427225c20..605cfce24b 100644
--- a/native_client_sdk/src/build_tools/sdk_files.list
+++ b/native_client_sdk/src/build_tools/sdk_files.list
@@ -40,6 +40,7 @@ examples/Makefile
examples/tutorial/debugging/*
examples/tutorial/dlopen/*
examples/tutorial/load_progress/*
+examples/tutorial/multi_platform/*
[win]examples/tutorial/make.bat
examples/tutorial/Makefile
examples/tutorial/testing/*
@@ -415,6 +416,7 @@ tools/create_nmf.py
tools/decode_dump.py
[linux,mac]tools/dump_syms
tools/fix_deps.py
+tools/fix_manifest.py
tools/genhttpfs.py
tools/getos.py
tools/host_gcc.mk
diff --git a/native_client_sdk/src/doc/devguide/tutorial/tutorial-part2.rst b/native_client_sdk/src/doc/devguide/tutorial/tutorial-part2.rst
index 91c9377700..36efa4fda9 100644
--- a/native_client_sdk/src/doc/devguide/tutorial/tutorial-part2.rst
+++ b/native_client_sdk/src/doc/devguide/tutorial/tutorial-part2.rst
@@ -69,7 +69,9 @@ Glibc NaCl) and two configurations (Debug, Release).
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
- ifeq ($(CONFIG),Release)
+ # The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+ # On NaCl, only produce a stripped binary for Release configs (not Debug).
+ ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
@@ -182,7 +184,7 @@ will use the variables we've defined above.
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
- ifeq ($(CONFIG),Release)
+ ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
@@ -206,11 +208,13 @@ example above, ``part2_arm.nexe``, ``part2_x86_32.nexe`` and
``part2_x86_64.nexe``.
When ``CONFIG`` is ``Release``, each executable is also stripped to remove
-debug information and reduce the file size:
+debug information and reduce the file size. Otherwise, when the ``TOOLCHAIN``
+is ``pnacl``, the workflow involves creating an unstripped binary for debugging
+and then finalizing it and stripping it for publishing.
.. naclcode::
- ifeq ($(CONFIG),Release)
+ ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst b/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
index 5bb5ac8688..cd62a2b252 100644
--- a/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
+++ b/native_client_sdk/src/doc/reference/pnacl-c-cpp-language-support.rst
@@ -59,7 +59,7 @@ locations to each other as the C11/C++11 standards do.
Non-atomic memory accesses may be reordered, separated, elided or fused
according to C and C++'s memory model before the pexe is created as well
as after its creation. Accessing atomic memory location through
-non-atomic primitives is `Undefined Behavior <undefined_behavior>`.
+non-atomic primitives is :ref:`Undefined Behavior <undefined_behavior>`.
As in C11/C++11 some atomic accesses may be implemented with locks on
certain platforms. The ``ATOMIC_*_LOCK_FREE`` macros will always be
@@ -202,7 +202,7 @@ Undefined Behavior
==================
The C and C++ languages expose some undefined behavior which is
-discussed in `PNaCl Undefined Behavior <undefined_behavior>`.
+discussed in :ref:`PNaCl Undefined Behavior <undefined_behavior>`.
Floating-Point
==============
diff --git a/native_client_sdk/src/examples/demo/nacl_io/handlers.c b/native_client_sdk/src/examples/demo/nacl_io/handlers.c
index d615eda92f..ae40d2d4db 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/handlers.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/handlers.c
@@ -379,11 +379,11 @@ int HandleFseek(int num_params, char** params, char** output) {
offset = ftell(file);
if (offset < 0) {
*output = PrintfToNewString(
- "fseek succeeded, but ftell returned error %d.", offset);
+ "fseek succeeded, but ftell returned error %ld.", offset);
return 4;
}
- *output = PrintfToNewString("fseek\1%s\1%d", file_index_string, offset);
+ *output = PrintfToNewString("fseek\1%s\1%ld", file_index_string, offset);
return 0;
}
@@ -507,7 +507,7 @@ int HandleStat(int num_params, char** params, char** output) {
return 2;
}
- *output = PrintfToNewString("stat\1%s\1%d", filename, buf.st_size);
+ *output = PrintfToNewString("stat\1%s\1%lld", filename, buf.st_size);
return 0;
}
@@ -601,8 +601,8 @@ int HandleReaddir(int num_params, char** params, char** output) {
entry = readdir(dir);
if (entry != NULL) {
- *output = PrintfToNewString("readdir\1%s\1%d\1%s", dir_index_string,
- entry->d_ino, entry->d_name);
+ *output = PrintfToNewString(
+ "readdir\1%s\1%lld\1%s", dir_index_string, entry->d_ino, entry->d_name);
} else {
*output = PrintfToNewString("readdir\1%s\1\1", dir_index_string);
}
diff --git a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
index 76eea394c3..66b2591c0d 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
+++ b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.c
@@ -349,7 +349,7 @@ static void Messaging_HandleMessage(PP_Instance instance,
if (!EnqueueMessage(strdup(buffer))) {
struct PP_Var var;
var = PrintfToVar(
- "Warning: dropped message \"%s\" because the queue was full.", message);
+ "Warning: dropped message \"%s\" because the queue was full.", buffer);
ppb_messaging_interface->PostMessage(g_instance, var);
}
}
diff --git a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
index 6eccb5ebd1..b5071108d1 100644
--- a/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
+++ b/native_client_sdk/src/examples/demo/nacl_io/nacl_io_demo.h
@@ -7,11 +7,12 @@
#include <stdarg.h>
#include "ppapi/c/pp_var.h"
+#include "sdk_util/macros.h" // for PRINTF_LIKE
struct PP_Var CStrToVar(const char* str);
-char* VprintfToNewString(const char* format, va_list args);
-char* PrintfToNewString(const char* format, ...);
-struct PP_Var PrintfToVar(const char* format, ...);
+char* VprintfToNewString(const char* format, va_list args) PRINTF_LIKE(1, 0);
+char* PrintfToNewString(const char* format, ...) PRINTF_LIKE(1, 2);
+struct PP_Var PrintfToVar(const char* format, ...) PRINTF_LIKE(1, 2);
uint32_t VarToCStr(struct PP_Var var, char* buffer, uint32_t length);
#endif /* NACL_IO_DEMO_H_ */
diff --git a/native_client_sdk/src/examples/tutorial/multi_platform/README b/native_client_sdk/src/examples/tutorial/multi_platform/README
new file mode 100644
index 0000000000..08218fd521
--- /dev/null
+++ b/native_client_sdk/src/examples/tutorial/multi_platform/README
@@ -0,0 +1,22 @@
+==================
+Multi-platform App
+==================
+
+Please see the online documentation here:
+
+ https://developer.chrome.com/native-client/devguide/distributing#packaged-application
+
+
+This example shows how to use the SDK build system to generate a Chrome App
+with support for multi-platform zip files.
+
+Starting with Chrome 28, the Chrome Web Store includes a feature called
+**multi-platform zip files.** This feature lets you structure your application
+directory and zip file in a way that reduces the size of the user download
+package. Here's how this feature works:
+
+* You still include all the .nexe files in the zip file that you upload to
+ the CWS, but you designate specific .nexe files (and other files if
+ appropriate) for specific architectures.
+* The Chrome Web Store re-packages your app, so that users only download
+ the files that they need for their specific architecture.
diff --git a/native_client_sdk/src/examples/tutorial/multi_platform/example.dsc b/native_client_sdk/src/examples/tutorial/multi_platform/example.dsc
new file mode 100644
index 0000000000..ad5cc23b60
--- /dev/null
+++ b/native_client_sdk/src/examples/tutorial/multi_platform/example.dsc
@@ -0,0 +1,20 @@
+{
+ 'TOOLS': ['newlib', 'glibc'],
+ 'TARGETS': [
+ {
+ 'NAME': 'multi_platform',
+ 'TYPE': 'main',
+ 'SOURCES': ['multi_platform.cc'],
+ 'LIBS': ['ppapi_cpp', 'ppapi', 'pthread'],
+ }
+ ],
+ 'DATA': [
+ 'example.js',
+ 'README',
+ ],
+ 'DEST': 'examples/tutorial',
+ 'NAME': 'multi_platform',
+ 'TITLE': 'Multi-platform App',
+ 'GROUP': 'Tutorial',
+ 'MULTI_PLATFORM': True,
+}
diff --git a/native_client_sdk/src/examples/tutorial/multi_platform/example.js b/native_client_sdk/src/examples/tutorial/multi_platform/example.js
new file mode 100644
index 0000000000..a2f86d0664
--- /dev/null
+++ b/native_client_sdk/src/examples/tutorial/multi_platform/example.js
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function moduleDidLoad() {
+ // The module is not hidden by default so we can easily see if the plugin
+ // failed to load.
+ common.hideModule();
+}
+
+// This function is called by common.js when a message is received from the
+// NaCl module.
+function handleMessage(message) {
+ var logEl = document.getElementById('log');
+ logEl.textContent += message.data;
+}
diff --git a/native_client_sdk/src/examples/tutorial/multi_platform/index.html b/native_client_sdk/src/examples/tutorial/multi_platform/index.html
new file mode 100644
index 0000000000..14d7cee0d2
--- /dev/null
+++ b/native_client_sdk/src/examples/tutorial/multi_platform/index.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <!--
+ Copyright (c) 2014 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+<head>
+ <meta http-equiv="Pragma" content="no-cache">
+ <meta http-equiv="Expires" content="-1">
+ <title>{{title}}</title>
+ <script type="text/javascript" src="common.js"></script>
+ <script type="text/javascript" src="example.js"></script>
+</head>
+<body {{attrs}}>
+ <h1>{{title}}</h1>
+ <h2>Status: <code id="statusField">NO-STATUS</code></h2>
+ <div id="listener"></div>
+ <div id="log"></div>
+</body>
+</html>
diff --git a/native_client_sdk/src/examples/tutorial/multi_platform/multi_platform.cc b/native_client_sdk/src/examples/tutorial/multi_platform/multi_platform.cc
new file mode 100644
index 0000000000..946808c714
--- /dev/null
+++ b/native_client_sdk/src/examples/tutorial/multi_platform/multi_platform.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+class Instance : public pp::Instance {
+ public:
+ explicit Instance(PP_Instance instance) : pp::Instance(instance) {}
+ virtual ~Instance() {}
+
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ PostMessage("Hello, multi-platform!");
+ return true;
+ }
+};
+
+class Module : public pp::Module {
+ public:
+ Module() : pp::Module() {}
+ virtual ~Module() {}
+
+ virtual pp::Instance* CreateInstance(PP_Instance instance) {
+ return new Instance(instance);
+ }
+};
+
+namespace pp {
+
+Module* CreateModule() {
+ return new ::Module();
+}
+
+} // namespace pp
diff --git a/native_client_sdk/src/gonacl_appengine/src/bullet/Makefile b/native_client_sdk/src/gonacl_appengine/src/bullet/Makefile
index 77ff8c07c1..a2e76da9a6 100644
--- a/native_client_sdk/src/gonacl_appengine/src/bullet/Makefile
+++ b/native_client_sdk/src/gonacl_appengine/src/bullet/Makefile
@@ -28,7 +28,9 @@ SOURCES = \
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/gonacl_appengine/src/cube/Makefile b/native_client_sdk/src/gonacl_appengine/src/cube/Makefile
index dbd9d63da0..feef4721ee 100644
--- a/native_client_sdk/src/gonacl_appengine/src/cube/Makefile
+++ b/native_client_sdk/src/gonacl_appengine/src/cube/Makefile
@@ -23,7 +23,9 @@ SOURCES = \
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/gonacl_appengine/src/earth/Makefile b/native_client_sdk/src/gonacl_appengine/src/earth/Makefile
index 6823ec64ac..16becb84b9 100644
--- a/native_client_sdk/src/gonacl_appengine/src/earth/Makefile
+++ b/native_client_sdk/src/gonacl_appengine/src/earth/Makefile
@@ -20,7 +20,9 @@ SOURCES = earth.cc
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/gonacl_appengine/src/life/Makefile b/native_client_sdk/src/gonacl_appengine/src/life/Makefile
index 890f37c3f7..4b3d3eef3c 100644
--- a/native_client_sdk/src/gonacl_appengine/src/life/Makefile
+++ b/native_client_sdk/src/gonacl_appengine/src/life/Makefile
@@ -20,7 +20,9 @@ SOURCES = life.c
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/gonacl_appengine/src/voronoi/Makefile b/native_client_sdk/src/gonacl_appengine/src/voronoi/Makefile
index d92fc5369b..65af2f3a69 100644
--- a/native_client_sdk/src/gonacl_appengine/src/voronoi/Makefile
+++ b/native_client_sdk/src/gonacl_appengine/src/voronoi/Makefile
@@ -20,7 +20,9 @@ SOURCES = voronoi.cc
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
-ifeq ($(CONFIG),Release)
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
diff --git a/native_client_sdk/src/gonacl_appengine/static/bullet/fullscreen.html b/native_client_sdk/src/gonacl_appengine/static/bullet/fullscreen.html
index 6892147c46..1de54dca8c 100644
--- a/native_client_sdk/src/gonacl_appengine/static/bullet/fullscreen.html
+++ b/native_client_sdk/src/gonacl_appengine/static/bullet/fullscreen.html
@@ -19,7 +19,7 @@
<script type="text/javascript" src="scenes.js"></script>
<script type="text/javascript">
- var expandoClosedMsg = 'more info';
+ var expandoClosedMsg = 'Click for options';
var expandoOpenMsg = '×';
var expandoClosed = true;
diff --git a/native_client_sdk/src/libraries/nacl_io/dbgprint.h b/native_client_sdk/src/libraries/nacl_io/dbgprint.h
deleted file mode 100644
index 305fea5c8c..0000000000
--- a/native_client_sdk/src/libraries/nacl_io/dbgprint.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file. */
-
-#ifndef LIBRARIES_NACL_IO_DBGPRINT_H_
-#define LIBRARIES_NACL_IO_DBGPRINT_H_
-
-#include "sdk_util/macros.h"
-
-EXTERN_C_BEGIN
-
-void dbgprintf(const char* format, ...);
-
-EXTERN_C_END
-
-#endif /* LIBRARIES_NACL_IO_DBGPRINT_H_ */
diff --git a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
index 26031583cd..f5f8089389 100644
--- a/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/httpfs/http_fs.cc
@@ -17,10 +17,10 @@
#include <ppapi/c/pp_errors.h>
-#include "nacl_io/dbgprint.h"
#include "nacl_io/dir_node.h"
#include "nacl_io/httpfs/http_fs_node.h"
#include "nacl_io/kernel_handle.h"
+#include "nacl_io/log.h"
#include "nacl_io/osinttypes.h"
#include "nacl_io/osunistd.h"
#include "sdk_util/string_util.h"
@@ -319,7 +319,7 @@ Error HttpFs::ParseManifest(const char* text) {
mode = S_IFCHR;
break;
default:
- dbgprintf("Unable to parse type %s for %s.\n",
+ LOG_ERROR("Unable to parse type %s for %s.\n",
modestr.c_str(),
name.c_str());
return EINVAL;
@@ -332,7 +332,7 @@ Error HttpFs::ParseManifest(const char* text) {
mode |= S_IRUSR | S_IRGRP | S_IROTH;
break;
default:
- dbgprintf("Unable to parse read %s for %s.\n",
+ LOG_ERROR("Unable to parse read %s for %s.\n",
modestr.c_str(),
name.c_str());
return EINVAL;
@@ -345,7 +345,7 @@ Error HttpFs::ParseManifest(const char* text) {
mode |= S_IWUSR | S_IWGRP | S_IWOTH;
break;
default:
- dbgprintf("Unable to parse write %s for %s.\n",
+ LOG_ERROR("Unable to parse write %s for %s.\n",
modestr.c_str(),
name.c_str());
return EINVAL;
diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc
index 7e526628a6..ab5d199852 100644
--- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc
+++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_dummy.cc
@@ -70,6 +70,10 @@ int _real_write(int fd, const void *buf, size_t count, size_t *nwrote) {
return 0;
}
+void _real_exit(int status) {
+ exit(status);
+}
+
#endif
// The Chromium build system defines __linux__ even for native client builds,
diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc
index 14855ccb9f..dbc2bb24d8 100644
--- a/native_client_sdk/src/libraries/nacl_io/library.dsc
+++ b/native_client_sdk/src/libraries/nacl_io/library.dsc
@@ -11,7 +11,6 @@
'NAME' : 'nacl_io',
'TYPE' : 'lib',
'SOURCES' : [
- 'dbgprint.c',
"devfs/dev_fs.cc",
"devfs/jspipe_node.cc",
"devfs/tty_event_emitter.cc",
@@ -40,6 +39,7 @@
"kernel_wrap_glibc.cc",
"kernel_wrap_newlib.cc",
"kernel_wrap_win.cc",
+ "log.c",
"memfs/mem_fs.cc",
"memfs/mem_fs_node.cc",
"nacl_io.cc",
@@ -161,7 +161,6 @@
{
'FILES': [
"char_node.h",
- "dbgprint.h",
"devfs/dev_fs.h",
"devfs/jspipe_node.h",
"devfs/tty_event_emitter.h",
@@ -192,6 +191,7 @@
"kernel_proxy.h",
"kernel_wrap.h",
"kernel_wrap_real.h",
+ "log.h",
"memfs/mem_fs.h",
"memfs/mem_fs_node.h",
"nacl_io.h",
diff --git a/native_client_sdk/src/libraries/nacl_io/dbgprint.c b/native_client_sdk/src/libraries/nacl_io/log.c
index b8a5bdf776..cc36cc7478 100644
--- a/native_client_sdk/src/libraries/nacl_io/dbgprint.c
+++ b/native_client_sdk/src/libraries/nacl_io/log.c
@@ -2,7 +2,7 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file. */
-#include "nacl_io/dbgprint.h"
+#include "nacl_io/log.h"
#include "nacl_io/kernel_wrap_real.h"
@@ -11,7 +11,7 @@
#include <stdio.h>
#include <string.h>
-void dbgprintf(const char* format, ...) {
+void nacl_io_log(const char* format, ...) {
va_list args;
size_t wrote;
char* output;
diff --git a/native_client_sdk/src/libraries/nacl_io/log.h b/native_client_sdk/src/libraries/nacl_io/log.h
new file mode 100644
index 0000000000..4e1a88eeae
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io/log.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+#ifndef LIBRARIES_NACL_IO_LOG_H_
+#define LIBRARIES_NACL_IO_LOG_H_
+
+#include "sdk_util/macros.h"
+
+#define LOG_PREFIX "nacl_io: "
+
+#if defined(NACL_IO_LOGGING)
+#define LOG_TRACE(format, ...) \
+ nacl_io_log(LOG_PREFIX format "\n", ##__VA_ARGS__)
+#else
+#define LOG_TRACE(format, ...)
+#endif
+
+#define LOG_ERROR(format, ...) \
+ nacl_io_log(LOG_PREFIX "error: " format "\n", ##__VA_ARGS__)
+
+EXTERN_C_BEGIN
+
+/*
+ * Low level logging function for nacl_io log messages.
+ *
+ * This function sends its output directly to the IRT standard out
+ * file descriptor, which by default will apear on the standard out
+ * or chrome or sel_ldr.
+ */
+void nacl_io_log(const char* format, ...) PRINTF_LIKE(1, 2);
+
+EXTERN_C_END
+
+#endif /* LIBRARIES_NACL_IO_LOG_H_ */
diff --git a/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h b/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
index a22e127a88..a889ecd2f0 100644
--- a/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
+++ b/native_client_sdk/src/libraries/nacl_io/pepper/all_interfaces.h
@@ -112,6 +112,14 @@ BEGIN_INTERFACE(VarArrayBufferInterface, PPB_VarArrayBuffer_1_0,
METHOD1(VarArrayBufferInterface, void, Unmap, PP_Var)
END_INTERFACE(VarArrayBufferInterface, PPB_VarArrayBuffer_1_0)
+BEGIN_INTERFACE(VarDictionaryInterface, PPB_VarDictionary_1_0,
+ PPB_VAR_DICTIONARY_INTERFACE_1_0)
+ METHOD0(VarDictionaryInterface, PP_Var, Create)
+ METHOD3(VarDictionaryInterface, PP_Bool, Set, PP_Var, PP_Var, PP_Var)
+ METHOD2(VarDictionaryInterface, PP_Var, Get, PP_Var, PP_Var)
+ METHOD1(VarDictionaryInterface, PP_Var, GetKeys, PP_Var)
+END_INTERFACE(VarDictionaryInterface, PPB_VarDictionary_1_0)
+
/* Chrome M18 required */
BEGIN_INTERFACE(VarInterface, PPB_Var_1_1, PPB_VAR_INTERFACE_1_1)
METHOD1(VarInterface, void, AddRef, PP_Var)
diff --git a/native_client_sdk/src/libraries/nacl_io/pepper_interface.h b/native_client_sdk/src/libraries/nacl_io/pepper_interface.h
index 6b25c922c5..c8964313c7 100644
--- a/native_client_sdk/src/libraries/nacl_io/pepper_interface.h
+++ b/native_client_sdk/src/libraries/nacl_io/pepper_interface.h
@@ -29,6 +29,7 @@
#include <ppapi/c/ppb_var.h>
#include <ppapi/c/ppb_var_array.h>
#include <ppapi/c/ppb_var_array_buffer.h>
+#include <ppapi/c/ppb_var_dictionary.h>
#include <sdk_util/macros.h>
diff --git a/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc b/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
index 3fcc7a0b1d..946cdd4eee 100644
--- a/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
+++ b/native_client_sdk/src/libraries/nacl_io/real_pepper_interface.cc
@@ -8,7 +8,7 @@
#include <stdio.h>
#include <ppapi/c/pp_errors.h>
-#include "nacl_io/dbgprint.h"
+#include "nacl_io/log.h"
namespace nacl_io {
@@ -88,7 +88,7 @@ RealPepperInterface::RealPepperInterface(PP_Instance instance,
if (iface) \
BaseClass##interface_ = new Real##BaseClass(iface); \
else \
- dbgprintf("nacl_io: interface missing: %s\n", InterfaceString); \
+ LOG_ERROR("interface missing: %s\n", InterfaceString); \
}
#include "nacl_io/pepper/all_interfaces.h"
}
diff --git a/native_client_sdk/src/libraries/sdk_util/macros.h b/native_client_sdk/src/libraries/sdk_util/macros.h
index e2e5400895..b1bc75e5e0 100644
--- a/native_client_sdk/src/libraries/sdk_util/macros.h
+++ b/native_client_sdk/src/libraries/sdk_util/macros.h
@@ -46,4 +46,20 @@
force_link_##x = 1; \
}
+/**
+ * Macro to error out when a printf-like function is passed incorrect arguments.
+ *
+ * Use like this:
+ * void foo(const char* fmt, ...) PRINTF_LIKE(1, 2);
+ *
+ * The first argument is the location of the fmt string (1-based).
+ * The second argument is the location of the first argument to validate (also
+ * 1-based, but can be zero if the function uses a va_list, like vprintf.)
+ */
+#if defined(__GNUC__)
+#define PRINTF_LIKE(a, b) __attribute__ ((format(printf, a, b)))
+#else
+#define PRINTF_LIKE(a, b)
+#endif
+
#endif /* LIBRARIES_SDK_UTIL_MACROS_H_ */
diff --git a/native_client_sdk/src/resources/Makefile.example.template b/native_client_sdk/src/resources/Makefile.example.template
index 1c0892a5bf..73f39963c2 100644
--- a/native_client_sdk/src/resources/Makefile.example.template
+++ b/native_client_sdk/src/resources/Makefile.example.template
@@ -34,6 +34,12 @@ NACL_SDK_ROOT ?= $(abspath $(CURDIR)/{{rel_sdk}})
EXTRA_INC_PATHS={{' '.join(targets[0]['INCLUDES'])}}
[[]]
+[[if multi_platform:]]
+# Build with platform-specific subdirectories, to reduce the download size of
+# the app.
+MULTI_PLATFORM = 1
+[[]]
+
include $(NACL_SDK_ROOT)/tools/common.mk
[[if desc.get('SOCKET_PERMISSIONS'):]]
@@ -96,8 +102,14 @@ $(eval $(call SO_RULE,{{name}},$({{sources}})))
[[ elif target['TYPE'] == 'so-standalone':]]
$(eval $(call SO_RULE,{{name}},$({{sources}}),,,1))
[[ else:]]
+# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
+# On NaCl, only produce a stripped binary for Release configs (not Debug).
+ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,{{name}}_unstripped,$({{sources}}),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,{{name}},{{name}}_unstripped))
+else
+$(eval $(call LINK_RULE,{{name}},$({{sources}}),$(LIBS),$(DEPS)))
+endif
[[]]
$(eval $(call NMF_RULE,$(TARGET),)){{post}}
diff --git a/native_client_sdk/src/resources/manifest.json.template b/native_client_sdk/src/resources/manifest.json.template
index 31882ce3eb..f240fd2fd8 100644
--- a/native_client_sdk/src/resources/manifest.json.template
+++ b/native_client_sdk/src/resources/manifest.json.template
@@ -26,5 +26,21 @@
[[]]
"scopes": ["https://www.googleapis.com/auth/drive"]
},
+[[if multi_platform:]]
+ "platforms": [
+ {
+ "nacl_arch": "x86-64",
+ "sub_package_path": "_platform_specific/x86-64"
+ },
+ {
+ "nacl_arch": "x86-32",
+ "sub_package_path": "_platform_specific/x86-32"
+ },
+ {
+ "nacl_arch": "arm",
+ "sub_package_path": "_platform_specific/arm"
+ }
+ ],
+[[]]
"permissions": {{permissions}}
}
diff --git a/native_client_sdk/src/tests/nacl_io_test/example.dsc b/native_client_sdk/src/tests/nacl_io_test/example.dsc
index 1a0c565ce1..15c0f47231 100644
--- a/native_client_sdk/src/tests/nacl_io_test/example.dsc
+++ b/native_client_sdk/src/tests/nacl_io_test/example.dsc
@@ -29,6 +29,8 @@
'fake_ppapi/fake_var_array_buffer_interface.h',
'fake_ppapi/fake_var_array_interface.cc',
'fake_ppapi/fake_var_array_interface.h',
+ 'fake_ppapi/fake_var_dictionary_interface.cc',
+ 'fake_ppapi/fake_var_dictionary_interface.h',
'fake_ppapi/fake_var_interface.cc',
'fake_ppapi/fake_var_interface.h',
'fake_ppapi/fake_var_manager.cc',
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.cc b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.cc
index f070c034cd..21f49f523a 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.cc
@@ -24,6 +24,9 @@ FakePepperInterface::FakePepperInterface()
var_array_interface_(&var_manager_),
var_array_buffer_interface_(&var_manager_),
var_interface_(&var_manager_),
+ var_dictionary_interface_(&var_manager_,
+ &var_interface_,
+ &var_array_interface_),
resolver_interface_(this),
net_address_interface_(this) {
FakeInstanceResource* instance_resource = new FakeInstanceResource;
@@ -48,6 +51,10 @@ VarArrayBufferInterface* FakePepperInterface::GetVarArrayBufferInterface() {
return &var_array_buffer_interface_;
}
+VarDictionaryInterface* FakePepperInterface::GetVarDictionaryInterface() {
+ return &var_dictionary_interface_;
+}
+
VarInterface* FakePepperInterface::GetVarInterface() {
return &var_interface_;
}
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.h
index a1a5ebcac4..1e6786c5c0 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_pepper_interface.h
@@ -12,6 +12,7 @@
#include "fake_ppapi/fake_resource_manager.h"
#include "fake_ppapi/fake_var_array_buffer_interface.h"
#include "fake_ppapi/fake_var_array_interface.h"
+#include "fake_ppapi/fake_var_dictionary_interface.h"
#include "fake_ppapi/fake_var_interface.h"
#include "fake_ppapi/fake_var_manager.h"
#include "nacl_io/pepper_interface_dummy.h"
@@ -25,6 +26,7 @@ class FakePepperInterface : public nacl_io::PepperInterfaceDummy {
virtual nacl_io::MessagingInterface* GetMessagingInterface();
virtual nacl_io::VarArrayInterface* GetVarArrayInterface();
virtual nacl_io::VarArrayBufferInterface* GetVarArrayBufferInterface();
+ virtual nacl_io::VarDictionaryInterface* GetVarDictionaryInterface();
virtual nacl_io::VarInterface* GetVarInterface();
virtual nacl_io::HostResolverInterface* GetHostResolverInterface();
virtual nacl_io::NetAddressInterface* GetNetAddressInterface();
@@ -43,6 +45,7 @@ class FakePepperInterface : public nacl_io::PepperInterfaceDummy {
FakeVarArrayInterface var_array_interface_;
FakeVarArrayBufferInterface var_array_buffer_interface_;
FakeVarInterface var_interface_;
+ FakeVarDictionaryInterface var_dictionary_interface_;
FakeHostResolverInterface resolver_interface_;
FakeNetAddressInterface net_address_interface_;
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_buffer_interface.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_buffer_interface.h
index fb48371e88..8f0d23e713 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_buffer_interface.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_buffer_interface.h
@@ -5,11 +5,6 @@
#ifndef TESTS_NACL_IO_TEST_FAKE_VAR_ARRAY_BUFFER_INTERFACE_H_
#define TESTS_NACL_IO_TEST_FAKE_VAR_ARRAY_BUFFER_INTERFACE_H_
-#include <map>
-#include <string>
-
-#include <ppapi/c/pp_var.h>
-
#include "nacl_io/pepper_interface.h"
#include "sdk_util/macros.h"
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_interface.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_interface.h
index 8b70174fe4..1c81583331 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_interface.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_array_interface.h
@@ -5,11 +5,6 @@
#ifndef TESTS_NACL_IO_TEST_FAKE_VAR_ARRAY_INTERFACE_H_
#define TESTS_NACL_IO_TEST_FAKE_VAR_ARRAY_INTERFACE_H_
-#include <map>
-#include <string>
-
-#include <ppapi/c/pp_var.h>
-
#include "nacl_io/pepper_interface.h"
#include "sdk_util/macros.h"
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.cc b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.cc
new file mode 100644
index 0000000000..8ae97e8731
--- /dev/null
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.cc
@@ -0,0 +1,104 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fake_ppapi/fake_var_dictionary_interface.h"
+
+#include "fake_ppapi/fake_var_manager.h"
+#include "gtest/gtest.h"
+
+FakeVarDictionaryInterface::FakeVarDictionaryInterface(FakeVarManager* manager,
+ nacl_io::VarInterface* var_interface,
+ nacl_io::VarArrayInterface* array_interface) :
+ manager_(manager),
+ var_interface_(var_interface),
+ array_interface_(array_interface) {}
+
+
+PP_Var FakeVarDictionaryInterface::Create() {
+ FakeVarData* var_data = manager_->CreateVarData();
+ var_data->type = PP_VARTYPE_DICTIONARY;
+
+ struct PP_Var result = {PP_VARTYPE_DICTIONARY, 0, {PP_FALSE}};
+ result.value.as_id = var_data->id;
+ return result;
+}
+
+PP_Bool FakeVarDictionaryInterface::Set(PP_Var var, PP_Var key, PP_Var value) {
+ EXPECT_EQ(PP_VARTYPE_DICTIONARY, var.type);
+ EXPECT_EQ(PP_VARTYPE_STRING, key.type);
+ FakeVarData* data = manager_->GetVarData(var);
+ FakeVarData* key_data = manager_->GetVarData(key);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), data);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), key_data);
+ const std::string& key_string = key_data->string_value;
+ FakeDictType& dict = data->dict_value;
+ manager_->AddRef(value);
+ // Release any existing value
+ if (dict.count(key_string) > 0) {
+ manager_->Release(dict[key_string]);
+ }
+ dict[key_string] = value;
+ return PP_TRUE;
+}
+
+PP_Var FakeVarDictionaryInterface::Get(PP_Var var, PP_Var key) {
+ EXPECT_EQ(PP_VARTYPE_DICTIONARY, var.type);
+ EXPECT_EQ(PP_VARTYPE_STRING, key.type);
+ FakeVarData* data = manager_->GetVarData(var);
+ FakeVarData* key_data = manager_->GetVarData(key);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), data);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), key_data);
+ FakeDictType& dict = data->dict_value;
+ const std::string& key_string = key_data->string_value;
+ PP_Var rtn = dict[key_string];
+ manager_->AddRef(rtn);
+ return rtn;
+}
+
+void FakeVarDictionaryInterface::Delete(PP_Var var, PP_Var key) {
+ EXPECT_EQ(PP_VARTYPE_DICTIONARY, var.type);
+ EXPECT_EQ(PP_VARTYPE_STRING, key.type);
+ FakeVarData* data = manager_->GetVarData(var);
+ FakeVarData* key_data = manager_->GetVarData(key);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), data);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), key_data);
+ FakeDictType& dict = data->dict_value;
+ const std::string& key_string = key_data->string_value;
+ if (dict.count(key_string) > 0) {
+ manager_->Release(dict[key_string]);
+ }
+ dict.erase(key_string);
+}
+
+PP_Bool FakeVarDictionaryInterface::HasKey(PP_Var var, PP_Var key) {
+ EXPECT_EQ(PP_VARTYPE_DICTIONARY, var.type);
+ EXPECT_EQ(PP_VARTYPE_STRING, key.type);
+ FakeVarData* data = manager_->GetVarData(var);
+ FakeVarData* key_data = manager_->GetVarData(key);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), data);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), key_data);
+ FakeDictType& dict = data->dict_value;
+ const std::string& key_string = key_data->string_value;
+ if (dict.count(key_string) > 0)
+ return PP_FALSE;
+ return PP_TRUE;
+}
+
+PP_Var FakeVarDictionaryInterface::GetKeys(PP_Var var) {
+ EXPECT_EQ(PP_VARTYPE_DICTIONARY, var.type);
+ FakeVarData* data = manager_->GetVarData(var);
+ EXPECT_NE(static_cast<FakeVarData*>(NULL), data);
+ FakeDictType& dict = data->dict_value;
+ PP_Var rtn = array_interface_->Create();
+ array_interface_->SetLength(rtn, dict.size());
+ int index = 0;
+ for (FakeDictType::iterator it = dict.begin(); it != dict.end(); it++) {
+ PP_Var key = var_interface_->VarFromUtf8(it->first.c_str(),
+ it->first.size());
+ array_interface_->Set(rtn, index, key);
+ manager_->Release(key);
+ index++;
+ }
+ return rtn;
+}
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.h
new file mode 100644
index 0000000000..5199863448
--- /dev/null
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_dictionary_interface.h
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TESTS_NACL_IO_TEST_FAKE_VAR_DICTIONARY_INTERFACE_H_
+#define TESTS_NACL_IO_TEST_FAKE_VAR_DICTIONARY_INTERFACE_H_
+
+#include "nacl_io/pepper_interface.h"
+#include "sdk_util/macros.h"
+
+class FakeVarManager;
+
+class FakeVarDictionaryInterface : public nacl_io::VarDictionaryInterface {
+ public:
+ explicit FakeVarDictionaryInterface(FakeVarManager* manager,
+ nacl_io::VarInterface* var_interface,
+ nacl_io::VarArrayInterface* array_interface);
+
+ virtual PP_Var Create();
+ virtual PP_Var Get(PP_Var dict, PP_Var key);
+ virtual PP_Bool Set(PP_Var dict, PP_Var key, PP_Var value);
+ virtual void Delete(PP_Var dict, PP_Var key);
+ virtual PP_Bool HasKey(PP_Var dict, PP_Var key);
+ virtual PP_Var GetKeys(PP_Var dict);
+
+ private:
+ FakeVarManager* manager_;
+ nacl_io::VarInterface* var_interface_;
+ nacl_io::VarArrayInterface* array_interface_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeVarDictionaryInterface);
+};
+
+#endif // TESTS_NACL_IO_TEST_FAKE_VAR_DICTIONARY_INTERFACE_H_
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_interface.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_interface.h
index 451553b2ad..c6dd4ea79b 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_interface.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_interface.h
@@ -5,8 +5,6 @@
#ifndef TESTS_NACL_IO_TEST_FAKE_VAR_INTERFACE_H_
#define TESTS_NACL_IO_TEST_FAKE_VAR_INTERFACE_H_
-#include <ppapi/c/pp_var.h>
-
#include "nacl_io/pepper_interface.h"
#include "sdk_util/macros.h"
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.cc b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.cc
index eb1809e3e7..e6c16bc947 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.cc
@@ -74,18 +74,29 @@ void FakeVarManager::DestroyVarData(FakeVarData* var_data) {
switch (var_data->type) {
case PP_VARTYPE_ARRAY: {
- std::vector<PP_Var>& vector = var_data->array_value;
- for (std::vector<PP_Var>::iterator it = vector.begin();
- it != vector.end(); ++it) {
+ FakeArrayType& vector = var_data->array_value;
+ for (FakeArrayType::iterator it = vector.begin();
+ it != vector.end(); ++it) {
Release(*it);
}
vector.clear();
break;
}
- case PP_VARTYPE_ARRAY_BUFFER:
+ case PP_VARTYPE_ARRAY_BUFFER: {
free(var_data->buffer_value.ptr);
var_data->buffer_value.ptr = NULL;
var_data->buffer_value.length = 0;
+ break;
+ }
+ case PP_VARTYPE_DICTIONARY: {
+ FakeDictType& dict = var_data->dict_value;
+ for (FakeDictType::iterator it = dict.begin();
+ it != dict.end(); it++) {
+ Release(it->second);
+ }
+ dict.clear();
+ break;
+ }
default:
break;
}
@@ -95,7 +106,10 @@ FakeVarData* FakeVarManager::GetVarData(PP_Var var) {
VarMap::iterator iter = var_map_.find(var.value.as_id);
if (iter == var_map_.end())
return NULL;
- return &iter->second;
+ FakeVarData* var_data = &iter->second;
+ EXPECT_GT(var_data->ref_count, 0)
+ << "Accessing freed " << Describe(*var_data);
+ return var_data;
}
void FakeVarManager::Release(PP_Var var) {
diff --git a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.h b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.h
index c8d13091c6..8f02bb5cf2 100644
--- a/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.h
+++ b/native_client_sdk/src/tests/nacl_io_test/fake_ppapi/fake_var_manager.h
@@ -12,12 +12,16 @@
#include "sdk_util/macros.h"
+typedef std::vector<PP_Var> FakeArrayType;
+typedef std::map<std::string, PP_Var> FakeDictType;
+
struct FakeVarData {
uint64_t id;
uint64_t type;
int32_t ref_count;
std::string string_value;
- std::vector<PP_Var> array_value;
+ FakeArrayType array_value;
+ FakeDictType dict_value;
struct {
void* ptr;
uint32_t length;
diff --git a/native_client_sdk/src/tools/fix_manifest.py b/native_client_sdk/src/tools/fix_manifest.py
new file mode 100755
index 0000000000..c9b892f589
--- /dev/null
+++ b/native_client_sdk/src/tools/fix_manifest.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Disable the lint error for too-long lines for the URL below.
+# pylint: disable=C0301
+
+"""Fix Chrome App manifest.json files for use with multi-platform zip files.
+
+See info about multi-platform zip files here:
+https://developer.chrome.com/native-client/devguide/distributing#packaged-application
+
+The manifest.json file needs to point to the correct platform-specific paths,
+but we build all toolchains and configurations in the same tree. As a result,
+we can't have one manifest.json for all combinations.
+
+Instead, we update the top-level manifest.json file during the build:
+
+ "platforms": [
+ {
+ "nacl_arch": "x86-64",
+ "sub_package_path": "_platform_specific/x86-64/"
+ },
+ ...
+
+Becomes
+
+ "platforms": [
+ {
+ "nacl_arch": "x86-64",
+ "sub_package_path": "<toolchain>/<config>/_platform_specific/x86-64/"
+ },
+ ...
+"""
+
+import collections
+import json
+import optparse
+import os
+import sys
+
+if sys.version_info < (2, 6, 0):
+ sys.stderr.write("python 2.6 or later is required run this script\n")
+ sys.exit(1)
+
+
+class Error(Exception):
+ """Local Error class for this file."""
+ pass
+
+
+def Trace(msg):
+ if Trace.verbose:
+ sys.stderr.write(str(msg) + '\n')
+
+Trace.verbose = False
+
+
+def main(argv):
+ parser = optparse.OptionParser(
+ usage='Usage: %prog [options] manifest.json', description=__doc__)
+ parser.add_option('-p', '--prefix',
+ help='Prefix to set for all sub_package_paths in the '
+ 'manifest. If none is specified, the prefix will be '
+ 'removed; i.e. the start of the path will be '
+ '"_platform_specific/..."')
+ parser.add_option('-v', '--verbose',
+ help='Verbose output', action='store_true')
+
+ options, args = parser.parse_args(argv)
+ if options.verbose:
+ Trace.verbose = True
+
+ if not args:
+ parser.error('Expected manifest file.')
+
+ manifest = args[0]
+
+ Trace('Reading %s' % manifest)
+ with open(manifest) as f:
+ # Keep the dictionary order. This is only supported on Python 2.7+
+ if sys.version_info >= (2, 7, 0):
+ data = json.load(f, object_pairs_hook=collections.OrderedDict)
+ else:
+ data = json.load(f)
+
+ if 'platforms' not in data:
+ raise Error('%s does not have "platforms" key.' % manifest)
+
+ platforms = data['platforms']
+ if type(platforms) is not list:
+ raise Error('Expected "platforms" key to be array.')
+
+ if options.prefix:
+ prefix = options.prefix + '/'
+ else:
+ prefix = ''
+
+ for platform in platforms:
+ nacl_arch = platform.get('nacl_arch')
+
+ if 'sub_package_path' not in platform:
+ raise Error('Expected each platform to have "sub_package_path" key.')
+
+ sub_package_path = platform['sub_package_path']
+ index = sub_package_path.find('_platform_specific')
+ if index == -1:
+ raise Error('Could not find "_platform_specific" in the '
+ '"sub_package_path" key.')
+
+ new_path = prefix + sub_package_path[index:]
+ platform['sub_package_path'] = new_path
+
+ Trace(' %s: "%s" -> "%s"' % (nacl_arch, sub_package_path, new_path))
+
+ with open(manifest, 'w') as f:
+ json.dump(data, f, indent=2)
+
+ return 0
+
+
+if __name__ == '__main__':
+ try:
+ rtn = main(sys.argv[1:])
+ except Error, e:
+ sys.stderr.write('%s: %s\n' % (os.path.basename(__file__), e))
+ rtn = 1
+ except KeyboardInterrupt:
+ sys.stderr.write('%s: interrupted\n' % os.path.basename(__file__))
+ rtn = 1
+ sys.exit(rtn)
diff --git a/native_client_sdk/src/tools/nacl_gcc.mk b/native_client_sdk/src/tools/nacl_gcc.mk
index ddd20d571a..832efeba97 100644
--- a/native_client_sdk/src/tools/nacl_gcc.mk
+++ b/native_client_sdk/src/tools/nacl_gcc.mk
@@ -10,9 +10,6 @@
#
# Macros for TOOLS
#
-# We always link with the C++ compiler but include -Wl,-as-needed flag
-# in LDFLAGS so the linker should drop libc++ unless it's actually needed.
-#
ifneq ($(TOOLCHAIN),bionic)
X86_32_CC := $(NACL_COMPILER_PREFIX) $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) -a x86_32 --tool=cc)
X86_32_CXX := $(NACL_COMPILER_PREFIX) $(shell $(NACL_CONFIG) -t $(TOOLCHAIN) -a x86_32 --tool=c++)
@@ -40,6 +37,17 @@ endif
NCVAL ?= python $(NACL_SDK_ROOT)/tools/ncval.py
+# Architecture-specific variables
+ifeq (,$(MULTI_PLATFORM))
+X86_32_OUTDIR ?= $(OUTDIR)
+X86_64_OUTDIR ?= $(OUTDIR)
+ARM_OUTDIR ?= $(OUTDIR)
+else
+X86_32_OUTDIR ?= $(OUTDIR)/_platform_specific/x86-32
+X86_64_OUTDIR ?= $(OUTDIR)/_platform_specific/x86-64
+ARM_OUTDIR ?= $(OUTDIR)/_platform_specific/arm
+endif
+
# Architecture-specific flags
X86_32_CFLAGS ?=
X86_64_CFLAGS ?=
@@ -55,9 +63,15 @@ ARM_CFLAGS ?=
ARM_CXXFLAGS ?=
endif
+ifeq (,$(MULTI_PLATFORM))
X86_32_LDFLAGS ?= -Wl,-Map,$(OUTDIR)/$(TARGET)_x86_32.map
X86_64_LDFLAGS ?= -Wl,-Map,$(OUTDIR)/$(TARGET)_x86_64.map
ARM_LDFLAGS ?= -Wl,-Map,$(OUTDIR)/$(TARGET)_arm.map
+else
+X86_32_LDFLAGS ?= -Wl,-Map,$(X86_32_OUTDIR)/$(TARGET)_x86_32.map
+X86_64_LDFLAGS ?= -Wl,-Map,$(X86_64_OUTDIR)/$(TARGET)_x86_64.map
+ARM_LDFLAGS ?= -Wl,-Map,$(ARM_OUTDIR)/$(TARGET)_arm.map
+endif
LDFLAGS_SHARED = -shared
@@ -185,52 +199,55 @@ GLIBC_REMAP :=
#
define SO_LINKER_RULE
ifneq (,$(findstring x86_32,$(ARCHES)))
-all: $(OUTDIR)/lib$(1)_x86_32.so
-$(OUTDIR)/lib$(1)_x86_32.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(X86_32_OUTDIR)/lib$(1)_x86_32.so
+$(X86_32_OUTDIR)/lib$(1)_x86_32.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(X86_32_LINK) -o $$@ $$(filter %.o,$$^) $(LDFLAGS_SHARED) -m32 $(NACL_LDFLAGS) $(X86_32_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(TOOLCHAIN)_x86_32/$(CONFIG)) $(foreach lib,$(3),-l$(lib)))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).so
install: $(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).so
-$(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).so: $(OUTDIR)/lib$(1)_x86_32.so
+$(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).so: $(X86_32_OUTDIR)/lib$(1)_x86_32.so
$(MKDIR) -p $$(dir $$@)
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
ifneq ($(6),1)
-GLIBC_SO_LIST += $(OUTDIR)/lib$(1)_x86_32.so
+GLIBC_SO_LIST += $(X86_32_OUTDIR)/lib$(1)_x86_32.so
GLIBC_REMAP += -n lib$(1)_x86_32.so,lib$(1).so
endif
endif
ifneq (,$(findstring x86_64,$(ARCHES)))
-all: $(OUTDIR)/lib$(1)_x86_64.so
-$(OUTDIR)/lib$(1)_x86_64.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(X86_64_OUTDIR)/lib$(1)_x86_64.so
+$(X86_64_OUTDIR)/lib$(1)_x86_64.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(X86_32_LINK) -o $$@ $$(filter %.o,$$^) $(LDFLAGS_SHARED) -m64 $(NACL_LDFLAGS) $(X86_64_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(TOOLCHAIN)_x86_64/$(CONFIG)) $(foreach lib,$(3),-l$(lib)))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).so
install: $(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).so
-$(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).so: $(OUTDIR)/lib$(1)_x86_64.so
+$(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).so: $(X86_64_OUTDIR)/lib$(1)_x86_64.so
$(MKDIR) -p $$(dir $$@)
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
ifneq ($(6),1)
-GLIBC_SO_LIST += $(OUTDIR)/lib$(1)_x86_64.so
+GLIBC_SO_LIST += $(X86_64_OUTDIR)/lib$(1)_x86_64.so
GLIBC_REMAP += -n lib$(1)_x86_64.so,lib$(1).so
endif
endif
ifneq (,$(findstring arm,$(ARCHES)))
-all: $(OUTDIR)/lib$(1)_arm.so
-$(OUTDIR)/lib$(1)_arm.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(ARM_OUTDIR)/lib$(1)_arm.so
+$(ARM_OUTDIR)/lib$(1)_arm.so: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm_pic)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(ARM_LINK) -o $$@ $$(filter %.o,$$^) $(LDFLAGS_SHARED) -marm $(NACL_LDFLAGS) $(ARM_LDFLAGS) $(LDFLAGS) $(foreach path,$(5),-L$(path)/$(TOOLCHAIN)_arm/$(CONFIG)) $(foreach lib,$(3),-l$(lib)))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).so
install: $(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).so
-$(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).so: $(OUTDIR)/lib$(1)_arm.so
+$(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).so: $(ARM_OUTDIR)/lib$(1)_arm.so
$(MKDIR) -p $$(dir $$@)
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
ifneq ($(6),1)
-GLIBC_SO_LIST += $(OUTDIR)/lib$(1)_arm.so
+GLIBC_SO_LIST += $(ARM_OUTDIR)/lib$(1)_arm.so
GLIBC_REMAP += -n lib$(1)_arm.so,lib$(1).so
endif
endif
@@ -261,45 +278,45 @@ $(STAMPDIR)/$(1).stamp:
@echo "TOUCHED $$@" > $(STAMPDIR)/$(1).stamp
ifneq (,$(findstring x86_32,$(ARCHES)))
-all: $(OUTDIR)/lib$(1)_x86_32.a
-$(OUTDIR)/lib$(1)_x86_32.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32))
+all: $(X86_32_OUTDIR)/lib$(1)_x86_32.a
+$(X86_32_OUTDIR)/lib$(1)_x86_32.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32))
$(MKDIR) -p $$(dir $$@)
$(RM) -f $$@
$(call LOG,LIB ,$$@,$(X86_32_LIB) -cr $$@ $$^)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).a
install: $(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).a
-$(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).a: $(OUTDIR)/lib$(1)_x86_32.a
+$(LIBDIR)/$(TOOLCHAIN)_x86_32/$(CONFIG)/lib$(1).a: $(X86_32_OUTDIR)/lib$(1)_x86_32.a
$(MKDIR) -p $$(dir $$@)
$(RM) -f $$@
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
endif
ifneq (,$(findstring x86_64,$(ARCHES)))
-all: $(OUTDIR)/lib$(1)_x86_64.a
-$(OUTDIR)/lib$(1)_x86_64.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64))
+all: $(X86_64_OUTDIR)/lib$(1)_x86_64.a
+$(X86_64_OUTDIR)/lib$(1)_x86_64.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64))
$(MKDIR) -p $$(dir $$@)
$(RM) -f $$@
$(call LOG,LIB ,$$@,$(X86_64_LIB) -cr $$@ $$^)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).a
install: $(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).a
-$(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).a: $(OUTDIR)/lib$(1)_x86_64.a
+$(LIBDIR)/$(TOOLCHAIN)_x86_64/$(CONFIG)/lib$(1).a: $(X86_64_OUTDIR)/lib$(1)_x86_64.a
$(MKDIR) -p $$(dir $$@)
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
endif
ifneq (,$(findstring arm,$(ARCHES)))
ifneq ($(TOOLCHAIN),glibc)
-all: $(OUTDIR)/lib$(1)_arm.a
-$(OUTDIR)/lib$(1)_arm.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm))
+all: $(ARM_OUTDIR)/lib$(1)_arm.a
+$(ARM_OUTDIR)/lib$(1)_arm.a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm))
$(MKDIR) -p $$(dir $$@)
$(RM) -f $$@
$(call LOG,LIB ,$$@,$(ARM_LIB) -cr $$@ $$^)
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).a
install: $(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).a
-$(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).a: $(OUTDIR)/lib$(1)_arm.a
+$(LIBDIR)/$(TOOLCHAIN)_arm/$(CONFIG)/lib$(1).a: $(ARM_OUTDIR)/lib$(1)_arm.a
$(MKDIR) -p $$(dir $$@)
$(call LOG,CP ,$$@,$(OSHELPERS) cp $$^ $$@)
endif
@@ -319,22 +336,25 @@ endef
#
define LINKER_RULE
ifneq (,$(findstring x86_32,$(ARCHES)))
-all: $(OUTDIR)/$(1)_x86_32.nexe
-$(OUTDIR)/$(1)_x86_32.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(X86_32_OUTDIR)/$(1)_x86_32.nexe
+$(X86_32_OUTDIR)/$(1)_x86_32.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_32)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(X86_32_LINK) -o $$@ $$(filter %.o,$$^) $(NACL_LDFLAGS) $(X86_32_LDFLAGS) $(foreach path,$(6),-L$(path)/$(TOOLCHAIN)_x86_32/$(CONFIG)) $(foreach lib,$(3),-l$(lib)) $(5))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
endif
ifneq (,$(findstring x86_64,$(ARCHES)))
-all: $(OUTDIR)/$(1)_x86_64.nexe
-$(OUTDIR)/$(1)_x86_64.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(X86_64_OUTDIR)/$(1)_x86_64.nexe
+$(X86_64_OUTDIR)/$(1)_x86_64.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_x86_64)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(X86_64_LINK) -o $$@ $$(filter %.o,$$^) $(NACL_LDFLAGS) $(X86_64_LDFLAGS) $(foreach path,$(6),-L$(path)/$(TOOLCHAIN)_x86_64/$(CONFIG)) $(foreach lib,$(3),-l$(lib)) $(5))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
endif
ifneq (,$(findstring arm,$(ARCHES)))
-all: $(OUTDIR)/$(1)_arm.nexe
-$(OUTDIR)/$(1)_arm.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+all: $(ARM_OUTDIR)/$(1)_arm.nexe
+$(ARM_OUTDIR)/$(1)_arm.nexe: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src),_arm)) $(foreach dep,$(4),$(STAMPDIR)/$(dep).stamp)
+ $(MKDIR) -p $$(dir $$@)
$(call LOG,LINK,$$@,$(ARM_LINK) -static -o $$@ $$(filter %.o,$$^) $(NACL_LDFLAGS) $(ARM_LDFLAGS) $(foreach path,$(6),-L$(path)/$(TOOLCHAIN)_arm/$(CONFIG)) $(foreach lib,$(3),-l$(lib)) $(5))
$(call LOG,VALIDATE,$$@,$(NCVAL) $$@)
endif
@@ -364,17 +384,17 @@ endef
#
define STRIP_ALL_RULE
ifneq (,$(findstring x86_32,$(ARCHES)))
-$(OUTDIR)/$(1)_x86_32.nexe: $(OUTDIR)/$(2)_x86_32.nexe
+$(X86_32_OUTDIR)/$(1)_x86_32.nexe: $(X86_32_OUTDIR)/$(2)_x86_32.nexe
$(call LOG,STRIP,$$@,$(X86_32_STRIP) -o $$@ $$^)
endif
ifneq (,$(findstring x86_64,$(ARCHES)))
-$(OUTDIR)/$(1)_x86_64.nexe: $(OUTDIR)/$(2)_x86_64.nexe
+$(X86_64_OUTDIR)/$(1)_x86_64.nexe: $(X86_64_OUTDIR)/$(2)_x86_64.nexe
$(call LOG,STRIP,$$@,$(X86_64_STRIP) -o $$@ $$^)
endif
ifneq (,$(findstring arm,$(ARCHES)))
-$(OUTDIR)/$(1)_arm.nexe: $(OUTDIR)/$(2)_arm.nexe
+$(ARM_OUTDIR)/$(1)_arm.nexe: $(ARM_OUTDIR)/$(2)_arm.nexe
$(call LOG,STRIP,$$@,$(ARM_STRIP) -o $$@ $$^)
endif
endef
@@ -399,20 +419,20 @@ endef
#
define MAP_ALL_RULE
ifneq (,$(findstring x86_32,$(ARCHES)))
-all: $(OUTDIR)/$(1)_x86_32.map
-$(OUTDIR)/$(1)_x86_32.map: $(OUTDIR)/$(2)_x86_32.nexe
+all: $(X86_32_OUTDIR)/$(1)_x86_32.map
+$(X86_32_OUTDIR)/$(1)_x86_32.map: $(X86_32_OUTDIR)/$(2)_x86_32.nexe
$(call LOG,MAP,$$@,$(X86_32_NM) -l $$^ > $$@)
endif
ifneq (,$(findstring x86_64,$(ARCHES)))
-all: $(OUTDIR)/$(1)_x86_64.map
-$(OUTDIR)/$(1)_x86_64.map: $(OUTDIR)/$(2)_x86_64.nexe
+all: $(X86_64_OUTDIR)/$(1)_x86_64.map
+$(X86_64_OUTDIR)/$(1)_x86_64.map: $(X86_64_OUTDIR)/$(2)_x86_64.nexe
$(call LOG,MAP,$$@,$(X86_64_NM) -l $$^ > $$@)
endif
ifneq (,$(findstring arm,$(ARCHES)))
-all: $(OUTDIR)/$(1)_arm.map
-$(OUTDIR)/$(1)_arm.map: $(OUTDIR)/$(2)_arm.nexe
+all: $(ARM_OUTDIR)/$(1)_arm.map
+$(ARM_OUTDIR)/$(1)_arm.map: $(ARM_OUTDIR)/$(2)_arm.nexe
$(call LOG,MAP,$$@,$(ARM_NM) -l $$^ > $$@ )
endif
endef
@@ -430,13 +450,6 @@ endef
#
-# Generate ARCH_SUFFIXES, a list of suffixes for executables corresponding to all
-# the architectures in the current build.
-#
-ARCH_SUFFIXES := $(foreach arch,$(ARCHES),_$(arch).nexe)
-
-
-#
# NMF Manifiest generation
#
# Use the python script create_nmf to scan the binaries for dependencies using
@@ -453,12 +466,47 @@ NMF_FLAGS += --debug-libs
HTML_FLAGS += --debug-libs
endif
-EXECUTABLES=$(foreach arch,$(ARCH_SUFFIXES),$(OUTDIR)/$(1)$(arch)) $(GLIBC_SO_LIST)
+EXECUTABLES = $(GLIBC_SO_LIST)
+ifneq (,$(findstring x86_32,$(ARCHES)))
+EXECUTABLES += $(X86_32_OUTDIR)/$(1)_x86_32.nexe
+endif
+ifneq (,$(findstring x86_64,$(ARCHES)))
+EXECUTABLES += $(X86_64_OUTDIR)/$(1)_x86_64.nexe
+endif
+ifneq (,$(findstring arm,$(ARCHES)))
+EXECUTABLES += $(ARM_OUTDIR)/$(1)_arm.nexe
+endif
+
+ifneq (,$(MULTI_PLATFORM))
+# When building a multi-platform package, stage all dependent shared libraries
+# in the same directory as the .nexe (which will be an architecture-specific
+# directory under _platform_specific).
+NMF_FLAGS += -s $(OUTDIR) --no-arch-prefix
+else
+# Otherwise stage dependent libraries the normal way, under lib32 for x86_32
+# libraries, and lib64 for x86_64 libraries.
+NMF_FLAGS += -s $(OUTDIR)
+endif
+
+ifneq (,$(MULTI_PLATFORM))
+# This script fixes the manifest.json file for this App to point to:
+#
+# <toolchain>/<config>/_platform_specific/<arch>/
+#
+# instead of
+#
+# _platform_specific/<arch>
+FIX_MANIFEST := python $(NACL_SDK_ROOT)/tools/fix_manifest.py
+MANIFEST_JSON ?= manifest.json
+endif
define NMF_RULE
all: $(OUTDIR)/$(1).nmf
-$(OUTDIR)/$(1).nmf: $(EXECUTABLES)
- $(call LOG,CREATE_NMF,$$@,$(NMF) $(NMF_FLAGS) -o $$@ $$^ $(GLIBC_PATHS) -s $(OUTDIR) $(2) $(GLIBC_REMAP))
+$(OUTDIR)/$(1).nmf $(MANIFEST_JSON): $(EXECUTABLES)
+ $(call LOG,CREATE_NMF,$$@,$(NMF) $(NMF_FLAGS) -o $$@ $$^ $(GLIBC_PATHS) $(2) $(GLIBC_REMAP))
+ifneq (,$(MULTI_PLATFORM))
+ $(call LOG,FIX_MANIFEST,$(MANIFEST_JSON),$(FIX_MANIFEST) $(MANIFEST_JSON)) -p "$(TOOLCHAIN)/$(CONFIG)"
+endif
endef
#
diff --git a/native_client_sdk/src/tools/nacl_llvm.mk b/native_client_sdk/src/tools/nacl_llvm.mk
index 61e08f2f98..96150233ac 100644
--- a/native_client_sdk/src/tools/nacl_llvm.mk
+++ b/native_client_sdk/src/tools/nacl_llvm.mk
@@ -121,10 +121,8 @@ endef
#
# Strip Macro
#
-# NOTE: pnacl-strip does not currently support stripping finalized pexes (in a
-# sense, they are already stripped). So we just copy the file instead.
-#
-# See https://code.google.com/p/nativeclient/issues/detail?id=3534
+# NOTE: pnacl-strip does not really do much for finalized pexes (in a
+# sense, they are already stripped), but set this rule up for uniformity.
#
# $1 = Target Name
# $2 = Input Name
@@ -132,19 +130,19 @@ endef
define STRIP_RULE
all: $(OUTDIR)/$(1).pexe
$(OUTDIR)/$(1).pexe: $(OUTDIR)/$(2).pexe
- $(CP) $$^ $$@
+ $(call LOG,STRIP,$$@,$(PNACL_STRIP) $$^ -o $$@)
endef
#
-# NMF Manifiest generation
+# NMF Manifest generation
#
# Use the python script create_nmf to scan the binaries for dependencies using
# objdump. Pass in the (-L) paths to the default library toolchains so that we
# can find those libraries and have it automatically copy the files (-s) to
# the target directory for us.
#
-# $1 = Target Name (the basename of the nmf
+# $1 = Target Name (the basename of the nmf)
# $2 = Additional create_nmf.py arguments
#
NMF:=python $(NACL_SDK_ROOT)/tools/create_nmf.py