NestedSet<? extends Artifact> dependentLinkedBinaries() { if (ruleContext.attributes().getAttributeDefinition("binary") == null) { return NestedSetBuilder.emptySet(Order.STABLE_ORDER); } NestedSetBuilder<Artifact> linkedBinaries = NestedSetBuilder.stableOrder(); for (ObjcProvider provider : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK, ObjcProvider.class)) { linkedBinaries.addTransitive(provider.get(ObjcProvider.LINKED_BINARY)); } return linkedBinaries.build(); }
/** Registers an action to copy Swift standard library dylibs into app bundle. */ private void registerSwiftStdlibActionsIfNecessary() { if (!objcProvider.is(USES_SWIFT)) { return; } ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); CustomCommandLine.Builder commandLine = CustomCommandLine.builder() .addPath(intermediateArtifacts.swiftFrameworksFileZip().getExecPath()) .add("--platform") .add(IosSdkCommands.swiftPlatform(objcConfiguration)) .addExecPath("--scan-executable", intermediateArtifacts.combinedArchitectureBinary()); ruleContext.registerAction( ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext) .setMnemonic("SwiftStdlibCopy") .setExecutable(attributes.swiftStdlibToolWrapper()) .setCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftFrameworksFileZip()) .addInput(intermediateArtifacts.combinedArchitectureBinary()) // TODO(dmaclach): Adding realpath and xcrunwrapper should not be required once // https://github.com/google/bazel/issues/285 is fixed. .addInput(attributes.realpath()) .addInput(CompilationSupport.xcrunwrapper(ruleContext).getExecutable()) .build(ruleContext)); }
/** * Adds any files to the given nested set builder that should be built if this application is the * top level target in a blaze invocation. * * @return this application support * @throws InterruptedException */ ReleaseBundlingSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild) throws InterruptedException { NestedSetBuilder<Artifact> debugSymbolBuilder = NestedSetBuilder.<Artifact>stableOrder() .addTransitive(objcProvider.get(ObjcProvider.DEBUG_SYMBOLS)); for (Artifact breakpadFile : getBreakpadFiles().values()) { filesToBuild.add(breakpadFile); } if (linkedBinary == LinkedBinary.LOCAL_AND_DEPENDENCIES && ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); debugSymbolBuilder .add(intermediateArtifacts.dsymPlist()) .add(intermediateArtifacts.dsymSymbol()) .add(intermediateArtifacts.breakpadSym()); } filesToBuild .add(ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA)) // TODO(bazel-team): Fat binaries may require some merging of these file rather than just // making them available. .addTransitive(debugSymbolBuilder.build()); return this; }
ImmutableMap<String, Artifact> cpuSpecificBreakpadFiles() { ImmutableMap.Builder<String, Artifact> results = ImmutableMap.builder(); if (ruleContext.attributes().has("binary", BuildType.LABEL)) { for (TransitiveInfoCollection prerequisite : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK)) { ObjcProvider prerequisiteProvider = prerequisite.getProvider(ObjcProvider.class); if (prerequisiteProvider != null) { Artifact sourceBreakpad = Iterables.getOnlyElement( prerequisiteProvider.get(ObjcProvider.BREAKPAD_FILE), null); if (sourceBreakpad != null) { String cpu = prerequisite.getConfiguration().getFragment(ObjcConfiguration.class).getIosCpu(); results.put(cpu, sourceBreakpad); } } } } return results.build(); }
private ReleaseBundlingSupport registerSignBundleAction( Artifact entitlements, Artifact ipaOutput, Artifact ipaUnsigned) { // TODO(bazel-team): Support variable substitution ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>(); // Explicitly sign Swift dylibs. Unfortunately --deep option on codesign doesn't do this // automatically. // The order here is important. The innermost code must singed first. String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir()); if (objcProvider.is(USES_SWIFT)) { dirsToSign.add(bundleDir + "/Frameworks/*"); } dirsToSign.add(bundleDir); StringBuilder codesignCommandLineBuilder = new StringBuilder(); for (String dir : dirsToSign.build()) { codesignCommandLineBuilder .append(codesignCommand(entitlements, "${t}/" + dir)) .append(" && "); } // TODO(bazel-team): Support nested code signing. String shellCommand = "set -e && " + "t=$(mktemp -d -t signing_intermediate) && " + "trap \"rm -rf ${t}\" EXIT && " // Get an absolute path since we need to cd into the temp directory for zip. + "signed_ipa=${PWD}/" + ipaOutput.getShellEscapedExecPathString() + " && " + "/usr/bin/unzip -qq " + ipaUnsigned.getShellEscapedExecPathString() + " -d ${t} && " + codesignCommandLineBuilder.toString() // Using zip since we need to preserve permissions + "cd ${t} && /usr/bin/zip -q -r \"${signed_ipa}\" ."; ruleContext.registerAction( ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand) .setMnemonic("IosSignBundle") .setProgressMessage("Signing iOS bundle: " + ruleContext.getLabel()) .addInput(ipaUnsigned) .addInput(attributes.provisioningProfile()) .addInput(entitlements) .addOutput(ipaOutput) .build(ruleContext)); return this; }
/** * Validates application-related attributes set on this rule and registers any errors with the * rule context. * * @return this application support */ ReleaseBundlingSupport validateAttributes() { // No asset catalogs. That means you cannot specify app_icon or // launch_image attributes, since they must not exist. However, we don't // run actool in this case, which means it does not do validity checks, // and we MUST raise our own error somehow... if (!objcProvider.hasAssetCatalogs()) { if (attributes.appIcon() != null) { ruleContext.attributeError( "app_icon", String.format(NO_ASSET_CATALOG_ERROR_FORMAT, attributes.appIcon())); } if (attributes.launchImage() != null) { ruleContext.attributeError( "launch_image", String.format(NO_ASSET_CATALOG_ERROR_FORMAT, attributes.launchImage())); } } if (bundleSupport.targetDeviceFamilies().isEmpty()) { ruleContext.attributeError("families", INVALID_FAMILIES_ERROR); } return this; }