summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2012-12-06 14:59:18 (GMT)
committerBrad King <brad.king@kitware.com>2012-12-07 14:51:19 (GMT)
commit711b63f7e095992d6ab84063af076d23a916b1f3 (patch)
tree416a696ab99e6cf27ec76607c73704e43049b44d
parentd5ac791366595be307896e9894c66815c1e1eb2f (diff)
downloadCMake-711b63f7e095992d6ab84063af076d23a916b1f3.zip
CMake-711b63f7e095992d6ab84063af076d23a916b1f3.tar.gz
CMake-711b63f7e095992d6ab84063af076d23a916b1f3.tar.bz2
Add policy CMP0019 to skip include/link variable re-expansion
Historically CMake has always expanded ${} variable references in the values given to include_directories(), link_directories(), and link_libraries(). This has been unnecessary since general ${} evaluation syntax was added to the language a LONG time ago, but has remained for compatibility with VERY early CMake versions. For a long time the re-expansion was a lightweight operation because it was only processed once at the directory level and the fast-path of cmMakefile::ExpandVariablesInString was usually taken because values did not have any '$' in them. Then commit d899eb71 (Call ExpandVariablesInString for each target's INCLUDE_DIRECTORIES, 2012-02-22) made the operation a bit heavier because the expansion is now needed on a per-target basis. In the future we will support generator expressions in INCLUDE_DIRECTORIES with $<> syntax, so the fast-path in cmMakefile::ExpandVariablesInString will no longer be taken and re-expansion will be very expensive. Add policy CMP0019 to skip the re-expansion altogether in NEW behavior. In OLD behavior perform the expansion but improve the fast-path heuristic to match ${} but not $<>. If the policy is not set then warn if expansion actually does anything. We expect this to be encountered very rarely in practice.
-rw-r--r--Source/cmMakefile.cxx75
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmPolicies.cxx17
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-NEW.cmake2
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt40
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-WARN.cmake1
-rw-r--r--Tests/RunCMake/CMP0019/CMP0019-code.cmake9
-rw-r--r--Tests/RunCMake/CMP0019/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0019/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
12 files changed, 145 insertions, 13 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 8498d72..d943c45 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -814,7 +814,7 @@ bool cmMakefile::NeedBackwardsCompatibility(unsigned int major,
void cmMakefile::FinalPass()
{
// do all the variable expansions here
- this->ExpandVariables();
+ this->ExpandVariablesCMP0019();
// give all the commands a chance to do something
// after the file has been parsed before generation
@@ -2122,21 +2122,33 @@ void cmMakefile::AddExtraDirectory(const char* dir)
this->AuxSourceDirectories.push_back(dir);
}
+static bool mightExpandVariablesCMP0019(const char* s)
+{
+ return s && *s && strstr(s,"${") && strchr(s,'}');
+}
-// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
-// include and library directories.
-
-void cmMakefile::ExpandVariables()
+void cmMakefile::ExpandVariablesCMP0019()
{
- // Now expand variables in the include and link strings
+ // Drop this ancient compatibility behavior with a policy.
+ cmPolicies::PolicyStatus pol = this->GetPolicyStatus(cmPolicies::CMP0019);
+ if(pol != cmPolicies::OLD && pol != cmPolicies::WARN)
+ {
+ return;
+ }
+ cmOStringStream w;
- // May not be necessary anymore... But may need a policy for strict
- // backwards compatibility
const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
- if (includeDirs)
+ if(mightExpandVariablesCMP0019(includeDirs))
{
std::string dirs = includeDirs;
this->ExpandVariablesInString(dirs, true, true);
+ if(pol == cmPolicies::WARN && dirs != includeDirs)
+ {
+ w << "Evaluated directory INCLUDE_DIRECTORIES\n"
+ << " " << includeDirs << "\n"
+ << "as\n"
+ << " " << dirs << "\n";
+ }
this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
}
@@ -2146,10 +2158,17 @@ void cmMakefile::ExpandVariables()
{
cmTarget &t = l->second;
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
- if (includeDirs)
+ if(mightExpandVariablesCMP0019(includeDirs))
{
std::string dirs = includeDirs;
this->ExpandVariablesInString(dirs, true, true);
+ if(pol == cmPolicies::WARN && dirs != includeDirs)
+ {
+ w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
+ << " " << includeDirs << "\n"
+ << "as\n"
+ << " " << dirs << "\n";
+ }
t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
}
}
@@ -2157,13 +2176,45 @@ void cmMakefile::ExpandVariables()
for(std::vector<std::string>::iterator d = this->LinkDirectories.begin();
d != this->LinkDirectories.end(); ++d)
{
- this->ExpandVariablesInString(*d, true, true);
+ if(mightExpandVariablesCMP0019(d->c_str()))
+ {
+ std::string orig = *d;
+ this->ExpandVariablesInString(*d, true, true);
+ if(pol == cmPolicies::WARN && *d != orig)
+ {
+ w << "Evaluated link directory\n"
+ << " " << orig << "\n"
+ << "as\n"
+ << " " << *d << "\n";
+ }
+ }
}
for(cmTarget::LinkLibraryVectorType::iterator l =
this->LinkLibraries.begin();
l != this->LinkLibraries.end(); ++l)
{
- this->ExpandVariablesInString(l->first, true, true);
+ if(mightExpandVariablesCMP0019(l->first.c_str()))
+ {
+ std::string orig = l->first;
+ this->ExpandVariablesInString(l->first, true, true);
+ if(pol == cmPolicies::WARN && l->first != orig)
+ {
+ w << "Evaluated link library\n"
+ << " " << orig << "\n"
+ << "as\n"
+ << " " << l->first << "\n";
+ }
+ }
+ }
+
+ if(!w.str().empty())
+ {
+ cmOStringStream m;
+ m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019)
+ << "\n"
+ << "The following variable evaluations were encountered:\n"
+ << w.str();
+ this->IssueMessage(cmake::AUTHOR_WARNING, m.str());
}
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 70cfe54..eff05d0 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -693,7 +693,7 @@ public:
/**
* Expand variables in the makefiles ivars such as link directories etc
*/
- void ExpandVariables();
+ void ExpandVariablesCMP0019();
/**
* Replace variables and #cmakedefine lines in the given string.
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 6aef502..eb7d666 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -491,6 +491,23 @@ cmPolicies::cmPolicies()
"CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
"honor the POSITION_INDEPENDENT_CODE target property.",
2,8,9,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0019, "CMP0019",
+ "Do not re-expand variables in include and link information.",
+ "CMake 2.8.10 and lower re-evaluated values given to the "
+ "include_directories, link_directories, and link_libraries "
+ "commands to expand any leftover variable references at the "
+ "end of the configuration step. "
+ "This was for strict compatibility with VERY early CMake versions "
+ "because all variable references are now normally evaluated during "
+ "CMake language processing. "
+ "CMake 2.8.11 and higher prefer to skip the extra evaluation."
+ "\n"
+ "The OLD behavior for this policy is to re-evaluate the values "
+ "for strict compatibility. "
+ "The NEW behavior for this policy is to leave the values untouched.",
+ 2,8,11,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 6932565..d7d945c 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -68,6 +68,7 @@ public:
CMP0018, ///< Ignore language flags for shared libs, and adhere to
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
/// instead.
+ CMP0019, ///< No variable re-expansion in include and link info
/** \brief Always the last entry.
*
diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake b/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake
new file mode 100644
index 0000000..3091e66
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0019 NEW)
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake b/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake
new file mode 100644
index 0000000..0f02f9c
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0019 OLD)
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
new file mode 100644
index 0000000..03faef9
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt
@@ -0,0 +1,40 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0019 is not set: Do not re-expand variables in include and link
+ information. Run "cmake --help-policy CMP0019" for policy details. Use
+ the cmake_policy command to set the policy and suppress this warning.
+
+ The following variable evaluations were encountered:
+
+ Evaluated directory INCLUDE_DIRECTORIES
+
+ /usr/include/\${VAR_INCLUDE};/usr/include/normal
+
+ as
+
+ /usr/include/VAL_INCLUDE;/usr/include/normal
+
+ Evaluated target some_target INCLUDE_DIRECTORIES
+
+ /usr/include/\${VAR_INCLUDE};/usr/include/normal
+
+ as
+
+ /usr/include/VAL_INCLUDE;/usr/include/normal
+
+ Evaluated link directory
+
+ /usr/lib/\${VAR_LINK_DIRS}
+
+ as
+
+ /usr/lib/VAL_LINK_DIRS
+
+ Evaluated link library
+
+ \${VAR_LINK_LIBS}
+
+ as
+
+ VAL_LINK_LIBS
+
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake b/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake
new file mode 100644
index 0000000..a419f30
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0019-code.cmake)
diff --git a/Tests/RunCMake/CMP0019/CMP0019-code.cmake b/Tests/RunCMake/CMP0019/CMP0019-code.cmake
new file mode 100644
index 0000000..26c0e5b
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMP0019-code.cmake
@@ -0,0 +1,9 @@
+set(VAR_INCLUDE "VAL_INCLUDE")
+set(VAR_LINK_DIRS "VAL_LINK_DIRS")
+set(VAR_LINK_LIBS "VAL_LINK_LIBS")
+add_custom_target(some_target)
+include_directories("/usr/include/\${VAR_INCLUDE}" /usr/include/normal)
+link_directories("/usr/lib/\${VAR_LINK_DIRS}" /usr/lib/normal)
+link_libraries("\${VAR_LINK_LIBS}" normal)
+add_custom_target(other_target)
+set_property(TARGET other_target PROPERTY INCLUDE_DIRECTORIES "")
diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt
new file mode 100644
index 0000000..e8db6b0
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0019/RunCMakeTest.cmake b/Tests/RunCMake/CMP0019/RunCMakeTest.cmake
new file mode 100644
index 0000000..119fc2b
--- /dev/null
+++ b/Tests/RunCMake/CMP0019/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0019-WARN)
+run_cmake(CMP0019-OLD)
+run_cmake(CMP0019-NEW)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 722d9c3..cc544a3 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -45,6 +45,7 @@ macro(add_RunCMake_test test)
)
endmacro()
+add_RunCMake_test(CMP0019)
add_RunCMake_test(GeneratorExpression)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)