示例#1
0
  /** Method to process the build queue, can be called by more than one thread */
  public void processBuildQueue() throws TablesawException {
    BuildAction ba;
    Rule rule;
    String target;

    synchronized (m_threadList) {
      m_threadList.add(Thread.currentThread());
    }

    try {
      doloop:
      do {
        synchronized (this) {
          try {
            ba = (BuildAction) m_buildQueue.removeLast();
          } catch (NoSuchElementException nsee) {
            break doloop;
            // ba = new BuildAction(m_fileManager, null);
          }

          if (m_printDebug) Debug.print("Processing: " + ba);

          if (m_makeException != null) break doloop;

          ba.waitForDependencies();

          if (m_makeException != null) break doloop;
        }

        rule = ba.getTargetRule();
        MakeAction action = rule.getMakeAction();

        // target = ba.getTarget();
        if (action != null) {
          action.doMakeAction(rule);

          rule.verify();
        }

        Debug.print("COMPLETE - " + ba);
        ba.complete(); // Complete the BuildAction
      } while (m_makeException == null);
    } catch (Exception e) {
      TablesawException cpe;

      if (e instanceof TablesawException) cpe = (TablesawException) e;
      else cpe = new TablesawException(e);

      synchronized (this) {
        m_makeException = cpe;

        for (Thread t : m_threadList) t.interrupt();
      }

      throw cpe;
    }

    // This causes worker threads to die off and the exception to
    // pass to the main thread
    if (m_makeException != null) throw m_makeException;
  }
示例#2
0
  // ---------------------------------------------------------------------------
  private BuildAction addToBuildQueue(String target, boolean primaryTarget, int insertPosition)
      throws TablesawException {
    // The target was already checked and does not need to be built
    if (m_noBuildCache.contains(target)) return (null);

    Debug.print("addToBuildQueue(" + target + ", " + primaryTarget + ", " + insertPosition + ")");
    Debug.indent();

    Rule trule = findTargetRule(target);

    CachedFile targetFile = null;
    BuildAction[] buildDep = null;
    BuildAction targetBA = null;
    BuildAction depBA = null;
    BuildAction ret = null;

    if (trule == null) {
      targetFile = m_fileManager.locateFile(target);

      // TODO: Add the rule that required this target to the error message
      if (targetFile == null)
        throw new TablesawException("Unable to locate rule for '" + target + "'");

      if (m_sourceFiles != null)
        m_sourceFiles.add(
            new File(
                targetFile.getPath())); // Doing this because locateFile will return a CachedFile

      // TODO: check file against cache file stamps and if changed return dummy rule
      Debug.print("Cache lookup for " + targetFile.getPath());

      // Add file to cache for next run
      m_newModificationCache.put(targetFile.getPath(), targetFile.lastModified());

      Long cacheModTime = m_modificationCache.get(targetFile.getPath());
      if (cacheModTime != null) {
        Debug.print("Cache hit " + cacheModTime + ":" + targetFile.lastModified());
        if (cacheModTime != targetFile.lastModified()) {
          Debug.print("returning obj for " + targetFile);
          Debug.popIndent();
          targetBA =
              new BuildAction(
                  m_fileManager, new ModifiedFileRule(targetFile.getPath()), m_classAnnotations);
          m_buildQueue.add(insertPosition, targetBA);
          return (targetBA);
        }
      } else Debug.print("Cache miss");

      // System.out.println("File "+targetFile);
      m_noBuildCache.add(target);
      Debug.print("Target " + target + " is a file with no rule");
      Debug.popIndent();
      return (null);
    }

    if ((m_sourceFiles != null) && (trule instanceof SourceFileSet)) {
      m_sourceFiles.addAll(((SourceFileSet) trule).getSourceFiles());
    }

    long targetTime = 0;
    boolean tExists = true;
    boolean tDir = false;
    boolean tPhony = true;

    boolean rebuild = false;

    targetBA = new BuildAction(m_fileManager, trule, m_classAnnotations);
    int index;

    if (m_buildQueueCache.containsKey(targetBA)) {
      // Get the build action from the queue
      targetBA = m_buildQueueCache.get(targetBA);

      Debug.print("target: " + trule + " already in build queue.");
      // Target has already been added to build queue
      Debug.popIndent();
      return (targetBA);
    }

    File f;

    trule.preBuild(m_depCache, m_modificationCache);

    // NOTE: need to add in dependencies that are individually declared
    // NOTE: getPrerequisites is also where dependency parsing happens to include C headers and
    // other java classes
    // String[] prereqs = getPrerequisites(trule, true);
    List<String> prereqs = new ArrayList<String>();

    for (String dn : trule.getDependNames()) {
      Debug.print("adding depend name " + dn);
      prereqs.add(dn);
    }

    for (Rule r : trule.getDependRules()) {
      Debug.print("adding depend rule " + r);
      if (r.getName() == null) {
        // Generate name for rule
        String genRuleName = NAMED_RULE_PREFIX + (m_ruleNameCounter++);
        r.setName(genRuleName);
        m_nameRuleMap.put(genRuleName, r);
      }

      prereqs.add(r.getName());
    }

    Debug.print("rule dependents " + prereqs.size());

    if (prereqs.size() > 0) {
      ListIterator<String> it = prereqs.listIterator();

      while (it.hasNext()) {
        String prereq = it.next();

        if (prereq.equals(target))
          throw new TablesawException("Target " + target + " depends on itself");

        /* //See if the prereq is the name of a rule first
        Rule nameRule = m_nameRuleMap.get(prereq);

        //Add the new rule targets to the prereqs list
        // TODO: some kind of check so we dont add the same named rule again and again.
        if (nameRule != null)
        	{
        	Iterable<String> ruleTargets = nameRule.getTargets();
        	boolean hasTargets = false;
        	for (String t : ruleTargets)
        		{
        		hasTargets = true;
        		it.add(t);
        		it.previous();
        		}

        	if (hasTargets)
        		continue;
        	} */

        // Add dependencies to build queue first.
        // f = m_fileManager.getFile(prereq);
        if ((depBA = addToBuildQueue(prereq, false, insertPosition)) != null) {
          targetBA.addDependency(depBA);
          // trule.addNewerDepend(prereq);
          if (depBA.isBinding()) {
            Debug.print("Rebuild: " + trule + " because rebuild of " + depBA.getTargetRule());
            rebuild = true;
          }
        }
      }
    }

    if (!rebuild) {
      rebuild = trule.needToRun();
      Debug.print("Rule needToRun() returned " + rebuild);
    }

    // TODO: change this to get depends from above and check if no depends
    if ((!rebuild)
        && (primaryTarget
            && (!trule
                .getTargets()
                .iterator()
                .hasNext()))) { // If target is the primary target and it has no targets
      Debug.print("Adding primary target: " + trule + " to build queue.");
      rebuild = true;
    }

    if (rebuild) { // Add target to build queue
      m_buildQueue.add(insertPosition, targetBA);
      m_buildQueueCache.put(targetBA, targetBA);
      Debug.print("Adding " + targetBA + " to build queue at pos " + insertPosition);
      // System.out.println("Adding "+targetBA+" to build queue at pos "+insertPosition);

      ret = targetBA;
    }

    // Add target to cache if it does not need to be built
    // This is to speed up incremental builds
    if (ret == null) m_noBuildCache.add(target);

    Debug.popIndent();
    return (ret);
  }