
com.android.build.gradle.model.ComponentNativeLibraryFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-experimental Show documentation
Show all versions of gradle-experimental Show documentation
Gradle plug-in to build Android applications.
/*
* Copyright (C) 2015 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.model;
import static com.android.build.gradle.model.AndroidComponentModelPlugin.COMPONENT_NAME;
import com.android.annotations.NonNull;
import com.android.build.gradle.internal.NdkHandler;
import com.android.build.gradle.internal.core.Abi;
import com.android.build.gradle.internal.dependency.NativeDependencyResolveResult;
import com.android.build.gradle.internal.dependency.NativeLibraryArtifact;
import com.android.build.gradle.internal.model.NativeLibraryFactory;
import com.android.build.gradle.internal.model.NativeLibraryImpl;
import com.android.build.gradle.internal.ndk.NativeCompilerArgsUtil;
import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.android.build.gradle.managed.NdkAbiOptions;
import com.android.build.gradle.managed.NdkConfig;
import com.android.build.gradle.managed.NdkOptions;
import com.android.build.gradle.model.internal.AndroidBinaryInternal;
import com.android.builder.model.NativeLibrary;
import com.android.utils.StringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import org.gradle.model.ModelMap;
import org.gradle.nativeplatform.NativeLibraryBinary;
import org.gradle.nativeplatform.NativeLibraryBinarySpec;
import org.gradle.nativeplatform.SharedLibraryBinary;
import org.gradle.nativeplatform.StaticLibraryBinary;
import org.gradle.platform.base.BinaryContainer;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Implementation of NativeLibraryFactory from in the component model plugin.
*
* The library extract information directly from the binaries.
*/
public class ComponentNativeLibraryFactory implements NativeLibraryFactory {
@NonNull
ModelMap binaries;
@NonNull
NdkHandler ndkHandler;
@NonNull
ModelMap abiOptions;
@NonNull
Multimap nativeDependencies;
@NonNull
Multimap jniLibsDependencies;
public ComponentNativeLibraryFactory(
@NonNull ModelMap binaries,
@NonNull NdkHandler ndkHandler,
@NonNull ModelMap abiOptions,
@NonNull Multimap nativeDependencies,
@NonNull Multimap jniLibsDependencies) {
this.binaries = binaries;
this.ndkHandler = ndkHandler;
this.abiOptions = abiOptions;
this.nativeDependencies = nativeDependencies;
this.jniLibsDependencies = jniLibsDependencies;
}
@NonNull
@Override
public Optional create(
@NonNull VariantScope scope,
@NonNull String toolchainName,
@NonNull final Abi abi) {
BaseVariantData extends BaseVariantOutputData> variantData = scope.getVariantData();
AndroidBinaryInternal androidBinary =
binaries.get(COMPONENT_NAME + StringHelper.capitalize(variantData.getName()));
if (androidBinary == null) {
// Binaries are not created for test variants.
return Optional.absent();
}
@SuppressWarnings("ConstantConditions")
Optional nativeBinary =
Iterables.tryFind(androidBinary.getNativeBinaries(),
new Predicate() {
@Override
public boolean apply(NativeLibraryBinarySpec binary) {
return binary.getTargetPlatform().getName().equals(abi.getName());
}
});
if (!nativeBinary.isPresent()) {
// We don't have native binaries, but the project may be dependent on other native
// projects. Create a NativeLibrary to supply the debuggable library directories.
return Optional.of(new NativeLibraryImpl(
abi.getName(),
toolchainName,
abi.getName(),
Collections.emptyList(), /*cIncludeDirs*/
Collections.emptyList(), /*cppIncludeDirs*/
Collections.emptyList(), /*cSystemIncludeDirs*/
Collections.emptyList(), /*cppSystemIncludeDirs*/
Collections.emptyList(), /*cDefines*/
Collections.emptyList(), /*cppDefines*/
Collections.emptyList(), /*cFlags*/
Collections.emptyList(), /*cppFlags*/
findDebuggableLibraryDirectories(variantData, androidBinary, abi)));
}
NdkOptions targetOptions = abiOptions.get(abi.getName());
Iterable cFlags = nativeBinary.get().getcCompiler().getArgs();
Iterable cppFlags = nativeBinary.get().getCppCompiler().getArgs();
if (targetOptions != null) {
if (!targetOptions.getCFlags().isEmpty()) {
cFlags = Iterables.concat(cFlags, targetOptions.getCFlags());
}
if (!targetOptions.getCppFlags().isEmpty()) {
cppFlags = Iterables.concat(cppFlags, targetOptions.getCppFlags());
}
}
List debuggableLibDir = findDebuggableLibraryDirectories(variantData, androidBinary, abi);
NdkConfig ndkConfig = androidBinary.getMergedNdkConfig();
// The DSL currently do not support all options available in the model such as the
// include dirs and the defines. Therefore, just pass an empty collection for now.
return Optional.of(new NativeLibraryImpl(
ndkConfig.getModuleName(),
toolchainName,
abi.getName(),
Collections.emptyList(), /*cIncludeDirs*/
Collections.emptyList(), /*cppIncludeDirs*/
Collections.emptyList(), /*cSystemIncludeDirs*/
ndkHandler.getStlIncludes(ndkConfig.getStl(), ndkConfig.getStlVersion(), abi),
Collections.emptyList(), /*cDefines*/
Collections.emptyList(), /*cppDefines*/
NativeCompilerArgsUtil.transform(cFlags),
NativeCompilerArgsUtil.transform(cppFlags),
debuggableLibDir));
}
/**
* Find all directories containing library with debug symbol.
* Include libraries from dependencies.
*/
private List findDebuggableLibraryDirectories(
@NonNull BaseVariantData extends BaseVariantOutputData> variantData,
@NonNull AndroidBinaryInternal binary,
@NonNull Abi abi) {
// Create LinkedHashSet to remove duplicated while maintaining order.
Set debuggableLibDir = Sets.newLinkedHashSet();
debuggableLibDir.add(variantData.getScope().getNdkDebuggableLibraryFolders(abi));
addNativeDebuggableLib(debuggableLibDir, binary, abi, nativeDependencies);
addJniLibsDebuggableLib(debuggableLibDir, binary, abi, jniLibsDependencies);
return ImmutableList.copyOf(debuggableLibDir);
}
private static void addNativeDebuggableLib(
@NonNull Collection debuggableLibDir,
@NonNull AndroidBinaryInternal binary,
@NonNull final Abi abi,
@NonNull Multimap dependencyMap) {
NativeLibraryBinarySpec nativeBinary =
Iterables.find(
binary.getNativeBinaries(),
new Predicate() {
@Override
public boolean apply(NativeLibraryBinarySpec nativeBinary) {
return nativeBinary.getTargetPlatform().getName().equals(abi.getName());
}
},
null);
if (nativeBinary != null) {
addDebuggableLib(
debuggableLibDir,
binary,
abi,
dependencyMap.get(nativeBinary.getName()));
}
}
private static void addJniLibsDebuggableLib(
@NonNull Collection debuggableLibDir,
@NonNull AndroidBinary binary,
@NonNull Abi abi,
@NonNull Multimap dependencyMap) {
addDebuggableLib(debuggableLibDir, binary, abi, dependencyMap.get(binary.getName()));
}
private static void addDebuggableLib(
@NonNull Collection debuggableLibDir,
@NonNull AndroidBinary binary,
@NonNull Abi abi,
@NonNull Iterable dependencies) {
for (NativeDependencyResolveResult dependency : dependencies) {
for (NativeLibraryArtifact artifact : dependency.getNativeArtifacts()) {
for (File lib : artifact.getLibraries()) {
debuggableLibDir.add(lib.getParentFile());
}
}
for (final NativeLibraryBinary nativeBinary : dependency.getPrebuiltLibraries()) {
if (nativeBinary.getTargetPlatform().getName().equals(abi.getName())) {
File output = nativeBinary instanceof SharedLibraryBinary
? ((SharedLibraryBinary) nativeBinary).getSharedLibraryFile()
: ((StaticLibraryBinary) nativeBinary).getStaticLibraryFile();
if (output != null) {
debuggableLibDir.add(output.getParentFile());
}
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy