Skip to content

Commit

Permalink
Introduce --apple_crosstool_top, which sets the crosstool for sources…
Browse files Browse the repository at this point in the history
… in objc_*/apple_*/ios_* targets and their dependencies.

--
PiperOrigin-RevId: 142702735
MOS_MIGRATED_REVID=142702735
  • Loading branch information
calpeyser authored and aehlig committed Dec 22, 2016
1 parent e81ff0e commit 87fd5ba
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 21 deletions.
Expand Up @@ -19,6 +19,7 @@
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Table;
import com.google.devtools.build.lib.analysis.ConfigurationCollectionFactory;
Expand All @@ -34,7 +35,10 @@
import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.Attribute.Transition;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses.LipoTransition;
import com.google.devtools.build.lib.rules.objc.AppleCrosstoolTransition;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -104,6 +108,17 @@ protected Transition getDynamicTransition(Transition configurationTransition) {
return super.getDynamicTransition(configurationTransition);
}
}

@Override
public BuildConfiguration toplevelConfigurationHook(Target toTarget) {
return (AppleConfiguration.APPLE_CROSSTOOL_RULE_CLASSES
.contains(toTarget.getAssociatedRule().getRuleClass()))
? Iterables.getOnlyElement(
configuration
.getTransitions()
.getSplitConfigurations(AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION))
: configuration;
}
}

@Override
Expand Down
Expand Up @@ -136,6 +136,16 @@ public class AppleCommandLineOptions extends FragmentOptions {
help = "Specifies to target CPU of iOS compilation.")
public String iosCpu;

@Option(
name = "apple_crosstool_top",
defaultValue = "@bazel_tools//tools/cpp:toolchain",
category = "version",
converter = LabelConverter.class,
help = "The label of the crosstool package to be used in Apple and Objc rules and their"
+ " dependencies."
)
public Label appleCrosstoolTop;

@Option(name = "apple_platform_type",
defaultValue = "IOS",
category = "undocumented",
Expand Down
Expand Up @@ -65,8 +65,20 @@ 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");
/**
* Rule classes that need a top level transition to the apple crosstool.
*
* <p>This list must not contain any rule classes that require some other split transition, as
* that transition would be suppressed by the top level transition to the apple crosstool. For
* example, if "apple_binary" were in this list, the multi-arch transition would not occur.
*/
public static final ImmutableList<String> APPLE_CROSSTOOL_RULE_CLASSES = ImmutableList.of(
"objc_library",
"objc_binary",
"experimental_objc_library");

private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION = DottedVersion.fromString("7");

private final DottedVersion iosSdkVersion;
private final DottedVersion iosMinimumOs;
private final DottedVersion watchosSdkVersion;
Expand Down Expand Up @@ -628,5 +640,7 @@ public enum ConfigurationDistinguisher {
APPLEBIN_WATCHOS,
/** Distinguisher for {@code apple_binary} rule with "tvos" platform_type. */
APPLEBIN_TVOS,
/** Distinguisher for the apple crosstool configuration. */
APPLE_CROSSTOOL,
}
}
@@ -0,0 +1,82 @@
// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.rules.objc;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import java.util.List;

/**
* Transition that produces a configuration that causes c++ toolchain selection to use the
* CROSSTOOL given in apple_crosstool_top.
*/
public class AppleCrosstoolTransition implements SplitTransition<BuildOptions> {

/**
* A singleton instance of AppleCrosstoolTransition.
*/
public static final SplitTransition<BuildOptions> APPLE_CROSSTOOL_TRANSITION =
new AppleCrosstoolTransition();

@Override
public boolean defaultsToSelf() {
return true;
}

@Override
public List<BuildOptions> split(BuildOptions buildOptions) {
BuildOptions result = buildOptions.clone();
result.get(AppleCommandLineOptions.class).configurationDistinguisher =
ConfigurationDistinguisher.APPLE_CROSSTOOL;


// TODO(b/29355778): Once ios_cpu is retired, introduce another top-level flag (perhaps
// --apple_cpu) for toolchain selection in top-level consuming rules.
String cpu = "ios_" + buildOptions.get(AppleCommandLineOptions.class).iosCpu;
setAppleCrosstoolTransitionConfiguration(buildOptions, result, cpu);
return ImmutableList.of(result);
}

/**
* Sets configuration fields required for a transition that uses apple_crosstool_top in place of
* the default CROSSTOOL.
*
* @param from options from the originating configuration
* @param to options for the destination configuration. This instance will be modified
* to so the destination configuration uses the apple crosstool
* @param cpu {@code --cpu} value for toolchain selection in the destination configuration
*/
public static void setAppleCrosstoolTransitionConfiguration(BuildOptions from,
BuildOptions to, String cpu) {
to.get(BuildConfiguration.Options.class).cpu = cpu;
to.get(CppOptions.class).crosstoolTop =
from.get(AppleCommandLineOptions.class).appleCrosstoolTop;

// --compiler = "compiler" for all OSX toolchains. We do not support asan/tsan, cfi, etc. on
// darwin.
to.get(CppOptions.class).cppCompiler = "compiler";

// OSX toolchains always use the runtime of the platform they are targeting (i.e. we do not
// support custom production environments).
to.get(CppOptions.class).libcTop = null;
to.get(CppOptions.class).glibc = null;
}

}
Expand Up @@ -21,7 +21,6 @@
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.packages.Attribute.SplitTransition;
import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider;
Expand All @@ -32,7 +31,6 @@
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.MultiArchPlatformRule;

