/** * Adds required configuration to the XcodeProvider support class for proto compilation. * * @param xcodeProviderBuilder The builder for the XcodeProvider support class. * @return this proto support */ public ProtoSupport addXcodeProviderOptions(XcodeProvider.Builder xcodeProviderBuilder) { xcodeProviderBuilder .addUserHeaderSearchPaths(getUserHeaderSearchPaths()) .addCopts(ObjcRuleClasses.objcConfiguration(ruleContext).getCopts()) .addHeaders(getGeneratedHeaders()) .setCompilationArtifacts(getCompilationArtifacts()); return this; }
/** * Adds bundle- and application-related settings to the given Xcode provider builder. * * @return this application support */ ReleaseBundlingSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder) { bundleSupport.addXcodeSettings(xcodeProviderBuilder); // Add application-related Xcode build settings to the main target only. The companion library // target does not need them. xcodeProviderBuilder.addMainTargetXcodeprojBuildSettings(buildSettings()); return this; }
@Override public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException { ObjcCommon common = common( ruleContext, ImmutableList.<SdkFramework>of(), ruleContext.attributes().get("alwayslink", Type.BOOLEAN), new ExtraImportLibraries(), ImmutableList.<ObjcProvider>of()); XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder(); NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().addAll(common.getCompiledArchive().asSet()); new CompilationSupport(ruleContext) .registerCompileAndArchiveActions(common) .addXcodeSettings(xcodeProviderBuilder, common) .validateAttributes(); new ResourceSupport(ruleContext).validateAttributes().addXcodeSettings(xcodeProviderBuilder); new XcodeSupport(ruleContext) .addFilesToBuild(filesToBuild) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC) .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)) .addNonPropagatedDependencies( xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET)) .registerActions(xcodeProviderBuilder.build()); return ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()) .addProvider(XcodeProvider.class, xcodeProviderBuilder.build()) .addProvider(ObjcProvider.class, common.getObjcProvider()) .addProvider(J2ObjcSrcsProvider.class, J2ObjcSrcsProvider.buildFrom(ruleContext)) .addProvider( J2ObjcMappingFileProvider.class, ObjcRuleClasses.j2ObjcMappingFileProvider(ruleContext)) .build(); }
/** * Adds a dummy source file to the Xcode target. This is needed if the target does not have any * source files but Xcode requires one. * * @return this xcode support */ XcodeSupport addDummySource(XcodeProvider.Builder xcodeProviderBuilder) { xcodeProviderBuilder.addAdditionalSources( ruleContext.getPrerequisiteArtifact("$dummy_source", Mode.TARGET)); return this; }
/** * {@inheritDoc} * * <p>Creates a target, including registering actions, just as {@link #create(RuleContext)} does. * The difference between {@link #create(RuleContext)} and this method is that this method does * only what is needed to support tests on the environment besides generate the Xcodeproj file and * build the app and test {@code .ipa}s. The {@link #create(RuleContext)} method delegates to this * method. */ @Override public final ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException { ProtobufSupport protoSupport = new ProtobufSupport(ruleContext).registerGenerationActions().registerCompilationActions(); Optional<ObjcProvider> protosObjcProvider = protoSupport.getObjcProvider(); Optional<XcodeProvider> protosXcodeProvider = protoSupport.getXcodeProvider(); ObjcCommon common = common(ruleContext, protosObjcProvider); if (!common.getCompilationArtifacts().get().getArchive().isPresent()) { ruleContext.ruleError(REQUIRES_SOURCE_ERROR); } if (!ruleContext.getFragment(AppleConfiguration.class).getIosMultiCpus().isEmpty()) { ruleContext.ruleError(NO_MULTI_CPUS_ERROR); } XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder().addPropagatedDependencies(protosXcodeProvider.asSet()); NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder(); addResourceFilesToBuild(ruleContext, common.getObjcProvider(), filesToBuild); XcodeProductType productType = getProductType(ruleContext); ExtraLinkArgs extraLinkArgs; Iterable<Artifact> extraLinkInputs; String bundleFormat; if (!isXcTest(ruleContext)) { extraLinkArgs = new ExtraLinkArgs(); extraLinkInputs = ImmutableList.of(); bundleFormat = ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT; } else { XcodeProvider appIpaXcodeProvider = ruleContext.getPrerequisite(XCTEST_APP_ATTR, Mode.TARGET, XcodeProvider.class); xcodeProviderBuilder.setTestHost(appIpaXcodeProvider).setProductType(productType); XcTestAppProvider testApp = xcTestAppProvider(ruleContext); Artifact bundleLoader = testApp.getBundleLoader(); // -bundle causes this binary to be linked as a bundle and not require an entry point // (i.e. main()) // -bundle_loader causes the code in this test to have access to the symbols in the test rig, // or more specifically, the flag causes ld to consider the given binary when checking for // missing symbols. // -rpath @loader_path/Frameworks allows test bundles to load dylibs from the app's // Frameworks directory. extraLinkArgs = new ExtraLinkArgs( "-bundle", "-bundle_loader", bundleLoader.getExecPathString(), "-Xlinker", "-rpath", "-Xlinker", "@loader_path/Frameworks"); extraLinkInputs = ImmutableList.of(bundleLoader); bundleFormat = ReleaseBundlingSupport.XCTEST_BUNDLE_DIR_FORMAT; filesToBuild.add(testApp.getIpa()); } J2ObjcMappingFileProvider j2ObjcMappingFileProvider = J2ObjcMappingFileProvider.union( ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcMappingFileProvider.class)); J2ObjcEntryClassProvider j2ObjcEntryClassProvider = new J2ObjcEntryClassProvider.Builder() .addTransitive( ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcEntryClassProvider.class)) .build(); new CompilationSupport(ruleContext) .registerLinkActions( common.getObjcProvider(), j2ObjcMappingFileProvider, j2ObjcEntryClassProvider, extraLinkArgs, extraLinkInputs, DsymOutputType.TEST) .registerCompileAndArchiveActions(common) .registerFullyLinkAction( common.getObjcProvider(), ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB)) .addXcodeSettings(xcodeProviderBuilder, common) .validateAttributes(); AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); new ReleaseBundlingSupport( ruleContext, common.getObjcProvider(), LinkedBinary.LOCAL_AND_DEPENDENCIES, bundleFormat, appleConfiguration.getMinimumOsForPlatformType(PlatformType.IOS), appleConfiguration.getMultiArchPlatform(PlatformType.IOS)) .registerActions(DsymOutputType.TEST) .addXcodeSettings(xcodeProviderBuilder) .addFilesToBuild(filesToBuild, Optional.of(DsymOutputType.TEST)) .validateResources() .validateAttributes(); new ResourceSupport(ruleContext).validateAttributes().addXcodeSettings(xcodeProviderBuilder); new XcodeSupport(ruleContext) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), productType) .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)) .addNonPropagatedDependencies( xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET)) .addFilesToBuild(filesToBuild) .registerActions(xcodeProviderBuilder.build()); XcodeProvider xcodeProvider = xcodeProviderBuilder.build(); NestedSet<Artifact> filesToBuildSet = filesToBuild.build(); Runfiles.Builder runfilesBuilder = new Runfiles.Builder( ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()) .addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES); NestedSetBuilder<Artifact> filesToBuildBuilder = NestedSetBuilder.<Artifact>stableOrder().addTransitive(filesToBuildSet); InstrumentedFilesProvider instrumentedFilesProvider = new CompilationSupport(ruleContext).getInstrumentedFilesProvider(common); TestSupport testSupport = new TestSupport(ruleContext) .registerTestRunnerActions() .addRunfiles(runfilesBuilder, instrumentedFilesProvider) .addFilesToBuild(filesToBuildBuilder); Artifact executable = testSupport.generatedTestScript(); Runfiles runfiles = runfilesBuilder.build(); RunfilesSupport runfilesSupport = RunfilesSupport.withExecutable(ruleContext, runfiles, executable); ImmutableMap.Builder<String, String> execInfoMapBuilder = new ImmutableMap.Builder<>(); execInfoMapBuilder.put(ExecutionRequirements.REQUIRES_DARWIN, ""); if (ruleContext.getFragment(ObjcConfiguration.class).runMemleaks()) { execInfoMapBuilder.put("nosandbox", ""); } return new RuleConfiguredTargetBuilder(ruleContext) .setFilesToBuild(filesToBuildBuilder.build()) .addProvider(xcodeProvider) .addProvider(RunfilesProvider.simple(runfiles)) .addProvider(new ExecutionInfoProvider(execInfoMapBuilder.build())) .addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider) .addProviders(testSupport.getExtraProviders()) .setRunfilesSupport(runfilesSupport, executable) .build(); }