Merge topic 'cmake-depend-in-project-only'

b06e17da Help: Add notes for topic 'cmake-depend-in-project-only'
52540245 Tests: Add test for CMAKE_DEPENDS_IN_PROJECT_ONLY variable
b1e1aa1e Makefile: Optionally scan only source and build trees for dependencies
This commit is contained in:
Brad King 2016-03-24 08:49:43 -04:00 committed by CMake Topic Stage
commit 917d49ed93
9 changed files with 107 additions and 0 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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)
{

View File

@ -0,0 +1,2 @@
#include <MakeInProjectOnly.h>
int main() { return MakeInProjectOnly(); }

View File

@ -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()
")

View File

@ -0,0 +1,3 @@
file(WRITE "${RunCMake_TEST_BINARY_DIR}/../MakeInProjectOnly.h" [[
int MakeInProjectOnly(void) { return 0; }
]])

View File

@ -0,0 +1,3 @@
file(WRITE "${RunCMake_TEST_BINARY_DIR}/../MakeInProjectOnly.h" [[
int MakeInProjectOnly(void) { return 1; }
]])

View File

@ -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