예제 #1
0
  private StepExecutionResult executeCCompilation(
      ExecutionContext context, ImmutableList.Builder<Path> linkerInputs)
      throws IOException, InterruptedException {

    ImmutableList.Builder<String> cCompileFlags = ImmutableList.builder();
    cCompileFlags.addAll(ocamlContext.getCCompileFlags());
    cCompileFlags.addAll(ocamlContext.getCommonCFlags());

    CxxPreprocessorInput cxxPreprocessorInput = ocamlContext.getCxxPreprocessorInput();

    for (SourcePath cSrc : ocamlContext.getCInput()) {
      Path outputPath = ocamlContext.getCOutput(resolver.getAbsolutePath(cSrc));
      linkerInputs.add(outputPath);
      Step compileStep =
          new OCamlCCompileStep(
              resolver,
              filesystem.getRootPath(),
              new OCamlCCompileStep.Args(
                  cCompilerEnvironment,
                  cCompiler,
                  ocamlContext.getOcamlCompiler().get(),
                  ocamlContext.getOCamlInteropIncludesDir(),
                  outputPath,
                  cSrc,
                  cCompileFlags.build(),
                  cxxPreprocessorInput.getIncludes()));
      StepExecutionResult compileExecutionResult = compileStep.execute(context);
      if (!compileExecutionResult.isSuccess()) {
        return compileExecutionResult;
      }
    }
    return StepExecutionResult.SUCCESS;
  }
예제 #2
0
 private StepExecutionResult executeMLBytecodeCompilation(
     ExecutionContext context,
     Path workingDirectory,
     ImmutableList<Path> sortedInput,
     ImmutableList.Builder<Path> linkerInputs)
     throws IOException, InterruptedException {
   MakeCleanDirectoryStep mkDir =
       new MakeCleanDirectoryStep(filesystem, ocamlContext.getCompileBytecodeOutputDir());
   StepExecutionResult mkDirExecutionResult = mkDir.execute(context);
   if (!mkDirExecutionResult.isSuccess()) {
     return mkDirExecutionResult;
   }
   for (Path inputOutput : sortedInput) {
     String inputFileName = inputOutput.getFileName().toString();
     String outputFileName =
         inputFileName
             .replaceFirst(OCamlCompilables.OCAML_ML_REGEX, OCamlCompilables.OCAML_CMO)
             .replaceFirst(OCamlCompilables.OCAML_RE_REGEX, OCamlCompilables.OCAML_CMO)
             .replaceFirst(OCamlCompilables.OCAML_MLI_REGEX, OCamlCompilables.OCAML_CMI)
             .replaceFirst(OCamlCompilables.OCAML_REI_REGEX, OCamlCompilables.OCAML_CMI);
     Path outputPath = ocamlContext.getCompileBytecodeOutputDir().resolve(outputFileName);
     if (!outputFileName.endsWith(OCamlCompilables.OCAML_CMI)) {
       linkerInputs.add(outputPath);
     }
     final ImmutableList<String> compileFlags =
         getCompileFlags(/* isBytecode */ true, /* excludeDeps */ false);
     Step compileBytecodeStep =
         new OCamlMLCompileStep(
             workingDirectory,
             resolver,
             new OCamlMLCompileStep.Args(
                 filesystem.getAbsolutifier(),
                 cCompilerEnvironment,
                 cCompiler,
                 ocamlContext.getOcamlBytecodeCompiler().get(),
                 ocamlContext.getOCamlInteropIncludesDir(),
                 outputPath,
                 inputOutput,
                 compileFlags));
     StepExecutionResult compileExecutionResult = compileBytecodeStep.execute(context);
     if (!compileExecutionResult.isSuccess()) {
       return compileExecutionResult;
     }
   }
   return StepExecutionResult.SUCCESS;
 }
예제 #3
0
 @Override
 public StepExecutionResult execute(ExecutionContext context)
     throws IOException, InterruptedException {
   ImmutableList<String> lldbCommandPrefix = lldb.getCommandPrefix(resolver);
   ProcessExecutorParams params =
       ProcessExecutorParams.builder()
           .addCommand(lldbCommandPrefix.toArray(new String[lldbCommandPrefix.size()]))
           .build();
   return StepExecutionResult.of(
       context
           .getProcessExecutor()
           .launchAndExecute(
               params,
               ImmutableSet.<ProcessExecutor.Option>of(),
               Optional.of(
                   String.format(
                       "target create %s\ntarget symbols add %s",
                       binaryBuildRule.getPathToOutput(), location)),
               Optional.<Long>absent(),
               Optional.<Function<Process, Void>>absent())
           .getExitCode());
 }
