Ejemplo n.º 1
0
 private static ImmutableList<Artifact> computeInputs(
     Artifact inputManifest, Artifact artifactMiddleman) {
   ImmutableList.Builder<Artifact> result = ImmutableList.<Artifact>builder().add(inputManifest);
   if (artifactMiddleman != null
       && !artifactMiddleman.getPath().getFileSystem().supportsSymbolicLinksNatively()) {
     result.add(artifactMiddleman);
   }
   return result.build();
 }
Ejemplo n.º 2
0
 @Override
 public void setUp() throws Exception {
   super.setUp();
   input = scratch.file("input.txt", "Hello, world.");
   inputArtifact = getSourceArtifact("input.txt");
   Path linkedInput = directories.getExecRoot().getRelative("input.txt");
   FileSystemUtils.createDirectoryAndParents(linkedInput.getParentDirectory());
   linkedInput.createSymbolicLink(input);
   outputArtifact = getBinArtifactWithNoOwner("destination.txt");
   output = outputArtifact.getPath();
   FileSystemUtils.createDirectoryAndParents(output.getParentDirectory());
   action = new SymlinkAction(NULL_ACTION_OWNER, inputArtifact, outputArtifact, "Symlinking test");
 }
Ejemplo n.º 3
0
 /**
  * Creates SymlinkTreeAction instance.
  *
  * @param owner action owner
  * @param inputManifest the input runfiles manifest
  * @param artifactMiddleman the middleman artifact representing all the files the symlinks point
  *     to (on Windows we need to know if the target of a "symlink" is a directory or a file so we
  *     need to build it before)
  * @param outputManifest the generated symlink tree manifest (must have "MANIFEST" base name).
  *     Symlink tree root will be set to the artifact's parent directory.
  * @param filesetTree true if this is fileset symlink tree, false if this is a runfiles symlink
  *     tree.
  */
 public SymlinkTreeAction(
     ActionOwner owner,
     Artifact inputManifest,
     @Nullable Artifact artifactMiddleman,
     Artifact outputManifest,
     boolean filesetTree,
     PathFragment shExecutable) {
   super(owner, computeInputs(inputManifest, artifactMiddleman), ImmutableList.of(outputManifest));
   Preconditions.checkArgument(outputManifest.getPath().getBaseName().equals("MANIFEST"));
   this.inputManifest = inputManifest;
   this.outputManifest = outputManifest;
   this.filesetTree = filesetTree;
   this.shExecutable = shExecutable;
 }