import java.util.List;

/**
Expand Down Expand Up @@ -161,17 +159,20 @@ public final List<BuildOptions> split(BuildOptions buildOptions) {

splitOptions.get(AppleCommandLineOptions.class).applePlatformType = platformType;
splitOptions.get(AppleCommandLineOptions.class).appleSplitCpu = cpu;
// Set for backwards compatibility with rules that depend on this flag, even when
// ios is not the platform type.
// TODO(b/28958783): Clean this up.
splitOptions.get(AppleCommandLineOptions.class).iosCpu = cpu;
if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
// Only set the (CC-compilation) CPU for dependencies if explicitly required by the user.
// This helps users of the iOS rules who do not depend on CC rules as these CPU values
// require additional flags to work (e.g. a custom crosstool) which now only need to be
// set if this feature is explicitly requested.
splitOptions.get(BuildConfiguration.Options.class).cpu =
String.format("%s_%s", platformType, cpu);
String platformCpu = String.format("%s_%s", platformType, cpu);
AppleCrosstoolTransition.setAppleCrosstoolTransitionConfiguration(buildOptions,
splitOptions, platformCpu);
} else {
// If the new configuration does not use the apple crosstool, then it needs ios_cpu to be
// to decide architecture.
// TODO(b/29355778, b/28403953): Use a crosstool for any apple rule, and remove this
// "else" clause. Deprecate ios_cpu.
splitOptions.get(AppleCommandLineOptions.class).iosCpu = cpu;
}
splitOptions.get(AppleCommandLineOptions.class).configurationDistinguisher =
configurationDistinguisher;
Expand All @@ -185,4 +186,4 @@ public boolean defaultsToSelf() {
return true;
}
}
}
}
Expand Up @@ -251,7 +251,8 @@ public class ObjcCommandLineOptions extends FragmentOptions {
public List<SplitTransition<BuildOptions>> getPotentialSplitTransitions() {
return ImmutableList.<SplitTransition<BuildOptions>>builder().add(
IosApplication.SPLIT_ARCH_TRANSITION, IosExtension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION,
AppleWatch1Extension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION)
AppleWatch1Extension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION,
AppleCrosstoolTransition.APPLE_CROSSTOOL_TRANSITION)
.addAll(MultiArchSplitTransitionProvider.getPotentialSplitTransitions())
.build();
}
Expand Down
Expand Up @@ -47,7 +47,6 @@
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Expand Down Expand Up @@ -1344,7 +1343,7 @@ public final List<BuildOptions> split(BuildOptions buildOptions) {
ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder();
for (String iosCpu : iosMultiCpus) {
BuildOptions splitOptions = buildOptions.clone();
setArchitectureOptions(splitOptions, iosCpu);
setArchitectureOptions(splitOptions, buildOptions, iosCpu);
setAdditionalOptions(splitOptions, buildOptions);
splitOptions.get(AppleCommandLineOptions.class).configurationDistinguisher =
getConfigurationDistinguisher();
Expand Down Expand Up @@ -1372,17 +1371,19 @@ protected ImmutableList<BuildOptions> defaultOptions(BuildOptions originalOption
*/
protected void setAdditionalOptions(BuildOptions splitOptions, BuildOptions originalOptions) {}

private void setArchitectureOptions(BuildOptions splitOptions, String iosCpu) {
private static void setArchitectureOptions(BuildOptions splitOptions,
BuildOptions originalOptions, String iosCpu) {
splitOptions.get(AppleCommandLineOptions.class).applePlatformType = PlatformType.IOS;
splitOptions.get(AppleCommandLineOptions.class).appleSplitCpu = iosCpu;
splitOptions.get(AppleCommandLineOptions.class).iosCpu = iosCpu;
if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
if (splitOptions.get(ObjcCommandLineOptions.class).enableCcDeps) {
// Only set the (CC-compilation) CPU for dependencies if explicitly required by the user.
// This helps users of the iOS rules who do not depend on CC rules as these CPU values
// require additional flags to work (e.g. a custom crosstool) which now only need to be set
// if this feature is explicitly requested.
splitOptions.get(BuildConfiguration.Options.class).cpu = "ios_" + iosCpu;
}
AppleCrosstoolTransition.setAppleCrosstoolTransitionConfiguration(originalOptions,
splitOptions, "ios_" + iosCpu);
}
}

@Override
Expand Down
Expand Up @@ -20,6 +20,10 @@ default_toolchain {
cpu: "darwin"
toolchain_identifier: "local_darwin"
}
default_toolchain {
cpu: "ios_x86_64"
toolchain_identifier: "local_ios"
}
default_toolchain {
cpu: "x64_windows"
toolchain_identifier: "local_windows_msys64"
Expand Down Expand Up @@ -354,6 +358,52 @@ toolchain {
supports_interface_shared_objects: true
}

# Stub crosstool to allow construction of apple crosstool configuration in a
# static configuration set.
# TODO(b/33804121): Remove this once dynamic configurations are in place.
toolchain {
toolchain_identifier: "local_ios"

host_system_name: "local"
target_system_name: "local"
target_cpu: "ios_x86_64"
target_libc: "ios"
compiler: "compiler"
linking_mode_flags { mode: DYNAMIC }

abi_version: "local"
abi_libc_version: "local"

tool_path { name: "ar" path: "/usr/bin/libtool" }
tool_path { name: "compat-ld" path: "/usr/bin/ld" }
tool_path { name: "cpp" path: "/usr/bin/cpp" }
tool_path { name: "dwp" path: "/usr/bin/dwp" }
tool_path { name: "gcc" path: "/usr/bin/gcc" }
tool_path { name: "gcov" path: "/usr/bin/gcov" }
tool_path { name: "ld" path: "/usr/bin/ld" }
tool_path { name: "nm" path: "/usr/bin/nm" }
tool_path { name: "objcopy" path: "/usr/bin/objcopy" }
tool_path { name: "objdump" path: "/usr/bin/objdump" }
tool_path { name: "strip" path: "/usr/bin/strip" }

needsPic: false

builtin_sysroot: ""
cxx_flag: "-std=c++0x"
ar_flag: "-static"
ar_flag: "-s"
ar_flag: "-o"
linker_flag: "-lstdc++"
cxx_builtin_include_directory: "/usr/include"
cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain"
cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs"
cxx_builtin_include_directory: "/opt/local/include"
cxx_builtin_include_directory: "/Library/Developer/CommandLineTools"
objcopy_embed_flag: "-I"
objcopy_embed_flag: "binary"
supports_interface_shared_objects: true
}

toolchain {
toolchain_identifier: "local_windows_mingw"

Expand Down
Expand Up @@ -87,6 +87,7 @@ public void setup(MockToolsConfig config) throws IOException {
" 'k8|compiler': ':cc-compiler-k8',",
" 'piii|compiler': ':cc-compiler-piii',",
" 'darwin|compiler': ':cc-compiler-darwin',",
" 'ios_x86_64|compiler': ':cc-compiler-ios_x86_64',",
" 'armeabi-v7a|compiler': ':cc-compiler-armeabi-v7a',",
" 'x64_windows|windows_msys64': ':cc-compiler-x64_windows',",
" 'ppc|compiler': ':cc-compiler-ppc',",
Expand Down Expand Up @@ -116,6 +117,13 @@ public void setup(MockToolsConfig config) throws IOException {
" module_map = 'crosstool.cppmap', supports_header_parsing = 1,",
" objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',",
")",
"cc_toolchain(name = 'cc-compiler-ios_x86_64', all_files = ':empty', ",
" compiler_files = ':empty',",
" cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ",
" linker_files = ':empty',",
" module_map = 'crosstool.cppmap', supports_header_parsing = 1,",
" objcopy_files = ':empty', static_runtime_libs = [':empty'], strip_files = ':empty',",
")",
"cc_toolchain(name = 'cc-compiler-armeabi-v7a', all_files = ':empty', ",
" compiler_files = ':empty',",
" cpu = 'local', dwp_files = ':empty', dynamic_runtime_libs = [':empty'], ",
Expand Down
4 changes: 2 additions & 2 deletions src/test/shell/bazel/apple/bazel_apple_test.sh
Expand Up @@ -753,8 +753,8 @@ EOF

bazel build --verbose_failures --xcode_version=$XCODE_VERSION -s \
//ios:bin >$TEST_log 2>&1 || fail "should build"
expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/dep/_objs/ios_dep.swiftmodule"
expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/swift_lib/_objs/ios_swift_lib.swiftmodule"
expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/apple_crosstool-ios_x86_64-fastbuild/genfiles/ios/dep/_objs/ios_dep.swiftmodule"
expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/apple_crosstool-ios_x86_64-fastbuild/genfiles/ios/swift_lib/_objs/ios_swift_lib.swiftmodule"
}

function test_swiftc_script_mode() {
Expand Down
4 changes: 2 additions & 2 deletions src/test/shell/bazel/apple/bazel_objc_test.sh
Expand Up @@ -207,9 +207,9 @@ EOF
# Dec 31 1969 or Jan 1 1970 -- either is fine.
# We would use 'date' here, but the format is slightly different (Jan 1 vs.
# Jan 01).
ar -tv bazel-bin/objclib/libobjclib.a \
ar -tv bazel-out/apple_crosstool-ios_x86_64-fastbuild/bin/objclib/libobjclib.a \
| grep "mysrc" | grep "Dec 31" | grep "1969" \
|| ar -tv bazel-bin/objclib/libobjclib.a \
|| ar -tv bazel-out/apple_crosstool-ios_x86_64-fastbuild/bin/objclib/libobjclib.a \
| grep "mysrc" | grep "Jan 1" | grep "1970" || \
fail "Timestamp of contents of archive file should be zero"
}
Expand Down

0 comments on commit 87fd5ba

Please sign in to comment.