cmGlobalCommonGenerator.cxx 2.79 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
3 4
#include "cmGlobalCommonGenerator.h"

5
#include <memory>
6 7
#include <utility>

8 9 10 11 12 13 14
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"

15 16
class cmake;

17 18
cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
  : cmGlobalGenerator(cm)
19 20 21
{
}

wahikihiki's avatar
wahikihiki committed
22
cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default;
23 24 25 26 27 28 29 30 31 32 33 34 35

std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
cmGlobalCommonGenerator::ComputeDirectoryTargets() const
{
  std::map<std::string, DirectoryTarget> dirTargets;
  for (cmLocalGenerator* lg : this->LocalGenerators) {
    std::string const& currentBinaryDir(
      lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
    DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
    dirTarget.LG = lg;

    // The directory-level rule should depend on the target-level rules
    // for all targets in the directory.
36
    for (const auto& gt : lg->GetGeneratorTargets()) {
37 38 39 40 41 42 43 44 45 46
      cmStateEnums::TargetType const type = gt->GetType();
      if (type != cmStateEnums::EXECUTABLE &&
          type != cmStateEnums::STATIC_LIBRARY &&
          type != cmStateEnums::SHARED_LIBRARY &&
          type != cmStateEnums::MODULE_LIBRARY &&
          type != cmStateEnums::OBJECT_LIBRARY &&
          type != cmStateEnums::UTILITY) {
        continue;
      }
      DirectoryTarget::Target t;
47
      t.GT = gt.get();
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
      if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
        if (cmIsOn(exclude)) {
          // This target has been explicitly excluded.
          t.ExcludeFromAll = true;
        } else {
          // This target has been explicitly un-excluded.  The directory-level
          // rule for every directory between this and the root should depend
          // on the target-level rule for this target.
          for (cmStateSnapshot dir =
                 lg->GetStateSnapshot().GetBuildsystemDirectoryParent();
               dir.IsValid(); dir = dir.GetBuildsystemDirectoryParent()) {
            std::string const& d = dir.GetDirectory().GetCurrentBinary();
            dirTargets[d].Targets.emplace_back(t);
          }
        }
      }
      dirTarget.Targets.emplace_back(t);
    }

    // The directory-level rule should depend on the directory-level
    // rules of the subdirectories.
    for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
      DirectoryTarget::Dir d;
      d.Path = state.GetDirectory().GetCurrentBinary();
      d.ExcludeFromAll =
        state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL");
      dirTarget.Children.emplace_back(std::move(d));
    }
  }

  return dirTargets;
}