diff options
author | Xavier Ducrohet <xav@google.com> | 2013-11-14 23:40:00 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2013-11-14 23:40:00 +0000 |
commit | 442c4711c9e2856bfb98e2f805e7d3a249f593ee (patch) | |
tree | 55bbba664328e96d42948744930c42a54c26a32c | |
parent | 984c1a5a52b0b962f903e73106e0c32cf18fd38f (diff) | |
parent | 4204c184b20dbbe7b81f06ca8f21605aa0cbc9e6 (diff) | |
download | build-442c4711c9e2856bfb98e2f805e7d3a249f593ee.tar.gz |
Merge "Support for jni lib in library project."
32 files changed, 651 insertions, 149 deletions
@@ -20,6 +20,7 @@ tests/libProguardLibDep/*/build tests/libsTest/*/build tests/multiproject/*/build tests/localJars/*/build +tests/ndkJniLib/*/build tests/proguardLib/*/build tests/renderscriptInLib/*/build tests/repo/*/build diff --git a/builder-model/src/main/java/com/android/builder/NdkConfig.java b/builder-model/src/main/java/com/android/builder/NdkConfig.java new file mode 100644 index 0000000..b3bebef --- /dev/null +++ b/builder-model/src/main/java/com/android/builder/NdkConfig.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder; + +import com.android.annotations.Nullable; + +import java.util.Set; + +/** + * Base class for NDK config file. + */ +public interface NdkConfig { + + /** + * The module name + */ + @Nullable + public String getModuleName(); + + /** + * The C Flags + */ + @Nullable + public String getcFlags(); + + /** + * The LD Libs + */ + @Nullable + public String getLdLibs(); + + /** + * The ABI Filters + */ + @Nullable + public Set<String> getAbiFilters(); +} diff --git a/builder-model/src/main/java/com/android/builder/model/BuildType.java b/builder-model/src/main/java/com/android/builder/model/BuildType.java index 33d9ada..d846a90 100644 --- a/builder-model/src/main/java/com/android/builder/model/BuildType.java +++ b/builder-model/src/main/java/com/android/builder/model/BuildType.java @@ -18,6 +18,7 @@ package com.android.builder.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.builder.NdkConfig; /** * a Build Type. This is only the configuration of the build type. @@ -97,4 +98,7 @@ public interface BuildType extends BaseConfig { * @return true if zipalign is enabled. */ boolean isZipAlign(); + + @Nullable + NdkConfig getNdkConfig(); } diff --git a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java index f281f8e..9563136 100644 --- a/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java +++ b/builder-model/src/main/java/com/android/builder/model/ProductFlavor.java @@ -18,6 +18,7 @@ package com.android.builder.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.builder.NdkConfig; /** * a Product Flavor. This is only the configuration of the flavor. @@ -125,4 +126,7 @@ public interface ProductFlavor extends BaseConfig { */ @Nullable Boolean getTestFunctionalTest(); + + @Nullable + NdkConfig getNdkConfig(); } diff --git a/builder/src/main/java/com/android/builder/DefaultBuildType.java b/builder/src/main/java/com/android/builder/DefaultBuildType.java index 5ebbd0b..f9ed1be 100644 --- a/builder/src/main/java/com/android/builder/DefaultBuildType.java +++ b/builder/src/main/java/com/android/builder/DefaultBuildType.java @@ -162,6 +162,12 @@ public class DefaultBuildType extends BaseConfigImpl implements BuildType { } @Override + @Nullable + public NdkConfig getNdkConfig() { + return null; + } + + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; diff --git a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java index f739a3f..e4f6e18 100644 --- a/builder/src/main/java/com/android/builder/DefaultProductFlavor.java +++ b/builder/src/main/java/com/android/builder/DefaultProductFlavor.java @@ -217,6 +217,12 @@ public class DefaultProductFlavor extends BaseConfigImpl implements ProductFlavo return this; } + @Override + @Nullable + public NdkConfig getNdkConfig() { + return null; + } + /** * Merges the flavor on top of a base platform and returns a new object with the result. * @param base the flavor to merge on top of @@ -359,5 +365,4 @@ public class DefaultProductFlavor extends BaseConfigImpl implements ProductFlavo release signing info (keystore, key alias, passwords,...). native abi filter */ - } diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java index a5978d4..72fbf9a 100644 --- a/builder/src/main/java/com/android/builder/VariantConfiguration.java +++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java @@ -22,6 +22,7 @@ import com.android.annotations.VisibleForTesting; import com.android.builder.dependency.DependencyContainer; import com.android.builder.dependency.JarDependency; import com.android.builder.dependency.LibraryDependency; +import com.android.builder.internal.NdkConfigImpl; import com.android.builder.model.SigningConfig; import com.android.builder.model.SourceProvider; import com.android.builder.testing.TestData; @@ -64,6 +65,7 @@ public class VariantConfiguration implements TestData { private LibraryDependency mOutput; private DefaultProductFlavor mMergedFlavor; + private final NdkConfigImpl mMergedNdkConfig = new NdkConfigImpl(); private final Set<JarDependency> mJars = Sets.newHashSet(); @@ -104,7 +106,7 @@ public class VariantConfiguration implements TestData { @NonNull DefaultProductFlavor defaultConfig, @NonNull SourceProvider defaultSourceProvider, @NonNull DefaultBuildType buildType, - @NonNull SourceProvider buildTypeSourceProvider, + @Nullable SourceProvider buildTypeSourceProvider, @Nullable String debugName) { this(defaultConfig, defaultSourceProvider, buildType, buildTypeSourceProvider, @@ -164,6 +166,7 @@ public class VariantConfiguration implements TestData { checkState(mType != Type.TEST || mTestedConfig != null); mMergedFlavor = mDefaultConfig; + computeNdkConfig(); if (testedConfig != null && testedConfig.mType == Type.LIBRARY && @@ -181,7 +184,9 @@ public class VariantConfiguration implements TestData { * comes to resolving Android resources overlays (ie earlier added flavors supersedes * latter added ones). * - * @param sourceProvider the configured product flavor + * @param productFlavor the configured product flavor + * @param sourceProvider + * * @return the config object */ @NonNull @@ -189,11 +194,32 @@ public class VariantConfiguration implements TestData { @NonNull SourceProvider sourceProvider) { mFlavorConfigs.add(productFlavor); mFlavorSourceProviders.add(sourceProvider); + mMergedFlavor = productFlavor.mergeOver(mMergedFlavor); + computeNdkConfig(); return this; } + private void computeNdkConfig() { + mMergedNdkConfig.reset(); + + if (mDefaultConfig.getNdkConfig() != null) { + mMergedNdkConfig.append(mDefaultConfig.getNdkConfig()); + } + + for (int i = mFlavorConfigs.size() - 1 ; i >= 0 ; i--) { + NdkConfig ndkConfig = mFlavorConfigs.get(i).getNdkConfig(); + if (ndkConfig != null) { + mMergedNdkConfig.append(ndkConfig); + } + } + + if (mBuildType.getNdkConfig() != null && mType != Type.TEST) { + mMergedNdkConfig.append(mBuildType.getNdkConfig()); + } + } + /** * Sets the dependencies * @@ -721,6 +747,21 @@ public class VariantConfiguration implements TestData { return assetSets; } + @NonNull + public List<File> getLibraryJniFolders() { + List<File> list = Lists.newArrayListWithExpectedSize(mFlatLibraries.size()); + + for (int n = mFlatLibraries.size() - 1 ; n >= 0 ; n--) { + LibraryDependency dependency = mFlatLibraries.get(n); + File jniFolder = dependency.getJniFolder(); + if (jniFolder.isDirectory()) { + list.add(jniFolder); + } + } + + return list; + } + /** * Returns all the renderscript import folder that are outside of the current project. */ @@ -944,11 +985,18 @@ public class VariantConfiguration implements TestData { } } + @NonNull + public NdkConfig getNdkConfig() { + return mMergedNdkConfig; + } @Nullable @Override public Set<String> getSupportedAbis() { - // TODO no ndk support yet, so return null + if (mMergedNdkConfig != null) { + return mMergedNdkConfig.getAbiFilters(); + } + return null; } } diff --git a/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java new file mode 100644 index 0000000..d4e8b4e --- /dev/null +++ b/builder/src/main/java/com/android/builder/internal/NdkConfigImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.builder.internal; + +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.builder.NdkConfig; +import com.google.common.collect.Sets; + +import java.util.Set; + +/** + */ +public class NdkConfigImpl implements NdkConfig { + + private String moduleName; + private String cFlags; + private String ldLibs; + private Set<String> abiFilters; + + public void reset() { + moduleName = null; + cFlags = null; + ldLibs = null; + abiFilters = null; + } + + @Override + @Nullable + public String getModuleName() { + return moduleName; + } + + @Override + @Nullable + public String getcFlags() { + return cFlags; + } + + @Override + @Nullable + public String getLdLibs() { + return ldLibs; + } + + @Override + @Nullable + public Set<String> getAbiFilters() { + return abiFilters; + } + + public void append(@NonNull NdkConfig ndkConfig) { + // override + if (ndkConfig.getModuleName() != null) { + moduleName = ndkConfig.getModuleName(); + } + if (ndkConfig.getAbiFilters() != null) { + if (abiFilters == null) { + abiFilters = Sets.newHashSetWithExpectedSize(ndkConfig.getAbiFilters().size()); + } else { + abiFilters.clear(); + } + abiFilters.addAll(ndkConfig.getAbiFilters()); + } + + // append + if (cFlags == null) { + cFlags = ndkConfig.getcFlags(); + } else if (ndkConfig.getcFlags() != null) { + cFlags = cFlags + " " + ndkConfig.getcFlags(); + } + + if (ldLibs == null) { + ldLibs = ndkConfig.getLdLibs(); + } else if (ndkConfig.getLdLibs() != null) { + ldLibs = ldLibs + " " + ndkConfig.getLdLibs(); + } + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy index 7367c00..77e9807 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy @@ -15,7 +15,6 @@ */ package com.android.build.gradle - import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.build.gradle.api.BaseVariant @@ -57,7 +56,6 @@ import static com.android.builder.BuilderConstants.INSTRUMENT_TEST import static com.android.builder.BuilderConstants.LINT import static com.android.builder.BuilderConstants.RELEASE import static com.android.builder.BuilderConstants.UI_TEST - /** * Gradle plugin class for 'application' projects. */ @@ -295,8 +293,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr for (BuildTypeData buildTypeData : buildTypes.values()) { def variantConfig = new VariantConfiguration( - defaultConfigData.productFlavor, defaultConfigData.sourceSet, - buildTypeData.buildType, buildTypeData.sourceSet, project.name) + defaultConfigData.productFlavor, + defaultConfigData.sourceSet, + buildTypeData.buildType, + buildTypeData.sourceSet, project.name) // create the variant and get its internal storage object. ApplicationVariantData appVariantData = new ApplicationVariantData(variantConfig) @@ -315,8 +315,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr // handle the test variant def testVariantConfig = new VariantConfiguration( - defaultConfigData.productFlavor, defaultConfigData.testSourceSet, - testData.buildType, null, + defaultConfigData.productFlavor, + defaultConfigData.testSourceSet, + testData.buildType, + null, VariantConfiguration.Type.TEST, testedVariantData.variantConfiguration, project.name) @@ -429,11 +431,16 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr variantProviders.add(buildTypeData) VariantConfiguration variantConfig = new VariantConfiguration( - extension.defaultConfig, getDefaultConfigData().sourceSet, - buildTypeData.buildType, buildTypeData.sourceSet, project.name) + extension.defaultConfig, + getDefaultConfigData().sourceSet, + buildTypeData.buildType, + buildTypeData.sourceSet, + project.name) for (ProductFlavorData data : flavorDataList) { - variantConfig.addProductFlavor(data.productFlavor, data.sourceSet) + variantConfig.addProductFlavor( + data.productFlavor, + data.sourceSet) variantProviders.add(data.mainProvider) } @@ -458,8 +465,10 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr // handle test variant VariantConfiguration testVariantConfig = new VariantConfiguration( - extension.defaultConfig, getDefaultConfigData().testSourceSet, - testData.buildType, null, + extension.defaultConfig, + getDefaultConfigData().testSourceSet, + testData.buildType, + null, VariantConfiguration.Type.TEST, testedVariantData.variantConfiguration, project.name) @@ -469,7 +478,9 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements Plugin<Pr List<ConfigurationProvider> testVariantProviders = [] for (ProductFlavorData data : flavorDataList) { - testVariantConfig.addProductFlavor(data.productFlavor, data.testSourceSet) + testVariantConfig.addProductFlavor( + data.productFlavor, + data.testSourceSet) testVariantProviders.add(data.testProvider) } diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy index bf799a6..b8a6c1d 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy @@ -15,7 +15,6 @@ */ package com.android.build.gradle - import com.android.annotations.NonNull import com.android.annotations.Nullable import com.android.build.gradle.api.AndroidSourceSet @@ -29,7 +28,6 @@ import com.android.build.gradle.internal.dependency.LibraryDependencyImpl import com.android.build.gradle.internal.dependency.ManifestDependencyImpl import com.android.build.gradle.internal.dependency.SymbolFileProviderImpl import com.android.build.gradle.internal.dependency.VariantDependencies -import com.android.build.gradle.internal.dsl.NdkConfigDsl import com.android.build.gradle.internal.dsl.SigningConfigDsl import com.android.build.gradle.internal.model.ModelBuilder import com.android.build.gradle.internal.tasks.AndroidReportTask @@ -123,7 +121,6 @@ import static com.android.builder.BuilderConstants.FD_INSTRUMENT_TESTS import static com.android.builder.BuilderConstants.FD_REPORTS import static com.android.builder.BuilderConstants.INSTRUMENT_TEST import static java.io.File.separator - /** * Base class for all Android plugins */ @@ -464,24 +461,7 @@ public abstract class BasePlugin { renderscriptTask.conventionMapping.libOutputDir = { project.file("$project.buildDir/rs/$variantData.dirName/lib") } - renderscriptTask.conventionMapping.ndkConfig = { - - //noinspection GroovyAssignabilityCheck - NdkConfigDsl mergedConfig = new NdkConfigDsl(config.defaultConfig.ndkConfig) - if (config.hasFlavors()) { - for (DefaultProductFlavor flavorConfig : config.flavorConfigs) { - //noinspection GroovyAssignabilityCheck - mergedConfig.append(flavorConfig.ndkConfig) - } - } - if (config.getType() != VariantConfiguration.Type.TEST) { - //noinspection GroovyAssignabilityCheck - mergedConfig.append(config.buildType.ndkConfig) - } - - return mergedConfig - } - + renderscriptTask.conventionMapping.ndkConfig = { config.ndkConfig } } protected void createMergeResourcesTask(@NonNull BaseVariantData variantData, @@ -750,6 +730,14 @@ public abstract class BasePlugin { } protected void createNdkTasks(@NonNull BaseVariantData variantData) { + createNdkTasks( + variantData, + { project.file("$project.buildDir/ndk/$variantData.dirName/lib") } + ) + } + + protected void createNdkTasks(@NonNull BaseVariantData variantData, + @NonNull Closure<File> soFolderClosure) { NdkCompile ndkCompile = project.tasks.create( "compile${variantData.name}Ndk", NdkCompile) @@ -781,23 +769,7 @@ public abstract class BasePlugin { project.file("$project.buildDir/ndk/$variantData.dirName/Android.mk") } - ndkCompile.conventionMapping.ndkConfig = { - - //noinspection GroovyAssignabilityCheck - NdkConfigDsl mergedConfig = new NdkConfigDsl(variantConfig.defaultConfig.ndkConfig) - if (variantConfig.hasFlavors()) { - for (DefaultProductFlavor flavorConfig : variantConfig.flavorConfigs) { - //noinspection GroovyAssignabilityCheck - mergedConfig.append(flavorConfig.ndkConfig) - } - } - if (variantConfig.getType() != VariantConfiguration.Type.TEST) { - //noinspection GroovyAssignabilityCheck - mergedConfig.append(variantConfig.buildType.ndkConfig) - } - - return mergedConfig - } + ndkCompile.conventionMapping.ndkConfig = { variantConfig.ndkConfig } ndkCompile.conventionMapping.debuggable = { variantConfig.buildType.jniDebugBuild @@ -806,10 +778,7 @@ public abstract class BasePlugin { ndkCompile.conventionMapping.objFolder = { project.file("$project.buildDir/ndk/$variantData.dirName/obj") } - - ndkCompile.conventionMapping.soFolder = { - project.file("$project.buildDir/ndk/$variantData.dirName/lib") - } + ndkCompile.conventionMapping.soFolder = soFolderClosure } /** @@ -1278,10 +1247,10 @@ public abstract class BasePlugin { } packageApp.conventionMapping.jniFolders = { // for now only the project's compilation output. - // TODO add dependencies Set<File> set = Sets.newHashSet() set.addAll(variantData.ndkCompileTask.soFolder) set.addAll(variantData.renderscriptCompileTask.libOutputDir) + set.addAll(variantConfig.libraryJniFolders) if (variantConfig.mergedFlavor.renderscriptSupportMode) { File rsLibs = getAndroidBuilder(variantData).getSupportNativeLibFolder() @@ -1292,9 +1261,7 @@ public abstract class BasePlugin { return set } - packageApp.conventionMapping.abiFilters = { - variantData.ndkCompileTask.getNdkConfig().abiFilters - } + packageApp.conventionMapping.abiFilters = { variantConfig.supportedAbis } packageApp.conventionMapping.jniDebugBuild = { variantConfig.buildType.jniDebugBuild } SigningConfigDsl sc = (SigningConfigDsl) variantConfig.signingConfig diff --git a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy index c45a827..69c7c2f 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy @@ -14,7 +14,6 @@ * limitations under the License. */ package com.android.build.gradle - import com.android.SdkConstants import com.android.annotations.NonNull import com.android.annotations.Nullable @@ -55,7 +54,6 @@ import org.gradle.tooling.BuildException import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import javax.inject.Inject - /** * Gradle plugin class for 'library' projects. */ @@ -137,10 +135,13 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { createLibraryVariant(releaseVariantData, true) VariantConfiguration testVariantConfig = new VariantConfiguration( - defaultConfigData.productFlavor, defaultConfigData.testSourceSet, - debugBuildTypeData.buildType, null, + defaultConfigData.productFlavor, + defaultConfigData.testSourceSet, + debugBuildTypeData.buildType, + null, VariantConfiguration.Type.TEST, - debugVariantData.variantConfiguration, project.name) + debugVariantData.variantConfiguration, + project.name) TestVariantData testVariantData = new TestVariantData(testVariantConfig, debugVariantData) // link the testVariant to the tested variant in the other direction @@ -168,9 +169,12 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { protected LibraryVariantData createLibVariant(@NonNull ProductFlavorData configData, @NonNull BuildTypeData buildTypeData) { VariantConfiguration variantConfig = new VariantConfiguration( - configData.productFlavor, configData.sourceSet, - buildTypeData.buildType, buildTypeData.sourceSet, - VariantConfiguration.Type.LIBRARY, project.name) + configData.productFlavor, + configData.sourceSet, + buildTypeData.buildType, + buildTypeData.sourceSet, + VariantConfiguration.Type.LIBRARY, + project.name) LibraryVariantData variantData = new LibraryVariantData(variantConfig) @@ -233,7 +237,9 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { createCompileTask(variantData, null/*testedVariant*/) // Add NDK tasks - createNdkTasks(variantData) + createNdkTasks( + variantData, + { project.file("$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/jni") }); // package the aidl files into the bundle folder Sync packageAidl = project.tasks.create("package${variantData.name}Aidl", Sync) @@ -251,11 +257,11 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.FD_RENDERSCRIPT")) // merge consumer proguard files from different build types and flavors - MergeFileTask mergeFileTask = project.tasks.create("merge${variantData.name}ProguardFiles", + MergeFileTask mergeProGuardFileTask = project.tasks.create("merge${variantData.name}ProguardFiles", MergeFileTask) - mergeFileTask.conventionMapping.inputFiles = { + mergeProGuardFileTask.conventionMapping.inputFiles = { project.files(variantConfig.getConsumerProguardFiles()).files } - mergeFileTask.conventionMapping.outputFile = { + mergeProGuardFileTask.conventionMapping.outputFile = { project.file( "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$LibraryBundle.FN_PROGUARD_TXT") } @@ -273,9 +279,9 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { createProguardTasks(variantData, variantConfig) // hack since bundle can't depend on variantData.proguardTask - mergeFileTask.dependsOn variantData.proguardTask + mergeProGuardFileTask.dependsOn variantData.proguardTask - bundle.dependsOn packageRes, packageAidl, packageRenderscript, mergeFileTask, lintCopy + bundle.dependsOn packageRes, packageAidl, packageRenderscript, mergeProGuardFileTask, lintCopy, variantData.ndkCompileTask } else { Sync packageLocalJar = project.tasks.create("package${variantData.name}LocalJar", Sync) packageLocalJar.from(getLocalJarFileList(variantData.variantDependency)) @@ -304,7 +310,7 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> { jar.exclude(packageName + "/BuildConfig.class") bundle.dependsOn packageRes, jar, packageAidl, packageRenderscript, packageLocalJar, - mergeFileTask, lintCopy + mergeProGuardFileTask, lintCopy, variantData.ndkCompileTask } bundle.setDescription("Assembles a bundle containing the library in ${variantData.name}."); diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy index 8a3cf68..ed4f651 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy @@ -16,8 +16,10 @@ package com.android.build.gradle.internal.dsl import com.android.annotations.NonNull +import com.android.annotations.Nullable import com.android.builder.BuilderConstants import com.android.builder.DefaultBuildType +import com.android.builder.NdkConfig import com.android.builder.model.SigningConfig import org.gradle.api.Action import org.gradle.api.internal.file.FileResolver @@ -42,6 +44,12 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable { ndkConfig = instantiator.newInstance(NdkConfigDsl.class) } + @Override + @Nullable + public NdkConfig getNdkConfig() { + return ndkConfig; + } + public void init(SigningConfig debugSigningConfig) { if (BuilderConstants.DEBUG.equals(getName())) { setDebuggable(true) @@ -63,10 +71,6 @@ public class BuildTypeDsl extends DefaultBuildType implements Serializable { return true } - public NdkConfigDsl getNdkConfig() { - return ndkConfig - } - // -- DSL Methods. TODO remove once the instantiator does what I expect it to do. public void buildConfig(String... lines) { diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java index 8765f3b..84476bd 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/NdkConfigDsl.java @@ -17,6 +17,7 @@ package com.android.build.gradle.internal.dsl; import com.android.annotations.NonNull; +import com.android.builder.NdkConfig; import com.google.common.collect.Sets; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Optional; @@ -27,7 +28,7 @@ import java.util.Set; /** */ -public class NdkConfigDsl implements Serializable { +public class NdkConfigDsl implements NdkConfig, Serializable { private static final long serialVersionUID = 1L; private String moduleName; @@ -45,6 +46,7 @@ public class NdkConfigDsl implements Serializable { setSrcDirs(ndkConfig.abiFilters); } + @Override @Input @Optional public String getModuleName() { return moduleName; @@ -54,6 +56,7 @@ public class NdkConfigDsl implements Serializable { this.moduleName = moduleName; } + @Override @Input @Optional public String getcFlags() { return cFlags; @@ -63,6 +66,7 @@ public class NdkConfigDsl implements Serializable { this.cFlags = cFlags; } + @Override @Input @Optional public String getLdLibs() { return ldLibs; @@ -72,6 +76,7 @@ public class NdkConfigDsl implements Serializable { this.ldLibs = ldLibs; } + @Override @Input @Optional public Set<String> getAbiFilters() { return abiFilters; @@ -111,32 +116,4 @@ public class NdkConfigDsl implements Serializable { } return this; } - - public void append(@NonNull NdkConfigDsl ndkConfig) { - // override - if (ndkConfig.moduleName != null) { - moduleName = ndkConfig.moduleName; - } - if (ndkConfig.abiFilters != null) { - if (abiFilters == null) { - abiFilters = Sets.newHashSetWithExpectedSize(ndkConfig.abiFilters.size()); - } else { - abiFilters.clear(); - } - abiFilters.addAll(ndkConfig.abiFilters); - } - - // append - if (cFlags == null) { - cFlags = ndkConfig.cFlags; - } else if (ndkConfig.cFlags != null) { - cFlags = cFlags + " " + ndkConfig.cFlags; - } - - if (ldLibs == null) { - ldLibs = ndkConfig.ldLibs; - } else if (ndkConfig.ldLibs != null) { - ldLibs = ldLibs + " " + ndkConfig.ldLibs; - } - } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy index daeb0ff..6b78c86 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy @@ -16,7 +16,9 @@ package com.android.build.gradle.internal.dsl import com.android.annotations.NonNull +import com.android.annotations.Nullable import com.android.builder.DefaultProductFlavor +import com.android.builder.NdkConfig import org.gradle.api.Action import org.gradle.api.internal.file.FileResolver import org.gradle.internal.reflect.Instantiator @@ -40,8 +42,10 @@ class ProductFlavorDsl extends DefaultProductFlavor { ndkConfig = instantiator.newInstance(NdkConfigDsl.class) } - public NdkConfigDsl getNdkConfig() { - return ndkConfig + @Override + @Nullable + public NdkConfig getNdkConfig() { + return ndkConfig; } // -- DSL Methods. TODO remove once the instantiator does what I expect it to do. diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java index 11b387d..03daa6f 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java @@ -18,6 +18,7 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.builder.NdkConfig; import com.android.builder.model.BuildType; import java.io.File; @@ -126,4 +127,10 @@ class BuildTypeImpl implements BuildType, Serializable { public List<File> getConsumerProguardFiles() { return Collections.emptyList(); } + + @Override + @Nullable + public NdkConfig getNdkConfig() { + return null; + } } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java index 8dabb11..d03ae14 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java @@ -18,6 +18,7 @@ package com.android.build.gradle.internal.model; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.android.builder.NdkConfig; import com.android.builder.model.ProductFlavor; import java.io.File; @@ -138,23 +139,6 @@ class ProductFlavorImpl implements ProductFlavor, Serializable { return mTestFunctionalTest; } - @Override - public String toString() { - return "ProductFlavorImpl{" + - "name='" + name + '\'' + - ", mMinSdkVersion=" + mMinSdkVersion + - ", mTargetSdkVersion=" + mTargetSdkVersion + - ", mRenderscriptTargetApi=" + mRenderscriptTargetApi + - ", mRenderscriptSupportMode=" + mRenderscriptSupportMode + - ", mVersionCode=" + mVersionCode + - ", mVersionName='" + mVersionName + '\'' + - ", mPackageName='" + mPackageName + '\'' + - ", mTestPackageName='" + mTestPackageName + '\'' + - ", mTestInstrumentationRunner='" + mTestInstrumentationRunner + '\'' + - ", mTestHandleProfiling='" + mTestHandleProfiling + '\'' + - ", mTestFunctionalTest='" + mTestFunctionalTest + '\'' + - '}'; - } @NonNull @Override @@ -173,4 +157,29 @@ class ProductFlavorImpl implements ProductFlavor, Serializable { public List<File> getConsumerProguardFiles() { return Collections.emptyList(); } + + @Override + @Nullable + public NdkConfig getNdkConfig() { + return null; + } + + @Override + public String toString() { + return "ProductFlavorImpl{" + + "name='" + name + '\'' + + ", mMinSdkVersion=" + mMinSdkVersion + + ", mTargetSdkVersion=" + mTargetSdkVersion + + ", mRenderscriptTargetApi=" + mRenderscriptTargetApi + + ", mRenderscriptSupportMode=" + mRenderscriptSupportMode + + ", mVersionCode=" + mVersionCode + + ", mVersionName='" + mVersionName + '\'' + + ", mPackageName='" + mPackageName + '\'' + + ", mTestPackageName='" + mTestPackageName + '\'' + + ", mTestInstrumentationRunner='" + mTestInstrumentationRunner + '\'' + + ", mTestHandleProfiling='" + mTestHandleProfiling + '\'' + + ", mTestFunctionalTest='" + mTestFunctionalTest + '\'' + + '}'; + } + } diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy new file mode 100644 index 0000000..a051aed --- /dev/null +++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/NdkTask.groovy @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.build.gradle.internal.tasks +import com.android.builder.NdkConfig +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional + +/** + * Base task for tasks that require an NdkConfig + */ +class NdkTask extends BaseTask { + + NdkConfig ndkConfig + + @Input @Optional + String getModuleName() { + return getNdkConfig()?.moduleName; + } + + @Input @Optional + String getcFlags() { + return getNdkConfig()?.cFlags; + } + + @Input @Optional + String getLdLibs() { + return getNdkConfig()?.ldLibs; + } + + @Input @Optional + Set<String> getAbiFilters() { + return getNdkConfig()?.abiFilters; + } +} diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy index ab38543..0a8e9b8 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/NdkCompile.groovy @@ -17,8 +17,8 @@ package com.android.build.gradle.tasks import com.android.annotations.NonNull -import com.android.build.gradle.internal.dsl.NdkConfigDsl -import com.android.build.gradle.internal.tasks.BaseTask +import com.android.build.gradle.internal.tasks.NdkTask +import com.android.builder.NdkConfig import com.android.sdklib.IAndroidTarget import com.google.common.base.Charsets import com.google.common.base.Joiner @@ -28,25 +28,20 @@ import org.gradle.api.GradleException import org.gradle.api.file.FileTree import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Nested import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.util.PatternSet - /** */ -class NdkCompile extends BaseTask { +class NdkCompile extends NdkTask { Set<File> sourceFolders @OutputFile File generatedMakefile - @Nested - NdkConfigDsl ndkConfig - @Input boolean debuggable @@ -57,7 +52,7 @@ class NdkCompile extends BaseTask { File objFolder @InputFiles - public FileTree getSource() { + FileTree getSource() { FileTree src = null Set<File> sources = getSourceFolders() if (!sources.isEmpty()) { @@ -117,7 +112,7 @@ class NdkCompile extends BaseTask { } private void writeMakefile(@NonNull Set<File> sourceFiles, @NonNull File makefile) { - NdkConfigDsl ndk = getNdkConfig() + NdkConfig ndk = getNdkConfig() StringBuilder sb = new StringBuilder() @@ -148,7 +143,7 @@ class NdkCompile extends BaseTask { } private void runNdkBuild(@NonNull File ndkLocation, @NonNull File makefile) { - NdkConfigDsl ndk = getNdkConfig() + NdkConfig ndk = getNdkConfig() List<String> commands = Lists.newArrayList() diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy index c7a748e..17985fc 100644 --- a/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy +++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/RenderscriptCompile.groovy @@ -16,17 +16,15 @@ package com.android.build.gradle.tasks -import com.android.build.gradle.internal.dsl.NdkConfigDsl -import com.android.build.gradle.internal.tasks.BaseTask +import com.android.build.gradle.internal.tasks.NdkTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Nested import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction /** * Task to compile Renderscript files. Supports incremental update. */ -public class RenderscriptCompile extends BaseTask { +public class RenderscriptCompile extends NdkTask { // ----- PUBLIC TASK API ----- @@ -63,9 +61,6 @@ public class RenderscriptCompile extends BaseTask { @Input boolean debugBuild - @Nested - NdkConfigDsl ndkConfig - @TaskAction void taskAction() { // this is full run (always), clean the previous outputs @@ -97,6 +92,6 @@ public class RenderscriptCompile extends BaseTask { getDebugBuild(), getOptimLevel(), getSupportMode(), - getNdkConfig().abiFilters) + getNdkConfig()?.abiFilters) } } diff --git a/tests/ndkJniLib/app/build.gradle b/tests/ndkJniLib/app/build.gradle new file mode 100644 index 0000000..0c26b2a --- /dev/null +++ b/tests/ndkJniLib/app/build.gradle @@ -0,0 +1,28 @@ +apply plugin: 'android' + +dependencies { + compile project(':lib') +} + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + productFlavors { + x86 { + ndk { + abiFilter "x86" + } + } + arm { + ndk { + abiFilter "armeabi-v7a" + } + } + mips { + ndk { + abiFilter "mips" + } + } + } +}
\ No newline at end of file diff --git a/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java b/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java new file mode 100644 index 0000000..feadc72 --- /dev/null +++ b/tests/ndkJniLib/app/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java @@ -0,0 +1,29 @@ +package com.example.hellojni.lib; + +import android.test.ActivityInstrumentationTestCase; + +/** + * This is a simple framework for a test of an Application. See + * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on + * how to write and extend Application tests. + * <p/> + * To run this test, you can type: + * adb shell am instrument -w \ + * -e class com.example.hellojni.HelloJniTest \ + * com.example.hellojni.tests/android.test.InstrumentationTestRunner + */ +public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> { + + public HelloJniTest() { + super("com.example.hellojni", HelloJni.class); + } + + + public void testJniName() { + final HelloJni a = getActivity(); + // ensure a valid handle to the activity has been returned + assertNotNull(a); + + assertFalse("unknown".equals(a.jniNameFromJNI())); + } +} diff --git a/tests/ndkJniLib/app/src/main/AndroidManifest.xml b/tests/ndkJniLib/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..aae7f79 --- /dev/null +++ b/tests/ndkJniLib/app/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.hellojni.app" + android:versionCode="1" + android:versionName="1.0"> + + <uses-sdk android:minSdkVersion="3" /> + + <application android:label="@string/app_name"> + </application> +</manifest> diff --git a/tests/ndkJniLib/app/src/main/res/values/strings.xml b/tests/ndkJniLib/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..c526073 --- /dev/null +++ b/tests/ndkJniLib/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">HelloJni</string> +</resources> diff --git a/tests/ndkJniLib/build.gradle b/tests/ndkJniLib/build.gradle new file mode 100644 index 0000000..b899f9a --- /dev/null +++ b/tests/ndkJniLib/build.gradle @@ -0,0 +1,8 @@ +buildscript { + repositories { + maven { url '../../../../out/host/gradle/repo' } + } + dependencies { + classpath 'com.android.tools.build:gradle:0.7.0-SNAPSHOT' + } +} diff --git a/tests/ndkJniLib/lib/build.gradle b/tests/ndkJniLib/lib/build.gradle new file mode 100644 index 0000000..5d18344 --- /dev/null +++ b/tests/ndkJniLib/lib/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'android-library' + +android { + compileSdkVersion 15 + buildToolsVersion "18.0.1" + + defaultConfig { + ndk { + moduleName "hello-jni" + } + } +}
\ No newline at end of file diff --git a/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java b/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java new file mode 100644 index 0000000..feadc72 --- /dev/null +++ b/tests/ndkJniLib/lib/src/instrumentTest/java/com/example/hellojni/lib/HelloJniTest.java @@ -0,0 +1,29 @@ +package com.example.hellojni.lib; + +import android.test.ActivityInstrumentationTestCase; + +/** + * This is a simple framework for a test of an Application. See + * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on + * how to write and extend Application tests. + * <p/> + * To run this test, you can type: + * adb shell am instrument -w \ + * -e class com.example.hellojni.HelloJniTest \ + * com.example.hellojni.tests/android.test.InstrumentationTestRunner + */ +public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> { + + public HelloJniTest() { + super("com.example.hellojni", HelloJni.class); + } + + + public void testJniName() { + final HelloJni a = getActivity(); + // ensure a valid handle to the activity has been returned + assertNotNull(a); + + assertFalse("unknown".equals(a.jniNameFromJNI())); + } +} diff --git a/tests/ndkJniLib/lib/src/main/AndroidManifest.xml b/tests/ndkJniLib/lib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ff4f566 --- /dev/null +++ b/tests/ndkJniLib/lib/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.hellojni.lib"> + + <uses-sdk android:minSdkVersion="3" /> + <application> + <activity android:name=".HelloJni" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java b/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java new file mode 100644 index 0000000..c97a0eb --- /dev/null +++ b/tests/ndkJniLib/lib/src/main/java/com/example/hellojni/lib/HelloJni.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.hellojni.lib; + +import android.app.Activity; +import android.widget.TextView; +import android.os.Bundle; + + +public class HelloJni extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + /* Create a TextView and set its content. + * the text is retrieved by calling a native + * function. + */ + TextView tv = new TextView(this); + tv.setText( stringFromJNI() ); + setContentView(tv); + } + + /* A native method that is implemented by the + * 'hello-jni' native library, which is packaged + * with this application. + */ + public native String stringFromJNI(); + + public native String jniNameFromJNI(); + + /* this is used to load the 'hello-jni' library on application + * startup. The library has already been unpacked into + * /data/data/com.example.hellojni/lib/libhello-jni.so at + * installation time by the package manager. + */ + static { + System.loadLibrary("hello-jni"); + } +} diff --git a/tests/ndkJniLib/lib/src/main/jni/hello-jni.c b/tests/ndkJniLib/lib/src/main/jni/hello-jni.c new file mode 100644 index 0000000..4ee252f --- /dev/null +++ b/tests/ndkJniLib/lib/src/main/jni/hello-jni.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include <string.h> +#include <jni.h> + +/* This is a trivial JNI example where we use a native method + * to return a new VM String. See the corresponding Java source + * file located at: + * + * apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java + */ +jstring +Java_com_example_hellojni_lib_HelloJni_stringFromJNI(JNIEnv* env, jobject thiz) +{ +#if defined(__arm__) + #if defined(__ARM_ARCH_7A__) + #if defined(__ARM_NEON__) + #define ABI "armeabi-v7a with NEON" + #else + #define ABI "armeabi-v7a" + #endif + #else + #define ABI "armeabi" + #endif +#elif defined(__i386__) + #define ABI "x86" +#elif defined(__mips__) + #define ABI "mips" +#else + #define ABI "unknown" +#endif + + return (*env)->NewStringUTF(env, "Hello from JNI ! My ABI is " ABI "."); +} + +jstring +Java_com_example_hellojni_lib_HelloJni_jniNameFromJNI(JNIEnv* env, jobject thiz) +{ +#if defined(__arm__) + #if defined(__ARM_ARCH_7A__) + #if defined(__ARM_NEON__) + #define ABI "armeabi-v7a with NEON" + #else + #define ABI "armeabi-v7a" + #endif + #else + #define ABI "armeabi" + #endif +#elif defined(__i386__) + #define ABI "x86" +#elif defined(__mips__) + #define ABI "mips" +#else + #define ABI "unknown" +#endif + + return (*env)->NewStringUTF(env, ABI); +} diff --git a/tests/ndkJniLib/lib/src/main/res/values/strings.xml b/tests/ndkJniLib/lib/src/main/res/values/strings.xml new file mode 100644 index 0000000..c526073 --- /dev/null +++ b/tests/ndkJniLib/lib/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">HelloJni</string> +</resources> diff --git a/tests/ndkJniLib/settings.gradle b/tests/ndkJniLib/settings.gradle new file mode 100644 index 0000000..7f37a58 --- /dev/null +++ b/tests/ndkJniLib/settings.gradle @@ -0,0 +1 @@ +include 'app', 'lib'
\ No newline at end of file diff --git a/tests/rsSupportMode/build.gradle b/tests/rsSupportMode/build.gradle index 86d1f22..96f40e4 100644 --- a/tests/rsSupportMode/build.gradle +++ b/tests/rsSupportMode/build.gradle @@ -13,7 +13,7 @@ android { buildToolsVersion "18.1" defaultConfig { - minSdkVersion 16 + minSdkVersion 8 targetSdkVersion 16 renderscriptTargetApi 18 renderscriptSupportMode true |