Skip to content

Commit

Permalink
Split actoolzip and ibtoolzip into separate binaries
Browse files Browse the repository at this point in the history
Have actoolzip abs-ify the partial info plist path because otherwise it picks
seemingly random directories to which to output the info plist files.

--
MOS_MIGRATED_REVID=88851706
  • Loading branch information
illicitonion authored and kchodorow committed Mar 18, 2015
1 parent 412ef48 commit 6683d64
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ static SpawnAction.Builder spawnOnDarwinActionBuilder() {

// TODO(bazel-team): Reference a rule target rather than a jar file when Darwin runfiles work
// better.
private static SpawnAction.Builder spawnJavaOnDarwinActionBuilder(Artifact deployJarArtifact) {
static SpawnAction.Builder spawnJavaOnDarwinActionBuilder(Artifact deployJarArtifact) {
return spawnOnDarwinActionBuilder()
.setExecutable(JAVA)
.addExecutableArguments("-jar", deployJarArtifact.getExecPathString())
Expand Down Expand Up @@ -300,24 +300,6 @@ public Iterable<String> arguments() {
return result.build();
}

private Action[] ibtoolzipAction(ObjcRuleClasses.Tools baseTools, String mnemonic, Artifact input,
Artifact zipOutput, String archiveRoot) {
return spawnJavaOnDarwinActionBuilder(baseTools.actooloribtoolzipDeployJar())
.setMnemonic(mnemonic)
.setCommandLine(new CustomCommandLine.Builder()
// The next three arguments are positional, i.e. they don't have flags before them.
.addPath(zipOutput.getExecPath())
.add(archiveRoot)
.addPath(IBTOOL)

.add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs())
.addPath(input.getExecPath())
.build())
.addOutput(zipOutput)
.addInput(input)
.build(context);
}

/**
* Creates actions to convert all files specified by the xibs attribute into nib format.
*/
Expand All @@ -327,7 +309,20 @@ private Iterable<Action> convertXibsActions(ObjcRuleClasses.Tools baseTools, Xib
Artifact zipOutput = intermediateArtifacts.compiledXibFileZip(original);
String archiveRoot = BundleableFile.flatBundlePath(
FileSystemUtils.replaceExtension(original.getExecPath(), ".nib"));
result.add(ibtoolzipAction(baseTools, "XibCompile", original, zipOutput, archiveRoot));
result.add(spawnJavaOnDarwinActionBuilder(baseTools.ibtoolzipDeployJar())
.setMnemonic("XibCompile")
.setCommandLine(new CustomCommandLine.Builder()
// The next three arguments are positional, i.e. they don't have flags before them.
.addPath(zipOutput.getExecPath())
.add(archiveRoot)
.addPath(IBTOOL)

.add("--minimum-deployment-target").add(objcConfiguration.getMinimumOs())
.addPath(original.getExecPath())
.build())
.addOutput(zipOutput)
.addInput(original)
.build(context));
}
return result.build();
}
Expand Down Expand Up @@ -363,7 +358,7 @@ void registerActoolzipAction(
// Note that below we set the archive root to the empty string. This means that the generated
// zip file will be rooted at the bundle root, and we have to prepend the bundle root to each
// entry when merging it with the final .ipa file.
register(spawnJavaOnDarwinActionBuilder(tools.actooloribtoolzipDeployJar())
register(spawnJavaOnDarwinActionBuilder(tools.actoolzipDeployJar())
.setMnemonic("AssetCatalogCompile")
.addTransitiveInputs(provider.get(ASSET_CATALOG))
.addOutput(zipOutput)
Expand Down Expand Up @@ -408,11 +403,6 @@ public Iterable<String> arguments() {
};
}

void registerIbtoolzipAction(ObjcRuleClasses.Tools tools, Artifact input, Artifact outputZip) {
String archiveRoot = BundleableFile.flatBundlePath(input.getExecPath()) + "c";
register(ibtoolzipAction(tools, "StoryboardCompile", input, outputZip, archiveRoot));
}

@VisibleForTesting
static Iterable<String> commonMomczipArguments(ObjcConfiguration configuration) {
return ImmutableList.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,10 @@ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder
.add(attr("$plmerge", LABEL).cfg(HOST).exec()
.value(env.getLabel("//tools/objc:plmerge")))
.add(attr("$actooloribtoolzip_deploy", LABEL).cfg(HOST)
.value(env.getLabel("//tools/objc:actooloribtoolzip_deploy.jar")))
.add(attr("$actoolzip_deploy", LABEL).cfg(HOST)
.value(env.getLabel("//tools/objc:actoolzip_deploy.jar")))
.add(attr("$ibtoolzip_deploy", LABEL).cfg(HOST)
.value(env.getLabel("//tools/objc:ibtoolzip_deploy.jar")))
.build();
}
}
Expand Down Expand Up @@ -850,8 +852,12 @@ static final class Tools {
this.ruleContext = Preconditions.checkNotNull(ruleContext);
}

Artifact actooloribtoolzipDeployJar() {
return ruleContext.getPrerequisiteArtifact("$actooloribtoolzip_deploy", Mode.HOST);
Artifact actoolzipDeployJar() {
return ruleContext.getPrerequisiteArtifact("$actoolzip_deploy", Mode.HOST);
}

Artifact ibtoolzipDeployJar() {
return ruleContext.getPrerequisiteArtifact("$ibtoolzip_deploy", Mode.HOST);
}

Artifact momczipDeployJar() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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.analysis.actions.CustomCommandLine;

/**
* Support for resource processing on Objc rules.
Expand Down Expand Up @@ -57,11 +58,36 @@ ResourceSupport registerActions(Storyboards storyboards) {
CompiledResourceFile.fromStringsFiles(intermediateArtifacts, attributes.strings())),
new XibFiles(attributes.xibs()),
datamodels);

registerInterfaceBuilderActions(storyboards, tools);
return this;
}

private void registerInterfaceBuilderActions(
Storyboards storyboards, ObjcRuleClasses.Tools tools) {
for (Artifact storyboardInput : storyboards.getInputs()) {
actionsBuilder.registerIbtoolzipAction(
tools, storyboardInput, intermediateArtifacts.compiledStoryboardZip(storyboardInput));
String archiveRoot = BundleableFile.flatBundlePath(storyboardInput.getExecPath()) + "c";
Artifact zipOutput = intermediateArtifacts.compiledStoryboardZip(storyboardInput);

String minimumOs =
ruleContext.getConfiguration().getFragment(ObjcConfiguration.class).getMinimumOs();
ruleContext.registerAction(
ObjcActionsBuilder.spawnJavaOnDarwinActionBuilder(tools.ibtoolzipDeployJar())
.setMnemonic("StoryboardCompile")
.setCommandLine(new CustomCommandLine.Builder()
// The next three arguments are positional,
// i.e. they don't have flags before them.
.addPath(zipOutput.getExecPath())
.add(archiveRoot)
.addPath(ObjcActionsBuilder.IBTOOL)

.add("--minimum-deployment-target").add(minimumOs)
.addPath(storyboardInput.getExecPath())
.build())
.addOutput(zipOutput)
.addInput(storyboardInput)
.build(ruleContext));
}
return this;
}

/**
Expand Down
5 changes: 0 additions & 5 deletions src/objc_tools/actooloribtoolzip/README

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2014 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.xcode.actoolzip;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.xcode.zippingoutput.Arguments;
import com.google.devtools.build.xcode.zippingoutput.Wrapper;
import com.google.devtools.build.xcode.zippingoutput.Wrappers;

import java.io.File;
import java.io.IOException;
import java.util.Set;

/**
* A tool which wraps actool by running actool and zipping its output. See the JavaDoc for
* {@link Wrapper} for more information.
*/
public class ActoolZip implements Wrapper {

private static final Function<String, String> CANONICAL_PATH =
new Function<String, String>() {
@Override
public String apply(String path) {
File file = new File(path);
if (file.exists()) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
// Pass through to return raw path
}
}
return path;
}
};

@Override
public String name() {
return "ActoolZip";
}

@Override
public String subtoolName() {
return "actool";
}

@Override
public Iterable<String> subCommand(Arguments args, String outputDirectory) {
return new ImmutableList.Builder<String>()
.add(args.subtoolCmd())
.add("--compile")
.add(outputDirectory)
// actool munges paths in some way which doesn't work if one of the directories in the path
// is a symlink.
.addAll(Iterables.transform(args.subtoolExtraArgs(), CANONICAL_PATH))
.build();
}

public static void main(String[] args) throws IOException, InterruptedException {
replaceInfoPlistPath(args);
Wrappers.execute(args, new ActoolZip());
}

/**
* Absolute-ify output partial info plist's path.
*
* <p>actool occasionally writes the partial info plist file to the wrong directory if a
* non-absolute path is passed as --output-partial-info-plist, so we optimistically try to
* absolute-ify its path. This isn't caught by the "CANONICAL_PATH" transform above, because the
* file doesn't exist at the time of flag parsing.
*
* <p>Modifies args in-place.
*/
private static void replaceInfoPlistPath(String[] args) {
String flag = "output-partial-info-plist";
Set<String> flagOptions = ImmutableSet.of(
"-" + flag,
"--" + flag);
for (int i = 0; i < args.length; ++i) {
for (String flagOption : flagOptions) {
String arg = args[i];
String flagEquals = flagOption + "=";
if (arg.startsWith(flagEquals)) {
args[i] = flagEquals + new File(arg.substring(flagEquals.length())).getAbsolutePath();
}
if (arg.equals(flagOption) && i + 1 < args.length) {
args[i + 1] = new File(args[i + 1]).getAbsolutePath();
}
}
}
}

@Override
public boolean outputDirectoryMustExist() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
actoolzip runs actool, which compiles asset catalog files and zips up the
output, because actool returns an unpredictable number of output files.

actool only runs on Darwin, so actoolzip only runs on Darwin.
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.xcode.actooloribtoolzip;
package com.google.devtools.build.xcode.ibtoolzip;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.xcode.zippingoutput.Arguments;
import com.google.devtools.build.xcode.zippingoutput.Wrapper;
import com.google.devtools.build.xcode.zippingoutput.Wrappers;

import java.io.File;
import java.io.IOException;

/**
* A tool which wraps actool or ibtool, by running actool/ibtool and zipping its output. See the
* JavaDoc for {@link Wrapper} for more information.
* A tool which wraps ibtool by running ibtool and zipping its output. See the JavaDoc for
* {@link Wrapper} for more information.
*/
public class ActoolOrIbtoolZip implements Wrapper {

private static final Function<String, String> CANONICAL_PATH =
new Function<String, String>() {
@Override
public String apply(String path) {
File file = new File(path);
if (file.exists()) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
// Pass through to return raw path
}
}
return path;
}
};
public class IbtoolZip implements Wrapper {

@Override
public String name() {
return "ActoolOrIbtoolZip";
return "IbtoolZip";
}

@Override
public String subtoolName() {
return "actool/ibtool";
return "ibtool";
}

@Override
Expand All @@ -62,14 +43,12 @@ public Iterable<String> subCommand(Arguments args, String outputDirectory) {
.add(args.subtoolCmd())
.add("--compile")
.add(outputDirectory)
// actool munges paths in some way which doesn't work if one of the directories in the path
// is a symlink.
.addAll(Iterables.transform(args.subtoolExtraArgs(), CANONICAL_PATH))
.addAll(args.subtoolExtraArgs())
.build();
}

public static void main(String[] args) throws IOException, InterruptedException {
Wrappers.execute(args, new ActoolOrIbtoolZip());
Wrappers.execute(args, new IbtoolZip());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ibtoolzip runs ibtool, which compiles storyboards, and zips up the output,
because ibtool returns an unpredictable number of output files.

ibtool only runs on Darwin, so ibtoolzip only runs on Darwin.

0 comments on commit 6683d64

Please sign in to comment.