示例#1
1
  // ---------------------------------------------------------------------------
  private void printDependencies() throws TablesawException {
    m_printedDependencies = new HashSet<String>();

    try {
      PrintWriter pw = new PrintWriter(new FileWriter("dependency.txt"));

      pw.println("Targets marked with a * have already been printed");
      // Create a reduced set of stuff to print
      Set<String> ruleNames = new HashSet<String>();

      for (String name : m_nameRuleMap.keySet()) ruleNames.add(name);

      for (String name : m_nameRuleMap.keySet()) {
        Rule rule = m_nameRuleMap.get(name);
        for (String dep : rule.getDependNames()) ruleNames.remove(dep);

        for (Rule dep : rule.getDependRules()) {
          if (dep.getName() != null) ruleNames.remove(dep.getName());
        }
      }

      for (String name : ruleNames) {
        if (!name.startsWith(NAMED_RULE_PREFIX)) printDependencies(name, pw, 0);
      }

      pw.close();
    } catch (IOException ioe) {
      throw new TablesawException("Cannot write to file dependency.txt", -1);
    }
  }
示例#2
0
  // ---------------------------------------------------------------------------
  public void addRule(Rule rule) {
    Debug.print("AddRule() " + rule.getName() + " " + rule);
    // do not get the rule name as it may not be set yet
    // rules are added often in the constructor when other values
    // have not been set yet.

    // todo: Get a list of provides and consumes annotations
    m_ruleList.add(rule);

    Class ruleClass = rule.getClass();
    DependencyAnnotations da = m_classAnnotations.get(ruleClass);
    if (da == null) m_classAnnotations.put(ruleClass, createDependencyAnnotations(ruleClass));
  }
示例#3
0
  // ---------------------------------------------------------------------------
  private void printDependencies(String target, PrintWriter pw, int spacing)
      throws TablesawException {
    Rule tr = findTargetRule(target);
    String[] pre;

    for (int I = 0; I < spacing; I++) pw.print("\t");

    List<String> targetList = new ArrayList<String>();
    if (tr != null) {
      for (String name : tr.getDependNames()) {
        targetList.add(name);
      }

      for (Rule r : tr.getDependRules()) {
        if ((r.getName() != null) && (!r.getName().startsWith(NAMED_RULE_PREFIX))) {
          targetList.add(r.getName());
        } else {
          for (String t : r.getTargets()) {
            targetList.add(t);
          }
        }
      }
    }

    if (!m_printedDependencies.add(target) && (targetList.size() != 0)) {
      pw.println(target + "*");
      return;
    }

    pw.println(target);

    for (String t : targetList) printDependencies(t, pw, spacing + 1);
  }
示例#4
0
 // ---------------------------------------------------------------------------
 private void addRule(String key, Rule rule) throws TablesawException {
   Debug.print("Adding rule for " + key);
   Rule old = m_targetRuleMap.put(key, rule);
   if ((old != null) && (!rule.getOverride()) && (!(old instanceof Overridable)))
     throw new TablesawException(
         "Duplicate rules for " + key + " rule1: " + old + " rule2: " + rule, 1);
 }
示例#5
0
  /**
   * This fills in the m_targetRuleMap. The keys are the names of the rules and the targets they
   * produce
   */
  private void resolveRules() throws TablesawException {
    for (Rule rule : m_ruleList) {
      // Add rule by name if it has one
      String name = rule.getName();
      if (name != null) {
        Debug.print("Adding rule name: " + name);
        Rule namedRule = m_nameRuleMap.get(name);
        if (namedRule == null) {
          m_nameRuleMap.put(name, rule);
        }
        /*else if (namedRule instanceof CompoundNameRule)
        {
        ((CompoundNameRule)namedRule).addDepends(rule);
        }*/
        else if ((namedRule instanceof Overridable) || (rule.getOverride())) {
          m_nameRuleMap.put(name, rule);
        } else {
          throw new TablesawException(
              "Multiple rules exist for '"
                  + name
                  + "'.  Call Rule.override() if you wish to override an existing rule.");
          /*System.out.println("GGGGGGGGGGGGGGGGGGGAAAAAAAAAAAAAHHHHHHHHHHH");
          CompoundNameRule cnr = new CompoundNameRule(name);
          cnr.addDepends(namedRule);
          cnr.addDepends(rule);
          m_nameRuleMap.put(name, cnr);*/
        }
      }

      // Add rule by each target it declares
      Iterable<String> targets = rule.getTargets();
      for (String t : targets) {
        Debug.print("Add target " + t);
        addRule(t, rule);
      }
    }

    m_resolved = true;
  }
示例#6
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;
  }
示例#7
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);
  }