private TransitiveLipoInfoProvider collectTransitiveLipoInfo(CcCompilationOutputs outputs) { if (CppHelper.getFdoSupport(ruleContext).getFdoRoot() == null) { return TransitiveLipoInfoProvider.EMPTY; } NestedSetBuilder<IncludeScannable> scannableBuilder = NestedSetBuilder.stableOrder(); // TODO(bazel-team): Only fetch the STL prerequisite in one place. TransitiveInfoCollection stl = ruleContext.getPrerequisite(":stl", Mode.TARGET); if (stl != null) { TransitiveLipoInfoProvider provider = stl.getProvider(TransitiveLipoInfoProvider.class); if (provider != null) { scannableBuilder.addTransitive(provider.getTransitiveIncludeScannables()); } } for (TransitiveLipoInfoProvider dep : AnalysisUtils.getProviders(deps, TransitiveLipoInfoProvider.class)) { scannableBuilder.addTransitive(dep.getTransitiveIncludeScannables()); } for (IncludeScannable scannable : outputs.getLipoScannables()) { Preconditions.checkState(scannable.getIncludeScannerSources().size() == 1); scannableBuilder.add(scannable); } return new TransitiveLipoInfoProvider(scannableBuilder.build()); }
/** * Returns the files transitively included by the source files of the given IncludeScannable. * * @param action IncludeScannable whose sources' transitive includes will be returned. * @param includeScannerSupplier supplies IncludeScanners to actually do the transitive scanning * (and caching results) for a given source file. * @param actionExecutionContext the context for {@code action}. * @param profilerTaskName what the {@link Profiler} should record this call for. */ public static Collection<Artifact> scanForIncludedInputs( IncludeScannable action, IncludeScannerSupplier includeScannerSupplier, ActionExecutionContext actionExecutionContext, String profilerTaskName) throws ExecException, InterruptedException, ActionExecutionException { Set<Artifact> includes = Sets.newConcurrentHashSet(); final List<PathFragment> absoluteBuiltInIncludeDirs = new ArrayList<>(); Artifact builtInInclude = action.getBuiltInIncludeFile(); if (builtInInclude != null) { includes.add(builtInInclude); } Profiler profiler = Profiler.instance(); try { profiler.startTask(ProfilerTask.SCANNER, profilerTaskName); // We need to scan the action itself, but also the auxiliary scannables // (for LIPO). There is no need to call getAuxiliaryScannables // recursively. for (IncludeScannable scannable : Iterables.concat(ImmutableList.of(action), action.getAuxiliaryScannables())) { Map<Artifact, Artifact> legalOutputPaths = scannable.getLegalGeneratedScannerFileMap(); // Deduplicate include directories. This can occur especially with "built-in" and "system" // include directories because of the way we retrieve them. Duplicate include directories // really mess up #include_next directives. Set<PathFragment> includeDirs = new LinkedHashSet<>(scannable.getIncludeDirs()); List<PathFragment> quoteIncludeDirs = scannable.getQuoteIncludeDirs(); List<String> cmdlineIncludes = scannable.getCmdlineIncludes(); includeDirs.addAll(scannable.getSystemIncludeDirs()); // Add the system include paths to the list of include paths. for (PathFragment pathFragment : action.getBuiltInIncludeDirectories()) { if (pathFragment.isAbsolute()) { absoluteBuiltInIncludeDirs.add(pathFragment); } includeDirs.add(pathFragment); } List<PathFragment> includeDirList = ImmutableList.copyOf(includeDirs); IncludeScanner scanner = includeScannerSupplier.scannerFor(quoteIncludeDirs, includeDirList); Artifact mainSource = scannable.getMainIncludeScannerSource(); Collection<Artifact> sources = scannable.getIncludeScannerSources(); scanner.process( mainSource, sources, legalOutputPaths, quoteIncludeDirs, includeDirList, cmdlineIncludes, includes, actionExecutionContext); } } catch (IOException e) { throw new EnvironmentalExecException(e.getMessage()); } finally { profiler.completeTask(ProfilerTask.SCANNER); } // Collect inputs and output List<Artifact> inputs = new ArrayList<>(); for (Artifact included : includes) { if (FileSystemUtils.startsWithAny( included.getPath().asFragment(), absoluteBuiltInIncludeDirs)) { // Skip include files found in absolute include directories. continue; } if (included.getRoot().getPath().getParentDirectory() == null) { throw new UserExecException( "illegal absolute path to include file: " + included.getPath()); } inputs.add(included); } return inputs; }