Ejemplo n.º 4
0
 public void testExecutableSymlink() throws Exception {
   Executor executor = new TestExecutorBuilder(directories, null).build();
   outputArtifact = getBinArtifactWithNoOwner("destination2.txt");
   output = outputArtifact.getPath();
   action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, inputArtifact, outputArtifact);
   assertFalse(input.isExecutable());
   ActionExecutionContext actionExecutionContext =
       new ActionExecutionContext(executor, null, null, null, null);
   try {
     action.execute(actionExecutionContext);
     fail("Expected ActionExecutionException");
   } catch (ActionExecutionException e) {
     MoreAsserts.assertContainsRegex("'input.txt' is not executable", e.getMessage());
   }
   input.setExecutable(true);
   action.execute(actionExecutionContext);
   assertTrue(output.isSymbolicLink());
   assertEquals(input, output.resolveSymbolicLinks());
 }
  protected void createActions(
      ConfiguredTarget base,
      RuleContext ruleContext,
      Iterable<Artifact> protoSources,
      NestedSet<Artifact> transitiveProtoSources,
      Iterable<Artifact> headerMappingFiles,
      Iterable<Artifact> classMappingFiles,
      J2ObjcSource j2ObjcSource) {
    String genDir = ruleContext.getConfiguration().getGenfilesDirectory().getExecPathString();
    Artifact compiler = ruleContext.getPrerequisiteArtifact("$protoc_darwin", Mode.HOST);
    Artifact j2objcPlugin = ruleContext.getPrerequisiteArtifact("$j2objc_plugin", Mode.HOST);

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .setMnemonic("TranslatingJ2ObjcProtos")
            .addInput(compiler)
            .addInput(j2objcPlugin)
            .addInputs(
                ruleContext.getPrerequisiteArtifacts("$protoc_support_darwin", Mode.HOST).list())
            .addInputs(protoSources)
            .addTransitiveInputs(transitiveProtoSources)
            .addOutputs(j2ObjcSource.getObjcSrcs())
            .addOutputs(j2ObjcSource.getObjcHdrs())
            .addOutputs(headerMappingFiles)
            .addOutputs(classMappingFiles)
            .setExecutable(new PathFragment("/usr/bin/python"))
            .setCommandLine(
                new CustomCommandLine.Builder()
                    .add(compiler.getPath().toString())
                    .add("-w")
                    .add(compiler.getRoot().getPath().toString())
                    .add("--generate-j2objc")
                    .add("--generator-param=file_dir_mapping")
                    .add("--generator-param=generate_class_mappings")
                    .add("--j2objc-plugin=" + j2objcPlugin.getExecPathString())
                    .add("--output-dir=" + genDir)
                    .addExecPaths(protoSources)
                    .build())
            .setExecutionInfo(ImmutableMap.of(ExecutionRequirements.REQUIRES_DARWIN, ""))
            .build(ruleContext));
  }
    /**
     * Finds and validates the resource directory PathFragment from the artifact Path.
     *
     * <p>If the artifact is not a Fileset, the resource directory is presumed to be the second
     * directory from the end. Filesets are expect to have the last directory as the resource
     * directory.
     */
    public static PathFragment findResourceDir(Artifact artifact) {
      PathFragment fragment = artifact.getPath().asFragment();
      int segmentCount = fragment.segmentCount();
      if (segmentCount < 3) {
        return null;
      }
      // TODO(bazel-team): Expand Fileset to verify, or remove Fileset as an option for resources.
      if (artifact.isFileset()) {
        return fragment.subFragment(segmentCount - 1, segmentCount);
      }

      // Check the resource folder type layout.
      // get the prefix of the parent folder of the fragment.
      String parentDirectory = fragment.getSegment(segmentCount - 2);
      int dashIndex = parentDirectory.indexOf('-');
      String androidFolder =
          dashIndex == -1 ? parentDirectory : parentDirectory.substring(0, dashIndex);
      if (!RESOURCE_DIRECTORY_TYPES.contains(androidFolder)) {
        return null;
      }

      return fragment.subFragment(segmentCount - 3, segmentCount - 2);
    }
