aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Rumou Duan <rduan@google.com>2016-07-27 15:14:29 +0000
committerGravatar Adam Michael <ajmichael@google.com>2016-07-28 18:36:29 -0400
commit009e05956acde1e9d61befad72f25375a5bad57b (patch)
tree8a14ae6bc171e8c98c71701104034af1912b515c /src/main/java/com
parent1b7abbf17405e7168272ab91fef13550cdbef5cc (diff)
Experimental java annotation support with unpredictable action inputs/outputs in j2objc_library behind flag --experimental_j2objc_annotation_processing
Also added flag --experimental_zip_tree_artifact to switch on and off the zipping implementation of tree artifact generation. -- MOS_MIGRATED_REVID=128586669
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/Artifact.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java43
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java346
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java167
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java27
9 files changed, 553 insertions, 116 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
index bbea1f5ed1..374f8872ba 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java
@@ -36,12 +36,10 @@ import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
-
import javax.annotation.Nullable;
/**
@@ -155,6 +153,16 @@ public class Artifact
}
};
+ /**
+ * A Predicate that evaluates to true if the Artifact <b>is</b> a tree artifact.
+ */
+ public static final Predicate<Artifact> IS_TREE_ARTIFACT = new Predicate<Artifact>() {
+ @Override
+ public boolean apply(Artifact input) {
+ return input.isTreeArtifact();
+ }
+ };
+
private final int hashCode;
private final Path path;
private final Root root;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
index 793069ec37..d314388fe4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/CustomCommandLine.java
@@ -27,13 +27,11 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
-
import javax.annotation.Nullable;
/**
@@ -136,7 +134,7 @@ public final class CustomCommandLine extends CommandLine {
void eval(ImmutableList.Builder<String> builder, ArtifactExpander artifactExpander) {
Set<Artifact> expandedArtifacts = new TreeSet<>();
artifactExpander.expand(treeArtifact, expandedArtifacts);
-
+
if (!expandedArtifacts.isEmpty()) {
builder.add(Artifact.joinExecPaths(delimiter, expandedArtifacts));
}
@@ -151,6 +149,34 @@ public final class CustomCommandLine extends CommandLine {
}
}
+ private static final class ExpandedTreeArtifactExecPathsArg
+ extends TreeArtifactExpansionArgvFragment {
+ private final Artifact treeArtifact;
+
+ private ExpandedTreeArtifactExecPathsArg(Artifact treeArtifact) {
+ Preconditions.checkArgument(
+ treeArtifact.isTreeArtifact(), "%s is not a TreeArtifact", treeArtifact);
+ this.treeArtifact = treeArtifact;
+ }
+
+ @Override
+ void eval(ImmutableList.Builder<String> builder, ArtifactExpander artifactExpander) {
+ Set<Artifact> expandedArtifacts = new TreeSet<>();
+ artifactExpander.expand(treeArtifact, expandedArtifacts);
+
+ for (Artifact expandedArtifact : expandedArtifacts) {
+ builder.add(expandedArtifact.getExecPathString());
+ }
+ }
+
+ @Override
+ public String describe() {
+ return String.format(
+ "ExpandedTreeArtifactExecPathsArg{ treeArtifact: %s}",
+ treeArtifact.getExecPathString());
+ }
+ }
+
private static final class PathWithTemplateArg extends ArgvFragment {
private final String template;
@@ -515,6 +541,17 @@ public final class CustomCommandLine extends CommandLine {
return this;
}
+ /**
+ * Adds the exec paths (one argument per exec path) of all {@link TreeFileArtifact}s under
+ * {@code treeArtifact}.
+ *
+ * @param treeArtifact the TreeArtifact containing the {@link TreeFileArtifact}s to add.
+ */
+ public Builder addExpandedTreeArtifactExecPaths(Artifact treeArtifact) {
+ arguments.add(new ExpandedTreeArtifactExecPathsArg(treeArtifact));
+ return this;
+ }
+
public Builder addBeforeEachPath(String repeated, Iterable<PathFragment> paths) {
if (repeated != null && paths != null) {
arguments.add(InterspersingArgs.fromStrings(paths, repeated, /*formatEach=*/ null));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
index 183da379fc..817ee99c60 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModuleMapAction.java
@@ -16,15 +16,17 @@ package com.google.devtools.build.lib.rules.cpp;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction;
+import com.google.devtools.build.lib.analysis.actions.AbstractFileWriteAction.DeterministicWriter;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
@@ -72,7 +74,13 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
boolean moduleMapHomeIsCwd,
boolean generateSubmodules,
boolean externDependencies) {
- super(owner, ImmutableList.<Artifact>of(), cppModuleMap.getArtifact(),
+ super(
+ owner,
+ ImmutableList.<Artifact>builder()
+ .addAll(Iterables.filter(privateHeaders, Artifact.IS_TREE_ARTIFACT))
+ .addAll(Iterables.filter(publicHeaders, Artifact.IS_TREE_ARTIFACT))
+ .build(),
+ cppModuleMap.getArtifact(),
/*makeExecutable=*/false);
this.cppModuleMap = cppModuleMap;
this.moduleMapHomeIsCwd = moduleMapHomeIsCwd;
@@ -87,6 +95,7 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
@Override
public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) {
+ final ArtifactExpander artifactExpander = ctx.getArtifactExpander();
return new DeterministicWriter() {
@Override
public void writeOutputFile(OutputStream out) throws IOException {
@@ -101,11 +110,11 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
content.append(" export *\n");
HashSet<PathFragment> deduper = new HashSet<>();
- for (Artifact artifact : publicHeaders) {
+ for (Artifact artifact : expandedHeaders(artifactExpander, publicHeaders)) {
appendHeader(
content, "", artifact.getExecPath(), leadingPeriods, /*canCompile=*/ true, deduper);
}
- for (Artifact artifact : privateHeaders) {
+ for (Artifact artifact : expandedHeaders(artifactExpander, privateHeaders)) {
appendHeader(
content,
"private",
@@ -137,7 +146,21 @@ public final class CppModuleMapAction extends AbstractFileWriteAction {
}
};
}
-
+
+ private static Iterable<Artifact> expandedHeaders(ArtifactExpander artifactExpander,
+ Iterable<Artifact> unexpandedHeaders) {
+ List<Artifact> expandedHeaders = new ArrayList<>();
+ for (Artifact unexpandedHeader : unexpandedHeaders) {
+ if (unexpandedHeader.isTreeArtifact()) {
+ artifactExpander.expand(unexpandedHeader, expandedHeaders);
+ } else {
+ expandedHeaders.add(unexpandedHeader);
+ }
+ }
+
+ return ImmutableList.copyOf(expandedHeaders);
+ }
+
private void appendHeader(StringBuilder content, String visibilitySpecifier, PathFragment path,
String leadingPeriods, boolean canCompile, HashSet<PathFragment> deduper) {
if (deduper.contains(path)) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index 056dd97934..97a4b01d6e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -55,9 +55,9 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
@@ -66,9 +66,10 @@ 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.CommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
+import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate.OutputPathMapper;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -180,10 +181,17 @@ public final class CompilationSupport {
new Predicate<Artifact>() {
@Override
public boolean apply(Artifact artifact) {
- // The current clang (clang-600.0.57) on Darwin doesn't support 'textual', so we can't
- // have '.inc' files in the module map (since they're implictly textual).
- // TODO(bazel-team): Use HEADERS file type once clang-700 is the base clang we support.
- return artifact.getFilename().endsWith(".h");
+ if (artifact.isTreeArtifact()) {
+ // Tree artifact is basically a directory, which does not have any information about
+ // the contained files and their extensions. Here we assume the passed in tree artifact
+ // contains proper header files with .h extension.
+ return true;
+ } else {
+ // The current clang (clang-600.0.57) on Darwin doesn't support 'textual', so we can't
+ // have '.inc' files in the module map (since they're implictly textual).
+ // TODO(bazel-team): Use HEADERS file type once clang-700 is the base clang we support.
+ return artifact.getFilename().endsWith(".h");
+ }
}
};
@@ -234,6 +242,19 @@ public final class CompilationSupport {
static final ImmutableList<String> DEFAULT_LINKER_FLAGS = ImmutableList.of("-ObjC");
/**
+ * A mapper that maps input ObjC source {@link Artifact.TreeFileArtifact}s to output
+ * object file {@link Artifact.TreeFileArtifact}s.
+ */
+ private static final OutputPathMapper COMPILE_ACTION_TEMPLATE_OUTPUT_PATH_MAPPER =
+ new OutputPathMapper() {
+ @Override
+ public PathFragment parentRelativeOutputPath(TreeFileArtifact inputTreeFileArtifact) {
+ return FileSystemUtils.replaceExtension(
+ inputTreeFileArtifact.getParentRelativePath(), ".o");
+ }
+ };
+
+ /**
* Returns information about the given rule's compilation artifacts.
*/
// TODO(bazel-team): Remove this information from ObjcCommon and move it internal to this class.
@@ -398,8 +419,7 @@ public final class CompilationSupport {
common.getObjcProvider(),
extraCompileArgs,
priorityHeaders,
- moduleMap,
- buildConfiguration.isCodeCoverageEnabled());
+ moduleMap);
}
return this;
}
@@ -413,8 +433,7 @@ public final class CompilationSupport {
ObjcProvider objcProvider,
ExtraCompileArgs extraCompileArgs,
Iterable<PathFragment> priorityHeaders,
- Optional<CppModuleMap> moduleMap,
- boolean isCodeCoverageEnabled) {
+ Optional<CppModuleMap> moduleMap) {
ImmutableList.Builder<Artifact> objFiles = new ImmutableList.Builder<>();
for (Artifact sourceFile : compilationArtifacts.getSrcs()) {
Artifact objFile = intermediateArtifacts.objFile(sourceFile);
@@ -422,30 +441,50 @@ public final class CompilationSupport {
if (ObjcRuleClasses.SWIFT_SOURCES.matches(sourceFile.getFilename())) {
registerSwiftCompileAction(sourceFile, objFile, objcProvider);
} else {
+ if (objFile.isTreeArtifact()) {
+ registerCompileActionTemplate(
+ sourceFile,
+ objFile,
+ objcProvider,
+ priorityHeaders,
+ moduleMap,
+ compilationArtifacts,
+ Iterables.concat(extraCompileArgs, ImmutableList.of("-fobjc-arc")));
+ } else {
+ registerCompileAction(
+ sourceFile,
+ objFile,
+ objcProvider,
+ priorityHeaders,
+ moduleMap,
+ compilationArtifacts,
+ Iterables.concat(extraCompileArgs, ImmutableList.of("-fobjc-arc")));
+ }
+ }
+ }
+ for (Artifact nonArcSourceFile : compilationArtifacts.getNonArcSrcs()) {
+ Artifact objFile = intermediateArtifacts.objFile(nonArcSourceFile);
+ objFiles.add(objFile);
+ if (objFile.isTreeArtifact()) {
+ registerCompileActionTemplate(
+ nonArcSourceFile,
+ objFile,
+ objcProvider,
+ priorityHeaders,
+ moduleMap,
+ compilationArtifacts,
+ Iterables.concat(extraCompileArgs, ImmutableList.of("-fno-objc-arc")));
+ } else {
registerCompileAction(
- sourceFile,
+ nonArcSourceFile,
objFile,
objcProvider,
priorityHeaders,
moduleMap,
compilationArtifacts,
- Iterables.concat(extraCompileArgs, ImmutableList.of("-fobjc-arc")),
- isCodeCoverageEnabled);
+ Iterables.concat(extraCompileArgs, ImmutableList.of("-fno-objc-arc")));
}
}
- for (Artifact nonArcSourceFile : compilationArtifacts.getNonArcSrcs()) {
- Artifact objFile = intermediateArtifacts.objFile(nonArcSourceFile);
- objFiles.add(objFile);
- registerCompileAction(
- nonArcSourceFile,
- objFile,
- objcProvider,
- priorityHeaders,
- moduleMap,
- compilationArtifacts,
- Iterables.concat(extraCompileArgs, ImmutableList.of("-fno-objc-arc")),
- isCodeCoverageEnabled);
- }
objFiles.addAll(compilationArtifacts.getPrecompiledSrcs());
@@ -454,7 +493,7 @@ public final class CompilationSupport {
}
for (Artifact archive : compilationArtifacts.getArchive().asSet()) {
- registerArchiveActions(objFiles, archive);
+ registerArchiveActions(objFiles.build(), archive);
}
}
@@ -478,35 +517,30 @@ public final class CompilationSupport {
return addSource(commandLine, sourceFile);
}
- private void registerCompileAction(
+ private CustomCommandLine compileActionCommandLine(
Artifact sourceFile,
Artifact objFile,
ObjcProvider objcProvider,
Iterable<PathFragment> priorityHeaders,
Optional<CppModuleMap> moduleMap,
- CompilationArtifacts compilationArtifacts,
+ Optional<Artifact> pchFile,
+ Optional<Artifact> dotdFile,
Iterable<String> otherFlags,
- boolean isCodeCoverageEnabled) {
- ImmutableList.Builder<String> coverageFlags = new ImmutableList.Builder<>();
- ImmutableList.Builder<Artifact> gcnoFiles = new ImmutableList.Builder<>();
- ImmutableList.Builder<Artifact> additionalInputs = new ImmutableList.Builder<>();
- if (isCodeCoverageEnabled && ObjcRuleClasses.isInstrumentable(sourceFile)) {
- coverageFlags.addAll(CLANG_COVERAGE_FLAGS);
- gcnoFiles.add(intermediateArtifacts.gcnoFile(sourceFile));
- }
- CustomCommandLine.Builder commandLine = new CustomCommandLine.Builder()
- .add(CLANG);
- if (ObjcRuleClasses.CPP_SOURCES.matches(sourceFile.getExecPath())) {
+ boolean collectCodeCoverage,
+ boolean isCPlusPlusSource,
+ boolean hasSwiftSources) {
+ CustomCommandLine.Builder commandLine = new CustomCommandLine.Builder().add(CLANG);
+
+ if (isCPlusPlusSource) {
commandLine.add("-stdlib=libc++");
commandLine.add("-std=gnu++11");
}
- if (compilationArtifacts.hasSwiftSources()) {
+ if (hasSwiftSources) {
// Add the directory that contains merged TargetName-Swift.h header to search path, in case
// any of ObjC files use it.
commandLine.add("-I");
commandLine.addPath(intermediateArtifacts.swiftHeader().getExecPath().getParentDirectory());
- additionalInputs.add(intermediateArtifacts.swiftHeader());
}
// The linker needs full debug symbol information to perform binary dead-code stripping.
@@ -514,35 +548,67 @@ public final class CompilationSupport {
commandLine.add("-g");
}
- Artifact dotdFile = intermediateArtifacts.dotdFile(sourceFile);
+ List<String> coverageFlags = ImmutableList.of();
+ if (collectCodeCoverage) {
+ coverageFlags = CLANG_COVERAGE_FLAGS;
+ }
+
commandLine
.add(compileFlagsForClang(appleConfiguration))
.add(commonLinkAndCompileFlagsForClang(objcProvider, objcConfiguration, appleConfiguration))
.add(objcConfiguration.getCoptsForCompilationMode())
.addBeforeEachPath("-iquote", ObjcCommon.userHeaderSearchPaths(buildConfiguration))
- .addBeforeEachExecPath("-include", compilationArtifacts.getPchFile().asSet())
+ .addBeforeEachExecPath("-include", pchFile.asSet())
.addBeforeEachPath("-I", priorityHeaders)
.addBeforeEachPath("-I", objcProvider.get(INCLUDE))
.addBeforeEachPath("-isystem", objcProvider.get(INCLUDE_SYSTEM))
.add(otherFlags)
.addFormatEach("-D%s", objcProvider.get(DEFINE))
- .add(coverageFlags.build())
+ .add(coverageFlags)
.add(getCompileRuleCopts());
- PathFragment sourceExecPathFragment = sourceFile.getExecPath();
- String sourcePath = sourceExecPathFragment.getPathString();
- if (!sourceExecPathFragment.isAbsolute() && objcConfiguration.getUseAbsolutePathsForActions()) {
- sourcePath = objcConfiguration.getXcodeWorkspaceRoot() + "/" + sourcePath;
+
+ // Add input source file arguments
+ commandLine.add("-c");
+ if (!sourceFile.getExecPath().isAbsolute()
+ && objcConfiguration.getUseAbsolutePathsForActions()) {
+ String workspaceRoot = objcConfiguration.getXcodeWorkspaceRoot();
+
+ // If the source file is a tree artifact, it means the file is basically a directory that may
+ // contain multiple concrete source files at execution time. When constructing the command
+ // line, we insert the source tree artifact as a placeholder, which will be replaced with
+ // one of its contained source files of type {@link Artifact.TreeFileArtifact} at execution
+ // time.
+ //
+ // We also do something similar for the object file arguments below.
+ if (sourceFile.isTreeArtifact()) {
+ commandLine.addPlaceholderTreeArtifactFormattedExecPath(workspaceRoot + "/%s", sourceFile);
+ } else {
+ commandLine.addPaths(workspaceRoot + "/%s", sourceFile.getExecPath());
+ }
+ } else {
+ if (sourceFile.isTreeArtifact()) {
+ commandLine.addPlaceholderTreeArtifactExecPath(sourceFile);
+ } else {
+ commandLine.addPath(sourceFile.getExecPath());
+ }
}
- commandLine
- .add("-c").add(sourcePath)
- .addExecPath("-o", objFile)
- .add("-MD")
- .addExecPath("-MF", dotdFile);
- if (objcConfiguration.moduleMapsEnabled()) {
- additionalInputs.addAll(objcProvider.get(MODULE_MAP));
+ // Add output object file arguments.
+ commandLine.add("-o");
+ if (objFile.isTreeArtifact()) {
+ commandLine.addPlaceholderTreeArtifactExecPath(objFile);
+ } else {
+ commandLine.addPath(objFile.getExecPath());
+ }
+
+ // Add Dotd file arguments.
+ if (dotdFile.isPresent()) {
+ commandLine
+ .add("-MD")
+ .addExecPath("-MF", dotdFile.get());
}
+ // Add module map arguments.
if (moduleMap.isPresent()) {
// If modules are enabled for the rule, -fmodules is added to the copts already. (This implies
// module map usage). Otherwise, we need to pass -fmodule-maps.
@@ -564,18 +630,63 @@ public final class CompilationSupport {
.add("-fmodule-name=" + moduleMap.get().getName());
}
+ return commandLine.build();
+ }
+
+ private void registerCompileAction(
+ Artifact sourceFile,
+ Artifact objFile,
+ ObjcProvider objcProvider,
+ Iterable<PathFragment> priorityHeaders,
+ Optional<CppModuleMap> moduleMap,
+ CompilationArtifacts compilationArtifacts,
+ Iterable<String> otherFlags) {
+ boolean isCPlusPlusSource = ObjcRuleClasses.CPP_SOURCES.matches(sourceFile.getExecPath());
+ boolean runCodeCoverage =
+ buildConfiguration.isCodeCoverageEnabled() && ObjcRuleClasses.isInstrumentable(sourceFile);
+ boolean hasSwiftSources = compilationArtifacts.hasSwiftSources();
+
+ CustomCommandLine commandLine = compileActionCommandLine(
+ sourceFile,
+ objFile,
+ objcProvider,
+ priorityHeaders,
+ moduleMap,
+ compilationArtifacts.getPchFile(),
+ Optional.of(intermediateArtifacts.dotdFile(sourceFile)),
+ otherFlags,
+ runCodeCoverage,
+ isCPlusPlusSource,
+ hasSwiftSources);
+
+ Optional<Artifact> gcnoFile = Optional.absent();
+ if (runCodeCoverage) {
+ gcnoFile = Optional.of(intermediateArtifacts.gcnoFile(sourceFile));
+ }
+
+ Optional<Artifact> swiftHeader = Optional.absent();
+ if (hasSwiftSources) {
+ swiftHeader = Optional.of(intermediateArtifacts.swiftHeader());
+ }
+
+ NestedSet<Artifact> moduleMapInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
+ if (objcConfiguration.moduleMapsEnabled()) {
+ moduleMapInputs = objcProvider.get(MODULE_MAP);
+ }
+
// TODO(bazel-team): Remote private headers from inputs once they're added to the provider.
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcCompile")
.setExecutable(xcrunwrapper(ruleContext))
- .setCommandLine(commandLine.build())
+ .setCommandLine(commandLine)
.addInput(sourceFile)
- .addInputs(additionalInputs.build())
+ .addInputs(swiftHeader.asSet())
+ .addTransitiveInputs(moduleMapInputs)
.addOutput(objFile)
- .addOutputs(gcnoFiles.build())
- .addOutput(dotdFile)
+ .addOutputs(gcnoFile.asSet())
+ .addOutput(intermediateArtifacts.dotdFile(sourceFile))
.addTransitiveInputs(objcProvider.get(HEADER))
.addInputs(compilationArtifacts.getPrivateHdrs())
.addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE))
@@ -585,6 +696,69 @@ public final class CompilationSupport {
}
/**
+ * Registers a SpawnActionTemplate to compile the source file tree artifact, {@code sourceFiles},
+ * which can contain multiple concrete source files unknown at analysis time. At execution time,
+ * the SpawnActionTemplate will register one ObjcCompile action for each individual source file
+ * under {@code sourceFiles}.
+ *
+ * <p>Note that this method currently does not support code coverage and sources other than ObjC
+ * sources.
+ *
+ * @param sourceFiles tree artifact containing source files to compile
+ * @param objFiles tree artifact containing object files compiled from {@code sourceFiles}
+ * @param objcProvider ObjcProvider instance for this invocation
+ * @param priorityHeaders priority headers to be included before the dependency headers
+ * @param moduleMap the module map generated from the associated headers
+ * @param compilationArtifacts the CompilationArtifacts instance for this invocation
+ * @param otherFlags extra compilation flags to add to the compile action command line
+ */
+ private void registerCompileActionTemplate(
+ Artifact sourceFiles,
+ Artifact objFiles,
+ ObjcProvider objcProvider,
+ Iterable<PathFragment> priorityHeaders,
+ Optional<CppModuleMap> moduleMap,
+ CompilationArtifacts compilationArtifacts,
+ Iterable<String> otherFlags) {
+ CustomCommandLine commandLine = compileActionCommandLine(
+ sourceFiles,
+ objFiles,
+ objcProvider,
+ priorityHeaders,
+ moduleMap,
+ compilationArtifacts.getPchFile(),
+ Optional.<Artifact>absent(),
+ otherFlags,
+ /* runCodeCoverage=*/false,
+ /* isCPlusPlusSource=*/false,
+ /* hasSwiftSources=*/false);
+
+ AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
+ Platform platform = appleConfiguration.getSingleArchPlatform();
+
+ NestedSet<Artifact> moduleMapInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
+ if (objcConfiguration.moduleMapsEnabled()) {
+ moduleMapInputs = objcProvider.get(MODULE_MAP);
+ }
+
+ ruleContext.registerAction(
+ new SpawnActionTemplate.Builder(sourceFiles, objFiles)
+ .setMnemonics("ObjcCompileActionTemplate", "ObjcCompile")
+ .setExecutable(xcrunwrapper(ruleContext))
+ .setCommandLineTemplate(commandLine)
+ .setEnvironment(ObjcRuleClasses.appleToolchainEnvironment(appleConfiguration, platform))
+ .setExecutionInfo(ObjcRuleClasses.darwinActionExecutionRequirement())
+ .setOutputPathMapper(COMPILE_ACTION_TEMPLATE_OUTPUT_PATH_MAPPER)
+ .addCommonTransitiveInputs(objcProvider.get(HEADER))
+ .addCommonTransitiveInputs(moduleMapInputs)
+ .addCommonInputs(compilationArtifacts.getPrivateHdrs())
+ .addCommonTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE))
+ .addCommonTransitiveInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE))
+ .addCommonInputs(compilationArtifacts.getPchFile().asSet())
+ .build(ruleContext.getActionOwner()));
+ }
+
+ /**
* Returns the copts for the compile action in the current rule context (using a combination
* of the rule's "copts" attribute as well as the current configuration copts).
*/
@@ -779,23 +953,17 @@ public final class CompilationSupport {
.build(ruleContext));
}
- private void registerArchiveActions(ImmutableList.Builder<Artifact> objFiles, Artifact archive) {
- for (Action action :
- archiveActions(objFiles.build(), archive, intermediateArtifacts.archiveObjList())) {
- ruleContext.registerAction(action);
- }
+ private void registerArchiveActions(List<Artifact> objFiles, Artifact archive) {
+ Artifact objList = intermediateArtifacts.archiveObjList();
+ registerObjFilelistAction(objFiles, objList);
+ registerArchiveAction(objFiles, archive);
}
- private Iterable<Action> archiveActions(
+ private void registerArchiveAction(
Iterable<Artifact> objFiles,
- Artifact archive,
- Artifact objList) {
-
- ImmutableList.Builder<Action> actions = new ImmutableList.Builder<>();
-
- actions.add(objFilelistAction(objFiles, objList));
-
- actions.add(ObjcRuleClasses.spawnAppleEnvActionBuilder(
+ Artifact archive) {
+ Artifact objList = intermediateArtifacts.archiveObjList();
+ ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
appleConfiguration, appleConfiguration.getSingleArchPlatform())
.setMnemonic("ObjcLink")
.setExecutable(libtool(ruleContext))
@@ -810,17 +978,31 @@ public final class CompilationSupport {
.addInput(objList)
.addOutput(archive)
.build(ruleContext));
-
- return actions.build();
}
- private Action objFilelistAction(Iterable<Artifact> objFiles, Artifact objList) {
+ private void registerObjFilelistAction(Iterable<Artifact> objFiles, Artifact objList) {
ImmutableSet<Artifact> dedupedObjFiles = ImmutableSet.copyOf(objFiles);
- return new FileWriteAction(
+ CustomCommandLine.Builder objFilesToLinkParam = new CustomCommandLine.Builder();
+ ImmutableList.Builder<Artifact> treeObjFiles = new ImmutableList.Builder<>();
+
+ for (Artifact objFile : dedupedObjFiles) {
+ // If the obj file is a tree artifact, we need to expand it into the contained individual
+ // files properly.
+ if (objFile.isTreeArtifact()) {
+ treeObjFiles.add(objFile);
+ objFilesToLinkParam.addExpandedTreeArtifactExecPaths(objFile);
+ } else {
+ objFilesToLinkParam.addPath(objFile.getExecPath());
+ }
+ }
+
+ ruleContext.registerAction(new ParameterFileWriteAction(
ruleContext.getActionOwner(),
+ treeObjFiles.build(),
objList,
- Artifact.joinExecPaths("\n", dedupedObjFiles),
- /*makeExecutable=*/ false);
+ objFilesToLinkParam.build(),
+ ParameterFile.ParameterFileType.UNQUOTED,
+ ISO_8859_1));
}
/**
@@ -1186,8 +1368,8 @@ public final class CompilationSupport {
// resulting in duplicate symbol errors unless they are deduped.
objFiles = Iterables.filter(objFiles, Predicates.not(Predicates.in(forceLinkArtifacts)));
- ruleContext.registerAction(objFilelistAction(objFiles, inputFileList));
-
+ registerObjFilelistAction(objFiles, inputFileList);
+
if (objcConfiguration.shouldPrioritizeStaticLibs()) {
commandLine.add("-filelist").add(inputFileList.getExecPathString());
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
index 8d8235dc54..7efef81544 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
@@ -229,7 +229,12 @@ public final class IntermediateArtifacts {
* artifact.
*/
public Artifact objFile(Artifact source) {
- return inUniqueObjsDir(source, ".o");
+ if (source.isTreeArtifact()) {
+ PathFragment rootRelativePath = source.getRootRelativePath().replaceName("obj_files");
+ return ruleContext.getTreeArtifact(rootRelativePath, ruleContext.getBinOrGenfilesDirectory());
+ } else {
+ return inUniqueObjsDir(source, ".o");
+ }
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
index a0d3411e80..36aa8d3d5f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.actions.Artifact.IS_TREE_ARTIFACT;
import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
@@ -21,9 +22,11 @@ import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
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.Artifact;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
@@ -34,6 +37,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
+import com.google.devtools.build.lib.analysis.actions.PopulateTreeArtifactAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
@@ -49,6 +53,7 @@ import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
+import com.google.devtools.build.lib.rules.java.JavaGenJarsProvider;
import com.google.devtools.build.lib.rules.java.JavaHelper;
import com.google.devtools.build.lib.rules.java.JavaSourceInfoProvider;
import com.google.devtools.build.lib.rules.java.Jvm;
@@ -56,7 +61,6 @@ import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraCompileA
import com.google.devtools.build.lib.rules.objc.J2ObjcSource.SourceType;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.vfs.PathFragment;
-
import java.util.List;
/**
@@ -142,6 +146,10 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
.direct_compile_time_input()
.cfg(HOST)
.value(new AppleToolchain.XcodeConfigLabel(toolsRepository)))
+ .add(attr("$zipper", LABEL)
+ .cfg(HOST)
+ .exec()
+ .value(Label.parseAbsoluteUnchecked(toolsRepository + "//tools/zip:zipper")))
.build();
}
@@ -154,17 +162,28 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
base.getProvider(JavaCompilationArgsProvider.class);
JavaSourceInfoProvider sourceInfoProvider =
base.getProvider(JavaSourceInfoProvider.class);
+ JavaGenJarsProvider genJarProvider =
+ base.getProvider(JavaGenJarsProvider.class);
ImmutableSet<Artifact> javaInputFiles = ImmutableSet.<Artifact>builder()
.addAll(sourceInfoProvider.getSourceFiles())
.addAll(sourceInfoProvider.getSourceJars())
.addAll(sourceInfoProvider.getSourceJarsForJarFiles())
.build();
+ Optional<Artifact> genSrcJar;
+ boolean annotationProcessingEnabled = ruleContext.getFragment(J2ObjcConfiguration.class)
+ .annotationProcessingEnabled();
+ if (genJarProvider != null && annotationProcessingEnabled) {
+ genSrcJar = Optional.fromNullable(genJarProvider.getGenSourceJar());
+ } else {
+ genSrcJar = Optional.<Artifact>absent();
+ }
+
XcodeProvider xcodeProvider;
ObjcCommon common;
if (!javaInputFiles.isEmpty()) {
- J2ObjcSource j2ObjcSource = buildJ2ObjcSource(ruleContext, javaInputFiles);
+ J2ObjcSource j2ObjcSource = buildJ2ObjcSource(ruleContext, javaInputFiles, genSrcJar);
J2ObjcMappingFileProvider depJ2ObjcMappingFileProvider =
depJ2ObjcMappingFileProvider(ruleContext);
createJ2ObjcTranspilationAction(
@@ -173,13 +192,23 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
depJ2ObjcMappingFileProvider.getClassMappingFiles(),
javaInputFiles,
compilationArgsProvider,
- j2ObjcSource);
+ j2ObjcSource,
+ genSrcJar);
+
+ boolean zipTreeArtifact = ruleContext.getFragment(J2ObjcConfiguration.class)
+ .zipTreeArtifact();
+ if (genSrcJar.isPresent() && zipTreeArtifact) {
+ for (Action action : genJarTreeArtifactCreationActions(ruleContext)) {
+ ruleContext.registerAction(action);
+ }
+ }
common = common(
ruleContext,
j2ObjcSource.getObjcSrcs(),
j2ObjcSource.getObjcHdrs(),
j2ObjcSource.getHeaderSearchPaths(),
DEPENDENT_ATTRIBUTES);
+
xcodeProvider = xcodeProvider(
ruleContext,
common,
@@ -244,13 +273,70 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
return j2ObjcMappingFileProvider;
}
- private static void createJ2ObjcTranspilationAction(
+ private List<Artifact> genJarOutputs(RuleContext ruleContext) {
+ boolean zipTreeArtifact = ruleContext
+ .getFragment(J2ObjcConfiguration.class)
+ .zipTreeArtifact();
+
+ if (zipTreeArtifact) {
+ return ImmutableList.of(
+ j2ObjcGenJarSourceZip(ruleContext),
+ j2ObjcGenJarSourceZipManifest(ruleContext),
+ j2ObjcGenJarHeaderZip(ruleContext),
+ j2ObjcGenJarHeaderZipManifest(ruleContext));
+ } else {
+ return ImmutableList.of(
+ j2ObjcGenJarTranslatedSourceFiles(ruleContext),
+ j2objcGenJarTranslatedHeaderFiles(ruleContext));
+ }
+ }
+
+ private List<String> genJarFlags(RuleContext ruleContext) {
+ boolean zipTreeArtifact = ruleContext.getFragment(J2ObjcConfiguration.class).zipTreeArtifact();
+
+ if (zipTreeArtifact) {
+ return ImmutableList.of(
+ "--output_gen_source_zip", j2ObjcGenJarSourceZip(ruleContext).getExecPathString(),
+ "--output_gen_header_zip", j2ObjcGenJarHeaderZip(ruleContext).getExecPathString());
+ } else {
+ return ImmutableList.of(
+ "--output_gen_source_dir",
+ j2ObjcGenJarTranslatedSourceFiles(ruleContext).getExecPathString(),
+ "--output_gen_header_dir",
+ j2objcGenJarTranslatedHeaderFiles(ruleContext).getExecPathString());
+ }
+ }
+
+ private List<Action> genJarTreeArtifactCreationActions(RuleContext ruleContext) {
+ Artifact sourceFiles = j2ObjcGenJarTranslatedSourceFiles(ruleContext);
+ Artifact headerFiles = j2objcGenJarTranslatedHeaderFiles(ruleContext);
+
+ ImmutableList.Builder<Action> actions = ImmutableList.builder();
+ actions.add(new PopulateTreeArtifactAction(
+ ruleContext.getActionOwner(),
+ j2ObjcGenJarSourceZip(ruleContext),
+ j2ObjcGenJarSourceZipManifest(ruleContext),
+ sourceFiles,
+ ruleContext.getExecutablePrerequisite("$zipper", Mode.HOST)));
+
+ actions.add(new PopulateTreeArtifactAction(
+ ruleContext.getActionOwner(),
+ j2ObjcGenJarHeaderZip(ruleContext),
+ j2ObjcGenJarHeaderZipManifest(ruleContext),
+ headerFiles,
+ ruleContext.getExecutablePrerequisite("$zipper", Mode.HOST)));
+
+ return actions.build();
+ }
+
+ private void createJ2ObjcTranspilationAction(
RuleContext ruleContext,
NestedSet<Artifact> depsHeaderMappingFiles,
NestedSet<Artifact> depsClassMappingFiles,
Iterable<Artifact> sources,
JavaCompilationArgsProvider compArgsProvider,
- J2ObjcSource j2ObjcSource) {
+ J2ObjcSource j2ObjcSource,
+ Optional<Artifact> genSrcJar) {
CustomCommandLine.Builder argBuilder = CustomCommandLine.builder();
PathFragment javaExecutable = ruleContext.getFragment(Jvm.class, HOST).getJavaExecutable();
argBuilder.add("--java").add(javaExecutable.getPathString());
@@ -259,12 +345,22 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
argBuilder.addExecPath("--j2objc", j2ObjcDeployJar);
argBuilder.add("--main_class").add("com.google.devtools.j2objc.J2ObjC");
- argBuilder.addJoinExecPaths("--translated_source_files", ",", j2ObjcSource.getObjcSrcs());
+ argBuilder.addJoinExecPaths(
+ "--translated_source_files",
+ ",",
+ Iterables.filter(j2ObjcSource.getObjcSrcs(), Predicates.not(IS_TREE_ARTIFACT)));
argBuilder.add("--objc_file_path").addPath(j2ObjcSource.getObjcFilePath());
Artifact outputDependencyMappingFile = j2ObjcOutputDependencyMappingFile(ruleContext);
argBuilder.addExecPath("--output_dependency_mapping_file", outputDependencyMappingFile);
+ ImmutableList.Builder<Artifact> genSrcOutputFiles = ImmutableList.builder();
+ if (genSrcJar.isPresent()) {
+ genSrcOutputFiles.addAll(genJarOutputs(ruleContext));
+ argBuilder.addExecPath("--gen_src_jar", genSrcJar.get());
+ argBuilder.add(genJarFlags(ruleContext));
+ }
+
Iterable<String> translationFlags = ruleContext
.getFragment(J2ObjcConfiguration.class)
.getTranslationFlags();
@@ -307,7 +403,8 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
ruleContext.getActionOwner(),
paramFile,
argBuilder.build(),
- ParameterFile.ParameterFileType.UNQUOTED, ISO_8859_1));
+ ParameterFile.ParameterFileType.UNQUOTED,
+ ISO_8859_1));
SpawnAction.Builder builder = new SpawnAction.Builder()
.setMnemonic("TranspilingJ2objc")
@@ -316,16 +413,18 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
.addInput(j2ObjcDeployJar)
.addInput(bootclasspathJar)
.addInputs(sources)
+ .addInputs(genSrcJar.asSet())
.addTransitiveInputs(compileTimeJars)
- .addInputs(JavaHelper.getHostJavabaseInputs(ruleContext))
+ .addTransitiveInputs(JavaHelper.getHostJavabaseInputs(ruleContext))
.addTransitiveInputs(depsHeaderMappingFiles)
.addTransitiveInputs(depsClassMappingFiles)
.addInput(paramFile)
.setCommandLine(CustomCommandLine.builder()
.addPaths("@%s", paramFile.getExecPath())
.build())
- .addOutputs(j2ObjcSource.getObjcSrcs())
- .addOutputs(j2ObjcSource.getObjcHdrs())
+ .addOutputs(Iterables.filter(j2ObjcSource.getObjcSrcs(), Predicates.not(IS_TREE_ARTIFACT)))
+ .addOutputs(Iterables.filter(j2ObjcSource.getObjcHdrs(), Predicates.not(IS_TREE_ARTIFACT)))
+ .addOutputs(genSrcOutputFiles.build())
.addOutput(outputHeaderMappingFile)
.addOutput(outputDependencyMappingFile)
.addOutput(archiveSourceMappingFile);
@@ -394,8 +493,38 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
ruleContext, ".archive_source_mapping.j2objc");
}
+ private static Artifact j2ObjcGenJarTranslatedSourceFiles(RuleContext ruleContext) {
+ PathFragment rootRelativePath = ruleContext
+ .getUniqueDirectory("_j2objc/gen_jar_files")
+ .getRelative("source_files");
+ return ruleContext.getTreeArtifact(rootRelativePath, ruleContext.getBinOrGenfilesDirectory());
+ }
+
+ private static Artifact j2objcGenJarTranslatedHeaderFiles(RuleContext ruleContext) {
+ PathFragment rootRelativePath = ruleContext
+ .getUniqueDirectory("_j2objc/gen_jar_files")
+ .getRelative("header_files");
+ return ruleContext.getTreeArtifact(rootRelativePath, ruleContext.getBinOrGenfilesDirectory());
+ }
+
+ private static Artifact j2ObjcGenJarSourceZip(RuleContext ruleContext) {
+ return ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".genjar_source.zip");
+ }
+
+ private static Artifact j2ObjcGenJarSourceZipManifest(RuleContext ruleContext) {
+ return ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".genjar_source.txt");
+ }
+
+ private static Artifact j2ObjcGenJarHeaderZip(RuleContext ruleContext) {
+ return ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".genjar_header.zip");
+ }
+
+ private static Artifact j2ObjcGenJarHeaderZipManifest(RuleContext ruleContext) {
+ return ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".genjar_header.txt");
+ }
+
private J2ObjcSource buildJ2ObjcSource(RuleContext ruleContext,
- Iterable<Artifact> javaInputSourceFiles) {
+ Iterable<Artifact> javaInputSourceFiles, Optional<Artifact> genSrcJar) {
PathFragment objcFileRootRelativePath = ruleContext.getUniqueDirectory("_j2objc");
PathFragment objcFileRootExecPath = ruleContext
.getConfiguration()
@@ -408,13 +537,23 @@ public class J2ObjcAspect extends NativeAspectClass implements ConfiguredAspectF
Iterable<PathFragment> headerSearchPaths = J2ObjcLibrary.j2objcSourceHeaderSearchPaths(
ruleContext, objcFileRootExecPath, javaInputSourceFiles);
+ Optional<Artifact> genJarTranslatedSrcs = Optional.absent();
+ Optional<Artifact> genJarTranslatedHdrs = Optional.absent();
+ Optional<PathFragment> genJarFileHeaderSearchPaths = Optional.absent();
+
+ if (genSrcJar.isPresent()) {
+ genJarTranslatedSrcs = Optional.of(j2ObjcGenJarTranslatedSourceFiles(ruleContext));
+ genJarTranslatedHdrs = Optional.of(j2objcGenJarTranslatedHeaderFiles(ruleContext));
+ genJarFileHeaderSearchPaths = Optional.of(genJarTranslatedHdrs.get().getExecPath());
+ }
+
return new J2ObjcSource(
ruleContext.getRule().getLabel(),
- objcSrcs,
- objcHdrs,
+ Iterables.concat(objcSrcs, genJarTranslatedSrcs.asSet()),
+ Iterables.concat(objcHdrs, genJarTranslatedHdrs.asSet()),
objcFileRootExecPath,
SourceType.JAVA,
- headerSearchPaths);
+ Iterables.concat(headerSearchPaths, genJarFileHeaderSearchPaths.asSet()));
}
private Iterable<Artifact> getOutputObjcFiles(RuleContext ruleContext,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
index 8f438d1825..ad76187a11 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcCommandLineOptions.java
@@ -19,7 +19,6 @@ import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.common.options.Converters;
import com.google.devtools.common.options.Option;
-
import java.util.List;
/**
@@ -52,6 +51,20 @@ public class J2ObjcCommandLineOptions extends FragmentOptions {
)
public boolean explicitJreDeps;
+ @Option(name = "experimental_j2objc_annotation_processing",
+ defaultValue = "false",
+ category = "undocumented",
+ help = "Whether to enable j2objc Java annotation processing."
+ )
+ public boolean annotationProcessingEnabled;
+
+ @Option(name = "experimental_zip_tree_artifact",
+ defaultValue = "true",
+ category = "undocumented",
+ help = "Whether to enable zipping/unzipping implementation of tree artifact creation"
+ )
+ public boolean zipTreeArtifact;
+
@Override
public void addAllLabels(Multimap<String, Label> labelMap) {}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java
index 0653d43a98..458e2bb6f6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcConfiguration.java
@@ -24,7 +24,6 @@ import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
-
import java.util.Collections;
import java.util.Set;
@@ -78,6 +77,8 @@ public class J2ObjcConfiguration extends Fragment {
private final Set<String> translationFlags;
private final boolean removeDeadCode;
private final boolean explicitJreDeps;
+ private final boolean annotationProcessingEnabled;
+ private final boolean zipTreeArtifact;
J2ObjcConfiguration(J2ObjcCommandLineOptions j2ObjcOptions) {
this.removeDeadCode = j2ObjcOptions.removeDeadCode;
@@ -86,6 +87,8 @@ public class J2ObjcConfiguration extends Fragment {
.addAll(j2ObjcOptions.translationFlags)
.addAll(J2OBJC_ALWAYS_ON_TRANSLATION_FLAGS)
.build();
+ this.annotationProcessingEnabled = j2ObjcOptions.annotationProcessingEnabled;
+ this.zipTreeArtifact = j2ObjcOptions.zipTreeArtifact;
}
/**
@@ -116,6 +119,20 @@ public class J2ObjcConfiguration extends Fragment {
return explicitJreDeps;
}
+ /**
+ * Returns whether to enable J2ObjC support for Java annotation processing.
+ */
+ public boolean annotationProcessingEnabled() {
+ return annotationProcessingEnabled;
+ }
+
+ /**
+ * Returns whether to enable the zipping/unzipping implementation of tree artifact creation.
+ */
+ public boolean zipTreeArtifact() {
+ return zipTreeArtifact;
+ }
+
@Override
public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) {
if (!Collections.disjoint(translationFlags, J2OBJC_BLACKLISTED_TRANSLATION_FLAGS)) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index e6feaae099..81c8d9bf5e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -213,20 +213,33 @@ public class ObjcRuleClasses {
*/
static SpawnAction.Builder spawnAppleEnvActionBuilder(AppleConfiguration appleConfiguration,
Platform targetPlatform) {
- ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.<String, String>builder()
- .putAll(appleConfiguration.getTargetAppleEnvironment(targetPlatform))
- .putAll(appleConfiguration.getAppleHostSystemEnv());
-
return spawnOnDarwinActionBuilder()
- .setEnvironment(envBuilder.build());
+ .setEnvironment(appleToolchainEnvironment(appleConfiguration, targetPlatform));
+ }
+
+ /**
+ * Returns apple environment variables that are typically needed by the apple toolchain.
+ */
+ static ImmutableMap<String, String> appleToolchainEnvironment(
+ AppleConfiguration appleConfiguration, Platform targetPlatform) {
+ return ImmutableMap.<String, String>builder()
+ .putAll(appleConfiguration.getTargetAppleEnvironment(targetPlatform))
+ .putAll(appleConfiguration.getAppleHostSystemEnv())
+ .build();
}
/**
* Creates a new spawn action builder that requires a darwin architecture to run.
*/
static SpawnAction.Builder spawnOnDarwinActionBuilder() {
- return new SpawnAction.Builder()
- .setExecutionInfo(ImmutableMap.of(ExecutionRequirements.REQUIRES_DARWIN, ""));
+ return new SpawnAction.Builder().setExecutionInfo(darwinActionExecutionRequirement());
+ }
+
+ /**
+ * Returns action requirement information for darwin architecture.
+ */
+ static ImmutableMap<String, String> darwinActionExecutionRequirement() {
+ return ImmutableMap.of(ExecutionRequirements.REQUIRES_DARWIN, "");
}
/**