aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java230
1 files changed, 16 insertions, 214 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
index aa02e1f23a..8c23b1d575 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProtoLibrary.java
@@ -14,196 +14,49 @@
package com.google.devtools.build.lib.rules.objc;
-import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE;
-import static com.google.common.base.CaseFormat.UPPER_CAMEL;
import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-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.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
-import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.proto.ProtoSourcesProvider;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.util.FileType;
-import com.google.devtools.build.lib.vfs.FileSystemUtils;
-import com.google.devtools.build.lib.vfs.PathFragment;
-
-import javax.annotation.Nullable;
/**
* Implementation for the "objc_proto_library" rule.
*/
public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
- private static final Function<Artifact, PathFragment> PARENT_PATHFRAGMENT =
- new Function<Artifact, PathFragment>() {
- @Override
- public PathFragment apply(Artifact input) {
- return input.getExecPath().getParentDirectory();
- }
- };
-
- @VisibleForTesting
- static final String NO_PROTOS_ERROR =
- "no protos to compile - a non-empty deps attribute is required";
-
- @VisibleForTesting
- static final String FILES_DEPRECATED_WARNING =
- "Using files and filegroups in objc_proto_library is deprecated";
-
@Override
public ConfiguredTarget create(final RuleContext ruleContext) throws InterruptedException {
- Artifact compileProtos = ruleContext.getPrerequisiteArtifact(
- ObjcProtoLibraryRule.COMPILE_PROTOS_ATTR, Mode.HOST);
- Optional<Artifact> optionsFile = Optional.fromNullable(
- ruleContext.getPrerequisiteArtifact(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, Mode.HOST));
-
- NestedSet<Artifact> protos = NestedSetBuilder.<Artifact>stableOrder()
- .addAll(maybeGetProtoFiles(ruleContext))
- .addTransitive(maybeGetProtoSources(ruleContext))
- .build();
-
- if (Iterables.isEmpty(protos)) {
- ruleContext.ruleError(NO_PROTOS_ERROR);
- }
-
- ImmutableList<Artifact> libProtobuf = ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.LIBPROTOBUF_ATTR, Mode.TARGET)
- .list();
- ImmutableList<Artifact> protoSupport = ruleContext
- .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PROTO_SUPPORT_ATTR, Mode.HOST)
- .list();
-
- // Generate sources in a package-and-rule-scoped directory; adds both the
- // package-and-rule-scoped directory and the header-containing-directory to the include path of
- // dependers.
- String uniqueDirectoryName = "_generated_protos";
-
- PathFragment rootRelativeOutputDir = ruleContext.getUniqueDirectory(uniqueDirectoryName);
- PathFragment workspaceRelativeOutputDir = new PathFragment(
- ruleContext.getBinOrGenfilesDirectory().getExecPath(), rootRelativeOutputDir);
- PathFragment generatedProtoDir =
- new PathFragment(workspaceRelativeOutputDir, ruleContext.getLabel().getPackageFragment());
-
- boolean outputCpp =
- ruleContext.attributes().get(ObjcProtoLibraryRule.OUTPUT_CPP_ATTR, Type.BOOLEAN);
-
- boolean useObjcHeaderNames =
- ruleContext.attributes().get(
- ObjcProtoLibraryRule.USE_OBJC_HEADER_NAMES_ATTR, Type.BOOLEAN);
-
- ImmutableList<Artifact> protoGeneratedSources = outputArtifacts(
- ruleContext, uniqueDirectoryName, protos, FileType.of(".pb." + (outputCpp ? "cc" : "m")),
- outputCpp);
- ImmutableList<Artifact> protoGeneratedHeaders = outputArtifacts(
- ruleContext, uniqueDirectoryName, protos,
- FileType.of(".pb" + (useObjcHeaderNames ? "objc.h" : ".h")), outputCpp);
-
- Artifact inputFileList = ruleContext.getUniqueDirectoryArtifact(
- "_protos", "_proto_input_files", ruleContext.getConfiguration().getGenfilesDirectory());
-
- ruleContext.registerAction(new FileWriteAction(
- ruleContext.getActionOwner(),
- inputFileList,
- Artifact.joinExecPaths("\n", protos),
- false));
+ ProtoSupport protoSupport = new ProtoSupport(ruleContext);
- CustomCommandLine.Builder commandLineBuilder = new CustomCommandLine.Builder()
- .add(compileProtos.getExecPathString())
- .add("--input-file-list").add(inputFileList.getExecPathString())
- .add("--output-dir").add(workspaceRelativeOutputDir.getSafePathString())
- .add("--working-dir").add(".");
- if (optionsFile.isPresent()) {
- commandLineBuilder
- .add("--compiler-options-path")
- .add(optionsFile.get().getExecPathString());
- }
- if (outputCpp) {
- commandLineBuilder.add("--generate-cpp");
- }
- if (useObjcHeaderNames) {
- commandLineBuilder.add("--use-objc-header-names");
- }
-
- if (!Iterables.isEmpty(protos)) {
- ruleContext.registerAction(ObjcRuleClasses.spawnOnDarwinActionBuilder()
- .setMnemonic("GenObjcProtos")
- .addInput(compileProtos)
- .addInputs(optionsFile.asSet())
- .addInputs(protos)
- .addInput(inputFileList)
- .addInputs(libProtobuf)
- .addInputs(protoSupport)
- .addOutputs(Iterables.concat(protoGeneratedSources, protoGeneratedHeaders))
- .setExecutable(new PathFragment("/usr/bin/python"))
- .setCommandLine(commandLineBuilder.build())
- .build(ruleContext));
- }
+ ObjcCommon.Builder commonBuilder = new ObjcCommon.Builder(ruleContext);
+ XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
+ NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
- IntermediateArtifacts intermediateArtifacts =
- ObjcRuleClasses.intermediateArtifacts(ruleContext);
- CompilationArtifacts compilationArtifacts = new CompilationArtifacts.Builder()
- .addNonArcSrcs(protoGeneratedSources)
- .setIntermediateArtifacts(intermediateArtifacts)
- .setPchFile(Optional.<Artifact>absent())
- .addAdditionalHdrs(protoGeneratedHeaders)
- .addAdditionalHdrs(protoGeneratedSources)
- .build();
+ protoSupport
+ .validate()
+ .addCommonOptions(commonBuilder)
+ .addXcodeProviderOptions(xcodeProviderBuilder)
+ .addFilesToBuild(filesToBuild)
+ .registerActions();
- ImmutableSet.Builder<PathFragment> searchPathEntriesBuilder =
- new ImmutableSet.Builder<PathFragment>()
- .add(workspaceRelativeOutputDir);
- if (ruleContext.attributes().get(
- ObjcProtoLibraryRule.PER_PROTO_INCLUDES, Type.BOOLEAN)) {
- searchPathEntriesBuilder
- .add(generatedProtoDir)
- .addAll(Iterables.transform(protoGeneratedHeaders, PARENT_PATHFRAGMENT));
+ if (ruleContext.hasErrors()) {
+ return null;
}
- ImmutableSet<PathFragment> searchPathEntries = searchPathEntriesBuilder.build();
- ObjcCommon common =
- new ObjcCommon.Builder(ruleContext)
- .setCompilationArtifacts(compilationArtifacts)
- .addUserHeaderSearchPaths(searchPathEntries)
- .addDepObjcProviders(
- ruleContext.getPrerequisites(
- ObjcProtoLibraryRule.LIBPROTOBUF_ATTR, Mode.TARGET, ObjcProvider.class))
- .setIntermediateArtifacts(intermediateArtifacts)
- .setHasModuleMap()
- .build();
+ ObjcCommon common = commonBuilder.build();
- NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder()
- .addAll(common.getCompiledArchive().asSet())
- .addAll(protoGeneratedSources)
- .addAll(protoGeneratedHeaders);
+ filesToBuild.addAll(common.getCompiledArchive().asSet());
- ObjcConfiguration configuration = ObjcRuleClasses.objcConfiguration(ruleContext);
- XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder()
- .addUserHeaderSearchPaths(searchPathEntries)
- .addCopts(configuration.getCopts())
- .addHeaders(protoGeneratedHeaders)
- .setCompilationArtifacts(common.getCompilationArtifacts().get());
-
- new CompilationSupport(ruleContext)
- .registerCompileAndArchiveActions(common);
+ new CompilationSupport(ruleContext).registerCompileAndArchiveActions(commonBuilder.build());
new XcodeSupport(ruleContext)
.addFilesToBuild(filesToBuild)
.addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC)
.addDependencies(
- xcodeProviderBuilder, new Attribute(ObjcProtoLibraryRule.LIBPROTOBUF_ATTR, Mode.TARGET))
+ xcodeProviderBuilder, new Attribute(ObjcProtoLibraryRule.PROTO_LIB_ATTR, Mode.TARGET))
.registerActions(xcodeProviderBuilder.build());
return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
@@ -211,55 +64,4 @@ public class ObjcProtoLibrary implements RuleConfiguredTargetFactory {
.addProvider(ObjcProvider.class, common.getObjcProvider())
.build();
}
-
- /**
- * Get .proto files added to the deps attribute. This is for backwards compatibility,
- * and emits a warning.
- */
- private ImmutableList<Artifact> maybeGetProtoFiles(RuleContext ruleContext) {
- PrerequisiteArtifacts prerequisiteArtifacts =
- ruleContext.getPrerequisiteArtifacts("deps", Mode.TARGET);
- ImmutableList<Artifact> protoFiles = prerequisiteArtifacts.filter(FileType.of(".proto")).list();
- if (!protoFiles.isEmpty()) {
- ruleContext.attributeWarning("deps", FILES_DEPRECATED_WARNING);
- }
- return protoFiles;
- }
-
- private NestedSet<Artifact> maybeGetProtoSources(RuleContext ruleContext) {
- NestedSetBuilder<Artifact> artifacts = new NestedSetBuilder<>(Order.STABLE_ORDER);
- Iterable<ProtoSourcesProvider> providers =
- ruleContext.getPrerequisites("deps", Mode.TARGET, ProtoSourcesProvider.class);
- for (ProtoSourcesProvider provider : providers) {
- artifacts.addTransitive(provider.getTransitiveProtoSources());
- }
- return artifacts.build();
- }
-
- private ImmutableList<Artifact> outputArtifacts(RuleContext ruleContext,
- String uniqueDirectoryName, Iterable<Artifact> protos, FileType newFileType,
- boolean outputCpp) {
- ImmutableList.Builder<Artifact> builder = new ImmutableList.Builder<>();
- for (Artifact proto : protos) {
- String protoOutputName;
- if (outputCpp) {
- protoOutputName = proto.getFilename();
- } else {
- String lowerUnderscoreBaseName = proto.getFilename().replace('-', '_').toLowerCase();
- protoOutputName = LOWER_UNDERSCORE.to(UPPER_CAMEL, lowerUnderscoreBaseName);
- }
- PathFragment rawFragment = new PathFragment(
- proto.getRootRelativePath().getParentDirectory(),
- new PathFragment(protoOutputName));
- @Nullable PathFragment outputFile = FileSystemUtils.replaceExtension(
- rawFragment,
- newFileType.getExtensions().get(0),
- ".proto");
- if (outputFile != null) {
- builder.add(ruleContext.getUniqueDirectoryArtifact(uniqueDirectoryName,
- outputFile, ruleContext.getBinOrGenfilesDirectory()));
- }
- }
- return builder.build();
- }
}