aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Peter Schmitt <schmitt@google.com>2016-05-19 14:01:21 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2016-05-19 18:01:48 +0000
commit438ee29d725a473f3f4586ec9a005e988021e714 (patch)
tree5df3de60300b1c82afad184902a9ef8369e8cb07 /src
parent402ca70bdd7950c51bec83ebbcf9ae9e659cb7d9 (diff)
Allow imports of dylib frameworks.
RELNOTES: objc_framework now supports dynamic frameworks. -- MOS_MIGRATED_REVID=122728042
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java44
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java57
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java110
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java41
8 files changed, 212 insertions, 114 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
index 35c228bb0b..a5a9a71240 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.ASSET_CATALOG;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_FILE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
@@ -54,6 +55,14 @@ import java.util.Set;
*/
@Immutable
final class Bundling {
+
+ /**
+ * Names of top-level directories in dynamic frameworks (i.e. directly under the
+ * {@code *.framework} directory) that should not be copied into the final bundle.
+ */
+ private static final ImmutableSet<String> STRIP_FRAMEWORK_DIRS =
+ ImmutableSet.of("Headers", "PrivateHeaders", "Modules");
+
static final class Builder {
private String name;
private String bundleDirFormat;
@@ -259,6 +268,34 @@ final class Bundling {
return binaryStringsBuilder.build();
}
+ private NestedSet<BundleableFile> dynamicFrameworkFiles() {
+ NestedSetBuilder<BundleableFile> frameworkFilesBuilder = NestedSetBuilder.stableOrder();
+ for (Artifact frameworkFile : objcProvider.get(DYNAMIC_FRAMEWORK_FILE)) {
+ PathFragment frameworkDir =
+ ObjcCommon.nearestContainerMatching(ObjcCommon.FRAMEWORK_CONTAINER_TYPE, frameworkFile)
+ .get();
+ String frameworkName = frameworkDir.getBaseName();
+ PathFragment inFrameworkPath = frameworkFile.getExecPath().relativeTo(frameworkDir);
+ if (inFrameworkPath.getFirstSegment(STRIP_FRAMEWORK_DIRS) == 0) {
+ continue;
+ }
+ // If this is a top-level file in the framework set the executable bit (to make sure we set
+ // the bit on the actual dylib binary - other files may also get it but we have no way to
+ // distinguish them).
+ int permissions =
+ inFrameworkPath.segmentCount() == 1
+ ? BundleableFile.EXECUTABLE_EXTERNAL_FILE_ATTRIBUTE
+ : BundleableFile.DEFAULT_EXTERNAL_FILE_ATTRIBUTE;
+ BundleableFile bundleFile =
+ new BundleableFile(
+ frameworkFile,
+ "Frameworks/" + frameworkName + "/" + inFrameworkPath.getPathString(),
+ permissions);
+ frameworkFilesBuilder.add(bundleFile);
+ }
+ return frameworkFilesBuilder.build();
+ }
+
/**
* Filters files that would map to the same location in the bundle, adding only one copy to the
* set of files returned.
@@ -289,12 +326,16 @@ final class Bundling {
Optional<Artifact> actoolzipOutput = actoolzipOutput();
Optional<Artifact> combinedArchitectureBinary = combinedArchitectureBinary();
NestedSet<BundleableFile> binaryStringsFiles = binaryStringsFiles();
+ NestedSet<BundleableFile> dynamicFrameworks = dynamicFrameworkFiles();
NestedSet<Artifact> mergeZips = mergeZips(actoolzipOutput);
NestedSet<Artifact> rootMergeZips =
NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(objcProvider.get(ROOT_MERGE_ZIP)).build();
- bundleFilesBuilder.addAll(binaryStringsFiles).addAll(objcProvider.get(BUNDLE_FILE));
+ bundleFilesBuilder
+ .addAll(binaryStringsFiles)
+ .addAll(dynamicFrameworks)
+ .addAll(objcProvider.get(BUNDLE_FILE));
ImmutableList<BundleableFile> bundleFiles =
deduplicateByBundlePaths(bundleFilesBuilder.build());
@@ -305,7 +346,6 @@ final class Bundling {
.addAll(bundleInfoplist.asSet())
.addTransitive(mergeZips)
.addTransitive(rootMergeZips)
- .addAll(BundleableFile.toArtifacts(binaryStringsFiles))
.addAll(BundleableFile.toArtifacts(bundleFiles));
return new Bundling(
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 6abcce77b3..45593190e1 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
@@ -17,11 +17,10 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
import static com.google.devtools.build.lib.rules.cpp.Link.LINK_LIBRARY_FILETYPES;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_FRAMEWORKS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
@@ -31,6 +30,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG_PLUSPLUS;
@@ -438,8 +438,7 @@ public final class CompilationSupport {
.add(compileFlagsForClang(appleConfiguration))
.add(commonLinkAndCompileFlagsForClang(objcProvider, objcConfiguration, appleConfiguration))
.add(objcConfiguration.getCoptsForCompilationMode())
- .addBeforeEachPath(
- "-iquote", ObjcCommon.userHeaderSearchPaths(buildConfiguration))
+ .addBeforeEachPath("-iquote", ObjcCommon.userHeaderSearchPaths(buildConfiguration))
.addBeforeEachExecPath("-include", compilationArtifacts.getPchFile().asSet())
.addBeforeEachPath("-I", objcProvider.get(INCLUDE))
.addBeforeEachPath("-isystem", objcProvider.get(INCLUDE_SYSTEM))
@@ -480,22 +479,24 @@ public final class CompilationSupport {
}
// TODO(bazel-team): Remote private headers from inputs once they're added to the provider.
- ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(
- ruleContext, appleConfiguration.getIosCpuPlatform())
- .setMnemonic("ObjcCompile")
- .setExecutable(xcrunwrapper(ruleContext))
- .setCommandLine(commandLine.build())
- .addInput(sourceFile)
- .addInputs(additionalInputs.build())
- .addOutput(objFile)
- .addOutputs(gcnoFiles.build())
- .addOutput(dotdFile)
- .addTransitiveInputs(objcProvider.get(HEADER))
- .addTransitiveInputs(objcProvider.get(MODULE_MAP))
- .addInputs(compilationArtifacts.getPrivateHdrs())
- .addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE))
- .addInputs(compilationArtifacts.getPchFile().asSet())
- .build(ruleContext));
+ ruleContext.registerAction(
+ ObjcRuleClasses.spawnAppleEnvActionBuilder(
+ ruleContext, appleConfiguration.getIosCpuPlatform())
+ .setMnemonic("ObjcCompile")
+ .setExecutable(xcrunwrapper(ruleContext))
+ .setCommandLine(commandLine.build())
+ .addInput(sourceFile)
+ .addInputs(additionalInputs.build())
+ .addOutput(objFile)
+ .addOutputs(gcnoFiles.build())
+ .addOutput(dotdFile)
+ .addTransitiveInputs(objcProvider.get(HEADER))
+ .addTransitiveInputs(objcProvider.get(MODULE_MAP))
+ .addInputs(compilationArtifacts.getPrivateHdrs())
+ .addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE))
+ .addTransitiveInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE))
+ .addInputs(compilationArtifacts.getPchFile().asSet())
+ .build(ruleContext));
}
/**
@@ -957,7 +958,8 @@ public final class CompilationSupport {
.addOutputs(linkmap.asSet())
.addTransitiveInputs(bazelBuiltLibraries)
.addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY))
- .addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE))
+ .addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE))
+ .addTransitiveInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE))
.addInputs(ccLibraries)
.addInputs(extraLinkInputs)
.addInputs(prunedJ2ObjcArchives)
@@ -1077,6 +1079,12 @@ public final class CompilationSupport {
.add("-objc_abi_version")
.add("-Xlinker")
.add("2")
+ // Set the rpath so that at runtime dylibs can be loaded from the bundle root's "Frameworks"
+ // directory.
+ .add("-Xlinker")
+ .add("-rpath")
+ .add("-Xlinker")
+ .add("@executable_path/Frameworks")
.add("-fobjc-link-runtime")
.add(DEFAULT_LINKER_FLAGS)
.addBeforeEach("-framework", frameworkNames(objcProvider))
@@ -1108,13 +1116,6 @@ public final class CompilationSupport {
commandLine.add("-L").add(AppleToolchain.swiftLibDir(appleConfiguration));
}
- if (objcProvider.is(USES_SWIFT) || objcProvider.is(USES_FRAMEWORKS)) {
- // Enable loading bundled frameworks.
- commandLine
- .add("-Xlinker").add("-rpath")
- .add("-Xlinker").add("@executable_path/Frameworks");
- }
-
for (String linkopt : attributes.linkopts()) {
commandLine.add("-Wl," + linkopt);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java
index 610382ecb7..4de6706c1f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java
@@ -16,11 +16,9 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.devtools.build.lib.rules.objc.ObjcCommon.uniqueContainers;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FLAG;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_FRAMEWORKS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@@ -123,8 +121,13 @@ public class IosFramework extends ReleaseBundlingTargetFactory {
ObjcProvider frameworkProvider =
new ObjcProvider.Builder()
.add(MERGE_ZIP, ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
- .add(FLAG, USES_FRAMEWORKS)
- .addAll(FRAMEWORK_FILE, frameworkImports)
+ // TODO(dmishe): The framework returned by this rule is dynamic, not static. But because
+ // this rule (incorrectly?) propagates its contents as a bundle (see "IPA" above) we
+ // cannot declare its files as dynamic framework files because they would then be copied
+ // into the final IPA, conflicting with the exported bundle. Instead we propagate using
+ // the static frameworks key which will see the files correctly added to compile and
+ // linker actions but not added to the final bundle.
+ .addAll(STATIC_FRAMEWORK_FILE, frameworkImports)
.addAll(
FRAMEWORK_DIR,
uniqueContainers(frameworkImports, ObjcCommon.FRAMEWORK_CONTAINER_TYPE))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
index f7d478928d..d15148b1e2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
@@ -24,11 +24,11 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.CC_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEBUG_SYMBOLS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEBUG_SYMBOLS_PLIST;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FLAG;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_FOR_XCODEGEN;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
-import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.GENERAL_RESOURCE_DIR;
@@ -46,6 +46,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SOURCE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.TOP_LEVEL_MODULE_MAP;
@@ -181,9 +182,8 @@ public final class ObjcCommon {
ImmutableList.Builder<PathFragment> paths = new ImmutableList.Builder<>();
PathFragment packageFragment =
ruleContext.getLabel().getPackageIdentifier().getPathFragment();
- List<PathFragment> rootFragments = ImmutableList.of(
- packageFragment,
- genfilesFragment.getRelative(packageFragment));
+ List<PathFragment> rootFragments =
+ ImmutableList.of(packageFragment, genfilesFragment.getRelative(packageFragment));
Iterable<PathFragment> relativeIncludes =
Iterables.filter(includes(), Predicates.not(PathFragment.IS_ABSOLUTE));
@@ -301,7 +301,8 @@ public final class ObjcCommon {
private Iterable<SdkFramework> extraSdkFrameworks = ImmutableList.of();
private Iterable<SdkFramework> extraWeakSdkFrameworks = ImmutableList.of();
private Iterable<String> extraSdkDylibs = ImmutableList.of();
- private Iterable<Artifact> frameworkImports = ImmutableList.of();
+ private Iterable<Artifact> staticFrameworkImports = ImmutableList.of();
+ private Iterable<Artifact> dynamicFrameworkImports = ImmutableList.of();
private Optional<CompilationArtifacts> compilationArtifacts = Optional.absent();
private Iterable<ObjcProvider> depObjcProviders = ImmutableList.of();
private Iterable<ObjcProvider> directDepObjcProviders = ImmutableList.of();
@@ -337,15 +338,19 @@ public final class ObjcCommon {
}
public Builder setCompilationAttributes(CompilationAttributes baseCompilationAttributes) {
- Preconditions.checkState(!this.compilationAttributes.isPresent(),
- "compilationAttributes is already set to: %s", this.compilationAttributes);
+ Preconditions.checkState(
+ !this.compilationAttributes.isPresent(),
+ "compilationAttributes is already set to: %s",
+ this.compilationAttributes);
this.compilationAttributes = Optional.of(baseCompilationAttributes);
return this;
}
public Builder setResourceAttributes(ResourceAttributes baseResourceAttributes) {
- Preconditions.checkState(!this.resourceAttributes.isPresent(),
- "resourceAttributes is already set to: %s", this.resourceAttributes);
+ Preconditions.checkState(
+ !this.resourceAttributes.isPresent(),
+ "resourceAttributes is already set to: %s",
+ this.resourceAttributes);
this.resourceAttributes = Optional.of(baseResourceAttributes);
return this;
}
@@ -366,14 +371,31 @@ public final class ObjcCommon {
return this;
}
- Builder addFrameworkImports(Iterable<Artifact> frameworkImports) {
- this.frameworkImports = Iterables.concat(this.frameworkImports, frameworkImports);
+ /**
+ * Adds all given artifacts as members of static frameworks. They must be contained in
+ * {@code .frameworks} directories and the binary in that framework should be statically linked.
+ */
+ Builder addStaticFrameworkImports(Iterable<Artifact> frameworkImports) {
+ this.staticFrameworkImports = Iterables.concat(this.staticFrameworkImports, frameworkImports);
+ return this;
+ }
+
+ /**
+ * Adds all given artifacts as members of dynamic frameworks. They must be contained in
+ * {@code .frameworks} directories and the binary in that framework should be dynamically
+ * linked.
+ */
+ Builder addDynamicFrameworkImports(Iterable<Artifact> frameworkImports) {
+ this.dynamicFrameworkImports =
+ Iterables.concat(this.dynamicFrameworkImports, frameworkImports);
return this;
}
Builder setCompilationArtifacts(CompilationArtifacts compilationArtifacts) {
- Preconditions.checkState(!this.compilationArtifacts.isPresent(),
- "compilationArtifacts is already set to: %s", this.compilationArtifacts);
+ Preconditions.checkState(
+ !this.compilationArtifacts.isPresent(),
+ "compilationArtifacts is already set to: %s",
+ this.compilationArtifacts);
this.compilationArtifacts = Optional.of(compilationArtifacts);
return this;
}
@@ -397,13 +419,13 @@ public final class ObjcCommon {
}
addDepObjcProviders(propagatedObjcDeps.build());
this.depCcHeaderProviders = Iterables.concat(this.depCcHeaderProviders, cppDeps.build());
- this.depCcLinkProviders =
- Iterables.concat(this.depCcLinkProviders, cppDepLinkParams.build());
+ this.depCcLinkProviders = Iterables.concat(this.depCcLinkProviders, cppDepLinkParams.build());
return this;
}
private <T extends TransitiveInfoProvider> ImmutableList.Builder<T> addAnyProviders(
- ImmutableList.Builder<T> listBuilder, TransitiveInfoCollection collection,
+ ImmutableList.Builder<T> listBuilder,
+ TransitiveInfoCollection collection,
Class<T> providerClass) {
if (collection.getProvider(providerClass) != null) {
listBuilder.add(collection.getProvider(providerClass));
@@ -425,8 +447,8 @@ public final class ObjcCommon {
* dependers on the declaring rule.
*/
Builder addNonPropagatedDepObjcProviders(Iterable<ObjcProvider> directDepObjcProviders) {
- this.directDepObjcProviders = Iterables.concat(
- this.directDepObjcProviders, directDepObjcProviders);
+ this.directDepObjcProviders =
+ Iterables.concat(this.directDepObjcProviders, directDepObjcProviders);
return this;
}
@@ -519,8 +541,13 @@ public final class ObjcCommon {
.addAll(SDK_FRAMEWORK, extraSdkFrameworks)
.addAll(WEAK_SDK_FRAMEWORK, extraWeakSdkFrameworks)
.addAll(SDK_DYLIB, extraSdkDylibs)
- .addAll(FRAMEWORK_FILE, frameworkImports)
- .addAll(FRAMEWORK_DIR, uniqueContainers(frameworkImports, FRAMEWORK_CONTAINER_TYPE))
+ .addAll(STATIC_FRAMEWORK_FILE, staticFrameworkImports)
+ .addAll(DYNAMIC_FRAMEWORK_FILE, dynamicFrameworkImports)
+ .addAll(
+ FRAMEWORK_DIR, uniqueContainers(staticFrameworkImports, FRAMEWORK_CONTAINER_TYPE))
+ .addAll(
+ FRAMEWORK_DIR,
+ uniqueContainers(dynamicFrameworkImports, FRAMEWORK_CONTAINER_TYPE))
.addAll(INCLUDE, userHeaderSearchPaths)
.addAllForDirectDependents(INCLUDE, directDependencyHeaderSearchPaths)
.addAll(DEFINE, defines)
@@ -559,7 +586,8 @@ public final class ObjcCommon {
for (LinkerInputs.LibraryToLink library : params.getLibraries()) {
Artifact artifact = library.getArtifact();
if (LINK_LIBRARY_FILETYPES.matches(artifact.getFilename())) {
- objcProvider.add(FORCE_LOAD_FOR_XCODEGEN,
+ objcProvider.add(
+ FORCE_LOAD_FOR_XCODEGEN,
"$(WORKSPACE_ROOT)/" + artifact.getExecPath().getSafePathString());
}
}
@@ -567,11 +595,12 @@ public final class ObjcCommon {
if (compilationAttributes.isPresent()) {
CompilationAttributes attributes = compilationAttributes.get();
- Iterable<PathFragment> sdkIncludes = Iterables.transform(
- Interspersing.prependEach(
- AppleToolchain.sdkDir() + "/usr/include/",
- PathFragment.safePathStrings(attributes.sdkIncludes())),
- TO_PATH_FRAGMENT);
+ Iterable<PathFragment> sdkIncludes =
+ Iterables.transform(
+ Interspersing.prependEach(
+ AppleToolchain.sdkDir() + "/usr/include/",
+ PathFragment.safePathStrings(attributes.sdkIncludes())),
+ TO_PATH_FRAGMENT);
objcProvider
.addAll(HEADER, attributes.hdrs())
.addAll(HEADER, attributes.textualHdrs())
@@ -652,14 +681,17 @@ public final class ObjcCommon {
for (CompilationArtifacts artifacts : compilationArtifacts.asSet()) {
for (Artifact archive : artifacts.getArchive().asSet()) {
objcProvider.add(FORCE_LOAD_LIBRARY, archive);
- objcProvider.add(FORCE_LOAD_FOR_XCODEGEN, String.format(
- "$(BUILT_PRODUCTS_DIR)/lib%s.a",
- XcodeProvider.xcodeTargetName(context.getLabel())));
+ objcProvider.add(
+ FORCE_LOAD_FOR_XCODEGEN,
+ String.format(
+ "$(BUILT_PRODUCTS_DIR)/lib%s.a",
+ XcodeProvider.xcodeTargetName(context.getLabel())));
}
}
for (Artifact archive : extraImportLibraries) {
objcProvider.add(FORCE_LOAD_LIBRARY, archive);
- objcProvider.add(FORCE_LOAD_FOR_XCODEGEN,
+ objcProvider.add(
+ FORCE_LOAD_FOR_XCODEGEN,
"$(WORKSPACE_ROOT)/" + archive.getExecPath().getSafePathString());
}
}
@@ -671,7 +703,8 @@ public final class ObjcCommon {
objcProvider.add(TOP_LEVEL_MODULE_MAP, moduleMap);
}
- objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet())
+ objcProvider
+ .addAll(LINKED_BINARY, linkedBinary.asSet())
.addAll(LINKMAP_FILE, linkmapFile.asSet());
if (dsymOutputType != null) {
@@ -698,7 +731,6 @@ public final class ObjcCommon {
ruleContext.getPrerequisiteArtifact("launch_storyboard", Mode.TARGET);
return launchStoryboard != null;
}
-
}
static final FileType BUNDLE_CONTAINER_TYPE = FileType.of(".bundle");
@@ -711,8 +743,7 @@ public final class ObjcCommon {
private final Optional<CompilationArtifacts> compilationArtifacts;
private ObjcCommon(
- ObjcProvider objcProvider,
- Optional<CompilationArtifacts> compilationArtifacts) {
+ ObjcProvider objcProvider, Optional<CompilationArtifacts> compilationArtifacts) {
this.objcProvider = Preconditions.checkNotNull(objcProvider);
this.compilationArtifacts = Preconditions.checkNotNull(compilationArtifacts);
}
@@ -738,9 +769,7 @@ public final class ObjcCommon {
}
static ImmutableList<PathFragment> userHeaderSearchPaths(BuildConfiguration configuration) {
- return ImmutableList.of(
- new PathFragment("."),
- configuration.getGenfilesFragment());
+ return ImmutableList.of(new PathFragment("."), configuration.getGenfilesFragment());
}
/**
@@ -842,8 +871,11 @@ public final class ObjcCommon {
for (Artifact artifact : artifacts) {
boolean inContainer = nearestContainerMatching(containerTypes, artifact).isPresent();
if (!inContainer) {
- errors.add(String.format(NOT_IN_CONTAINER_ERROR_FORMAT,
- artifact.getExecPath(), Iterables.toString(containerTypes)));
+ errors.add(
+ String.format(
+ NOT_IN_CONTAINER_ERROR_FORMAT,
+ artifact.getExecPath(),
+ Iterables.toString(containerTypes)));
}
}
return errors;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
index 86788d96ac..1b86ca0935 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFramework.java
@@ -24,7 +24,9 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.objc.ObjcCommon.Builder;
import com.google.devtools.build.lib.rules.objc.ObjcSdkFrameworks.Attributes;
+import com.google.devtools.build.lib.syntax.Type;
/**
* Implementation for the {@code objc_framework} rule.
@@ -34,15 +36,19 @@ public class ObjcFramework implements RuleConfiguredTargetFactory {
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
Attributes sdkFrameworkAttributes = new Attributes(ruleContext);
+ ObjcCommon.Builder commonBuilder =
+ new Builder(ruleContext)
+ .addExtraSdkFrameworks(sdkFrameworkAttributes.sdkFrameworks())
+ .addExtraWeakSdkFrameworks(sdkFrameworkAttributes.weakSdkFrameworks())
+ .addExtraSdkDylibs(sdkFrameworkAttributes.sdkDylibs());
+
ImmutableList<Artifact> frameworkImports =
ruleContext.getPrerequisiteArtifacts("framework_imports", Mode.TARGET).list();
- ObjcCommon common = new ObjcCommon.Builder(ruleContext)
- .addFrameworkImports(
- frameworkImports)
- .addExtraSdkFrameworks(sdkFrameworkAttributes.sdkFrameworks())
- .addExtraWeakSdkFrameworks(sdkFrameworkAttributes.weakSdkFrameworks())
- .addExtraSdkDylibs(sdkFrameworkAttributes.sdkDylibs())
- .build();
+ if (ruleContext.attributes().get("is_dynamic", Type.BOOLEAN)) {
+ commonBuilder.addDynamicFrameworkImports(frameworkImports);
+ } else {
+ commonBuilder.addStaticFrameworkImports(frameworkImports);
+ }
Iterable<String> containerErrors =
ObjcCommon.notInContainerErrors(frameworkImports, ObjcCommon.FRAMEWORK_CONTAINER_TYPE);
@@ -52,7 +58,7 @@ public class ObjcFramework implements RuleConfiguredTargetFactory {
NestedSet<Artifact> filesToBuild = NestedSetBuilder.emptySet(STABLE_ORDER);
return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild)
- .addProvider(ObjcProvider.class, common.getObjcProvider())
+ .addProvider(ObjcProvider.class, commonBuilder.build().getObjcProvider())
.build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
index a4c68ac4c6..9f264f9d4a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcFrameworkRule.java
@@ -22,6 +22,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileTypeSet;
/**
@@ -36,10 +37,16 @@ public class ObjcFrameworkRule implements RuleDefinition {
The list of files under a <code>.framework</code> directory which are
provided to Objective-C targets that depend on this target.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr("framework_imports", LABEL_LIST)
- .allowedFileTypes(FileTypeSet.ANY_FILE)
- .mandatory()
- .nonEmpty())
+ .add(
+ attr("framework_imports", LABEL_LIST)
+ .allowedFileTypes(FileTypeSet.ANY_FILE)
+ .mandatory()
+ .nonEmpty())
+ /* <!-- #BLAZE_RULE(objc_framework).ATTRIBUTE(is_dynamic) -->
+ Indicates whether this framework is linked dynamically. If this attribute is set, the
+ framework will be copied into the final application bundle.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("is_dynamic", Type.BOOLEAN).value(false))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index 8705e5728f..b44550036c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -228,11 +228,19 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
new Key<>(LINK_ORDER, "framework_dir", PathFragment.class);
/**
- * Files in {@code .framework} directories that should be included as inputs when compiling and
- * linking.
+ * Files in {@code .framework} directories belonging to a statically linked framework. They should
+ * be included as inputs when compiling and linking.
*/
- public static final Key<Artifact> FRAMEWORK_FILE =
- new Key<>(STABLE_ORDER, "framework_file", Artifact.class);
+ public static final Key<Artifact> STATIC_FRAMEWORK_FILE =
+ new Key<>(STABLE_ORDER, "static_framework_file", Artifact.class);
+
+ /**
+ * Files in {@code .framework} directories belonging to a dynamically linked framework. They
+ * should be included as inputs when compiling and linking as well as copied into the final
+ * application bundle.
+ */
+ public static final Key<Artifact> DYNAMIC_FRAMEWORK_FILE =
+ new Key<>(STABLE_ORDER, "dynamic_framework_file", Artifact.class);
/**
* Bundles which should be linked in as a nested bundle to the final application.
@@ -322,11 +330,6 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
USES_SWIFT,
/**
- * Indicates that the resulting bundle will have embedded frameworks. This affects linking step.
- */
- USES_FRAMEWORKS,
-
- /**
* Indicates that watch os 1 extension is present in the bundle.
*/
HAS_WATCH1_EXTENSION,
@@ -357,7 +360,8 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
XCDATAMODEL,
MODULE_MAP,
MERGE_ZIP,
- FRAMEWORK_FILE,
+ STATIC_FRAMEWORK_FILE,
+ DYNAMIC_FRAMEWORK_FILE,
DEBUG_SYMBOLS,
DEBUG_SYMBOLS_PLIST,
BREAKPAD_FILE,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
index 5115d33229..e3572eb85e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
@@ -488,13 +488,14 @@ public final class ReleaseBundlingSupport {
}
private String signingCommandLine() {
- 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.
+ ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>();
String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir());
- if (objcProvider.is(USES_SWIFT)) {
+
+ // Explicitly sign the frameworks (raw .dylib files and .framework directories in Frameworks/).
+ // Unfortunately the --deep option on codesign doesn't do this automatically.
+ if (objcProvider.is(USES_SWIFT)
+ || !objcProvider.get(ObjcProvider.DYNAMIC_FRAMEWORK_FILE).isEmpty()) {
dirsToSign.add(bundleDir + "/Frameworks/*");
}
dirsToSign.add(bundleDir);
@@ -686,21 +687,25 @@ public final class ReleaseBundlingSupport {
// We want access to #import-able things from our test rig's dependency graph, but we don't
// want to link anything since that stuff is shared automatically by way of the
// -bundle_loader linker flag.
- ObjcProvider partialObjcProvider = new ObjcProvider.Builder()
- .addTransitiveAndPropagate(ObjcProvider.HEADER, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.INCLUDE, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.DEFINE, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.SDK_DYLIB, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.SDK_FRAMEWORK, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.SOURCE, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.WEAK_SDK_FRAMEWORK, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.FRAMEWORK_DIR, objcProvider)
- .addTransitiveAndPropagate(ObjcProvider.FRAMEWORK_FILE, objcProvider)
- .build();
+ ObjcProvider partialObjcProvider =
+ new ObjcProvider.Builder()
+ .addTransitiveAndPropagate(ObjcProvider.HEADER, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.INCLUDE, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.DEFINE, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.SDK_DYLIB, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.SDK_FRAMEWORK, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.SOURCE, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.WEAK_SDK_FRAMEWORK, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.FRAMEWORK_DIR, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.STATIC_FRAMEWORK_FILE, objcProvider)
+ .addTransitiveAndPropagate(ObjcProvider.DYNAMIC_FRAMEWORK_FILE, objcProvider)
+ .build();
// TODO(bazel-team): Handle the FRAMEWORK_DIR key properly. We probably want to add it to
// framework search paths, but not actually link it with the -framework flag.
- return new XcTestAppProvider(intermediateArtifacts
- .combinedArchitectureBinary(), releaseBundling.getIpaArtifact(), partialObjcProvider);
+ return new XcTestAppProvider(
+ intermediateArtifacts.combinedArchitectureBinary(),
+ releaseBundling.getIpaArtifact(),
+ partialObjcProvider);
}
/**