diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index f3eb249..662c2df 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -6,6 +6,7 @@
 #include "cmsys/FStream.hxx"
 #include <algorithm>
 #include <assert.h>
+#include <iostream>
 #include <iterator>
 #include <sstream>
 #include <stdio.h>
@@ -70,6 +71,7 @@ bool cmTarget::StrictTargetComparison::operator()(cmTarget const* t1,
 
 cmGlobalGenerator::cmGlobalGenerator(cmake* cm)
   : CMakeInstance(cm)
+  , changeset()
 {
   // By default the .SYMBOLIC dependency is not needed on symbolic rules.
   this->NeedSymbolicMark = false;
@@ -1328,6 +1330,66 @@ bool cmGlobalGenerator::Compute()
   return true;
 }
 
+void cmGlobalGenerator::CalculateChangesetTargets(std::vector<std::string> _changeset)
+{
+  this->changeset = _changeset;
+  std::set<cmGeneratorTarget const*> initialTargetsToBuild; // detect initial set of targets from source file changes
+  for (TargetDependMap::iterator it = TargetDependencies.begin(); it != TargetDependencies.end(); ++it) {
+    cmGeneratorTarget const* target = it->first;
+    bool addDependencies = doesTargetDependOnChangeset(target);
+    if (addDependencies) {
+      std::string targetName = target->GetName();
+      targetName.append("_unity");
+      GeneratorTargetMap::iterator unityTargetItr = GeneratorTargetSearchIndex.find(targetName);
+      if (unityTargetItr != GeneratorTargetSearchIndex.end()) {
+        initialTargetsToBuild.insert(unityTargetItr->second);
+      }
+    }
+  }
+
+  targetsToBuild = initialTargetsToBuild;
+  // scan through whole list of TargetDependencies, adding targets which depend on anything in the current set of targets to build. We only need one pass because everything which was indirectly dependent was already added
+
+  for (TargetDependMap::iterator it = TargetDependencies.begin(); it != TargetDependencies.end(); ++it) {
+    cmGeneratorTarget const* target = it->first;
+    TargetDependSet depends = it->second;
+    for (std::set<cmGeneratorTarget const*>::iterator it2 = initialTargetsToBuild.begin(); it2 != initialTargetsToBuild.end(); ++it2) {
+      if (depends.find(*it2) != depends.end()) {
+        targetsToBuild.insert(target);
+        break;
+      }
+    }
+  }
+
+  std::cout << "The changeset affects the following targets:";
+  for (std::set<cmGeneratorTarget const*>::iterator it = targetsToBuild.begin(); it != targetsToBuild.end(); ++it) {
+    std::cout << " " << (*it)->GetName();
+  }
+  std::cout << std::endl;
+
+}
+
+bool cmGlobalGenerator::doesTargetDependOnChangeset(cmGeneratorTarget const* target)
+{
+  // access the source files of the cmGeneratorTarget, check if one of the changeset files is here
+  // if it is, return true, else return false
+  std::cout << "checking target " << target->GetName() << std::endl;
+
+  std::vector<cmSourceFile*> sourceFiles;
+  target->GetSourceFiles(sourceFiles, "");
+  std::cout << "source files:\n";
+  for (std::vector<cmSourceFile*>::iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) {
+    cmSourceFile* sf = *it;
+    std::cout << "\tfull path: " << sf->GetFullPath(CM_NULLPTR) << std::endl;
+    if (std::find(changeset.begin(), changeset.end(), sf->GetFullPath()) != changeset.end()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+
 void cmGlobalGenerator::Generate()
 {
   // Create a map from local generator to the complete set of targets
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index cc7ffed..38d50d3 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -308,6 +308,10 @@ public:
   TargetDependSet const& GetTargetDirectDepends(
     const cmGeneratorTarget* target);
 
+  void CalculateChangesetTargets(std::vector<std::string> _changeset);
+
+  bool doesTargetDependOnChangeset(cmGeneratorTarget const* target);
+
   const std::map<std::string, std::vector<cmLocalGenerator*> >& GetProjectMap()
     const
   {
@@ -489,6 +493,9 @@ private:
   TargetMap TargetSearchIndex;
   GeneratorTargetMap GeneratorTargetSearchIndex;
 
+  std::set<cmGeneratorTarget const*> targetsToBuild;
+  std::vector<std::string> changeset;
+
   // Map efficiently from source directory path to cmMakefile instance.
   // Do not use this structure for looping over all directories.
   // It may not contain all of them (see note in IndexMakefile method).
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 53e9ab0..450f185 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -110,6 +110,7 @@
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
 #include <algorithm>
+#include <fstream>
 #include <iostream>
 #include <sstream>
 #include <stdio.h>
@@ -144,6 +145,9 @@ cmake::cmake(Role role)
   this->WarnUnused = false;
   this->WarnUnusedCli = true;
   this->CheckSystemVars = false;
+  this->CalculateChangeset = false;
+  this->TargetsFromFiles = false;
+  this->TargetsFromFilesPath = "";
   this->DebugOutput = false;
   this->DebugTryCompile = false;
   this->ClearBuildSystem = false;
@@ -706,6 +710,13 @@ void cmake::SetArgs(const std::vector<std::string>& args,
       std::cout << "Also check system files when warning about unused and "
                 << "uninitialized variables.\n";
       this->SetCheckSystemVars(true);
+    } else if (arg.find("--change-set=", 0) == 0) {
+      std::cout << "Building targets depending on given files.\n";
+      std::string file = arg.substr(strlen("--change-set="));
+      std::cout << "got file=" << file << "\n";
+      this->SetTargetsFromFiles(true);
+      this->SetTargetsFromFilesPath(file);
+      this->SetCalculateChangeset(true);
     } else if (arg.find("-A", 0) == 0) {
       std::string value = arg.substr(2);
       if (value.empty()) {
@@ -1589,6 +1600,20 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
     return 0;
   }
 
+  if (this->GetTargetsFromFiles()) {
+    if(!this->ParseChangedFileList(this->GetTargetsFromFilesPath())) {
+      cmSystemTools::Error("Could not parse the changeset file. Aborting.\n");
+      return -1;
+    }
+    else {
+      std::cout << "Got changed files:";
+      for (std::vector<std::string>::iterator it = this->ChangedFiles.begin() ; it != this->ChangedFiles.end(); ++it) {
+        std::cout << " '" << (*it) << "'";
+      }
+      std::cout << std::endl;
+    }
+  }
+
   int ret = this->Configure();
   if (ret || this->GetWorkingMode() != NORMAL_MODE) {
 #if defined(CMAKE_HAVE_VS_GENERATORS)
@@ -1622,6 +1647,10 @@ int cmake::Generate()
   if (!this->GlobalGenerator->Compute()) {
     return -1;
   }
+  if (this->GetCalculateChangeset()) {
+    this->GlobalGenerator->CalculateChangesetTargets(this->ChangedFiles);
+    return 0;
+  }
   this->GlobalGenerator->Generate();
   if (!this->GraphVizFile.empty()) {
     std::cout << "Generate graphviz: " << this->GraphVizFile << std::endl;
@@ -1789,6 +1818,33 @@ void cmake::SetIsInTryCompile(bool b)
   this->State->SetIsInTryCompile(b);
 }
 
+bool cmake::ParseChangedFileList(std::string filePath)
+{
+  std::ifstream changedFileList(filePath.c_str());
+  std::string line;
+
+  std::string srcDirectory = std::string(this->GetState()->GetSourceDirectory());
+  if (*srcDirectory.rbegin() != '/') {
+    srcDirectory.append("/");
+  }
+
+  if (changedFileList.is_open()) {
+    while (std::getline(changedFileList, line)) {
+      this->ChangedFiles.push_back(srcDirectory + line);
+    }
+    changedFileList.close();
+  }
+  else {
+    std::cout << "Error: can not open '" << filePath << "'\n";
+    return false;
+  }
+  if (this->ChangedFiles.empty()) {
+    std::cout << "Error: changed file list is empty\n";
+    return false;
+  }
+  return true;
+}
+
 void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v)
 {
   for (RegisteredGeneratorsVector::const_iterator i = this->Generators.begin();
diff --git a/Source/cmake.h b/Source/cmake.h
index 4ddacf7..57f410f 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -183,6 +183,8 @@ public:
   bool DeleteCache(const std::string& path);
   void PreLoadCMakeFiles();
 
+  bool ParseChangedFileList(std::string const filePath);
+
   ///! Create a GlobalGenerator
   cmGlobalGenerator* CreateGlobalGenerator(const std::string& name);
 
@@ -342,6 +344,12 @@ public:
   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
   bool GetCheckSystemVars() { return this->CheckSystemVars; }
   void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
+  void SetCalculateChangeset(bool b) { this->CalculateChangeset = b; }
+  bool GetCalculateChangeset() { return this->CalculateChangeset; }
+  void SetTargetsFromFiles(bool b) { this->TargetsFromFiles = b; }
+  bool GetTargetsFromFiles() { return this->TargetsFromFiles; }
+  void SetTargetsFromFilesPath(std::string const s) { this->TargetsFromFilesPath = s; }
+  std::string GetTargetsFromFilesPath() const { return this->TargetsFromFilesPath; }
 
   void MarkCliAsUsed(const std::string& variable);
 
@@ -480,6 +488,10 @@ private:
   bool WarnUnused;
   bool WarnUnusedCli;
   bool CheckSystemVars;
+  bool CalculateChangeset;
+  bool TargetsFromFiles;
+  std::string TargetsFromFilesPath;
+  std::vector<std::string> ChangedFiles;
   std::map<std::string, bool> UsedCliVariables;
   std::string CMakeEditCommand;
   std::string CXXEnvironment;
