aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
blob: e2d057d99057df47c3e2036a6d1f442025ad905f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2015 Google Inc. 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.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;

import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;

/**
 * Support for Objc rule types that export an Xcode provider or generate xcode project files.
 *
 * <p>Methods on this class can be called in any order without impacting the result.
 */
public final class XcodeSupport {

  /**
   * Template for a target's xcode project.
   */
  public static final SafeImplicitOutputsFunction PBXPROJ =
      fromTemplates("%{name}.xcodeproj/project.pbxproj");

  private final RuleContext ruleContext;

  /**
   * Creates a new xcode support for the given context.
   */
  XcodeSupport(RuleContext ruleContext) {
    this.ruleContext = ruleContext;
  }

  /**
   * Adds xcode project files to the given builder.
   *
   * @return this xcode support
   */
  XcodeSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild) {
    filesToBuild.add(ruleContext.getImplicitOutputArtifact(PBXPROJ));
    return this;
  }

  /**
   * Adds a dummy source file to the Xcode target. This is needed if the target does not have any
   * source files but Xcode requires one.
   *
   * @return this xcode support
   */
  XcodeSupport addDummySource(XcodeProvider.Builder xcodeProviderBuilder) {
    xcodeProviderBuilder.addAdditionalSources(
        ruleContext.getPrerequisiteArtifact("$dummy_source", Mode.TARGET));
    return this;
  }

  /**
   * Registers actions that generate the rule's Xcode project.
   *
   * @param xcodeProvider information about this rule's xcode settings and that of its dependencies
   * @return this xcode support
   */
  XcodeSupport registerActions(XcodeProvider xcodeProvider) {
    ObjcActionsBuilder actionsBuilder = ObjcRuleClasses.actionsBuilder(ruleContext);
    actionsBuilder.registerXcodegenActions(
        new ObjcRuleClasses.Tools(ruleContext),
        ruleContext.getImplicitOutputArtifact(XcodeSupport.PBXPROJ),
        XcodeProvider.Project.fromTopLevelTarget(xcodeProvider));
    return this;
  }

  /**
   * Adds common xcode settings to the given provider builder.
   *
   * @param objcProvider provider containing all dependencies' information as well as some of this
   *    rule's
   * @param productType type of this rule's Xcode target
   *
   * @return this xcode support
   */
  XcodeSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder,
      ObjcProvider objcProvider, XcodeProductType productType) {
    xcodeProviderBuilder
        .setLabel(ruleContext.getLabel())
        .setArchitecture(ObjcRuleClasses.objcConfiguration(ruleContext).getIosCpu())
        .setObjcProvider(objcProvider)
        .setProductType(productType);
    return this;
  }

  /**
   * Adds dependencies to the given provider builder from the given attribute.
   *
   * @return this xcode support
   */
  XcodeSupport addDependencies(Builder xcodeProviderBuilder, Attribute attribute) {
    xcodeProviderBuilder.addPropagatedDependencies(
        ruleContext.getPrerequisites(
            attribute.getName(), attribute.getAccessMode(), XcodeProvider.class),
        ObjcRuleClasses.objcConfiguration(ruleContext));
    return this;
  }

  /**
   * Adds non-propagated dependencies to the given provider builder from the given attribute.
   *
   * <p>A non-propagated dependency will not be linked into the final app bundle and can only serve
   * as a compile-only dependency for its direct dependent.
   *
   * @return this xcode support
   */
  XcodeSupport addNonPropagatedDependencies(Builder xcodeProviderBuilder, Attribute attribute) {
    xcodeProviderBuilder.addNonPropagatedDependencies(
        ruleContext.getPrerequisites(
            attribute.getName(), attribute.getAccessMode(), XcodeProvider.class),
        ObjcRuleClasses.objcConfiguration(ruleContext));
    return this;
  }

  /**
   * Generates an extra {@link XcodeProductType#LIBRARY_STATIC} Xcode target with the same
   * compilation artifacts as the main Xcode target associated with this Xcode support. The extra
   * Xcode library target, instead of the main Xcode target, will act as a dependency for all
   * dependent Xcode targets.
   *
   * <p>This is needed to build the Xcode binary target generated by ios_application in XCode.
   * Currently there is an Xcode target dependency between the binary target from ios_application
   * and the binary target from objc_binary. But Xcode does not link in compiled artifacts from
   * binary dependencies, so any sources specified on objc_binary rules will not be compiled and
   * linked into the app bundle in dependent binary targets associated with ios_application in
   * XCode.
   */
  // TODO(bazel-team): Remove this when the binary rule types and bundling rule types are merged.
  XcodeSupport generateCompanionLibXcodeTarget(Builder xcodeProviderBuilder) {
    xcodeProviderBuilder.generateCompanionLibTarget();
    return this;
  }
}