summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/release/dev/cmake-depend-in-project-only.rst6
-rw-r--r--Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst10
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx61
-rw-r--r--Tests/RunCMake/BuildDepends/MakeInProjectOnly.c2
-rw-r--r--Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake16
-rw-r--r--Tests/RunCMake/BuildDepends/MakeInProjectOnly.step1.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/MakeInProjectOnly.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake5
9 files changed, 107 insertions, 0 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index cb50051..5fd5c5c 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/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
diff --git a/Help/release/dev/cmake-depend-in-project-only.rst b/Help/release/dev/cmake-depend-in-project-only.rst
new file mode 100644
index 0000000..8553e80
--- /dev/null
+++ b/Help/release/dev/cmake-depend-in-project-only.rst
@@ -0,0 +1,6 @@
+cmake-depend-in-project-only
+----------------------------
+
+* The :ref:`Makefile Generators` learned to optionally limit dependency
+ scanning only to files in the project source and build trees.
+ See the :variable:`CMAKE_DEPENDS_IN_PROJECT_ONLY` variable.
diff --git a/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst b/Help/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY.rst
new file mode 100644
index 0000000..7179071
--- /dev/null
+++ b/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.
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 62fea3d..afdff33 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/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)
{
diff --git a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.c b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.c
new file mode 100644
index 0000000..bcb8745
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.c
@@ -0,0 +1,2 @@
+#include <MakeInProjectOnly.h>
+int main() { return MakeInProjectOnly(); }
diff --git a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake
new file mode 100644
index 0000000..add9aeb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+get_filename_component(include_dir "${CMAKE_BINARY_DIR}" PATH)
+include_directories("${include_dir}")
+add_executable(MakeInProjectOnly MakeInProjectOnly.c)
+set(CMAKE_DEPENDS_IN_PROJECT_ONLY 1)
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+if (check_step EQUAL 1)
+ set(check_pairs
+ \"$<TARGET_FILE:MakeInProjectOnly>|${include_dir}/MakeInProjectOnly.h\"
+ )
+else()
+ set(check_pairs
+ \"${include_dir}/MakeInProjectOnly.h|\$<TARGET_FILE:MakeInProjectOnly>\"
+ )
+endif()
+")
diff --git a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step1.cmake b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step1.cmake
new file mode 100644
index 0000000..d6551ab
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/../MakeInProjectOnly.h" [[
+int MakeInProjectOnly(void) { return 0; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step2.cmake b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step2.cmake
new file mode 100644
index 0000000..145605b
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/MakeInProjectOnly.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/../MakeInProjectOnly.h" [[
+int MakeInProjectOnly(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 26ffcc0..6b2b85a 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -41,6 +41,11 @@ endif()
run_BuildDepends(Custom-Always)
+if(RunCMake_GENERATOR MATCHES "Make" AND
+ NOT "${RunCMake_BINARY_DIR}" STREQUAL "${RunCMake_SOURCE_DIR}")
+ run_BuildDepends(MakeInProjectOnly)
+endif()
+
function(run_ReGeneration)
# test re-generation of project even if CMakeLists.txt files disappeared