aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/apple
diff options
context:
space:
mode:
authorGravatar lberki <lberki@google.com>2017-10-19 10:12:38 +0200
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2017-10-20 14:04:05 +0200
commitf9a379157d1e992390c5b6f0b75ef853e0870689 (patch)
treedbaa9811fb0b7eb113a0761a9c9e6ac019fb3a43 /src/main/java/com/google/devtools/build/lib/rules/apple
parente147372b073708631f1366bb2b9086ed413cb0c3 (diff)
Remove OS/Xcode versions (and thus package loading) from AppleConfiguration.Loader.
Fixes #3424. RELNOTES[INC]: Selecting on "xcode_version" and "{ios,tvos,macos,watchos}_sdk_version" is not supported anymore. What was config_setting(values={"$FOO_version": $VALUE}) is now config_setting(flag_values={"@bazel_tools//tools/osx:$FOO_version_flag": $VALUE}). PiperOrigin-RevId: 172714477
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/apple')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java201
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java131
2 files changed, 23 insertions, 309 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
index c445d1710f..cdd22ee85f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
@@ -14,22 +14,17 @@
package com.google.devtools.build.lib.rules.apple;
-import static com.google.devtools.build.lib.skyframe.serialization.SerializationCommonUtils.deserializeNullable;
-import static com.google.devtools.build.lib.skyframe.serialization.SerializationCommonUtils.serializeNullable;
-
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
@@ -46,8 +41,6 @@ import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.Objects;
import javax.annotation.Nullable;
/** A configuration containing flags required for Apple platforms and tools. */
@@ -75,23 +68,12 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
*/
public static final String APPLE_SDK_PLATFORM_ENV_NAME = "APPLE_SDK_PLATFORM";
- private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION = DottedVersion.fromString("7");
-
/** Prefix for iOS cpu values. */
public static final String IOS_CPU_PREFIX = "ios_";
/** Default cpu for iOS builds. */
@VisibleForTesting static final String DEFAULT_IOS_CPU = "x86_64";
- @Nullable private final DottedVersion xcodeVersion;
- private final DottedVersion iosSdkVersion;
- private final DottedVersion iosMinimumOs;
- private final DottedVersion watchosSdkVersion;
- private final DottedVersion watchosMinimumOs;
- private final DottedVersion tvosSdkVersion;
- private final DottedVersion tvosMinimumOs;
- private final DottedVersion macosSdkVersion;
- private final DottedVersion macosMinimumOs;
private final String iosCpu;
private final String appleSplitCpu;
private final PlatformType applePlatformType;
@@ -110,34 +92,8 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
private final boolean objcProviderFromLinked;
@VisibleForTesting
- AppleConfiguration(
- AppleCommandLineOptions options,
- String iosCpu,
- @Nullable DottedVersion xcodeVersion,
- DottedVersion iosSdkVersion,
- DottedVersion iosMinimumOs,
- DottedVersion watchosSdkVersion,
- DottedVersion watchosMinimumOs,
- DottedVersion tvosSdkVersion,
- DottedVersion tvosMinimumOs,
- DottedVersion macosSdkVersion,
- DottedVersion macosMinimumOs) {
+ AppleConfiguration(AppleCommandLineOptions options, String iosCpu) {
this.options = options;
- this.iosSdkVersion = Preconditions.checkNotNull(iosSdkVersion, "iosSdkVersion");
- this.iosMinimumOs = Preconditions.checkNotNull(iosMinimumOs, "iosMinimumOs");
- this.watchosSdkVersion =
- Preconditions.checkNotNull(watchosSdkVersion, "watchOsSdkVersion");
- this.watchosMinimumOs =
- Preconditions.checkNotNull(watchosMinimumOs, "watchOsMinimumOs");
- this.tvosSdkVersion =
- Preconditions.checkNotNull(tvosSdkVersion, "tvOsSdkVersion");
- this.tvosMinimumOs =
- Preconditions.checkNotNull(tvosMinimumOs, "tvOsMinimumOs");
- this.macosSdkVersion =
- Preconditions.checkNotNull(macosSdkVersion, "macOsSdkVersion");
- this.macosMinimumOs = Preconditions.checkNotNull(macosMinimumOs, "macOsMinimumOs");
-
- this.xcodeVersion = xcodeVersion;
this.iosCpu = iosCpu;
this.appleSplitCpu = Preconditions.checkNotNull(options.appleSplitCpu, "appleSplitCpu");
this.applePlatformType =
@@ -177,32 +133,6 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
return options;
}
- /***
- * @deprecated use {@link XcodeConfig#getMinimumOsForPlatformType(RuleContext, PlatformType)}.
- *
- * <p>This is only here because the minimum OS version is currently part of the name of the output
- * directory.
- */
- @Deprecated
- // Bug tracking the removal of this method: https://github.com/bazelbuild/bazel/issues/3424
- public DottedVersion getMinimumOsForPlatformType(PlatformType platformType) {
- // TODO(b/37240784): Look into using only a single minimum OS flag tied to the current
- // apple_platform_type.
- switch (platformType) {
- case IOS:
- return iosMinimumOs;
- case TVOS:
- return tvosMinimumOs;
- case WATCHOS:
- return watchosMinimumOs;
- case MACOS:
- return macosMinimumOs;
- default:
- throw new IllegalArgumentException("Unhandled platform: " + platformType);
- }
- }
-
-
/**
* Returns a map of environment variables (derived from configuration) that should be propagated
* for actions pertaining to building applications for apple platforms. These environment
@@ -564,23 +494,6 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
}
@Override
- public Map<String, Object> lateBoundOptionDefaults() {
- // xcode_version and *_sdk_version defaults come from processing the
- // target with label given in --xcode_version_override.
- ImmutableMap.Builder<String, Object> mapBuilder = ImmutableMap.builder();
-
- if (xcodeVersion != null) {
- mapBuilder.put("xcode_version", xcodeVersion.toString());
- }
- return mapBuilder
- .put("ios_sdk_version", iosSdkVersion)
- .put("tvos_sdk_version", tvosSdkVersion)
- .put("watchos_sdk_version", watchosSdkVersion)
- .put("macos_sdk_version", macosSdkVersion)
- .build();
- }
-
- @Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
@@ -589,124 +502,29 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
return false;
}
AppleConfiguration that = (AppleConfiguration) obj;
- return this.options.equals(that.options)
- && Objects.equals(this.xcodeVersion, that.xcodeVersion)
- && this.iosSdkVersion.equals(that.iosSdkVersion)
- && this.iosMinimumOs.equals(that.iosMinimumOs)
- && this.watchosSdkVersion.equals(that.watchosSdkVersion)
- && this.watchosMinimumOs.equals(that.watchosMinimumOs)
- && this.tvosSdkVersion.equals(that.tvosSdkVersion)
- && this.tvosMinimumOs.equals(that.tvosMinimumOs)
- && this.macosSdkVersion.equals(that.macosSdkVersion)
- && this.macosMinimumOs.equals(that.macosMinimumOs);
+ return this.options.equals(that.options);
}
@Override
public int hashCode() {
- return Objects.hash(
- options,
- xcodeVersion,
- iosSdkVersion,
- iosMinimumOs,
- watchosSdkVersion,
- watchosMinimumOs,
- tvosSdkVersion,
- tvosMinimumOs,
- macosSdkVersion,
- macosMinimumOs);
+ return options.hashCode();
}
void serialize(CodedOutputStream out) throws IOException, SerializationException {
options.serialize(out);
out.writeStringNoTag(iosCpu);
- serializeNullable(xcodeVersion, out, DottedVersion.CODEC);
- DottedVersion.CODEC.serialize(iosSdkVersion, out);
- DottedVersion.CODEC.serialize(iosMinimumOs, out);
- DottedVersion.CODEC.serialize(watchosSdkVersion, out);
- DottedVersion.CODEC.serialize(watchosMinimumOs, out);
- DottedVersion.CODEC.serialize(tvosSdkVersion, out);
- DottedVersion.CODEC.serialize(tvosMinimumOs, out);
- DottedVersion.CODEC.serialize(macosSdkVersion, out);
- DottedVersion.CODEC.serialize(macosMinimumOs, out);
}
static AppleConfiguration deserialize(CodedInputStream in)
throws IOException, SerializationException {
AppleCommandLineOptions options = AppleCommandLineOptions.deserialize(in);
String iosCpu = StringCodecs.asciiOptimized().deserialize(in);
- DottedVersion xcodeVersion = deserializeNullable(in, DottedVersion.CODEC);
- return new AppleConfiguration(
- options,
- iosCpu,
- xcodeVersion,
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in),
- DottedVersion.CODEC.deserialize(in));
+ return new AppleConfiguration(options, iosCpu);
}
@VisibleForTesting
- static AppleConfiguration create(
- AppleCommandLineOptions appleOptions,
- String cpu,
- XcodeVersionProperties xcodeVersionProperties)
- throws InvalidConfigurationException {
- DottedVersion iosSdkVersion =
- (appleOptions.iosSdkVersion != null)
- ? appleOptions.iosSdkVersion
- : xcodeVersionProperties.getDefaultIosSdkVersion();
- DottedVersion iosMinimumOsVersion =
- (appleOptions.iosMinimumOs != null) ? appleOptions.iosMinimumOs : iosSdkVersion;
- DottedVersion watchosSdkVersion =
- (appleOptions.watchOsSdkVersion != null)
- ? appleOptions.watchOsSdkVersion
- : xcodeVersionProperties.getDefaultWatchosSdkVersion();
- DottedVersion watchosMinimumOsVersion =
- (appleOptions.watchosMinimumOs != null) ? appleOptions.watchosMinimumOs : watchosSdkVersion;
- DottedVersion tvosSdkVersion =
- (appleOptions.tvOsSdkVersion != null)
- ? appleOptions.tvOsSdkVersion
- : xcodeVersionProperties.getDefaultTvosSdkVersion();
- DottedVersion tvosMinimumOsVersion =
- (appleOptions.tvosMinimumOs != null) ? appleOptions.tvosMinimumOs : tvosSdkVersion;
- DottedVersion macosSdkVersion =
- (appleOptions.macOsSdkVersion != null)
- ? appleOptions.macOsSdkVersion
- : xcodeVersionProperties.getDefaultMacosSdkVersion();
- DottedVersion macosMinimumOsVersion =
- (appleOptions.macosMinimumOs != null) ? appleOptions.macosMinimumOs : macosSdkVersion;
- AppleConfiguration configuration =
- new AppleConfiguration(
- appleOptions,
- iosCpuFromCpu(cpu),
- xcodeVersionProperties.getXcodeVersion().orNull(),
- iosSdkVersion,
- iosMinimumOsVersion,
- watchosSdkVersion,
- watchosMinimumOsVersion,
- tvosSdkVersion,
- tvosMinimumOsVersion,
- macosSdkVersion,
- macosMinimumOsVersion);
-
- validate(configuration);
- return configuration;
- }
-
- private static void validate(AppleConfiguration config) throws InvalidConfigurationException {
- DottedVersion xcodeVersion = config.xcodeVersion;
- if (config.getBitcodeMode() != AppleBitcodeMode.NONE
- && xcodeVersion != null
- && xcodeVersion.compareTo(MINIMUM_BITCODE_XCODE_VERSION) < 0) {
- throw new InvalidConfigurationException(
- String.format(
- "apple_bitcode mode '%s' is unsupported for xcode version '%s'",
- config.getBitcodeMode(), xcodeVersion));
- }
+ static AppleConfiguration create(AppleCommandLineOptions appleOptions, String cpu) {
+ return new AppleConfiguration(appleOptions, iosCpuFromCpu(cpu));
}
/**
@@ -714,13 +532,10 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
*/
public static class Loader implements ConfigurationFragmentFactory {
@Override
- public AppleConfiguration create(ConfigurationEnvironment env, BuildOptions buildOptions)
- throws InvalidConfigurationException, InterruptedException {
+ public AppleConfiguration create(ConfigurationEnvironment env, BuildOptions buildOptions) {
AppleCommandLineOptions appleOptions = buildOptions.get(AppleCommandLineOptions.class);
String cpu = buildOptions.get(BuildConfiguration.Options.class).cpu;
- XcodeVersionProperties xcodeVersionProperties = XcodeConfig.
- getXcodeVersionProperties(env, appleOptions);
- return AppleConfiguration.create(appleOptions, cpu, xcodeVersionProperties);
+ return AppleConfiguration.create(appleOptions, cpu);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
index 7444c45bc0..1b6e998d3c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
@@ -15,79 +15,25 @@
package com.google.devtools.build.lib.rules.apple;
import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.RedirectChaser;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
-import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
-import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NoSuchPackageException;
-import com.google.devtools.build.lib.packages.NoSuchTargetException;
-import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
-import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.Target;
-import java.util.List;
+import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
import java.util.Map;
-import javax.annotation.Nullable;
/**
* Implementation for the {@code xcode_config} rule.
*/
public class XcodeConfig implements RuleConfiguredTargetFactory {
-
- private static ImmutableList<XcodeVersionRuleData> getAvailableVersions(
- ConfigurationEnvironment env, Rule xcodeConfigTarget)
- throws InvalidConfigurationException, InterruptedException {
- List<Label> xcodeVersionLabels = NonconfigurableAttributeMapper.of(xcodeConfigTarget)
- .get(XcodeConfigRule.VERSIONS_ATTR_NAME, BuildType.LABEL_LIST);
- ImmutableList.Builder<XcodeVersionRuleData> xcodeVersionRuleListBuilder =
- ImmutableList.builder();
- for (Label label : xcodeVersionLabels) {
- Rule xcodeVersionRule = getRuleForLabel(label, "xcode_version", env, "xcode_version");
- xcodeVersionRuleListBuilder.add(new XcodeVersionRuleData(label, xcodeVersionRule));
- }
- return xcodeVersionRuleListBuilder.build();
- }
-
- /**
- * Uses the {@link AppleCommandLineOptions#xcodeVersion} and {@link
- * AppleCommandLineOptions#xcodeVersionConfig} command line options to determine and return the
- * effective xcode version properties. Returns absent if no explicit xcode version is declared,
- * and host system defaults should be used.
- *
- * @param env the current configuration environment
- * @param appleOptions the command line options
- * @throws InvalidConfigurationException if the options given (or configuration targets) were
- * malformed and thus the xcode version could not be determined
- */
- static XcodeVersionProperties getXcodeVersionProperties(
- ConfigurationEnvironment env, AppleCommandLineOptions appleOptions)
- throws InvalidConfigurationException, InterruptedException {
- Label xcodeVersionConfigLabel = appleOptions.xcodeVersionConfig;
-
- Rule xcodeConfigRule = getRuleForLabel(
- xcodeVersionConfigLabel, "xcode_config", env, "xcode_version_config");
-
- ImmutableList<XcodeVersionRuleData> versions = getAvailableVersions(env, xcodeConfigRule);
- XcodeVersionRuleData defaultVersion = getDefaultVersion(env, xcodeConfigRule);
-
- try {
- return resolveXcodeVersion(appleOptions.xcodeVersion, versions, defaultVersion);
- } catch (XcodeConfigException e) {
- throw new InvalidConfigurationException(e.getMessage());
- }
- }
+ private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION = DottedVersion.fromString("7");
/**
* An exception that signals that an Xcode config setup was invalid.
@@ -102,8 +48,8 @@ public class XcodeConfig implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- AppleCommandLineOptions appleOptions =
- ruleContext.getFragment(AppleConfiguration.class).getOptions();
+ AppleConfiguration appleConfig = ruleContext.getFragment(AppleConfiguration.class);
+ AppleCommandLineOptions appleOptions = appleConfig.getOptions();
XcodeVersionRuleData defaultVersion = ruleContext.getPrerequisite(
XcodeConfigRule.DEFAULT_ATTR_NAME, RuleConfiguredTarget.Mode.TARGET,
XcodeVersionRuleData.class);
@@ -145,6 +91,16 @@ public class XcodeConfig implements RuleConfiguredTargetFactory {
macosSdkVersion, macosMinimumOsVersion,
xcodeVersionProperties.getXcodeVersion().orNull());
+ AppleBitcodeMode bitcodeMode = appleConfig.getBitcodeMode();
+ DottedVersion xcodeVersion = xcodeVersions.getXcodeVersion();
+ if (bitcodeMode != AppleBitcodeMode.NONE
+ && xcodeVersion != null
+ && xcodeVersion.compareTo(MINIMUM_BITCODE_XCODE_VERSION) < 0) {
+ ruleContext.throwWithRuleError(String.format(
+ "apple_bitcode mode '%s' is unsupported for xcode version '%s'",
+ bitcodeMode, xcodeVersion));
+ }
+
return new RuleConfiguredTargetBuilder(ruleContext)
.addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
.addNativeDeclaredProvider(xcodeVersions)
@@ -226,25 +182,6 @@ public class XcodeConfig implements RuleConfiguredTargetFactory {
}
/**
- * Returns the default xcode version to use, if no {@code --xcode_version} command line flag was
- * specified.
- */
- @Nullable
- private static XcodeVersionRuleData getDefaultVersion(
- ConfigurationEnvironment env, Rule xcodeConfigTarget)
- throws InvalidConfigurationException, InterruptedException {
- Label defaultVersionLabel = NonconfigurableAttributeMapper.of(xcodeConfigTarget)
- .get(XcodeConfigRule.DEFAULT_ATTR_NAME, BuildType.LABEL);
- if (defaultVersionLabel != null) {
- Rule defaultVersionRule = getRuleForLabel(
- defaultVersionLabel, "xcode_version", env, "default xcode version");
- return new XcodeVersionRuleData(defaultVersionLabel, defaultVersionRule);
- } else {
- return null;
- }
- }
-
- /**
* Returns a map where keys are "names" of xcode versions as defined by the configuration target,
* and values are the rule data objects which contain information regarding that xcode version.
*
@@ -294,54 +231,16 @@ public class XcodeConfig implements RuleConfiguredTargetFactory {
}
/**
- * If the given label (following redirects) is a target for a rule of type {@code type}, then
- * returns the {@link Rule} representing that target. Otherwise, throws a {@link
- * InvalidConfigurationException}.
- */
- static Rule getRuleForLabel(
- Label label, String type, ConfigurationEnvironment env, String description)
- throws InvalidConfigurationException, InterruptedException {
- label = RedirectChaser.followRedirects(env, label, description);
-
- if (label == null) {
- throw new InvalidConfigurationException(String.format(
- "Expected value of %s (%s) to resolve to a target of type %s",
- description, label, type));
- }
-
- try {
- Target target = env.getTarget(label);
-
- if (target instanceof Rule && ((Rule) target).getRuleClass().equals(type)) {
- return (Rule) target;
- } else {
- throw new InvalidConfigurationException(String.format(
- "Expected value of %s (%s) to resolve to a target of type %s",
- description, label, type));
- }
- } catch (NoSuchPackageException | NoSuchTargetException exception) {
- env.getEventHandler().handle(Event.error(exception.getMessage()));
- throw new InvalidConfigurationException(exception);
- }
- }
-
- /**
* Returns the minimum compatible OS version for target simulator and devices for a particular
* platform type.
*/
public static DottedVersion getMinimumOsForPlatformType(
RuleContext ruleContext, ApplePlatform.PlatformType platformType) {
- AppleConfiguration config = ruleContext.getFragment(AppleConfiguration.class);
XcodeConfigProvider versions = ruleContext.getPrerequisite(
XcodeConfigRule.XCODE_CONFIG_ATTR_NAME,
RuleConfiguredTarget.Mode.TARGET,
XcodeConfigProvider.PROVIDER);
- DottedVersion fromProvider = versions.getMinimumOsForPlatformType(platformType);
- DottedVersion fromConfig = config.getMinimumOsForPlatformType(platformType);
- // This sanity check is there to keep this provider in sync with AppleConfiguration until the
- // latter can be removed. Tracking bug: https://github.com/bazelbuild/bazel/issues/3424
- Preconditions.checkState(fromProvider.equals(fromConfig));
- return fromProvider;
+ return versions.getMinimumOsForPlatformType(platformType);
}
/**