Ejemplo n.º 7
0
    /**
     * 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;
    }
Ejemplo n.º 8
0
  private void setupCompileBuildVariables(
      CppCompileActionBuilder builder,
      boolean usePic,
      PathFragment ccRelativeName,
      PathFragment autoFdoImportPath,
      Artifact gcnoFile,
      Artifact dwoFile,
      Map<String, String> sourceSpecificBuildVariables) {
    CcToolchainFeatures.Variables.Builder buildVariables =
        new CcToolchainFeatures.Variables.Builder();

    // TODO(bazel-team): Pull out string constants for all build variables.

    CppCompilationContext builderContext = builder.getContext();
    CppModuleMap cppModuleMap = builderContext.getCppModuleMap();
    Artifact sourceFile = builder.getSourceFile();
    Artifact outputFile = builder.getOutputFile();
    String realOutputFilePath;

    buildVariables.addVariable("source_file", sourceFile.getExecPathString());
    buildVariables.addVariable("output_file", outputFile.getExecPathString());

    if (builder.getTempOutputFile() != null) {
      realOutputFilePath = builder.getTempOutputFile().getPathString();
    } else {
      realOutputFilePath = builder.getOutputFile().getExecPathString();
    }

    if (FileType.contains(outputFile, CppFileTypes.ASSEMBLER, CppFileTypes.PIC_ASSEMBLER)) {
      buildVariables.addVariable("output_assembly_file", realOutputFilePath);
    } else if (FileType.contains(
        outputFile,
        CppFileTypes.PREPROCESSED_C,
        CppFileTypes.PREPROCESSED_CPP,
        CppFileTypes.PIC_PREPROCESSED_C,
        CppFileTypes.PIC_PREPROCESSED_CPP)) {
      buildVariables.addVariable("output_preprocess_file", realOutputFilePath);
    } else {
      buildVariables.addVariable("output_object_file", realOutputFilePath);
    }

    DotdFile dotdFile =
        CppFileTypes.mustProduceDotdFile(sourceFile.getPath().toString())
            ? Preconditions.checkNotNull(builder.getDotdFile())
            : null;
    // Set dependency_file to enable <object>.d file generation.
    if (dotdFile != null) {
      buildVariables.addVariable("dependency_file", dotdFile.getSafeExecPath().getPathString());
    }

    if (featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAPS) && cppModuleMap != null) {
      // If the feature is enabled and cppModuleMap is null, we are about to fail during analysis
      // in any case, but don't crash.
      buildVariables.addVariable("module_name", cppModuleMap.getName());
      buildVariables.addVariable("module_map_file", cppModuleMap.getArtifact().getExecPathString());
      CcToolchainFeatures.Variables.ValueSequence.Builder sequence =
          new CcToolchainFeatures.Variables.ValueSequence.Builder();
      for (Artifact artifact : builderContext.getDirectModuleMaps()) {
        sequence.addValue(artifact.getExecPathString());
      }
      buildVariables.addSequence("dependent_module_map_files", sequence.build());
    }
    if (featureConfiguration.isEnabled(CppRuleClasses.USE_HEADER_MODULES)) {
      buildVariables.addSequenceVariable("module_files", getHeaderModulePaths(builder, usePic));
    }
    if (featureConfiguration.isEnabled(CppRuleClasses.INCLUDE_PATHS)) {
      buildVariables.addSequenceVariable(
          "include_paths", getSafePathStrings(builderContext.getIncludeDirs()));
      buildVariables.addSequenceVariable(
          "quote_include_paths", getSafePathStrings(builderContext.getQuoteIncludeDirs()));
      buildVariables.addSequenceVariable(
          "system_include_paths", getSafePathStrings(builderContext.getSystemIncludeDirs()));
    }

    if (featureConfiguration.isEnabled(CppRuleClasses.PREPROCESSOR_DEFINES)) {
      String fdoBuildStamp = CppHelper.getFdoBuildStamp(ruleContext);
      ImmutableList<String> defines;
      if (fdoBuildStamp != null) {
        // Stamp FDO builds with FDO subtype string
        defines =
            ImmutableList.<String>builder()
                .addAll(builderContext.getDefines())
                .add(
                    CppConfiguration.FDO_STAMP_MACRO
                        + "=\""
                        + CppHelper.getFdoBuildStamp(ruleContext)
                        + "\"")
                .build();
      } else {
        defines = builderContext.getDefines();
      }

      buildVariables.addSequenceVariable("preprocessor_defines", defines);
    }

    if (usePic) {
      if (!featureConfiguration.isEnabled(CppRuleClasses.PIC)) {
        ruleContext.ruleError("PIC compilation is requested but the toolchain does not support it");
      }
      buildVariables.addVariable("pic", "");
    }

    if (ccRelativeName != null) {
      CppHelper.getFdoSupport(ruleContext)
          .configureCompilation(
              builder,
              buildVariables,
              ruleContext,
              ccRelativeName,
              autoFdoImportPath,
              usePic,
              featureConfiguration);
    }
    if (gcnoFile != null) {
      buildVariables.addVariable("gcov_gcno_file", gcnoFile.getExecPathString());
    }

    if (dwoFile != null) {
      buildVariables.addVariable("per_object_debug_info_file", dwoFile.getExecPathString());
    }

    buildVariables.addAllVariables(CppHelper.getToolchain(ruleContext).getBuildVariables());

    buildVariables.addAllVariables(sourceSpecificBuildVariables);

    for (VariablesExtension extension : variablesExtensions) {
      extension.addVariables(buildVariables);
    }

    CcToolchainFeatures.Variables variables = buildVariables.build();
    builder.setVariables(variables);
  }