예제 #4
0
 private StepExecutionResult generateSources(ExecutionContext context, Path workingDirectory)
     throws IOException, InterruptedException {
   MakeCleanDirectoryStep mkDir =
       new MakeCleanDirectoryStep(filesystem, ocamlContext.getGeneratedSourceDir());
   StepExecutionResult mkDirExecutionResult = mkDir.execute(context);
   if (!mkDirExecutionResult.isSuccess()) {
     return mkDirExecutionResult;
   }
   for (SourcePath yaccSource : ocamlContext.getYaccInput()) {
     SourcePath output = ocamlContext.getYaccOutput(ImmutableSet.of(yaccSource)).get(0);
     OCamlYaccStep yaccStep =
         new OCamlYaccStep(
             workingDirectory,
             resolver,
             new OCamlYaccStep.Args(
                 ocamlContext.getYaccCompiler().get(),
                 resolver.getAbsolutePath(output),
                 resolver.getAbsolutePath(yaccSource)));
     StepExecutionResult yaccExecutionResult = yaccStep.execute(context);
     if (!yaccExecutionResult.isSuccess()) {
       return yaccExecutionResult;
     }
   }
   for (SourcePath lexSource : ocamlContext.getLexInput()) {
     SourcePath output = ocamlContext.getLexOutput(ImmutableSet.of(lexSource)).get(0);
     OCamlLexStep lexStep =
         new OCamlLexStep(
             workingDirectory,
             resolver,
             new OCamlLexStep.Args(
                 ocamlContext.getLexCompiler().get(),
                 resolver.getAbsolutePath(output),
                 resolver.getAbsolutePath(lexSource)));
     StepExecutionResult lexExecutionResult = lexStep.execute(context);
     if (!lexExecutionResult.isSuccess()) {
       return lexExecutionResult;
     }
   }
   return StepExecutionResult.SUCCESS;
 }
예제 #5
0
  @Override
  public StepExecutionResult execute(ExecutionContext context)
      throws IOException, InterruptedException {
    if (hasGeneratedSources) {
      StepExecutionResult genExecutionResult = generateSources(context, filesystem.getRootPath());
      if (!genExecutionResult.isSuccess()) {
        return genExecutionResult;
      }
    }

    StepExecutionResult depToolExecutionResult = depToolStep.execute(context);
    if (!depToolExecutionResult.isSuccess()) {
      return depToolExecutionResult;
    }

    // OCaml requires module A to be present in command line to ocamlopt or ocamlc before
    // module B if B depends on A. In OCaml circular dependencies are prohibited, so all
    // dependency relations among modules form DAG. Topologically sorting this graph satisfies the
    // requirement.
    //
    // To get the DAG we launch ocamldep tool which provides the direct dependency information, like
    // module A depends on modules B, C, D.
    ImmutableList<Path> sortedInput =
        sortDependency(
            depToolStep.getStdout(),
            ocamlContext.getSourcePathResolver().getAllAbsolutePaths(ocamlContext.getMLInput()));

    ImmutableList.Builder<Path> nativeLinkerInputs = ImmutableList.builder();

    if (!bytecodeOnly) {
      StepExecutionResult mlCompileNativeExecutionResult =
          executeMLNativeCompilation(
              context, filesystem.getRootPath(), sortedInput, nativeLinkerInputs);
      if (!mlCompileNativeExecutionResult.isSuccess()) {
        return mlCompileNativeExecutionResult;
      }
    }

    ImmutableList.Builder<Path> bytecodeLinkerInputs = ImmutableList.builder();
    StepExecutionResult mlCompileBytecodeExecutionResult =
        executeMLBytecodeCompilation(
            context, filesystem.getRootPath(), sortedInput, bytecodeLinkerInputs);
    if (!mlCompileBytecodeExecutionResult.isSuccess()) {
      return mlCompileBytecodeExecutionResult;
    }

    ImmutableList.Builder<Path> cLinkerInputs = ImmutableList.builder();
    StepExecutionResult cCompileExecutionResult = executeCCompilation(context, cLinkerInputs);
    if (!cCompileExecutionResult.isSuccess()) {
      return cCompileExecutionResult;
    }

    ImmutableList<Path> cObjects = cLinkerInputs.build();

    if (!bytecodeOnly) {
      nativeLinkerInputs.addAll(cObjects);
      StepExecutionResult nativeLinkExecutionResult =
          executeNativeLinking(context, nativeLinkerInputs.build());
      if (!nativeLinkExecutionResult.isSuccess()) {
        return nativeLinkExecutionResult;
      }
    }

    bytecodeLinkerInputs.addAll(cObjects);
    StepExecutionResult bytecodeLinkExecutionResult =
        executeBytecodeLinking(context, bytecodeLinkerInputs.build());
    if (!bytecodeLinkExecutionResult.isSuccess()) {
      return bytecodeLinkExecutionResult;
    }

    if (!ocamlContext.isLibrary()) {
      Step debugLauncher =
          new OCamlDebugLauncherStep(
              filesystem,
              resolver,
              new OCamlDebugLauncherStep.Args(
                  ocamlContext.getOcamlDebug().get(),
                  ocamlContext.getBytecodeOutput(),
                  ocamlContext.getOCamlInput(),
                  ocamlContext.getBytecodeIncludeFlags()));
      return debugLauncher.execute(context);
    } else {
      return StepExecutionResult.SUCCESS;
    }
  }