Browse Source

Makefile: Optionally scan only source and build trees for dependencies

Add a `CMAKE_DEPENDS_IN_PROJECT_ONLY` variable to activate the behavior.
pull/230/head
Attila Krasznahorkay 9 years ago
committed by Brad King
parent
commit
b1e1aa1e6a
  1. 1
      Help/manual/cmake-variables.7.rst
  2. 10
      Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
  3. 61
      Source/cmLocalUnixMakefileGenerator3.cxx

1
Help/manual/cmake-variables.7.rst

@ -114,6 +114,7 @@ Variables that Change Behavior
/variable/CMAKE_COLOR_MAKEFILE
/variable/CMAKE_CONFIGURATION_TYPES
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY
/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName
/variable/CMAKE_ERROR_DEPRECATED
/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION

10
Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst

@ -0,0 +1,10 @@
CMAKE_DEPENDS_IN_PROJECT_ONLY
-----------------------------
When set to ``TRUE`` in a directory, the build system produced by the
:ref:`Makefile Generators` is set up to only consider dependencies on source
files that appear either in the source or in the binary directories. Changes
to source files outside of these directories will not cause rebuilds.
This should be used carefully in cases where some source files are picked up
through external headers during the build.

61
Source/cmLocalUnixMakefileGenerator3.cxx

@ -34,6 +34,7 @@
#include <cmsys/Terminal.h>
#include <queue>
#include <algorithm>
//----------------------------------------------------------------------------
// Escape special characters in Makefile dependency lines
@ -1971,6 +1972,57 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
}
namespace
{
// Helper predicate for removing absolute paths that don't point to the
// source or binary directory. It is used when CMAKE_DEPENDS_IN_PROJECT_ONLY
// is set ON, to only consider in-project dependencies during the build.
class NotInProjectDir
{
public:
// Constructor with the source and binary directory's path
NotInProjectDir(const std::string& sourceDir,
const std::string& binaryDir)
: SourceDir(sourceDir), BinaryDir(binaryDir) {}
// Operator evaluating the predicate
bool operator()(const std::string& path) const
{
// Keep all relative paths:
if(!cmSystemTools::FileIsFullPath(path))
{
return false;
}
// If it's an absolute path, check if it starts with the source
// direcotory:
return (!(IsInDirectory(SourceDir, path)||
IsInDirectory(BinaryDir, path)));
}
private:
// Helper function used by the predicate
static bool IsInDirectory(const std::string& baseDir,
const std::string& testDir)
{
// First check if the test directory "starts with" the base directory:
if (testDir.find(baseDir) != 0)
{
return false;
}
// If it does, then check that it's either the same string, or that the
// next character is a slash:
return ((testDir.size() == baseDir.size())||
(testDir[baseDir.size()] == '/'));
}
// The path to the source directory
std::string SourceDir;
// The path to the binary directory
std::string BinaryDir;
};
}
void cmLocalUnixMakefileGenerator3
::WriteDependLanguageInfo(std::ostream& cmakefileStream,
cmGeneratorTarget* target)
@ -2058,6 +2110,15 @@ void cmLocalUnixMakefileGenerator3
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->GetIncludeDirectories(includes, target,
l->first, config);
if(this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY"))
{
const char* sourceDir = this->GetState()->GetSourceDirectory();
const char* binaryDir = this->GetState()->GetBinaryDirectory();
std::vector<std::string>::iterator itr =
std::remove_if(includes.begin(), includes.end(),
::NotInProjectDir(sourceDir, binaryDir));
includes.erase(itr, includes.end());
}
for(std::vector<std::string>::iterator i = includes.begin();
i != includes.end(); ++i)
{

Loading…
Cancel
Save