// 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.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.baseArtifactNames;
import static com.google.devtools.build.lib.rules.objc.CompilationSupport.ABSOLUTE_INCLUDES_PATH_FORMAT;
import static com.google.devtools.build.lib.rules.objc.CompilationSupport.BOTH_MODULE_NAME_AND_MODULE_MAP_SPECIFIED;
import static com.google.devtools.build.lib.rules.objc.CompilationSupport.FILE_IN_SRCS_AND_HDRS_WARNING_FORMAT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.ASSET_CATALOG;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.CC_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.NON_ARC_SRCS_TYPE;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SRCS_TYPE;
import static org.junit.Assert.fail;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionExecutionException;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandAction;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.analysis.util.ScratchAttributeWriter;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.util.MockObjcSupport;
import com.google.devtools.build.lib.rules.apple.ApplePlatform;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.cpp.CppCompileAction;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test case for objc_library. */
@RunWith(JUnit4.class)
public class ObjcLibraryTest extends ObjcRuleTestCase {

  static final RuleType RULE_TYPE = new OnlyNeedsSourcesRuleType("objc_library");
  private static final String WRAPPED_CLANG = "wrapped_clang";

  /**
   * Middleman artifact arising from //tools/osx/crosstool:link, containing tools that should be
   * inputs to link actions.
   */
  private static final String CROSSTOOL_LINK_MIDDLEMAN = "tools_Sosx_Scrosstool_Clink";

  /** Creates an {@code objc_library} target writer. */
  @Override
  protected ScratchAttributeWriter createLibraryTargetWriter(String labelString) {
    return ScratchAttributeWriter.fromLabelString(this, "objc_library", labelString);
  }

  @Test
  public void testConfigTransitionWithTopLevelAppleConfiguration() throws Exception {
    scratch.file("bin/BUILD",
        "objc_library(",
        "    name = 'objc',",
        "    srcs = ['objc.m'],",
        ")",
        "cc_binary(",
        "    name = 'cc',",
        "    srcs = ['cc.cc'],",
        "    deps = [':objc'],",
        ")");

    useConfiguration(
        "--apple_platform_type=ios",
        "--cpu=ios_x86_64",
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);

    ConfiguredTarget cc = getConfiguredTarget("//bin:cc");
    Artifact objcObject = ActionsTestUtil.getFirstArtifactEndingWith(
        actionsTestUtil().artifactClosureOf(getFilesToBuild(cc)), "objc.o");
    assertThat(objcObject.getExecPathString()).startsWith(
        TestConstants.PRODUCT_NAME + "-out/ios_x86_64-fastbuild/");
  }

  @Test
  public void testFilesToBuild() throws Exception {
    ConfiguredTarget target =
        createLibraryTargetWriter("//objc:One")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .write();

    Iterable<Artifact> files = getFilesToBuild(target);
    assertThat(Artifact.toRootRelativePaths(files)).containsExactly("objc/libOne.a");
  }

  @Test
  public void testCompilesSources() throws Exception {
    createLibraryTargetWriter("//objc/lib1")
        .setAndCreateFiles("srcs", "a.m")
        .setAndCreateFiles("hdrs", "hdr.h")
        .write();

    createLibraryTargetWriter("//objc/lib2")
        .setAndCreateFiles("srcs", "a.m")
        .setAndCreateFiles("hdrs", "hdr.h")
        .setList("deps", "//objc/lib1")
        .write();

    createLibraryTargetWriter("//objc:x")
        .setAndCreateFiles("srcs", "a.m", "private.h")
        .setAndCreateFiles("hdrs", "hdr.h")
        .setList("deps", "//objc/lib2:lib2")
        .write();

    CppCompileAction compileA = (CppCompileAction) compileAction("//objc:x", "a.o");

    assertThat(Artifact.toRootRelativePaths(compileA.getPossibleInputsForTesting()))
        .containsAllOf("objc/a.m", "objc/hdr.h", "objc/private.h");
    assertThat(Artifact.toRootRelativePaths(compileA.getOutputs()))
        .containsExactly("objc/_objs/x/arc/a.o", "objc/_objs/x/arc/a.d");
  }

  @Test
  public void testCompilesSourcesWithSameBaseName() throws Exception {
    createLibraryTargetWriter("//foo:lib")
        .setAndCreateFiles("srcs", "a.m", "pkg1/a.m", "b.m")
        .setAndCreateFiles("non_arc_srcs", "pkg2/a.m")
        .write();

    getConfiguredTarget("//foo:lib");

    Artifact a0 = getBinArtifact("_objs/lib/arc/0/a.o", getConfiguredTarget("//foo:lib"));
    Artifact a1 = getBinArtifact("_objs/lib/arc/1/a.o", getConfiguredTarget("//foo:lib"));
    Artifact a2 = getBinArtifact("_objs/lib/non_arc/a.o", getConfiguredTarget("//foo:lib"));
    Artifact b = getBinArtifact("_objs/lib/arc/b.o", getConfiguredTarget("//foo:lib"));

    assertThat(getGeneratingAction(a0)).isNotNull();
    assertThat(getGeneratingAction(a1)).isNotNull();
    assertThat(getGeneratingAction(a2)).isNotNull();
    assertThat(getGeneratingAction(b)).isNotNull();

    assertThat(getGeneratingAction(a0).getInputs()).contains(getSourceArtifact("foo/a.m"));
    assertThat(getGeneratingAction(a1).getInputs()).contains(getSourceArtifact("foo/pkg1/a.m"));
    assertThat(getGeneratingAction(a2).getInputs()).contains(getSourceArtifact("foo/pkg2/a.m"));
    assertThat(getGeneratingAction(b).getInputs()).contains(getSourceArtifact("foo/b.m"));
  }

  @Test
  public void testObjcPlusPlusCompile() throws Exception {
    useConfiguration(
        "--apple_platform_type=ios",
        "--cpu=ios_i386",
        "--ios_cpu=i386",
        "--ios_minimum_os=9.10.11");
    createLibraryTargetWriter("//objc:lib")
        .setList("srcs", "a.mm")
        .write();
    CommandAction compileAction = compileAction("//objc:lib", "a.o");
    assertThat(compileAction.getArguments())
        .containsAllOf("-stdlib=libc++", "-std=gnu++11", "-mios-simulator-version-min=9.10.11");
  }

  @Test
  public void testObjcPlusPlusCompileDarwin() throws Exception {
    useConfiguration(
        "--cpu=darwin_x86_64",
        "--macos_minimum_os=9.10.11",
        // TODO(b/36126423): Darwin should imply macos, so the
        // following line should not be necessary.
        "--apple_platform_type=macos");
    createLibraryTargetWriter("//objc:lib")
        .setList("srcs", "a.mm")
        .write();
    CommandAction compileAction = compileAction("//objc:lib", "a.o");
    assertThat(compileAction.getArguments())
        .containsAllOf("-stdlib=libc++", "-std=gnu++11", "-mmacosx-version-min=9.10.11");
  }

