コード例 #1
0
  @Override
  protected IProject[] build(
      final int kind, @SuppressWarnings("unchecked") final Map args, final IProgressMonitor monitor)
      throws CoreException {

    // don't start two builds simultaneously
    synchronized (buildMutex) {
      if (building) {
        // System.out.println("already building: aborting");
        return null;
      } else building = true;
    }

    final IProgressMonitor buildMonitor;
    if (monitor == null) buildMonitor = new NullProgressMonitor();
    else buildMonitor = monitor;

    try {
      if (kind == CLEAN_BUILD) buildMonitor.beginTask("Cleaning Project", IProgressMonitor.UNKNOWN);
      else buildMonitor.beginTask("Making Project", IProgressMonitor.UNKNOWN);

      final IProject project;
      if (this.project == null) project = this.getProject();
      else project = this.project;

      if (kind == IncrementalProjectBuilder.AUTO_BUILD) return null;

      String makeCmd = "";
      MakeUtility makeUtility = new MakeUtility(project);
      switch (makeUtility.getVariant()) {
        case GNU_MAKE:
          makeCmd = OcamlPlugin.getMakeFullPath();
          break;
        case OMAKE:
          makeCmd = OcamlPlugin.getOMakeFullPath();
          break;
      }
      makeCmd = makeCmd.trim();
      if (makeCmd.trim().equals("")) {
        OcamlPlugin.logError(
            "The "
                + MakeUtility.getName(makeUtility.getVariant())
                + " command couldn't be found. Please configure its path in the preferences.");
        return null;
      }

      String path = project.getLocation().toOSString();

      ArrayList<String> commandLine = new ArrayList<String>();
      commandLine.add(makeCmd);
      switch (makeUtility.getVariant()) {
        case OMAKE:
          commandLine.add("--no--progress");
          commandLine.add("-w");
          break;
        case GNU_MAKE:
          commandLine.add("-C" + path);
          break;
      }

      for (String option : makeUtility.getOptions()) commandLine.add(option);

      MakefileTargets makefileTargets = new MakefileTargets(project);
      String[] targets = null;
      if (kind == CLEAN_BUILD) targets = makefileTargets.getCleanTargets();
      else targets = makefileTargets.getTargets();

      for (String target : targets) commandLine.add(target);

      String[] strCommandLine = commandLine.toArray(new String[commandLine.size()]);

      final StringBuilder output = new StringBuilder();

      IExecEvents events =
          new IExecEvents() {

            public void processNewInput(final String input) {
              output.append(input);
              Display.getDefault()
                  .asyncExec(
                      new Runnable() {
                        public void run() {
                          OcamlCompilerOutput outputView = OcamlCompilerOutput.get();
                          if (outputView != null) outputView.append(input);
                        }
                      });
            }

            // not used, because the error output is merged with the standard output
            public void processNewError(String error) {}

            public void processEnded(int exitValue) {
              if (kind == CLEAN_BUILD) cleanFinished(project);
              else makefileFinished(output.toString(), project);
            }
          };

      // clean the output from the last compilation
      /*
       * Display.getDefault().syncExec(new Runnable() { public void run() { OcamlCompilerOutput output =
       * OcamlCompilerOutput.get(); if (output != null) output.clear(); } });
       */

      File dir = project.getLocation().toFile();
      ExecHelper execHelper = null;
      try {
        // use OS-inherited environment for the make process
        execHelper = ExecHelper.execMerge(events, strCommandLine, System.getenv(), dir);
      } catch (Exception e) {
        OcamlPlugin.logError("ocaml plugin error", e);
        return null;
      }

      /*
       * Check at regular intervals whether the user canceled the build. When that happens, we kill the
       * "make" process.
       */
      while (execHelper.isRunning()) {
        if (buildMonitor.isCanceled()) execHelper.kill();
        try {
          buildMonitor.worked(1);
          Thread.sleep(100);
        } catch (InterruptedException e) {
        }
      }

      execHelper.join();

      return null;
    } finally {
      buildMonitor.worked(1);
      buildMonitor.done();
      building = false;
    }
  }