summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsl.ostapenko@samsung.com <sl.ostapenko@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-07 08:44:55 +0000
committersl.ostapenko@samsung.com <sl.ostapenko@samsung.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-07 08:44:55 +0000
commit1d70cc60526e7cb00f5e2f293f951f202ed016e6 (patch)
treea473590f0ffb07bbe0e834cd306cf62a70480ef8
parent33ed90e0e7389ef045de283bbe2bdab2e3a91f4f (diff)
downloadchromium_src-1d70cc60526e7cb00f5e2f293f951f202ed016e6.zip
chromium_src-1d70cc60526e7cb00f5e2f293f951f202ed016e6.tar.gz
chromium_src-1d70cc60526e7cb00f5e2f293f951f202ed016e6.tar.bz2
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
-rwxr-xr-xbase/android/jni_generator/jni_generator.py82
-rwxr-xr-xbase/android/jni_generator/jni_generator_tests.py41
-rw-r--r--base/android/jni_generator/testNativeExportsOption.golden216
-rw-r--r--build/android/android_exports.lst14
-rw-r--r--build/common.gypi19
-rw-r--r--build/jar_file_jni_generator.gypi1
-rw-r--r--build/jni_generator.gypi1
-rw-r--r--mojo/mojo_public.gypi20
-rw-r--r--mojo/mojo_services.gypi8
9 files changed, 383 insertions, 19 deletions
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 35a7510..5018cf53 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -793,6 +793,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
for native in self.natives:
if native.type != 'method':
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)
def GetConstantFieldsString(self):
@@ -814,6 +816,9 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
ret += self.GetEagerCalledByNativeMethodStubs()
else:
ret += self.GetLazyCalledByNativeMethodStubs()
+
+ if self.options.native_exports and ret:
+ return '\nextern "C" {\n' + "\n".join(ret) + '\n}; // extern "C"'
return '\n'.join(ret)
def GetLazyCalledByNativeMethodStubs(self):
@@ -859,6 +864,8 @@ jmethodID g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME} = NULL;""")
def GetJNINativeMethodsString(self):
"""Returns the implementation of the array of native methods."""
+ if self.options.native_exports:
+ return ''
template = Template("""\
static const JNINativeMethod kMethods${JAVA_CLASS}[] = {
${KMETHODS}
@@ -913,6 +920,9 @@ ${CALLED_BY_NATIVES}
def GetRegisterNativesImplString(self):
"""Returns the shared implementation for RegisterNatives."""
+ if self.options.native_exports:
+ return ''
+
template = Template("""\
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) {
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 = ''
if 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,
'NAMESPACE': namespace,
'REGISTER_NATIVES_IMPL': self.GetRegisterNativesImplString()
@@ -995,23 +1011,52 @@ Java_${FULLY_QUALIFIED_CLASS}_${INIT_NATIVE_NAME}(JNIEnv* env, jclass clazz) {
for param in called_by_native.params])
def GetForwardDeclaration(self, native):
- template = Template("""
+ template_str = """
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),
'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)
def GetNativeMethodStubString(self, native):
"""Returns stubs for native methods."""
- template = Template("""\
-static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {
+ if self.options.native_exports:
+ 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});
CHECK_NATIVE_PTR(env, jcaller, native, "${NAME}"${OPTIONAL_ERROR_RETURN});
return native->${NAME}(${PARAMS_IN_CALL})${POST_CALL};
}
-""")
+"""
+
+ template = Template(template_str)
params = []
if not self.options.pure_native_methods:
params = ['env', 'jcaller']
@@ -1024,9 +1069,19 @@ static ${RETURN} ${NAME}(JNIEnv* env, ${PARAMS_IN_DECLARATION}) {
post_call = ''
if re.match(RE_SCOPED_JNI_RETURN_TYPES, return_type):
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 = {
'RETURN': return_type,
'OPTIONAL_ERROR_RETURN': optional_error_return,
+ 'JAVA_NAME': java_name,
'NAME': native.name,
'PARAMS_IN_DECLARATION': self.GetParamsInDeclaration(native),
'PARAM0_NAME': native.params[0].name,
@@ -1174,8 +1229,12 @@ ${FUNCTION_HEADER}
const char k${JAVA_CLASS}ClassPath[] = "${JNI_CLASS_PATH}";""")
native_classes = self.GetUniqueClasses(self.natives)
called_by_native_classes = self.GetUniqueClasses(self.called_by_natives)
- all_classes = native_classes
- all_classes.update(called_by_native_classes)
+ if self.options.native_exports:
+ all_classes = called_by_native_classes
+ else:
+ all_classes = native_classes
+ all_classes.update(called_by_native_classes)
+
for clazz in all_classes:
values = {
'JAVA_CLASS': clazz,
@@ -1394,6 +1453,9 @@ See SampleForTests.java for more details.
help='The path to cpp command.')
option_parser.add_option('--javap', default='javap',
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)
if options.jar_file:
input_file = ExtractJarInputFile(options.jar_file, options.input_file,
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index 6b7c010..98dd8de 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -42,7 +42,7 @@ class TestOptions(object):
self.eager_called_by_natives = False
self.cpp = 'cpp'
self.javap = 'javap'
-
+ self.native_exports = False
class TestGenerator(unittest.TestCase):
def assertObjEquals(self, first, second):
@@ -996,6 +996,45 @@ class Foo {
test_data, 'org/chromium/example/jni_generator/Test', options)
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):
test_data = """
package org.chromium.media;
diff --git a/base/android/jni_generator/testNativeExportsOption.golden b/base/android/jni_generator/testNativeExportsOption.golden
new file mode 100644
index 0000000..231be7c
--- /dev/null
+++ b/base/android/jni_generator/testNativeExportsOption.golden
@@ -0,0 +1,216 @@
+// 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
diff --git a/build/android/android_exports.lst b/build/android/android_exports.lst
new file mode 100644
index 0000000..820d6ec
--- /dev/null
+++ b/build/android/android_exports.lst
@@ -0,0 +1,14 @@
+# 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: *;
+};
diff --git a/build/common.gypi b/build/common.gypi
index 73c2a44..a1a9b79 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -1731,6 +1731,9 @@
# Copy it out one scope.
'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"
['android_webview_build==1', {
# When building the WebView in the Android tree, jarjar will remap all
@@ -4150,7 +4153,13 @@
},
'target_conditions': [
['_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.
@@ -4216,8 +4225,7 @@
'ldflags': [
'-nostdlib',
'-Wl,--no-undefined',
- # Don't export symbols from statically linked libraries.
- '-Wl,--exclude-libs=ALL',
+
],
'libraries': [
'-l<(android_stlport_library)',
@@ -4228,11 +4236,6 @@
'-lm',
],
'conditions': [
- ['component=="shared_library"', {
- 'ldflags!': [
- '-Wl,--exclude-libs=ALL',
- ],
- }],
['clang==1', {
'cflags': [
# Work around incompatibilities between bionic and clang
diff --git a/build/jar_file_jni_generator.gypi b/build/jar_file_jni_generator.gypi
index dc43c49..59ab64e 100644
--- a/build/jar_file_jni_generator.gypi
+++ b/build/jar_file_jni_generator.gypi
@@ -54,6 +54,7 @@
'<(jni_generator_includes)',
'--optimize_generation',
'<(optimize_jni_generation)',
+ '--native_exports',
],
'message': 'Generating JNI bindings from <(input_jar_file)/<(input_java_class)',
'process_outputs_as_sources': 1,
diff --git a/build/jni_generator.gypi b/build/jni_generator.gypi
index da99331..da4b880 100644
--- a/build/jni_generator.gypi
+++ b/build/jni_generator.gypi
@@ -61,6 +61,7 @@
'<(jni_generator_jarjar_file)',
'--ptr_type',
'<(jni_generator_ptr_type)',
+ '--native_exports',
],
'message': 'Generating JNI bindings from <(RULE_INPUT_PATH)',
'process_outputs_as_sources': 1,
diff --git a/mojo/mojo_public.gypi b/mojo/mojo_public.gypi
index fc4a2c2..8f10f5c 100644
--- a/mojo/mojo_public.gypi
+++ b/mojo/mojo_public.gypi
@@ -66,6 +66,16 @@
'public/gles2/gles2_private.h',
],
'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"', {
'xcode_settings': {
# Make it a run-path dependent library.
@@ -95,6 +105,16 @@
'public/tests/test_support_private.h',
],
'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"', {
'xcode_settings': {
# Make it a run-path dependent library.
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index b2da5f2..eaedd51 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -179,6 +179,14 @@
'dependencies': [
'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',
+ ],
}],
],
},