  @Test
  public void testCompilationModeDbg() throws Exception {
    useConfiguration(
        "--cpu=ios_i386",
        "--ios_cpu=i386",
        "--compilation_mode=dbg");
    scratch.file("objc/a.m");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch,
            "objc",
            "lib",
            "srcs",
            "['a.m']"));

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).contains("--DBG_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).doesNotContain("--FASTBUILD_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).doesNotContain("--OPT_ONLY_FLAG");
  }

  @Test
  public void testCompilationModeFastbuild() throws Exception {
    useConfiguration(
        "--cpu=ios_i386",
        "--ios_cpu=i386",
        "--compilation_mode=fastbuild");
    scratch.file("objc/a.m");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch,
            "objc",
            "lib",
            "srcs",
            "['a.m']"));

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).doesNotContain("--DBG_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).contains("--FASTBUILD_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).doesNotContain("--OPT_ONLY_FLAG");
  }

  @Test
  public void testCompilationModeOpt() throws Exception {
    useConfiguration(
        "--cpu=ios_i386",
        "--ios_cpu=i386",
        "--compilation_mode=opt");
    scratch.file("objc/a.m");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch,
            "objc",
            "lib",
            "srcs",
            "['a.m']"));

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).doesNotContain("--DBG_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).doesNotContain("--FASTBUILD_ONLY_FLAG");
    assertThat(compileActionA.getArguments()).contains("--OPT_ONLY_FLAG");
  }

  @Test
  public void testCreate_runfilesWithSourcesOnly() throws Exception {
    ConfiguredTarget target =
        createLibraryTargetWriter("//objc:One")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .write();
    RunfilesProvider provider = target.getProvider(RunfilesProvider.class);
    assertThat(baseArtifactNames(provider.getDefaultRunfiles().getArtifacts())).isEmpty();
    assertThat(Artifact.toRootRelativePaths(provider.getDataRunfiles().getArtifacts()))
        .containsExactly("objc/libOne.a");
  }

  @Test
  public void testCreate_noErrorForEmptySourcesButHasDependency() throws Exception {
    createLibraryTargetWriter("//baselib:baselib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .write();
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("hdrs", "a.h")
        .setList("deps", "//baselib:baselib")
        .write();
    ObjcProvider provider = providerForTarget("//lib:lib");
    assertThat(provider.get(LIBRARY))
        .containsExactlyElementsIn(archiveAction("//baselib:baselib").getOutputs());
  }

  @Test
  public void testCreate_errorForEmptyFilegroupSources() throws Exception {
    checkError(
        "x",
        "x",
        "does not produce any objc_library srcs files (expected " + SRCS_TYPE + ")",
        "filegroup(name = 'fg', srcs = [])",
        "objc_library(name = 'x', srcs = ['fg'])");
  }

  @Test
  public void testCreate_srcsContainingHeaders() throws Exception {
    scratch.file("x/a.m", "dummy source file");
    scratch.file("x/a.h", "dummy header file");
    scratch.file("x/BUILD", "objc_library(name = 'Target', srcs = ['a.m', 'a.h'])");
    assertThat(view.hasErrors(getConfiguredTarget("//x:Target"))).isFalse();
  }

  @Test
  public void testCreate_warningForOverlappingSrcsAndHdrs() throws Exception {
    scratch.file("/x/a.h", "dummy header file");
    checkWarning(
        "x",
        "x",
        String.format(FILE_IN_SRCS_AND_HDRS_WARNING_FORMAT, "x/a.h"),
        "objc_library(name = 'x', srcs = ['a.h'], hdrs = ['a.h'])");
  }

  @Test
  public void testCreate_headerAndCompiledSourceWithSameName() throws Exception {
    scratch.file("objc/BUILD", "objc_library(name = 'Target', srcs = ['a.m'], hdrs = ['a.h'])");
    assertThat(view.hasErrors(getConfiguredTarget("//objc:Target"))).isFalse();
  }

  @Test
  public void testCreate_errorForCcInNonArcSources() throws Exception {
    scratch.file("x/cc.cc");
    checkError(
        "x",
        "x",
        "'//x:cc.cc' does not produce any objc_library non_arc_srcs files (expected "
            + NON_ARC_SRCS_TYPE
            + ")",
        "objc_library(name = 'x', non_arc_srcs = ['cc.cc'])");
  }

  @Test
  public void testFileInSrcsAndNonArcSources() throws Exception {
    checkError(
        "x",
        "x",
        String.format(CompilationSupport.FILE_IN_SRCS_AND_NON_ARC_SRCS_ERROR_FORMAT, "x/foo.m"),
        "objc_library(name = 'x', srcs = ['foo.m'], non_arc_srcs = ['foo.m'])");
  }

  @Test
  public void testCreate_headerContainingDotMAndDotCFiles() throws Exception {
    scratch.file("x/a.m", "dummy source file");
    scratch.file("x/a.h", "dummy header file");
    scratch.file("x/b.m", "dummy source file");
    scratch.file("x/a.c", "dummy source file");
    scratch.file(
        "x/BUILD", "objc_library(name = 'Target', srcs = ['a.m'], hdrs = ['a.h', 'b.m', 'a.c'])");
    assertThat(view.hasErrors(getConfiguredTarget("//x:Target"))).isFalse();
  }

  @Test
  public void testProvidesObjcHeadersWithDotMFiles() throws Exception {
    ConfiguredTarget target =
        createLibraryTargetWriter("//objc:lib")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .setAndCreateFiles("hdrs", "a.h", "b.h", "f.m")
            .write();
    ConfiguredTarget depender =
        createLibraryTargetWriter("//objc2:lib")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .setAndCreateFiles("hdrs", "d.h", "e.m")
            .setList("deps", "//objc:lib")
            .write();
    assertThat(getArifactPaths(target, HEADER))
        .containsExactly("objc/a.h", "objc/b.h", "objc/f.m");
    assertThat(getArifactPaths(depender, HEADER))
        .containsExactly("objc/a.h", "objc/b.h", "objc/f.m", "objc2/d.h", "objc2/e.m");
  }

  @Test
  public void testMultiPlatformLibrary() throws Exception {
    useConfiguration("--ios_multi_cpus=i386,x86_64,armv7,arm64", "--ios_cpu=armv7");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "a.h")
        .write();

    assertThat(view.hasErrors(getConfiguredTarget("//objc:lib"))).isFalse();
  }

  static Iterable<String> iquoteArgs(ObjcProvider provider, BuildConfiguration configuration) {
    return Interspersing.beforeEach(
        "-iquote",
        Iterables.transform(
            ObjcCommon.userHeaderSearchPaths(provider, configuration),
            PathFragment::getSafePathString));
  }

  @Test
  public void testCompilationActions_simulator() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--ios_cpu=i386");

    scratch.file("objc/a.m");
    scratch.file("objc/non_arc.m");
    scratch.file("objc/private.h");
    scratch.file("objc/c.h");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch,
            "objc",
            "lib",
            "srcs",
            "['a.m', 'private.h']",
            "hdrs",
            "['c.h']",
            "non_arc_srcs",
            "['non_arc.m']"));

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    CommandAction compileActionNonArc = compileAction("//objc:lib", "non_arc.o");

    assertRequiresDarwin(compileActionA);
    assertThat(compileActionA.getArguments())
        .contains("tools/osx/crosstool/iossim/" + WRAPPED_CLANG);
    assertThat(compileActionA.getArguments())
        .containsAllOf("-isysroot", AppleToolchain.sdkDir()).inOrder();
    assertThat(Collections.frequency(compileActionA.getArguments(),
        "-F" + AppleToolchain.sdkDir() + "/Developer/Library/Frameworks")).isEqualTo(1);
    assertThat(
            Collections.frequency(
                compileActionA.getArguments(), "-F" + frameworkDir(ApplePlatform.IOS_SIMULATOR)))
        .isEqualTo(1);
    assertThat(compileActionA.getArguments())
        .containsAllIn(AppleToolchain.DEFAULT_WARNINGS.values());
    assertThat(compileActionA.getArguments())
        .containsAllIn(CompilationSupport.DEFAULT_COMPILER_FLAGS);
    assertThat(compileActionA.getArguments())
        .containsAllIn(CompilationSupport.SIMULATOR_COMPILE_FLAGS);
    assertThat(compileActionA.getArguments()).contains("-fobjc-arc");
    assertThat(compileActionA.getArguments()).containsAllOf("-c", "objc/a.m");
    assertThat(compileActionNonArc.getArguments()).contains("-fno-objc-arc");
    assertThat(compileActionA.getArguments()).containsAllIn(FASTBUILD_COPTS);
    assertThat(compileActionA.getArguments())
        .contains("-mios-simulator-version-min=" + DEFAULT_IOS_SDK_VERSION);
    assertThat(compileActionA.getArguments()).contains("-arch i386");
  }

  @Test
  public void testCompilationActions_device() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_armv7", "--ios_cpu=armv7");

    scratch.file("objc/a.m");
    scratch.file("objc/non_arc.m");
    scratch.file("objc/private.h");
    scratch.file("objc/c.h");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch,
            "objc",
            "lib",
            "srcs",
            "['a.m', 'private.h']",
            "hdrs",
            "['c.h']",
            "non_arc_srcs",
            "['non_arc.m']"));

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    CommandAction compileActionNonArc = compileAction("//objc:lib", "non_arc.o");

    assertRequiresDarwin(compileActionA);
    assertThat(compileActionA.getArguments()).contains("tools/osx/crosstool/ios/" + WRAPPED_CLANG);
    assertThat(compileActionA.getArguments())
        .containsAllOf("-isysroot", AppleToolchain.sdkDir()).inOrder();
    assertThat(Collections.frequency(compileActionA.getArguments(),
        "-F" + AppleToolchain.sdkDir() + "/Developer/Library/Frameworks")).isEqualTo(1);
    assertThat(
            Collections.frequency(
                compileActionA.getArguments(), "-F" + frameworkDir(ApplePlatform.IOS_DEVICE)))
        .isEqualTo(1);
    assertThat(compileActionA.getArguments())
        .containsAllIn(AppleToolchain.DEFAULT_WARNINGS.values());
    assertThat(compileActionA.getArguments())
        .containsAllIn(CompilationSupport.DEFAULT_COMPILER_FLAGS);
    assertThat(compileActionA.getArguments())
        .containsNoneIn(CompilationSupport.SIMULATOR_COMPILE_FLAGS);

    assertThat(compileActionA.getArguments()).contains("-fobjc-arc");
    assertThat(compileActionA.getArguments()).containsAllOf("-c", "objc/a.m");

    assertThat(compileActionNonArc.getArguments()).contains("-fno-objc-arc");
    assertThat(compileActionA.getArguments()).containsAllIn(FASTBUILD_COPTS);
    assertThat(compileActionA.getArguments())
        .contains("-miphoneos-version-min=" + DEFAULT_IOS_SDK_VERSION);
    assertThat(compileActionA.getArguments()).contains("-arch armv7");
  }

  @Test
  public void testArchivesPrecompiledObjectFiles() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file("objc/a.m");
    scratch.file("objc/b.o");
    scratch.file("objc/BUILD", RULE_TYPE.target(scratch, "objc", "x", "srcs", "['a.m', 'b.o']"));
    assertThat(Artifact.toRootRelativePaths(archiveAction("//objc:x").getInputs()))
        .contains("objc/b.o");
  }

  @Test
  public void testCompileWithFrameworkImportsIncludesFlagsAndInputArtifacts() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    addBinWithTransitiveDepOnFrameworkImport();
    CommandAction compileAction = compileAction("//lib:lib", "a.o");

    assertThat(compileAction.getArguments()).doesNotContain("-framework");
    assertThat(Joiner.on("").join(compileAction.getArguments())).contains("-Ffx");
    assertThat(compileAction.getInputs())
        .containsAllOf(
            getSourceArtifact("fx/fx1.framework/a"),
            getSourceArtifact("fx/fx1.framework/b"),
            getSourceArtifact("fx/fx2.framework/c"),
            getSourceArtifact("fx/fx2.framework/d"));
  }

  @Test
  public void testPrecompiledHeaders() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file("objc/a.m");
    scratch.file("objc/c.pch");
    scratch.file(
        "objc/BUILD",
        RULE_TYPE.target(
            scratch, "objc", "x", "srcs", "['a.m']", "non_arc_srcs", "['b.m']", "pch", "'c.pch'"));
    CppCompileAction compileAction = (CppCompileAction) compileAction("//objc:x", "a.o");
    assertThat(Joiner.on(" ").join(compileAction.getArguments()))
        .contains("-include objc/c.pch");
    assertThat(Artifact.toRootRelativePaths(compileAction.getPossibleInputsForTesting()))
        .contains("objc/c.pch");
  }

  @Test
  public void testCompilationActionsWithCopts() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--ios_cpu=i386");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .setList("copts", "-Ifoo", "--monkeys=$(TARGET_CPU)")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    assertThat(compileActionA.getArguments()).containsAllOf("-Ifoo", "--monkeys=ios_i386");
  }

  @Test
  public void testObjcCopts() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--objccopt=-foo");
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .write();
    List<String> args = compileAction("//lib:lib", "a.o").getArguments();
    assertThat(args).contains("-foo");
  }

  @Test
  public void testObjcCopts_argumentOrdering() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--objccopt=-foo");
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("copts", "-bar")
        .write();
    List<String> args = compileAction("//lib:lib", "a.o").getArguments();
    assertThat(args).containsAllOf("-fobjc-arc", "-foo", "-bar").inOrder();
  }

  @Test
  public void testBothModuleNameAndModuleMapGivesError() throws Exception {
    checkError(
        "x",
        "x",
        BOTH_MODULE_NAME_AND_MODULE_MAP_SPECIFIED,
        "objc_library( name = 'x', module_name = 'x', module_map = 'x.modulemap' )");
  }

  @Test
  public void testCompilationActionsWithModuleMapsEnabled() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--experimental_objc_enable_module_maps");
    String target = "//objc/library:lib@a-foo_foobar";
    createLibraryTargetWriter(target)
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileActionA = compileAction(target, "a.o");
    assertThat(compileActionA.getArguments())
        .containsAllIn(moduleMapArtifactArguments("//objc/library", "lib@a-foo_foobar"));
    assertThat(compileActionA.getArguments()).contains("-fmodule-maps");
    assertThat(Artifact.toRootRelativePaths(compileActionA.getInputs()))
        .doesNotContain("objc/library/lib@a-foo_foobar.modulemaps/module.modulemap");
  }

  @Test
  public void testCompilationActionsWithEmbeddedBitcode() throws Exception {
    useConfiguration(
        "--apple_platform_type=ios", "--ios_multi_cpus=arm64", "--apple_bitcode=embedded");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).contains("-fembed-bitcode");
  }

  @Test
  public void testCompilationActionsWithEmbeddedBitcodeMarkers() throws Exception {
    useConfiguration(
        "--apple_platform_type=ios", "--ios_multi_cpus=arm64", "--apple_bitcode=embedded_markers");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).contains("-fembed-bitcode-marker");
  }

  @Test
  public void testCompilationActionsWithNoBitcode() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--ios_multi_cpus=arm64",
        "--apple_bitcode=none");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).doesNotContain("-fembed-bitcode");
    assertThat(compileActionA.getArguments()).doesNotContain("-fembed-bitcode-marker");
  }

  /**
   * Tests that bitcode is disabled for simulator builds even if enabled by flag.
   */
  @Test
  public void testCompilationActionsWithBitcode_simulator() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--ios_multi_cpus=x86_64",
        "--apple_bitcode=embedded");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments()).doesNotContain("-fembed-bitcode");
    assertThat(compileActionA.getArguments()).doesNotContain("-fembed-bitcode-marker");
  }

  @Test
  public void testModuleNameAttributeChangesName() throws Exception {
    RULE_TYPE.scratchTarget(scratch, "module_name", "'foo'");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//x:x");
    Artifact moduleMap = getGenfilesArtifact("x.modulemaps/module.modulemap", configuredTarget);

    CppModuleMapAction genMap = (CppModuleMapAction) getGeneratingAction(moduleMap);

    CppModuleMap cppModuleMap = genMap.getCppModuleMap();
    assertThat(cppModuleMap.getName()).isEqualTo("foo");
  }

  @Test
  public void testModuleMapActionFiltersHeaders() throws Exception {
    RULE_TYPE.scratchTarget(
        scratch,
        "srcs",
        "['a.m', 'b.m', 'private.h', 'private.inc']",
        "hdrs",
        "['a.h', 'x.inc', 'foo.m', 'bar.mm']");

    ConfiguredTarget configuredTarget = getConfiguredTarget("//x:x");
    Artifact moduleMap = getGenfilesArtifact("x.modulemaps/module.modulemap", configuredTarget);

    CppModuleMapAction genMap = (CppModuleMapAction) getGeneratingAction(moduleMap);

    assertThat(Artifact.toRootRelativePaths(genMap.getPrivateHeaders())).isEmpty();
    assertThat(Artifact.toRootRelativePaths(genMap.getPublicHeaders())).containsExactly("x/a.h");

    // now check the generated name
    CppModuleMap cppModuleMap = genMap.getCppModuleMap();
    assertThat(cppModuleMap.getName()).isEqualTo("x_x");
  }

  @Test
  public void testCompilationActionsWithCoptFmodules() throws Exception {
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .setList("copts", "-fmodules")
        .write();
    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    assertThat(compileActionA.getArguments()).containsAllOf("-fmodules",
        "-fmodules-cache-path=" + getModulesCachePath());
  }

  @Test
  public void testCompilationActionsWithCoptFmodulesCachePath() throws Exception {
    checkWarning("objc", "lib", CompilationSupport.MODULES_CACHE_PATH_WARNING,
        "objc_library(",
        "    name = 'lib',",
        "    srcs = ['a.m'],",
        "    copts = ['-fmodules', '-fmodules-cache-path=foobar']",
        ")");

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    assertThat(compileActionA.getArguments()).containsAllOf("-fmodules",
        "-fmodules-cache-path=" + getModulesCachePath());
  }

  @Test
  public void testArchiveAction_simulator() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--ios_cpu=i386");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction archiveAction = archiveAction("//objc:lib");
    assertThat(archiveAction.getArguments())
        .isEqualTo(
            ImmutableList.of(
                "tools/osx/crosstool/iossim/libtool",
                "-static",
                "-filelist",
                getBinArtifact("lib-archive.objlist", getConfiguredTarget("//objc:lib"))
                    .getExecPathString(),
                "-arch_only",
                "i386",
                "-syslibroot",
                AppleToolchain.sdkDir(),
                "-o",
                Iterables.getOnlyElement(archiveAction.getOutputs()).getExecPathString()));
    assertThat(baseArtifactNames(archiveAction.getInputs()))
        .containsAllOf("a.o", "b.o", "lib-archive.objlist", CROSSTOOL_LINK_MIDDLEMAN);
    assertThat(baseArtifactNames(archiveAction.getOutputs())).containsExactly("liblib.a");
    assertRequiresDarwin(archiveAction);
  }

  @Test
  public void testArchiveAction_device() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_armv7", "--ios_cpu=armv7");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction archiveAction = archiveAction("//objc:lib");

    assertThat(archiveAction.getArguments())
        .isEqualTo(
            ImmutableList.of(
                "tools/osx/crosstool/ios/libtool",
                "-static",
                "-filelist",
                getBinArtifact("lib-archive.objlist", getConfiguredTarget("//objc:lib"))
                    .getExecPathString(),
                "-arch_only",
                "armv7",
                "-syslibroot",
                AppleToolchain.sdkDir(),
                "-o",
                Iterables.getOnlyElement(archiveAction.getOutputs()).getExecPathString()));
    assertThat(baseArtifactNames(archiveAction.getInputs()))
        .containsAllOf("a.o", "b.o", "lib-archive.objlist");
    assertThat(baseArtifactNames(archiveAction.getOutputs())).containsExactly("liblib.a");
    assertRequiresDarwin(archiveAction);
  }

  @Test
  public void testFullyLinkArchiveAction_simulator() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_i386", "--ios_cpu=i386");
    createLibraryTargetWriter("//objc:lib_dep")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "a.h", "b.h")
        .write();
    createLibraryTargetWriter("//objc2:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h", "d.h")
        .setList("deps", "//objc:lib_dep")
        .write();
    CommandAction linkAction =
        (CommandAction) getGeneratingActionForLabel("//objc2:lib_fully_linked.a");
    assertRequiresDarwin(linkAction);
    assertThat(linkAction.getArguments())
        .isEqualTo(
            ImmutableList.of(
                "tools/osx/crosstool/iossim/libtool",
                "-static",
                "-arch_only",
                "i386",
                "-syslibroot",
                AppleToolchain.sdkDir(),
                "-o",
                Iterables.getOnlyElement(linkAction.getOutputs()).getExecPathString(),
                getBinArtifact("liblib.a", getConfiguredTarget("//objc2:lib")).getExecPathString(),
                getBinArtifact("liblib_dep.a", getConfiguredTarget("//objc:lib_dep"))
                    .getExecPathString()));
    // TODO(hlopko): make containsExactly once crosstools are updated so
    // link_dynamic_library.sh is not needed anymore
    assertThat(baseArtifactNames(linkAction.getInputs())).containsAllOf(
        "liblib_dep.a",
        "liblib.a",
        CROSSTOOL_LINK_MIDDLEMAN);
  }

  @Test
  public void testFullyLinkArchiveAction_device() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_armv7", "--ios_cpu=armv7");
    createLibraryTargetWriter("//objc:lib_dep")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "a.h", "b.h")
        .write();
    createLibraryTargetWriter("//objc2:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h", "d.h")
        .setList("deps", "//objc:lib_dep")
        .write();
    CommandAction linkAction =
        (CommandAction) getGeneratingActionForLabel("//objc2:lib_fully_linked.a");
    assertRequiresDarwin(linkAction);
    assertThat(linkAction.getArguments())
        .isEqualTo(
            ImmutableList.of(
                "tools/osx/crosstool/ios/libtool",
                "-static",
                "-arch_only",
                "armv7",
                "-syslibroot",
                AppleToolchain.sdkDir(),
                "-o",
                Iterables.getOnlyElement(linkAction.getOutputs()).getExecPathString(),
                getBinArtifact("liblib.a", getConfiguredTarget("//objc2:lib")).getExecPathString(),
                getBinArtifact("liblib_dep.a", getConfiguredTarget("//objc:lib_dep"))
                    .getExecPathString()));
    // TODO(hlopko): make containsExactly once crosstools are updated so
    // link_dynamic_library.sh is not needed anymore
    assertThat(baseArtifactNames(linkAction.getInputs())).containsAllOf(
        "liblib_dep.a",
        "liblib.a",
        CROSSTOOL_LINK_MIDDLEMAN);
  }

  @Test
  public void checkDoesNotStoreObjcLibsAsCC() throws Exception {
    createLibraryTargetWriter("//objc:lib_dep")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "a.h", "b.h")
        .write();
    createLibraryTargetWriter("//objc2:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h", "d.h")
        .setList("deps", "//objc:lib_dep")
        .write();
    ObjcProvider objcProvider = providerForTarget("//objc2:lib");
    assertThat(objcProvider.get(CC_LIBRARY)).isEmpty();
  }

  @Test
  public void testIncludesDirsGetPassedToCompileAction() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("includes", "../third_party/foo", "opensource/bar")
        .write();
    CommandAction compileAction = compileAction("//lib:lib", "a.o");

    for (String path :
        rootedIncludePaths(
            getAppleCrosstoolConfiguration(), "third_party/foo", "lib/opensource/bar")) {
      assertThat(Joiner.on("").join(compileAction.getArguments())).contains("-I" + path);
    }
  }

  @Test
  public void testPropagatesDefinesToDependersTransitively() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_x86_64", "--ios_cpu=x86_64");
    createLibraryTargetWriter("//lib1:lib1")
        .setAndCreateFiles("srcs", "a.m")
        .setAndCreateFiles("non_arc_srcs", "b.m")
        .setList("defines", "A=foo", "B", "MONKEYS=$(TARGET_CPU)")
        .write();
    createLibraryTargetWriter("//lib2:lib2")
        .setAndCreateFiles("srcs", "a.m")
        .setAndCreateFiles("non_arc_srcs", "b.m")
        .setList("deps", "//lib1:lib1")
        .setList("defines", "C=bar", "D")
        .write();
    createBinaryTargetWriter("//bin:bin")
        .setList("deps", "//lib2:lib2")
        .write();

    assertThat(compileAction("//lib1:lib1", "a.o").getArguments())
        .containsAllOf("-DA=foo", "-DB", "-DMONKEYS=ios_x86_64")
        .inOrder();
    assertThat(compileAction("//lib1:lib1", "b.o").getArguments())
        .containsAllOf("-DA=foo", "-DB", "-DMONKEYS=ios_x86_64")
        .inOrder();
    assertThat(compileAction("//lib2:lib2", "a.o").getArguments())
        .containsAllOf("-DA=foo", "-DB", "-DMONKEYS=ios_x86_64", "-DC=bar", "-DD")
        .inOrder();
    assertThat(compileAction("//lib2:lib2", "b.o").getArguments())
        .containsAllOf("-DA=foo", "-DB", "-DMONKEYS=ios_x86_64", "-DC=bar", "-DD")
        .inOrder();
    // TODO: Add tests for //bin:bin once experimental_objc_binary is implemented
  }

  @Test
  public void testDuplicateDefines() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m")
        .setList("defines", "foo=bar", "foo=bar")
        .write();
    int timesDefinesAppear = 0;
    for (String arg : compileAction("//lib:lib", "a.o").getArguments()) {
      if (arg.equals("-Dfoo=bar")) {
        timesDefinesAppear++;
      }
    }
    assertWithMessage("Duplicate define \"foo=bar\" should occur only once in command line")
        .that(timesDefinesAppear)
        .isEqualTo(1);
  }

  @Test
  public void checkDefinesFromCcLibraryDep() throws Exception {
    checkDefinesFromCcLibraryDep(RULE_TYPE);
  }

  @Test
  public void testCppSourceCompilesWithCppFlags() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    createLibraryTargetWriter("//objc:x")
        .setAndCreateFiles("srcs", "a.mm", "b.cc", "c.mm", "d.cxx", "e.c", "f.m", "g.C")
        .write();
    assertThat(compileAction("//objc:x", "a.o").getArguments()).contains("-std=gnu++11");
    assertThat(compileAction("//objc:x", "b.o").getArguments()).contains("-std=gnu++11");
    assertThat(compileAction("//objc:x", "c.o").getArguments()).contains("-std=gnu++11");
    assertThat(compileAction("//objc:x", "d.o").getArguments()).contains("-std=gnu++11");
    assertThat(compileAction("//objc:x", "e.o").getArguments()).doesNotContain("-std=gnu++11");
    assertThat(compileAction("//objc:x", "f.o").getArguments()).doesNotContain("-std=gnu++11");
    assertThat(compileAction("//objc:x", "g.o").getArguments()).contains("-std=gnu++11");
  }

  @Test
  public void testAssetCatalogsAttributeErrorForNotInXcAssetsDir() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--incompatible_disable_objc_library_resources=false");
    scratch.file("lib/ac/notinxcassets1");
    scratch.file("lib/ac/notinxcassets2");
    scratch.file("lib/ac/foo.xcassets/isinxcassets");
    checkError("lib", "lib",
        String.format(ObjcCommon.NOT_IN_CONTAINER_ERROR_FORMAT,
            "lib/ac/notinxcassets2", ImmutableList.of(ObjcCommon.ASSET_CATALOG_CONTAINER_TYPE)),
        "objc_library(name = 'lib', srcs = ['src.m'], asset_catalogs = glob(['ac/**']))");
  }

  @Test
  public void testXcdatamodelsAttributeErrorForNotInXcdatamodelDir() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--incompatible_disable_objc_library_resources=false");
    scratch.file("lib/xcd/notinxcdatamodel1");
    scratch.file("lib/xcd/notinxcdatamodel2");
    scratch.file("lib/xcd/foo.xcdatamodel/isinxcdatamodel");
    scratch.file("lib/xcd/bar.xcdatamodeld/isinxcdatamodeld");
    checkError("lib", "lib",
        String.format(ObjcCommon.NOT_IN_CONTAINER_ERROR_FORMAT,
            "lib/xcd/notinxcdatamodel1", Xcdatamodels.CONTAINER_TYPES),
        "objc_library(name = 'lib', srcs = ['src.m'], datamodels = glob(['xcd/**']))");
  }

  @Test
  public void testProvidesStoryboardOptions() throws Exception {
    checkProvidesStoryboardObjects(RULE_TYPE);
  }

  @Test
  public void testDoesNotUseCxxUnfilteredFlags() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    createLibraryTargetWriter("//lib:lib")
        .setList("srcs", "a.m")
        .write();
    // -pthread is an unfiltered_cxx_flag in the osx crosstool.
    assertThat(compileAction("//lib:lib", "a.o").getArguments()).doesNotContain("-pthread");
  }

  @Test
  public void testDoesNotUseDotdPruning() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--objc_use_dotd_pruning=false");
    createLibraryTargetWriter("//lib:lib")
        .setList("srcs", "a.m")
        .write();
    CppCompileAction compileAction = (CppCompileAction) compileAction("//lib:lib", "a.o");
    assertThat(
            compileAction.discoverInputsFromDotdFiles(
                new ActionExecutionContextBuilder().build(), null, null, null))
        .isEmpty();
  }

  @Test
  public void testProvidesObjcLibraryAndHeaders() throws Exception {
    ConfiguredTarget target =
        createLibraryTargetWriter("//objc:lib")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .setAndCreateFiles("hdrs", "a.h", "b.h")
            .write();
    ConfiguredTarget depender =
        createLibraryTargetWriter("//objc2:lib")
            .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
            .setAndCreateFiles("hdrs", "c.h", "d.h")
            .setList("deps", "//objc:lib")
            .write();
    assertThat(getArifactPaths(target, LIBRARY)).containsExactly("objc/liblib.a");
    assertThat(getArifactPaths(depender, LIBRARY)).containsExactly(
        "objc/liblib.a", "objc2/liblib.a");
    assertThat(getArifactPaths(target, HEADER))
        .containsExactly("objc/a.h", "objc/b.h");
    assertThat(getArifactPaths(depender, HEADER))
        .containsExactly("objc/a.h", "objc/b.h", "objc2/c.h", "objc2/d.h");
  }

  private Iterable<String> getArifactPaths(ConfiguredTarget target, Key<Artifact> artifactKey) {
    return Artifact.toRootRelativePaths(
        target.get(ObjcProvider.SKYLARK_CONSTRUCTOR).get(artifactKey));
  }

  @Test
  public void testWeakSdkFrameworks_objcProvider() throws Exception {
    createLibraryTargetWriter("//base_lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("weak_sdk_frameworks", "foo")
        .write();
    createLibraryTargetWriter("//depender_lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("weak_sdk_frameworks", "bar")
        .setList("deps", "//base_lib:lib")
        .write();

    ObjcProvider baseProvider = providerForTarget("//base_lib:lib");
    ObjcProvider dependerProvider = providerForTarget("//depender_lib:lib");

    assertThat(baseProvider.get(WEAK_SDK_FRAMEWORK)).containsExactly(new SdkFramework("foo"));
    assertThat(dependerProvider.get(WEAK_SDK_FRAMEWORK))
        .containsExactly(new SdkFramework("foo"), new SdkFramework("bar"));
  }

  @Test
  public void testErrorIfDepDoesNotExist() throws Exception {
    checkErrorIfNotExist("deps", "[':nonexistent']");
  }

  @Test
  public void testArIsNotImplicitOutput() throws Exception {
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .write();
    try {
      reporter.removeHandler(failFastHandler);
      getTarget("//lib:liblib.a");
      fail("should have thrown");
    } catch (NoSuchTargetException expected) {
    }
  }

  @Test
  public void testErrorForAbsoluteIncludesPath() throws Exception {
    scratch.file("x/a.m");
    checkError(
        "x",
        "x",
        String.format(ABSOLUTE_INCLUDES_PATH_FORMAT, "/absolute/path"),
        "objc_library(",
        "    name = 'x',",
        "    srcs = ['a.m'],",
        "    includes = ['/absolute/path'],",
        ")");
  }

  @Test
  public void testDylibsProvided() throws Exception {
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("sdk_dylibs", "libdy1", "libdy2")
        .write();
    ObjcProvider provider = providerForTarget("//lib:lib");
    assertThat(provider.get(SDK_DYLIB)).containsExactly("libdy1", "libdy2").inOrder();
  }

  @Test
  public void testPopulatesCompilationArtifacts() throws Exception {
    checkPopulatesCompilationArtifacts(RULE_TYPE);
  }

  @Test
  public void testProvidesXcassetCatalogsTransitively() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=false");
    scratch.file("lib1/ac.xcassets/foo");
    scratch.file("lib1/ac.xcassets/bar");
    createLibraryTargetWriter("//lib1:lib1")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .set("asset_catalogs", "glob(['ac.xcassets/**'])")
        .write();
    scratch.file("lib2/ac.xcassets/baz");
    scratch.file("lib2/ac.xcassets/42");
    createLibraryTargetWriter("//lib2:lib2")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .set("asset_catalogs", "glob(['ac.xcassets/**'])")
        .setList("deps", "//lib1:lib1")
        .write();

    ObjcProvider lib2Provider = providerForTarget("//lib2:lib2");
    assertThat(Artifact.toExecPaths(lib2Provider.get(ASSET_CATALOG)))
        .containsExactly(
            "lib1/ac.xcassets/foo",
            "lib1/ac.xcassets/bar",
            "lib2/ac.xcassets/baz",
            "lib2/ac.xcassets/42");
    assertThat(lib2Provider.get(XCASSETS_DIR))
        .containsExactly(
            PathFragment.create("lib1/ac.xcassets"), PathFragment.create("lib2/ac.xcassets"));

    ObjcProvider lib1Provider = providerForTarget("//lib1:lib1");
    assertThat(Artifact.toExecPaths(lib1Provider.get(ASSET_CATALOG)))
        .containsExactly("lib1/ac.xcassets/foo", "lib1/ac.xcassets/bar");
    assertThat(lib1Provider.get(XCASSETS_DIR))
        .containsExactly(PathFragment.create("lib1/ac.xcassets"))
        .inOrder();
  }

  @Test
  public void testObjcListFileInArchiveGeneration() throws Exception {
    scratch.file("lib/a.m");
    scratch.file("lib/b.m");
    scratch.file("lib/BUILD", "objc_library(name = 'lib1', srcs = ['a.m', 'b.m'])");
    ConfiguredTarget target = getConfiguredTarget("//lib:lib1");
    Artifact lib = getBinArtifact("liblib1.a", target);
    Action action = getGeneratingAction(lib);
    assertThat(paramFileArgsForAction(action))
        .containsExactlyElementsIn(
            Artifact.toExecPaths(inputsEndingWith(archiveAction("//lib:lib1"), ".o")));
  }

  @Test
  public void testErrorsWrongFileTypeForSrcsWhenCompiling() throws Exception {
    checkErrorsWrongFileTypeForSrcsWhenCompiling(RULE_TYPE);
  }

  @Test
  public void testCompilationActionsForDebug() throws Exception {
    checkClangCoptsForCompilationMode(RULE_TYPE, CompilationMode.DBG, CodeCoverageMode.NONE);
  }

  @Test
  public void testClangCoptsForDebugModeWithoutGlib() throws Exception {
    checkClangCoptsForDebugModeWithoutGlib(RULE_TYPE);
  }

  @Test
  public void testCompilationActionsForOptimized() throws Exception {
    checkClangCoptsForCompilationMode(RULE_TYPE, CompilationMode.OPT, CodeCoverageMode.NONE);
  }

  @Test
  public void testUsesDefinesFromTransitiveCcDeps() throws Exception {
    scratch.file(
        "package/BUILD",
        "cc_library(",
        "    name = 'cc_lib',",
        "    srcs = ['a.cc'],",
        "    defines = ['FOO'],",
        ")",
        "",
        "objc_library(",
        "    name = 'objc_lib',",
        "    srcs = ['b.m'],",
        "    deps = [':cc_lib'],",
        ")");

    CommandAction compileAction = compileAction("//package:objc_lib", "b.o");
    assertThat(compileAction.getArguments()).contains("-DFOO");
  }

  @Test
  public void testAllowVariousNonBlacklistedTypesInHeaders() throws Exception {
    checkAllowVariousNonBlacklistedTypesInHeaders(RULE_TYPE);
  }

  @Test
  public void testWarningForBlacklistedTypesInHeaders() throws Exception {
    checkWarningForBlacklistedTypesInHeaders(RULE_TYPE);
  }

  @Test
  public void testAppleSdkVersionEnv() throws Exception {
    useConfiguration("--apple_platform_type=ios");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertAppleSdkVersionEnv(action);
  }

  @Test
  public void testNonDefaultAppleSdkVersionEnv() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--ios_sdk_version=8.1");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertAppleSdkVersionEnv(action, "8.1");
  }

  @Test
  public void testXcodeVersionEnv() throws Exception {
    useConfiguration("--xcode_version=5.8");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertXcodeVersionEnv(action, "5.8");
  }

  @Test
  public void testXcodeVersionFeature() throws Exception {
    useConfiguration("--xcode_version=5.8");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertThat(action.getArguments()).contains("-DXCODE_FEATURE_FOR_TESTING=xcode_5.8");
  }

  @Test
  public void testXcodeVersionFeatureUnused() throws Exception {
    useConfiguration("--xcode_version=7.3");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertThat(action.getArguments()).doesNotContain("-DXCODE_FEATURE_FOR_TESTING=xcode_5.8");
  }

  @Test
  public void testXcodeVersionFeatureTwoComponentsTooMany() throws Exception {
    useConfiguration("--xcode_version=7.3.1");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertThat(action.getArguments()).contains("-DXCODE_FEATURE_FOR_TESTING=xcode_7.3");
  }

  @Test
  public void testXcodeVersionFeatureTwoComponentsTooFew() throws Exception {
    useConfiguration("--xcode_version=5");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertThat(action.getArguments()).contains("-DXCODE_FEATURE_FOR_TESTING=xcode_5.0");
  }

  @Test
  public void testIosSdkVersionCannotBeDefinedButEmpty() throws Exception {
    try {
      useConfiguration("--ios_sdk_version=");
      fail("Should fail for empty ios_sdk_version");
    } catch (OptionsParsingException e) {
      assertThat(e).hasMessageThat().contains("--ios_sdk_version");
    }
  }

  private void checkErrorIfNotExist(String attribute, String value) throws Exception {
    scratch.file("x/a.m");
    checkError(
        "x",
        "x",
        "in "
            + attribute
            + " attribute of objc_library rule //x:x: rule '//x:nonexistent' does not exist",
        "objc_library(",
        "    name = 'x',",
        "    srcs = ['a.m'],",
        attribute + " = " + value,
        ")");
  }

  @Test
  public void testCompilesWithHdrs() throws Exception {
    checkCompilesWithHdrs(ObjcLibraryTest.RULE_TYPE);
  }

  @Test
  public void testCompilesAssemblyWithPreprocessing() throws Exception {
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.S")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileAction = compileAction("//objc:lib", "b.o");

    // Clang automatically preprocesses .S files, so the assembler-with-cpp flag is unnecessary.
    // Regression test for b/22636858.
    assertThat(compileAction.getArguments()).doesNotContain("-x");
    assertThat(compileAction.getArguments()).doesNotContain("assembler-with-cpp");
    assertThat(baseArtifactNames(compileAction.getOutputs())).containsExactly("b.o", "b.d");
    assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting()))
        .containsAllOf("c.h", "b.S");
  }

  @Test
  public void testReceivesTransitivelyPropagatedDefines() throws Exception {
    checkReceivesTransitivelyPropagatedDefines(RULE_TYPE);
  }

  @Test
  public void testSdkIncludesUsedInCompileAction() throws Exception {
    checkSdkIncludesUsedInCompileAction(RULE_TYPE);
  }

  // Test with ios device SDK version 9.0. Framework path differs from previous versions.
  @Test
  public void testCompilationActions_deviceSdk9() throws Exception {
    useConfiguration("--cpu=ios_armv7", "--ios_minimum_os=1.0", "--ios_sdk_version=9.0");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileAction = compileAction("//objc:lib", "a.o");

    // We remove spaces, since the crosstool rules do not use spaces in command line args.

    String compileArgs = Joiner.on("").join(compileAction.getArguments()).replace(" ", "");
    assertThat(compileArgs)
        .contains("-F" + AppleToolchain.sdkDir() + AppleToolchain.SYSTEM_FRAMEWORK_PATH);
  }

  @Test
  public void testCompilationActionsWithPch() throws Exception {
    useConfiguration("--apple_platform_type=ios");
    ApplePlatform platform = ApplePlatform.IOS_SIMULATOR;
    scratch.file("objc/foo.pch");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .set("pch", "'some.pch'")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");

    assertThat(compileActionA.getArguments())
        .containsAllIn(
            new ImmutableList.Builder<String>()
                .addAll(AppleToolchain.DEFAULT_WARNINGS.values())
                .add("-fexceptions")
                .add("-fasm-blocks")
                .add("-fobjc-abi-version=2")
                .add("-fobjc-legacy-dispatch")
                .addAll(CompilationSupport.DEFAULT_COMPILER_FLAGS)
                .add("-mios-simulator-version-min=" + DEFAULT_IOS_SDK_VERSION)
                .add("-arch x86_64")
                .add("-isysroot", AppleToolchain.sdkDir())
                .add("-F" + AppleToolchain.sdkDir() + "/Developer/Library/Frameworks")
                .add("-F" + frameworkDir(platform))
                .addAll(FASTBUILD_COPTS)
                .addAll(
                    iquoteArgs(
                        getConfiguredTarget("//objc:lib").get(ObjcProvider.SKYLARK_CONSTRUCTOR),
                        getAppleCrosstoolConfiguration()))
                .add("-include", "objc/some.pch")
                .add("-fobjc-arc")
                .add("-c", "objc/a.m")
                .addAll(outputArgs(compileActionA.getOutputs()))
                .build());

    assertThat(compileActionA.getPossibleInputsForTesting()).contains(
        getFileConfiguredTarget("//objc:some.pch").getArtifact());
  }

  // Converts output artifacts into expected command-line arguments.
  protected List<String> outputArgs(Set<Artifact> outputs) {
    ImmutableList.Builder<String> result = new ImmutableList.Builder<>();
    for (String output : Artifact.toExecPaths(outputs)) {
      if (output.endsWith(".o")) {
        result.add("-o", output);
      } else if (output.endsWith(".d")) {
        result.add("-MD", "-MF", output);
      } else {
        throw new IllegalArgumentException(
            "output " + output + " has unknown ending (not in (.d, .o)");
      }
    }
    return result.build();
  }

  @Test
  public void checkStoresCcLibsAsCc() throws Exception {
    ScratchAttributeWriter.fromLabelString(this, "cc_library", "//cc:lib")
        .setAndCreateFiles("srcs", "a.cc")
        .write();
    scratch.file(
        "third_party/cc_lib/BUILD",
        "licenses(['unencumbered'])",
        "cc_library(",
        "    name = 'cc_lib_impl',",
        "    srcs = [",
        "        'a.c',",
        "        'a.h',",
        "    ],",
        ")",
        "",
        "cc_library(",
        "    name = 'cc_lib',",
        "    hdrs = ['a.h'],",
        "    deps = [':cc_lib_impl'],",
        ")");
    createLibraryTargetWriter("//objc2:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m")
        .setAndCreateFiles("hdrs", "c.h", "d.h")
        .setList("deps", "//cc:lib", "//third_party/cc_lib:cc_lib_impl")
        .write();
    ObjcProvider objcProvider = providerForTarget("//objc2:lib");

    Iterable<Artifact> linkerInputArtifacts =
        Iterables.transform(
            objcProvider.get(CC_LIBRARY),
            new Function<LibraryToLink, Artifact>() {
              @Override
              public Artifact apply(LibraryToLink library) {
                return library.getStaticLibrary();
              }
            });

    assertThat(linkerInputArtifacts)
        .containsAllOf(
            getBinArtifact(
                "liblib.a", getConfiguredTarget("//cc:lib", getAppleCrosstoolConfiguration())),
            getBinArtifact(
                "libcc_lib_impl.a",
                getConfiguredTarget(
                    "//third_party/cc_lib:cc_lib_impl", getAppleCrosstoolConfiguration())));
  }

  @Test
  public void testCollectsSdkFrameworksTransitively() throws Exception {
    createLibraryTargetWriter("//base_lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("sdk_frameworks", "foo")
        .write();
    createLibraryTargetWriter("//depender_lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("sdk_frameworks", "bar")
        .setList("deps", "//base_lib:lib")
        .write();

    ObjcProvider baseProvider = providerForTarget("//base_lib:lib");
    ObjcProvider dependerProvider = providerForTarget("//depender_lib:lib");

    Set<SdkFramework> baseFrameworks = ImmutableSet.of(new SdkFramework("foo"));
    Set<SdkFramework> dependerFrameworks =
        ImmutableSet.of(new SdkFramework("foo"), new SdkFramework("bar"));
    assertThat(baseProvider.get(SDK_FRAMEWORK)).containsExactlyElementsIn(baseFrameworks);
    assertThat(dependerProvider.get(SDK_FRAMEWORK)).containsExactlyElementsIn(dependerFrameworks);

    // Make sure that the archive action does not actually include the frameworks. This is needed
    // for creating binaries but is ignored for libraries.
    CommandAction archiveAction = archiveAction("//depender_lib:lib");
    assertThat(archiveAction.getArguments())
        .containsAllIn(
            new ImmutableList.Builder<String>()
                .add("-static")
                .add("-filelist")
                .add(
                    getBinArtifact("lib-archive.objlist", getConfiguredTarget("//depender_lib:lib"))
                        .getExecPathString())
                .add("-arch_only", "x86_64")
                .add("-syslibroot")
                .add(AppleToolchain.sdkDir())
                .add("-o")
                .addAll(Artifact.toExecPaths(archiveAction.getOutputs()))
                .build());
  }

  @Test
  public void testMultipleRulesCompilingOneSourceGenerateUniqueObjFiles() throws Exception {
    scratch.file("lib/a.m");
    scratch.file("lib/BUILD",
        "objc_library(name = 'lib1', srcs = ['a.m'], copts = ['-Ilib1flag'])",
        "objc_library(name = 'lib2', srcs = ['a.m'], copts = ['-Ilib2flag'])");
    Artifact obj1 = Iterables.getOnlyElement(
        inputsEndingWith(archiveAction("//lib:lib1"), ".o"));
    Artifact obj2 = Iterables.getOnlyElement(
        inputsEndingWith(archiveAction("//lib:lib2"), ".o"));

    // The exec paths of each obj file should be based on the objc_library target.
    assertThat(obj1.getExecPathString()).contains("lib1");
    assertThat(obj1.getExecPathString()).doesNotContain("lib2");
    assertThat(obj2.getExecPathString()).doesNotContain("lib1");
    assertThat(obj2.getExecPathString()).contains("lib2");

    CommandAction compile1 = (CommandAction) getGeneratingAction(obj1);
    CommandAction compile2 = (CommandAction) getGeneratingAction(obj2);
    assertThat(compile1.getArguments()).contains("-Ilib1flag");
    assertThat(compile2.getArguments()).contains("-Ilib2flag");
  }

  @Test
  public void testIncludesDirsOfTransitiveDepsGetPassedToCompileAction() throws Exception {
    createLibraryTargetWriter("//lib1:lib1")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("includes", "third_party/foo", "opensource/bar")
        .write();

    createLibraryTargetWriter("//lib2:lib2")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setList("includes", "more_includes")
        .setList("deps", "//lib1:lib1")
        .write();
    CommandAction compileAction = compileAction("//lib2:lib2", "a.o");
    // We remove spaces, since the crosstool rules do not use spaces in include paths
    String compileActionArgs = Joiner.on("")
        .join(compileAction.getArguments())
        .replace(" ", "");
    List<String> expectedIncludePaths = rootedIncludePaths(
        getAppleCrosstoolConfiguration(),
        "lib2/more_includes",
        "lib1/third_party/foo",
        "lib1/opensource/bar");
    for (String expectedIncludePath : expectedIncludePaths) {
      assertThat(compileActionArgs).contains("-I" + expectedIncludePath);
    }
  }

  @Test
  public void testIncludesDirsOfTransitiveCcDepsGetPassedToCompileAction() throws Exception {
    scratch.file("package/BUILD",
        "cc_library(",
        "    name = 'cc_lib',",
        "    srcs = ['a.cc'],",
        "    includes = ['foo/bar'],",
        ")",
        "",
        "objc_library(",
        "    name = 'objc_lib',",
        "    srcs = ['b.m'],",
        "    deps = [':cc_lib'],",
        ")");

    CommandAction compileAction = compileAction("//package:objc_lib", "b.o");
    assertContainsSublist(
        compileAction.getArguments(),
        ImmutableList.copyOf(
            Interspersing.beforeEach(
                "-isystem",
                rootedIncludePaths(getAppleCrosstoolConfiguration(), "package/foo/bar"))));
  }

  @Test
  public void testIncludesDirsOfTransitiveCcIncDepsGetPassedToCompileAction() throws Exception {
    scratch.file(
        "third_party/cc_lib/BUILD",
        "licenses(['unencumbered'])",
        "cc_library(",
        "    name = 'cc_lib_impl',",
        "    srcs = [",
        "        'v1/a.c',",
        "        'v1/a.h',",
        "    ],",
        ")",
        "",
        "cc_library(",
        "    name = 'cc_lib',",
        "    hdrs = ['v1/a.h'],",
        "    strip_include_prefix = 'v1',",
        "    deps = [':cc_lib_impl'],",
        ")");

    scratch.file(
        "package/BUILD",
        "objc_library(",
        "    name = 'objc_lib',",
        "    srcs = ['b.m'],",
        "    deps = ['//third_party/cc_lib:cc_lib'],",
        ")");

    CommandAction compileAction = compileAction("//package:objc_lib", "b.o");
    // We remove spaces, since the crosstool rules do not use spaces for include paths.
    String compileActionArgs = Joiner.on("")
        .join(compileAction.getArguments())
        .replace(" ", "");
    assertThat(compileActionArgs)
        .matches(".*-iquote.*/third_party/cc_lib/_virtual_includes/cc_lib.*");
  }

  @Test
  public void testIncludesIquoteFlagForGenFilesRoot() throws Exception {
    createLibraryTargetWriter("//lib:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .write();
    CommandAction compileAction = compileAction("//lib:lib", "a.o");
    BuildConfiguration config = getAppleCrosstoolConfiguration();
    assertContainsSublist(compileAction.getArguments(), ImmutableList.of(
        "-iquote", config.getGenfilesFragment().getSafePathString()));
  }

  @Test
  public void testCompilesAssemblyAsm() throws Exception {
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.asm")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileAction = compileAction("//objc:lib", "b.o");

    assertThat(compileAction.getArguments()).doesNotContain("-x");
    assertThat(compileAction.getArguments()).doesNotContain("assembler-with-cpp");
    assertThat(baseArtifactNames(compileAction.getOutputs())).contains("b.o");
    assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting()))
        .containsAllOf("c.h", "b.asm");
  }

  @Test
  public void testCompilesAssemblyS() throws Exception {
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.s")
        .setAndCreateFiles("hdrs", "c.h")
        .write();

    CommandAction compileAction = compileAction("//objc:lib", "b.o");

    assertThat(compileAction.getArguments()).doesNotContain("-x");
    assertThat(compileAction.getArguments()).doesNotContain("assembler-with-cpp");
    assertThat(baseArtifactNames(compileAction.getOutputs())).contains("b.o");
    assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting()))
        .containsAllOf("c.h", "b.s");
  }

  @Test
  public void testProvidesHdrsAndIncludes() throws Exception {
    checkProvidesHdrsAndIncludes(RULE_TYPE);
  }

  @Test
  public void testUsesDotdPruning() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL, "--objc_use_dotd_pruning");
    createLibraryTargetWriter("//lib:lib").setList("srcs", "a.m").write();
    CppCompileAction compileAction = (CppCompileAction) compileAction("//lib:lib", "a.o");
    try {
      compileAction.discoverInputsFromDotdFiles(
          new ActionExecutionContextBuilder().build(), null, null, null);
      fail("Expected ActionExecutionException");
    } catch (ActionExecutionException expected) {
      assertThat(expected).hasMessageThat().contains("error while parsing .d file");
    }
  }

  @Test
  public void testAppleSdkDefaultPlatformEnv() throws Exception {
    useConfiguration("--apple_platform_type=ios");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertAppleSdkPlatformEnv(action, "iPhoneSimulator");
  }

  @Test
  public void testAppleSdkDevicePlatformEnv() throws Exception {
    useConfiguration("--apple_platform_type=ios", "--cpu=ios_arm64");

    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .write();
    CommandAction action = compileAction("//objc:lib", "a.o");

    assertAppleSdkPlatformEnv(action, "iPhoneOS");
  }

  @Test
  public void testApplePlatformEnvForCcLibraryDep() throws Exception {
    useConfiguration("--cpu=ios_i386");

    scratch.file(
        "package/BUILD",
        "cc_library(",
        "    name = 'cc_lib',",
        "    srcs = ['a.cc'],",
        ")",
        "",
        "apple_binary(",
        "    name = 'objc_bin',",
        "    platform_type = 'ios',",
        "    deps = [':main_lib'],",
        ")",
        "objc_library(",
        "    name = 'main_lib',",
        "    srcs = ['b.m'],",
        "    deps = [':cc_lib'],",
        ")");

    Action binLinkAction = linkAction("//package:objc_bin");
    Artifact artifact =
        ActionsTestUtil.getFirstArtifactEndingWith(binLinkAction.getInputs(), "libcc_lib.a");
    Action cppLibLinkAction = getGeneratingAction(artifact);
    Artifact cppLibArtifact =
        ActionsTestUtil.getFirstArtifactEndingWith(cppLibLinkAction.getInputs(), ".o");

    CppCompileAction action = (CppCompileAction) getGeneratingAction(cppLibArtifact);
    assertAppleSdkVersionEnv(action.getIncompleteEnvironmentForTesting());
  }

  @Test
  public void testDoesNotPropagateProtoIncludes() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file(
        "x/BUILD",
        "proto_library(",
        "   name = 'protos',",
        "   srcs = ['data.proto'],",
        ")",
        "objc_proto_library(",
        "   name = 'objc_proto_lib',",
        "   deps = [':protos'],",
        "   portable_proto_filters = ['data_filter.pbascii'],",
        ")");
    createLibraryTargetWriter("//a:lib")
        .setList("srcs", "a.m")
        .setList("deps", "//x:objc_proto_lib")
        .write();
    createLibraryTargetWriter("//b:lib").setList("srcs", "b.m").setList("deps", "//a:lib").write();

    CommandAction compileAction1 = compileAction("//a:lib", "a.o");
    CommandAction compileAction2 = compileAction("//b:lib", "b.o");

    assertThat(Joiner.on(" ").join(compileAction1.getArguments())).contains("objc_proto_lib");
    assertThat(Joiner.on(" ").join(compileAction2.getArguments())).doesNotContain("objc_proto_lib");
  }

  @Test
  public void testExportsJ2ObjcProviders() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    ConfiguredTarget lib = createLibraryTargetWriter("//a:lib").write();
    assertThat(lib.getProvider(J2ObjcEntryClassProvider.class)).isNotNull();
    assertThat(lib.getProvider(J2ObjcMappingFileProvider.class)).isNotNull();
  }

  @Test
  public void testObjcProtoLibraryDoesNotCrash() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file(
        "x/BUILD",
        "objc_library(",
        "   name = 'objc',",
        "   srcs = ['source.m'],",
        "   deps = [':objc_proto_lib'],",
        ")",
        "proto_library(",
        "   name = 'protos',",
        "   srcs = ['data.proto'],",
        ")",
        "objc_proto_library(",
        "   name = 'objc_proto_lib',",
        "   deps = [':protos'],",
        "   portable_proto_filters = ['data_filter.pbascii'],",
        ")");
    assertThat(getConfiguredTarget("//x:objc")).isNotNull();
  }

  @Test
  public void testLegacyObjcProtoLibraryDoesNotCrash() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file(
        "x/BUILD",
        "objc_library(",
        "   name = 'objc',",
        "   srcs = ['source.m'],",
        "   deps = [':objc_proto_lib'],",
        ")",
        "proto_library(",
        "   name = 'protos',",
        "   srcs = ['data.proto'],",
        ")",
        "objc_proto_library(",
        "   name = 'objc_proto_lib',",
        "   deps = [':protos'],",
        ")");
    assertThat(getConfiguredTarget("//x:objc")).isNotNull();
  }

  @Test
  public void testObjcImportDoesNotCrash() throws Exception {
    useConfiguration("--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL);
    scratch.file(
        "x/BUILD",
        "objc_library(",
        "   name = 'objc',",
        "   srcs = ['source.m'],",
        "   deps = [':import'],",
        ")",
        "objc_import(",
        "   name = 'import',",
        "   archives = ['archive.a'],",
        ")");
    assertThat(getConfiguredTarget("//x:objc")).isNotNull();
  }

  @Test
  public void testCompilationActionsWithIQuotesInCopts() throws Exception {
    useConfiguration(
        "--cpu=ios_i386",
        "--ios_cpu=i386");
    createLibraryTargetWriter("//objc:lib")
        .setAndCreateFiles("srcs", "a.m", "b.m", "private.h")
        .setAndCreateFiles("hdrs", "c.h")
        .setList("copts", "-iquote foo/bar", "-iquote bam/baz")
        .write();

    CommandAction compileActionA = compileAction("//objc:lib", "a.o");
    String action = String.join(" ", compileActionA.getArguments());
    assertThat(action).contains("-iquote foo/bar");
    assertThat(action).contains("-iquote bam/baz");
  }
  @Test
  public void testCollectCodeCoverageWithGCOVFlags() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL, "--collect_code_coverage");
    createLibraryTargetWriter("//objc:x")
        .setAndCreateFiles("srcs", "a.mm", "b.cc", "c.mm", "d.cxx", "e.c", "f.m", "g.C")
        .write();
    List<String> copts = ImmutableList.of("-fprofile-arcs", "-ftest-coverage");
    assertThat(compileAction("//objc:x", "a.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "b.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "c.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "d.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "e.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "f.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "g.o").getArguments()).containsAllIn(copts);
  }

  @Test
  public void testCollectCodeCoverageWithLLVMCOVFlags() throws Exception {
    useConfiguration(
        "--crosstool_top=" + MockObjcSupport.DEFAULT_OSX_CROSSTOOL,
        "--collect_code_coverage",
        "--experimental_use_llvm_covmap");
    createLibraryTargetWriter("//objc:x")
        .setAndCreateFiles("srcs", "a.mm", "b.cc", "c.mm", "d.cxx", "e.c", "f.m", "g.C")
        .write();
    List<String> copts = ImmutableList.of("-fprofile-instr-generate", "-fcoverage-mapping");
    assertThat(compileAction("//objc:x", "a.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "b.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "c.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "d.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "e.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "f.o").getArguments()).containsAllIn(copts);
    assertThat(compileAction("//objc:x", "g.o").getArguments()).containsAllIn(copts);
   }

  @Test
  public void testNoG0IfGeneratesDsym() throws Exception {
    useConfiguration("--apple_generate_dsym", "-c", "opt");
    createLibraryTargetWriter("//x:x").setList("srcs", "a.m").write();
    CommandAction compileAction = compileAction("//x:x", "a.o");
    assertThat(compileAction.getArguments()).doesNotContain("-g0");
  }

  @Test
  public void testFilesToCompileOutputGroup() throws Exception {
    checkFilesToCompileOutputGroup(RULE_TYPE);
  }

  @Test
  @Ignore("apple_grte_top isn't being applied because the cpu doesn't change")
  public void testSysrootArgSpecifiedWithGrteTopFlag() throws Exception {
    MockObjcSupport.setup(mockToolsConfig);
    useConfiguration(
        "--cpu=ios_x86_64",
        "--ios_cpu=x86_64",
        "--apple_grte_top=//x");
    scratch.file(
        "x/BUILD",
        "objc_library(",
        "   name = 'objc',",
        "   srcs = ['source.m'],",
        ")",
        "filegroup(",
        "    name = 'everything',",
        "    srcs = ['header.h'],",
        ")");
    CommandAction compileAction = compileAction("//x:objc", "source.o");
    assertThat(compileAction.getArguments()).contains("--sysroot=x");
  }

  @Test
  public void testDefaultEnabledFeatureIsUsed() throws Exception {
    // Although using --cpu=ios_x86_64, it transitions to darwin_x86_64, so the actual
    // cc_toolchain in use will be the darwin_x86_64 one.
    MockObjcSupport.setupCcToolchainConfig(
        mockToolsConfig, MockObjcSupport.darwinX86_64().withFeatures("default_feature"));
    useConfiguration(
        "--cpu=ios_x86_64",
        "--ios_cpu=x86_64");
    scratch.file(
        "x/BUILD",
        "objc_library(",
        "   name = 'objc',",
        "   srcs = ['source.m'],",
        ")");
    CommandAction compileAction = compileAction("//x:objc", "source.o");
    assertThat(compileAction.getArguments()).contains("-dummy");
  }

  @Test
  public void testCustomModuleMap() throws Exception {
    checkCustomModuleMapPropagatedByTargetUnderTest(RULE_TYPE);
  }

  private boolean containsObjcFeature(String srcName) throws Exception {
    MockObjcSupport.setupCcToolchainConfig(
        mockToolsConfig, MockObjcSupport.darwinX86_64().withFeatures("contains_objc_sources"));
    createLibraryTargetWriter("//bottom:lib").setList("srcs", srcName).write();
    createLibraryTargetWriter("//middle:lib")
        .setList("srcs", "b.cc")
        .setList("deps", "//bottom:lib")
        .write();
    createLibraryTargetWriter("//top:lib")
        .setList("srcs", "a.cc")
        .setList("deps", "//middle:lib")
        .write();

    CommandAction compileAction = compileAction("//top:lib", "a.o");
    return compileAction.getArguments().contains("DUMMY_FLAG");
  }

  @Test
  public void testObjcSourcesFeatureCC() throws Exception {
    assertThat(containsObjcFeature("c.cc")).isFalse();
  }

  @Test
  public void testObjcSourcesFeatureObjc() throws Exception {
     assertThat(containsObjcFeature("c.m")).isTrue();
  }

  @Test
  public void testObjcSourcesFeatureObjcPlusPlus() throws Exception {
     assertThat(containsObjcFeature("c.mm")).isTrue();
  }

  @Test
  public void testHeaderPassedToCcLib() throws Exception {
    createLibraryTargetWriter("//objc:lib").setList("hdrs", "objc_hdr.h").write();
    ScratchAttributeWriter.fromLabelString(this, "cc_library", "//cc:lib")
        .setList("srcs", "a.cc")
        .setList("deps", "//objc:lib")
        .write();
    CommandAction compileAction = compileAction("//cc:lib", "a.o");
    assertThat(Artifact.toRootRelativePaths(compileAction.getPossibleInputsForTesting()))
        .contains("objc/objc_hdr.h");
  }

  @Test
  public void testTextualHeaderPassedToCcLib() throws Exception {
    ScratchAttributeWriter.fromLabelString(this, "cc_library", "//cc/txt_dep")
        .setList("textual_hdrs", "hdr.h")
        .write();
    createLibraryTargetWriter("//objc:lib").setList("deps", "//cc/txt_dep").write();
    ScratchAttributeWriter.fromLabelString(this, "cc_library", "//cc/lib")
        .setList("srcs", "a.cc")
        .setList("deps", "//objc:lib")
        .write();
    CommandAction compileAction = compileAction("//cc/lib", "a.o");
    assertThat(Artifact.toRootRelativePaths(compileAction.getPossibleInputsForTesting()))
        .contains("cc/txt_dep/hdr.h");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_assetCatalogs() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', asset_catalogs = ['fg'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_datamodels() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', datamodels = ['fg'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_resources() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', resources = ['fg'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_storyboards() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', storyboards = ['fg.storyboard'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_strings() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', strings = ['fg.strings'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_structuredResources() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', structured_resources = ['fg'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_xibs() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', xibs = ['fg.xib'])");
  }

  @Test
  public void testIncompatibleResourceAttributeFlag_resourcesEmpty() throws Exception {
    useConfiguration("--incompatible_disable_objc_library_resources=true");

    checkError(
        "x",
        "x",
        "objc_library resource attributes are not allowed. Please use the 'data' attribute instead",
        "objc_library(name = 'x', resources = [])");
  }

  /** Regression test for https://github.com/bazelbuild/bazel/issues/7721. */
  @Test
  public void testToolchainRuntimeLibrariesSolibDir() throws Exception {
    MockObjcSupport.setupCcToolchainConfig(
        mockToolsConfig,
        MockObjcSupport.darwinX86_64()
            .withFeatures(
                CppRuleClasses.SUPPORTS_INTERFACE_SHARED_LIBRARIES,
                CppRuleClasses.SUPPORTS_DYNAMIC_LINKER));
    scratch.file(
        "foo/BUILD",
        "cc_test(name = 'd', deps = [':b'])",
        "objc_library(name = 'b', deps = [':a'])",
        "cc_library(name = 'a', srcs = ['a.c'])");
    ConfiguredTarget configuredTarget = getConfiguredTarget("//foo:d");
    assertThat(configuredTarget).isNotNull();
  }
}
