Remove unneeded JNI registrations.

Rather than registering all jni bindings at startup, only get references
to the class object for those files which require bindings. All others
are satisfied by exporting symbols which can be found automatically by
dalvik.

This patch replaces excldue-libs=ALL with ld version script to strip unwanted
symbols: https://sourceware.org/binutils/docs-2.24/ld/VERSION.html#VERSION

BUG=

Review URL: https://codereview.chromium.org/147533004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275652 0039d316-1c4b-4281-b951-d872f2087c98
parent 33ed90e0
...@@ -793,6 +793,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") ...@@ -793,6 +793,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
for native in self.natives: for native in self.natives:
if native.type != 'method': if native.type != 'method':
ret += [self.GetForwardDeclaration(native)] ret += [self.GetForwardDeclaration(native)]
if self.options.native_exports and ret:
return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
return '\n'.join(ret) return '\n'.join(ret)
def GetConstantFieldsString(self): def GetConstantFieldsString(self):
...@@ -814,6 +816,9 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") ...@@ -814,6 +816,9 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
ret += self.GetEagerCalledByNativeMethodStubs() ret += self.GetEagerCalledByNativeMethodStubs()
else: else:
ret += self.GetLazyCalledByNativeMethodStubs() ret += self.GetLazyCalledByNativeMethodStubs()
if self.options.native_exports and ret:
return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
return '\n'.join(ret) return '\n'.join(ret)
def GetLazyCalledByNativeMethodStubs(self): def GetLazyCalledByNativeMethodStubs(self):
...@@ -859,6 +864,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""") ...@@ -859,6 +864,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
def GetJNINativeMethodsString(self): def GetJNINativeMethodsString(self):
"""Returns the implementation of the array of native methods.""" """Returns the implementation of the array of native methods."""
if self.options.native_exports:
return ''
template = Template("""\ template = Template("""\
static const JNINativeMethod kMethods${JAVA_CLASS}[] = { static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
${KMETHODS} ${KMETHODS}
...@@ -913,6 +920,9 @@ ${CALLED_BY_NATIVES} ...@@ -913,6 +920,9 @@ ${CALLED_BY_NATIVES}
def GetRegisterNativesImplString(self): def GetRegisterNativesImplString(self):
"""Returns the shared implementation for RegisterNatives.""" """Returns the shared implementation for RegisterNatives."""
if self.options.native_exports:
return ''
template = Template("""\ template = Template("""\
const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS}); const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
...@@ -937,11 +947,17 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { ...@@ -937,11 +947,17 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
return ${NAMESPACE}RegisterNativesImpl(env, clazz); return ${NAMESPACE}RegisterNativesImpl(env, clazz);
} }
""") """)
fully_qualified_class = self.fully_qualified_class.replace('/', '_')
if self.options.native_exports:
java_name = JniParams.RemapClassName(self.fully_qualified_class)
java_name = java_name.replace('_', '_1').replace('/', '_')
else:
java_name = self.fully_qualified_class.replace('/', '_')
namespace = '' namespace = ''
if self.namespace: if self.namespace:
namespace = self.namespace + '::' namespace = self.namespace + '::'
values = {'FULLY_QUALIFIED_CLASS': fully_qualified_class, values = {'FULLY_QUALIFIED_CLASS': java_name,
'INIT_NATIVE_NAME': 'native' + self.init_native.name, 'INIT_NATIVE_NAME': 'native' + self.init_native.name,
'NAMESPACE': namespace, 'NAMESPACE': namespace,
'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString() 'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
...@@ -995,23 +1011,52 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) { ...@@ -995,23 +1011,52 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
for param in called_by_native.params]) for param in called_by_native.params])
def GetForwardDeclaration(self, native): def GetForwardDeclaration(self, native):
template = Template(""" template_str = """
static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS}); static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS});
""") """
if self.options.native_exports:
template_str += """
__attribute__((visibility("default")))
${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env, ${PARAMS}) {
return ${NAME}(${PARAMS_IN_CALL});
}
"""
template = Template(template_str)
params_in_call = []
if not self.options.pure_native_methods:
params_in_call = ['env', 'jcaller']
params_in_call = ', '.join(params_in_call + [p.name for p in native.params])
java_name = JniParams.RemapClassName(self.fully_qualified_class)
java_name = java_name.replace('_', '_1').replace('/', '_')
if native.java_class_name:
java_name += '_00024' + native.java_class_name
values = {'RETURN': JavaDataTypeToC(native.return_type), values = {'RETURN': JavaDataTypeToC(native.return_type),
'NAME': native.name, 'NAME': native.name,
'PARAMS': self.GetParamsInDeclaration(native)} 'JAVA_NAME': java_name,
'PARAMS': self.GetParamsInDeclaration(native),
'PARAMS_IN_CALL': params_in_call}
return template.substitute(values) return template.substitute(values)
def GetNativeMethodStubString(self, native): def GetNativeMethodStubString(self, native):
"""Returns stubs for native methods.""" """Returns stubs for native methods."""
template = Template("""\ if self.options.native_exports:
static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { template_str = """\
__attribute__((visibility("default")))
${RETURN} Java_${JAVA_NAME}_native${NAME}(JNIEnv* env,
${PARAMS_IN_DECLARATION}) {"""
else:
template_str = """\
static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {"""
template_str += """
${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME}); ${P0_TYPE}* native = reinterpret_cast<${P0_TYPE}*>(${PARAM0_NAME});
CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN}); CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL}; return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
} }
""") """
template = Template(template_str)
params = [] params = []
if not self.options.pure_native_methods: if not self.options.pure_native_methods:
params = ['env', 'jcaller'] params = ['env', 'jcaller']
...@@ -1024,9 +1069,19 @@ static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) { ...@@ -1024,9 +1069,19 @@ static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {
post_call = '' post_call = ''
if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type): if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
post_call = '.Release()' post_call = '.Release()'
if self.options.native_exports:
java_name = JniParams.RemapClassName(self.fully_qualified_class)
java_name = java_name.replace('_', '_1').replace('/', '_')
if native.java_class_name:
java_name += '_00024' + native.java_class_name
else:
java_name = ''
values = { values = {
'RETURN': return_type, 'RETURN': return_type,
'OPTIONAL_ERROR_RETURN': optional_error_return, 'OPTIONAL_ERROR_RETURN': optional_error_return,
'JAVA_NAME': java_name,
'NAME': native.name, 'NAME': native.name,
'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native), 'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
'PARAM0_NAME': native.params[0].name, 'PARAM0_NAME': native.params[0].name,
...@@ -1174,8 +1229,12 @@ ${FUNCTION_HEADER} ...@@ -1174,8 +1229,12 @@ ${FUNCTION_HEADER}
const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""") const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
native_classes = self.GetUniqueClasses(self.natives) native_classes = self.GetUniqueClasses(self.natives)
called_by_native_classes = self.GetUniqueClasses(self.called_by_natives) called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
if self.options.native_exports:
all_classes = called_by_native_classes
else:
all_classes = native_classes all_classes = native_classes
all_classes.update(called_by_native_classes) all_classes.update(called_by_native_classes)
for clazz in all_classes: for clazz in all_classes:
values = { values = {
'JAVA_CLASS': clazz, 'JAVA_CLASS': clazz,
...@@ -1394,6 +1453,9 @@ See SampleForTests.java for more details. ...@@ -1394,6 +1453,9 @@ See SampleForTests.java for more details.
help='The path to cpp command.') help='The path to cpp command.')
option_parser.add_option('--javap', default='javap', option_parser.add_option('--javap', default='javap',
help='The path to javap command.') help='The path to javap command.')
option_parser.add_option('--native_exports', action='store_true',
help='Native method registration through .so '
'exports.')
options, args = option_parser.parse_args(argv) options, args = option_parser.parse_args(argv)
if options.jar_file: if options.jar_file:
input_file = ExtractJarInputFile(options.jar_file, options.input_file, input_file = ExtractJarInputFile(options.jar_file, options.input_file,
......
...@@ -42,7 +42,7 @@ class TestOptions(object): ...@@ -42,7 +42,7 @@ class TestOptions(object):
self.eager_called_by_natives = False self.eager_called_by_natives = False
self.cpp = 'cpp' self.cpp = 'cpp'
self.javap = 'javap' self.javap = 'javap'
self.native_exports = False
class TestGenerator(unittest.TestCase): class TestGenerator(unittest.TestCase):
def assertObjEquals(self, first, second): def assertObjEquals(self, first, second):
...@@ -996,6 +996,45 @@ class Foo { ...@@ -996,6 +996,45 @@ class Foo {
test_data, 'org/chromium/example/jni_generator/Test', options) test_data, 'org/chromium/example/jni_generator/Test', options)
self.assertGoldenTextEquals(jni_from_java.GetContent()) self.assertGoldenTextEquals(jni_from_java.GetContent())
def testNativeExportsOption(self):
test_data = """
package org.chromium.example.jni_generator;
/** The pointer to the native Test. */
long nativeTest;
class Test {
private static native boolean nativeInitNativeClass();
private static native int nativeStaticMethod(long nativeTest, int arg1);
private native int nativeMethod(long nativeTest, int arg1);
@CalledByNative
private void testMethodWithParam(int iParam);
@CalledByNative
private String testMethodWithParamAndReturn(int iParam);
@CalledByNative
private static int testStaticMethodWithParam(int iParam);
@CalledByNative
private static double testMethodWithNoParam();
@CalledByNative
private static String testStaticMethodWithNoParam();
class MyInnerClass {
@NativeCall("MyInnerClass")
private native int nativeInit();
}
class MyOtherInnerClass {
@NativeCall("MyOtherInnerClass")
private native int nativeInit();
}
}
"""
options = TestOptions()
options.jni_init_native_name = 'nativeInitNativeClass'
options.native_exports = True
jni_from_java = jni_generator.JNIFromJavaSource(
test_data, 'org/chromium/example/jni_generator/SampleForTests', options)
self.assertGoldenTextEquals(jni_from_java.GetContent())
def testOuterInnerRaises(self): def testOuterInnerRaises(self):
test_data = """ test_data = """
package org.chromium.media; package org.chromium.media;
......
// 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.
// This file is autogenerated by
// base/android/jni_generator/jni_generator.py
// For
// org/chromium/example/jni_generator/SampleForTests
#ifndef org_chromium_example_jni_generator_SampleForTests_JNI
#define org_chromium_example_jni_generator_SampleForTests_JNI
#include <jni.h>
#include "base/android/jni_generator/jni_generator_helper.h"
#include "base/android/jni_int_wrapper.h"
// Step 1: forward declarations.
namespace {
const char kSampleForTestsClassPath[] =
"org/chromium/example/jni_generator/SampleForTests";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_SampleForTests_clazz = NULL;
} // namespace
extern "C" {
static jint Init(JNIEnv* env, jobject jcaller);
__attribute__((visibility("default")))
jint
Java_org_chromium_example_jni_1generator_SampleForTests_00024MyInnerClass_nativeInit(JNIEnv*
env, jobject jcaller) {
return Init(env, jcaller);
}
static jint Init(JNIEnv* env, jobject jcaller);
__attribute__((visibility("default")))
jint
Java_org_chromium_example_jni_1generator_SampleForTests_00024MyOtherInnerClass_nativeInit(JNIEnv*
env, jobject jcaller) {
return Init(env, jcaller);
}
}; // extern "C"
// Step 2: method stubs.
extern "C" {
__attribute__((visibility("default")))
jint
Java_org_chromium_example_jni_1generator_SampleForTests_nativeStaticMethod(JNIEnv*
env,
jobject jcaller,
jlong nativeTest,
jint arg1) {
Test* native = reinterpret_cast<Test*>(nativeTest);
CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0);
return native->StaticMethod(env, jcaller, arg1);
}
__attribute__((visibility("default")))
jint
Java_org_chromium_example_jni_1generator_SampleForTests_nativeMethod(JNIEnv*
env,
jobject jcaller,
jlong nativeTest,
jint arg1) {
Test* native = reinterpret_cast<Test*>(nativeTest);
CHECK_NATIVE_PTR(env, jcaller, native, "Method", 0);
return native->Method(env, jcaller, arg1);
}
static base::subtle::AtomicWord g_SampleForTests_testMethodWithParam = 0;
static void Java_SampleForTests_testMethodWithParam(JNIEnv* env, jobject obj,
JniIntWrapper iParam) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, obj,
g_SampleForTests_clazz);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_SampleForTests_clazz,
"testMethodWithParam",
"("
"I"
")"
"V",
&g_SampleForTests_testMethodWithParam);
env->CallVoidMethod(obj,
method_id, as_jint(iParam));
jni_generator::CheckException(env);
}
static base::subtle::AtomicWord g_SampleForTests_testMethodWithParamAndReturn =
0;
static base::android::ScopedJavaLocalRef<jstring>
Java_SampleForTests_testMethodWithParamAndReturn(JNIEnv* env, jobject obj,
JniIntWrapper iParam) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, obj,
g_SampleForTests_clazz, NULL);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, g_SampleForTests_clazz,
"testMethodWithParamAndReturn",
"("
"I"
")"
"Ljava/lang/String;",
&g_SampleForTests_testMethodWithParamAndReturn);
jstring ret =
static_cast<jstring>(env->CallObjectMethod(obj,
method_id, as_jint(iParam)));
jni_generator::CheckException(env);
return base::android::ScopedJavaLocalRef<jstring>(env, ret);
}
static base::subtle::AtomicWord g_SampleForTests_testStaticMethodWithParam = 0;
static jint Java_SampleForTests_testStaticMethodWithParam(JNIEnv* env,
JniIntWrapper iParam) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, g_SampleForTests_clazz,
g_SampleForTests_clazz, 0);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_SampleForTests_clazz,
"testStaticMethodWithParam",
"("
"I"
")"
"I",
&g_SampleForTests_testStaticMethodWithParam);
jint ret =
env->CallStaticIntMethod(g_SampleForTests_clazz,
method_id, as_jint(iParam));
jni_generator::CheckException(env);
return ret;
}
static base::subtle::AtomicWord g_SampleForTests_testMethodWithNoParam = 0;
static jdouble Java_SampleForTests_testMethodWithNoParam(JNIEnv* env) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, g_SampleForTests_clazz,
g_SampleForTests_clazz, 0);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_SampleForTests_clazz,
"testMethodWithNoParam",
"("
")"
"D",
&g_SampleForTests_testMethodWithNoParam);
jdouble ret =
env->CallStaticDoubleMethod(g_SampleForTests_clazz,
method_id);
jni_generator::CheckException(env);
return ret;
}
static base::subtle::AtomicWord g_SampleForTests_testStaticMethodWithNoParam =
0;
static base::android::ScopedJavaLocalRef<jstring>
Java_SampleForTests_testStaticMethodWithNoParam(JNIEnv* env) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, g_SampleForTests_clazz,
g_SampleForTests_clazz, NULL);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_STATIC>(
env, g_SampleForTests_clazz,
"testStaticMethodWithNoParam",
"("
")"
"Ljava/lang/String;",
&g_SampleForTests_testStaticMethodWithNoParam);
jstring ret =
static_cast<jstring>(env->CallStaticObjectMethod(g_SampleForTests_clazz,
method_id));
jni_generator::CheckException(env);
return base::android::ScopedJavaLocalRef<jstring>(env, ret);
}
}; // extern "C"
// Step 3: RegisterNatives.
static bool RegisterNativesImpl(JNIEnv* env, jclass clazz) {
g_SampleForTests_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));
return true;
}
extern "C" JNIEXPORT bool JNICALL
Java_org_chromium_example_jni_1generator_SampleForTests_nativeInitNativeClass(JNIEnv*
env, jclass clazz) {
return RegisterNativesImpl(env, clazz);
}
#endif // org_chromium_example_jni_generator_SampleForTests_JNI
# 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.
# Default exports specification for chromium shared libraries on android.
# Check ld version script manual:
# https://sourceware.org/binutils/docs-2.24/ld/VERSION.html#VERSION
{
global:
Java_*_native*;
JNI_OnLoad;
local: *;
};
...@@ -1731,6 +1731,9 @@ ...@@ -1731,6 +1731,9 @@
# Copy it out one scope. # Copy it out one scope.
'android_webview_build%': '<(android_webview_build)', 'android_webview_build%': '<(android_webview_build)',
# Default android linker script for shared library exports.
'android_linker_script%': '<!(cd <(DEPTH) && pwd -P)/build/android/android_exports.lst',
}], # OS=="android" }], # OS=="android"
['android_webview_build==1', { ['android_webview_build==1', {
# When building the WebView in the Android tree, jarjar will remap all # When building the WebView in the Android tree, jarjar will remap all
...@@ -4152,6 +4155,12 @@ ...@@ -4152,6 +4155,12 @@
['_type=="shared_library"', { ['_type=="shared_library"', {
'product_extension': '<(android_product_extension)', 'product_extension': '<(android_product_extension)',
}], }],
['_toolset=="target" and component=="static_library" and _type=="shared_library"', {
'ldflags': [
# Only export symbols that are specified in version script.
'-Wl,--version-script=<(android_linker_script)',
],
}],
# Settings for building device targets using Android's toolchain. # Settings for building device targets using Android's toolchain.
# These are based on the setup.mk file from the Android NDK. # These are based on the setup.mk file from the Android NDK.
...@@ -4216,8 +4225,7 @@ ...@@ -4216,8 +4225,7 @@
'ldflags': [ 'ldflags': [
'-nostdlib', '-nostdlib',
'-Wl,--no-undefined', '-Wl,--no-undefined',
# Don't export symbols from statically linked libraries.
'-Wl,--exclude-libs=ALL',
], ],
'libraries': [ 'libraries': [
'-l<(android_stlport_library)', '-l<(android_stlport_library)',
...@@ -4228,11 +4236,6 @@ ...@@ -4228,11 +4236,6 @@
'-lm', '-lm',
], ],
'conditions': [ 'conditions': [
['component=="shared_library"', {
'ldflags!': [
'-Wl,--exclude-libs=ALL',
],
}],
['clang==1', { ['clang==1', {
'cflags': [ 'cflags': [
# Work around incompatibilities between bionic and clang # Work around incompatibilities between bionic and clang
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
'<(jni_generator_includes)', '<(jni_generator_includes)',
'--optimize_generation', '--optimize_generation',
'<(optimize_jni_generation)', '<(optimize_jni_generation)',
'--native_exports',
], ],
'message': 'Generating JNI bindings from <(input_jar_file)/<(input_java_class)', 'message': 'Generating JNI bindings from <(input_jar_file)/<(input_java_class)',
'process_outputs_as_sources': 1, 'process_outputs_as_sources': 1,
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
'<(jni_generator_jarjar_file)', '<(jni_generator_jarjar_file)',
'--ptr_type', '--ptr_type',
'<(jni_generator_ptr_type)', '<(jni_generator_ptr_type)',
'--native_exports',
], ],
'message': 'Generating JNI bindings from <(RULE_INPUT_PATH)', 'message': 'Generating JNI bindings from <(RULE_INPUT_PATH)',
'process_outputs_as_sources': 1, 'process_outputs_as_sources': 1,
......
...@@ -66,6 +66,16 @@ ...@@ -66,6 +66,16 @@
'public/gles2/gles2_private.h', 'public/gles2/gles2_private.h',
], ],
'conditions': [ 'conditions': [
['OS=="android"', {
'ldflags!': [
# Remove default export list because this lib has different exports.
'-Wl,--version-script=<(android_linker_script)',
],
'ldflags': [
# Don't export symbols from statically linked libraries.
'-Wl,--exclude-libs=ALL',
],
}],
['OS=="mac"', { ['OS=="mac"', {
'xcode_settings': { 'xcode_settings': {
# Make it a run-path dependent library. # Make it a run-path dependent library.
...@@ -95,6 +105,16 @@ ...@@ -95,6 +105,16 @@
'public/tests/test_support_private.h', 'public/tests/test_support_private.h',
], ],
'conditions': [ 'conditions': [
['OS=="android"', {
'ldflags!': [
# Remove default export list because this lib has different exports.
'-Wl,--version-script=<(android_linker_script)',
],
'ldflags': [
# Don't export symbols from statically linked libraries.
'-Wl,--exclude-libs=ALL',
],
}],
['OS=="mac"', { ['OS=="mac"', {
'xcode_settings': { 'xcode_settings': {
# Make it a run-path dependent library. # Make it a run-path dependent library.
......
...@@ -179,6 +179,14 @@ ...@@ -179,6 +179,14 @@
'dependencies': [ 'dependencies': [
'mojo_jni_headers', 'mojo_jni_headers',
], ],
'ldflags!': [
# Remove default export list because this lib has different exports.
'-Wl,--version-script=<(android_linker_script)',
],
'ldflags': [
# Don't export symbols from statically linked libraries.
'-Wl,--exclude-libs=ALL',
],
}], }],
], ],
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment