
org.gradle.language.nativeplatform.internal.Dimensions Maven / Gradle / Ivy
/*
* Copyright 2018 the original author or authors.
*
* 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 org.gradle.language.nativeplatform.internal;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.gradle.api.Action;
import org.gradle.api.Named;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.attributes.Usage;
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.SetProperty;
import org.gradle.language.cpp.internal.DefaultUsageContext;
import org.gradle.language.cpp.internal.NativeVariantIdentity;
import org.gradle.nativeplatform.Linkage;
import org.gradle.nativeplatform.MachineArchitecture;
import org.gradle.nativeplatform.OperatingSystemFamily;
import org.gradle.nativeplatform.TargetMachine;
import org.gradle.nativeplatform.TargetMachineFactory;
import org.gradle.nativeplatform.internal.DefaultTargetMachineFactory;
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.gradle.language.cpp.CppBinary.DEBUGGABLE_ATTRIBUTE;
import static org.gradle.language.cpp.CppBinary.LINKAGE_ATTRIBUTE;
import static org.gradle.language.cpp.CppBinary.OPTIMIZED_ATTRIBUTE;
import static org.gradle.nativeplatform.MachineArchitecture.ARCHITECTURE_ATTRIBUTE;
import static org.gradle.nativeplatform.OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE;
public class Dimensions {
public static String createDimensionSuffix(Named dimensionValue, Collection> multivalueProperty) {
return createDimensionSuffix(dimensionValue.getName(), multivalueProperty);
}
public static String createDimensionSuffix(String dimensionValue, Collection> multivalueProperty) {
if (isDimensionVisible(multivalueProperty)) {
return StringUtils.capitalize(dimensionValue.toLowerCase());
}
return "";
}
private static boolean isDimensionVisible(Collection> multivalueProperty) {
return multivalueProperty.size() > 1;
}
public static void unitTestVariants(Provider baseName, SetProperty declaredTargetMachines, @Nullable SetProperty declaredTargetMachinesOfTestedComponent,
ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory,
Provider group, Provider version,
Action action) {
Collection targetMachines = extractAndValidate("target machine", "unit test", declaredTargetMachines);
if (declaredTargetMachinesOfTestedComponent != null) {
Collection targetMachinesOfTestedComponent = extractAndValidate("target machine", "component under test", declaredTargetMachinesOfTestedComponent);
validateTargetMachines(targetMachines, targetMachinesOfTestedComponent);
}
variants(baseName, Arrays.asList(BuildType.DEBUG), targetMachines, objectFactory, attributesFactory, group, version, action);
}
public static void applicationVariants(Provider baseName, SetProperty declaredTargetMachines,
ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory,
Provider group, Provider version,
Action action) {
Collection buildTypes = BuildType.DEFAULT_BUILD_TYPES;
Collection targetMachines = extractAndValidate("target machine", "application", declaredTargetMachines);
variants(baseName, buildTypes, targetMachines, objectFactory, attributesFactory, group, version, action);
}
public static void libraryVariants(Provider baseName, SetProperty declaredLinkages, SetProperty declaredTargetMachines,
ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory,
Provider group, Provider version,
Action action) {
Collection buildTypes = BuildType.DEFAULT_BUILD_TYPES;
Collection linkages = extractAndValidate("linkage", "library", declaredLinkages);
Collection targetMachines = extractAndValidate("target machine", "library", declaredTargetMachines);
variants(baseName, buildTypes, linkages, targetMachines, objectFactory, attributesFactory, group, version, action);
}
private static Collection extractAndValidate(String propertyName, String componentName, SetProperty declared) {
declared.finalizeValue();
Collection value = declared.get();
assertNonEmpty(propertyName, componentName, value);
return value;
}
private static void assertNonEmpty(String propertyName, String componentName, Collection> property) {
if (property.isEmpty()) {
throw new IllegalArgumentException(String.format("A %s needs to be specified for the %s.", propertyName, componentName));
}
}
private static void validateTargetMachines(Collection testTargetMachines, Collection mainTargetMachines) {
for (TargetMachine machine : testTargetMachines) {
if (!mainTargetMachines.contains(machine)) {
throw new IllegalArgumentException("The target machine " + machine.toString() + " was specified for the unit test, but this target machine was not specified on the component under test.");
}
}
}
private static void variants(Provider baseName, Collection buildTypes, Collection linkages, Collection targetMachines,
ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory,
// TODO: These should come from somewhere else, probably
Provider group, Provider version,
Action action) {
for (BuildType buildType : buildTypes) {
for (Linkage linkage : linkages) {
for (TargetMachine targetMachine : targetMachines) {
Usage runtimeUsage = objectFactory.named(Usage.class, Usage.NATIVE_RUNTIME);
Usage linkUsage = objectFactory.named(Usage.class, Usage.NATIVE_LINK);
List variantNameToken = Lists.newArrayList();
// FIXME: Always build type name to keep parity with previous Gradle version in tooling API
variantNameToken.add(buildType.getName());
variantNameToken.add(createDimensionSuffix(linkage, linkages));
variantNameToken.add(createDimensionSuffix(targetMachine.getOperatingSystemFamily(), targetMachinesToOperatingSystems(targetMachines)));
variantNameToken.add(createDimensionSuffix(targetMachine.getArchitecture(), targetMachinesToArchitectures(targetMachines)));
String variantName = StringUtils.uncapitalize(String.join("", variantNameToken));
AttributeContainer runtimeAttributes = attributesFactory.mutable();
runtimeAttributes.attribute(Usage.USAGE_ATTRIBUTE, runtimeUsage);
addCommonAttributes(buildType, targetMachine, runtimeAttributes);
runtimeAttributes.attribute(LINKAGE_ATTRIBUTE, linkage);
DefaultUsageContext runtimeUsageContext = new DefaultUsageContext(variantName + "Runtime", runtimeUsage, runtimeAttributes);
AttributeContainer linkAttributes = attributesFactory.mutable();
linkAttributes.attribute(Usage.USAGE_ATTRIBUTE, linkUsage);
addCommonAttributes(buildType, targetMachine, linkAttributes);
linkAttributes.attribute(LINKAGE_ATTRIBUTE, linkage);
DefaultUsageContext linkUsageContext = new DefaultUsageContext(variantName + "Link", linkUsage, linkAttributes);
NativeVariantIdentity variantIdentity = new NativeVariantIdentity(variantName, baseName, group, version, buildType.isDebuggable(), buildType.isOptimized(), targetMachine, linkUsageContext, runtimeUsageContext, linkage);
action.execute(variantIdentity);
}
}
}
}
private static void variants(Provider baseName, Collection buildTypes, Collection targetMachines,
ObjectFactory objectFactory, ImmutableAttributesFactory attributesFactory,
// TODO: These should come from somewhere else, probably
Provider group, Provider version,
Action action) {
for (BuildType buildType : buildTypes) {
for (TargetMachine targetMachine : targetMachines) {
Usage runtimeUsage = objectFactory.named(Usage.class, Usage.NATIVE_RUNTIME);
List variantNameToken = Lists.newArrayList();
// FIXME: Always build type name to keep parity with previous Gradle version in tooling API
variantNameToken.add(buildType.getName());
variantNameToken.add(createDimensionSuffix(targetMachine.getOperatingSystemFamily(), targetMachinesToOperatingSystems(targetMachines)));
variantNameToken.add(createDimensionSuffix(targetMachine.getArchitecture(), targetMachinesToArchitectures(targetMachines)));
String variantName = StringUtils.uncapitalize(String.join("", variantNameToken));
AttributeContainer runtimeAttributes = attributesFactory.mutable();
runtimeAttributes.attribute(Usage.USAGE_ATTRIBUTE, runtimeUsage);
addCommonAttributes(buildType, targetMachine, runtimeAttributes);
DefaultUsageContext runtimeUsageContext = new DefaultUsageContext(variantName + "Runtime", runtimeUsage, runtimeAttributes);
DefaultUsageContext linkUsageContext = null;
NativeVariantIdentity variantIdentity = new NativeVariantIdentity(variantName, baseName, group, version, buildType.isDebuggable(), buildType.isOptimized(), targetMachine, linkUsageContext, runtimeUsageContext, null);
action.execute(variantIdentity);
}
}
}
private static Set targetMachinesToOperatingSystems(Collection targetMachines) {
return targetMachines.stream().map(TargetMachine::getOperatingSystemFamily).collect(Collectors.toSet());
}
private static Set targetMachinesToArchitectures(Collection targetMachines) {
return targetMachines.stream().map(TargetMachine::getArchitecture).collect(Collectors.toSet());
}
private static void addCommonAttributes(BuildType buildType, TargetMachine targetMachine, AttributeContainer runtimeAttributes) {
runtimeAttributes.attribute(DEBUGGABLE_ATTRIBUTE, buildType.isDebuggable());
runtimeAttributes.attribute(OPTIMIZED_ATTRIBUTE, buildType.isOptimized());
runtimeAttributes.attribute(ARCHITECTURE_ATTRIBUTE, targetMachine.getArchitecture());
runtimeAttributes.attribute(OPERATING_SYSTEM_ATTRIBUTE, targetMachine.getOperatingSystemFamily());
}
/**
* Used by all native plugins to work around the missing default feature on Property
*
* See https://github.com/gradle/gradle-native/issues/918
*
* @since 5.1
*/
public static Set useHostAsDefaultTargetMachine(TargetMachineFactory targetMachineFactory) {
return Collections.singleton(((DefaultTargetMachineFactory) targetMachineFactory).host());
}
public static boolean tryToBuildOnHost(NativeVariantIdentity identity) {
return DefaultNativePlatform.getCurrentOperatingSystem().toFamilyName().equals(identity.getTargetMachine().getOperatingSystemFamily().getName());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy