// Copyright 2017 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 static com.google.common.truth.Truth.assertThat; import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.getFirstArtifactEndingWith; import com.google.common.base.Joiner; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.CommandAction; import com.google.devtools.build.lib.analysis.util.ScratchAttributeWriter; import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppLinkAction; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Test case for the use of the OSX crosstool. */ @RunWith(JUnit4.class) public class AppleToolchainSelectionTest extends ObjcRuleTestCase { @Test public void testToolchainSelectionDefault() throws Exception { createLibraryTargetWriter("//a:lib").write(); CppConfiguration cppConfig = getAppleCrosstoolConfiguration().getFragment(CppConfiguration.class); assertThat(cppConfig.getCrosstoolTopPathFragment().toString()) .isEqualTo("tools/osx/crosstool"); assertThat(cppConfig.getToolchainIdentifier()) .isEqualTo("ios_x86_64"); } @Test public void testToolchainSelectionIosDevice() throws Exception { useConfiguration("--cpu=ios_armv7"); createLibraryTargetWriter("//a:lib").write(); CppConfiguration cppConfig = getAppleCrosstoolConfiguration().getFragment(CppConfiguration.class); assertThat(cppConfig.getCrosstoolTopPathFragment().toString()) .isEqualTo("tools/osx/crosstool"); assertThat(cppConfig.getToolchainIdentifier()) .isEqualTo("ios_armv7"); } @Test public void testToolchainSelectionCcDepDefault() throws Exception { ScratchAttributeWriter .fromLabelString(this, "cc_library", "//b:lib") .setList("srcs", "b.cc") .write(); createBinaryTargetWriter("//a:bin") .setList("deps", "//b:lib") .write(); Action lipoAction = actionProducingArtifact("//a:bin", "_lipobin"); String x8664Bin = configurationBin("x86_64", ConfigurationDistinguisher.APPLEBIN_IOS) + "a/bin_bin"; Artifact binArtifact = getFirstArtifactEndingWith(lipoAction.getInputs(), x8664Bin); CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact); CppLinkAction ccArchiveAction = (CppLinkAction) getGeneratingAction(getFirstArtifactEndingWith(linkAction.getInputs(), "liblib.a")); Artifact ccObjectFile = getFirstArtifactEndingWith(ccArchiveAction.getInputs(), ".o"); CommandAction ccCompileAction = (CommandAction) getGeneratingAction(ccObjectFile); assertThat(ccCompileAction.getArguments()).contains("tools/osx/crosstool/iossim/wrapped_clang"); } @Test public void testToolchainSelectionCcDepDevice() throws Exception { useConfiguration("--cpu=ios_armv7"); ScratchAttributeWriter .fromLabelString(this, "cc_library", "//b:lib") .setList("srcs", "b.cc") .write(); createBinaryTargetWriter("//a:bin") .setList("deps", "//b:lib") .write(); Action lipoAction = actionProducingArtifact("//a:bin", "_lipobin"); String armv7Bin = configurationBin("armv7", ConfigurationDistinguisher.APPLEBIN_IOS) + "a/bin_bin"; Artifact binArtifact = getFirstArtifactEndingWith(lipoAction.getInputs(), armv7Bin); CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact); CppLinkAction ccArchiveAction = (CppLinkAction) getGeneratingAction(getFirstArtifactEndingWith(linkAction.getInputs(), "liblib.a")); Artifact ccObjectFile = getFirstArtifactEndingWith(ccArchiveAction.getInputs(), ".o"); CommandAction ccCompileAction = (CommandAction) getGeneratingAction(ccObjectFile); assertThat(ccCompileAction.getArguments()).contains("tools/osx/crosstool/ios/wrapped_clang"); } @Test public void testToolchainSelectionMultiArchIos() throws Exception { useConfiguration("--ios_multi_cpus=armv7,arm64"); ScratchAttributeWriter .fromLabelString(this, "cc_library", "//b:lib") .setList("srcs", "a.cc") .write(getAppleCrosstoolConfiguration()); ScratchAttributeWriter .fromLabelString(this, "apple_binary", "//a:bin") .set("platform_type", "'ios'") .setList("deps", "//b:lib") .write(); Action lipoAction = actionProducingArtifact("//a:bin", "_lipobin"); String armv64Bin = configurationBin("arm64", ConfigurationDistinguisher.APPLEBIN_IOS) + "a/bin_bin"; Artifact binArtifact = getFirstArtifactEndingWith(lipoAction.getInputs(), armv64Bin); CppLinkAction linkAction = (CppLinkAction) getGeneratingAction(binArtifact); CppLinkAction objcLibArchiveAction = (CppLinkAction) getGeneratingAction( getFirstArtifactEndingWith(linkAction.getInputs(), "liblib.a")); assertThat(Joiner.on(" ").join(objcLibArchiveAction.getArguments())).contains("ios_arm64"); } @Test public void testToolchainSelectionMultiArchWatchos() throws Exception { useConfiguration( "--ios_multi_cpus=armv7,arm64", "--watchos_cpus=armv7k"); ScratchAttributeWriter .fromLabelString(this, "cc_library", "//b:lib") .setList("srcs", "a.cc") .write(getAppleCrosstoolConfiguration()); ScratchAttributeWriter .fromLabelString(this, "apple_binary", "//a:bin") .setList("deps", "//b:lib") .set("platform_type", "\"watchos\"") .write(); CommandAction linkAction = linkAction("//a:bin"); CppLinkAction objcLibCompileAction = (CppLinkAction) getGeneratingAction( getFirstArtifactEndingWith(linkAction.getInputs(), "liblib.a")); assertThat(Joiner.on(" ").join(objcLibCompileAction.getArguments())).contains("watchos_armv7k"); } }