summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/install.rst6
-rw-r--r--Help/release/3.0.0.rst4
-rw-r--r--Source/cmInstallCommand.cxx5
-rw-r--r--Source/cmInstallFilesCommand.cxx3
-rw-r--r--Source/cmInstallFilesGenerator.cxx51
-rw-r--r--Source/cmInstallFilesGenerator.h5
-rw-r--r--Source/cmInstallProgramsCommand.cxx3
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt16
-rw-r--r--Tests/ExportImport/Export/testLib1file1.txt1
-rw-r--r--Tests/ExportImport/Export/testLib1file2.txt1
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt6
-rw-r--r--Tests/ExportImport/Import/A/check_testLib1_genex.cmake11
12 files changed, 105 insertions, 7 deletions
diff --git a/Help/command/install.rst b/Help/command/install.rst
index ebc95d7..47108f0 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -169,6 +169,12 @@ default permissions for the installed file also include ``OWNER_EXECUTE``,
programs that are not targets, such as shell scripts. Use the ``TARGETS``
form to install targets built within the project.
+The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
+"generator expressions" with the syntax ``$<...>``. See the
+:manual:`cmake-generator-expressions(7)` manual for available expressions.
+However, if any item begins in a generator expression it must evaluate
+to a full path.
+
------------------------------------------------------------------------------
::
diff --git a/Help/release/3.0.0.rst b/Help/release/3.0.0.rst
index 105d651..677c7a8 100644
--- a/Help/release/3.0.0.rst
+++ b/Help/release/3.0.0.rst
@@ -102,6 +102,10 @@ Commands
configuration because it will not be available.
Use :ref:`Alias Targets` instead. See policy :policy:`CMP0024`.
+* The :command:`install(FILES)` command learned to support
+ :manual:`generator expressions <cmake-generator-expressions(7)>`
+ in the list of files.
+
* The :command:`project` command learned to set some version variables
to values specified by the new ``VERSION`` option or to empty strings.
See policy :policy:`CMP0048`.
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index f4fbb8a..0878aae 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -1355,7 +1355,8 @@ bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
++fileIt)
{
std::string file = (*fileIt);
- if(!cmSystemTools::FileIsFullPath(file.c_str()))
+ std::string::size_type gpos = cmGeneratorExpression::Find(file);
+ if(gpos != 0 && !cmSystemTools::FileIsFullPath(file.c_str()))
{
file = this->Makefile->GetCurrentDirectory();
file += "/";
@@ -1363,7 +1364,7 @@ bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
}
// Make sure the file is not a directory.
- if(cmSystemTools::FileIsDirectory(file.c_str()))
+ if(gpos == file.npos && cmSystemTools::FileIsDirectory(file.c_str()))
{
cmOStringStream e;
e << modeName << " given directory \"" << (*fileIt) << "\" to install.";
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 32e463b..488d486 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -148,7 +148,8 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
*/
std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
{
- if(cmSystemTools::FileIsFullPath(name))
+ if(cmSystemTools::FileIsFullPath(name) ||
+ cmGeneratorExpression::Find(name) == 0)
{
// This is a full path.
return name;
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 506dcbf..ec15044 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -11,6 +11,9 @@
============================================================================*/
#include "cmInstallFilesGenerator.h"
+#include "cmGeneratorExpression.h"
+#include "cmSystemTools.h"
+
//----------------------------------------------------------------------------
cmInstallFilesGenerator
::cmInstallFilesGenerator(cmMakefile* mf,
@@ -27,6 +30,15 @@ cmInstallFilesGenerator
FilePermissions(file_permissions),
Rename(rename), Optional(optional)
{
+ // We need per-config actions if any files have generator expressions.
+ for(std::vector<std::string>::const_iterator i = files.begin();
+ !this->ActionsPerConfig && i != files.end(); ++i)
+ {
+ if(cmGeneratorExpression::Find(*i) != std::string::npos)
+ {
+ this->ActionsPerConfig = true;
+ }
+ }
}
//----------------------------------------------------------------------------
@@ -36,8 +48,9 @@ cmInstallFilesGenerator
}
//----------------------------------------------------------------------------
-void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
- Indent const& indent)
+void cmInstallFilesGenerator::AddFilesInstallRule(
+ std::ostream& os, Indent const& indent,
+ std::vector<std::string> const& files)
{
// Write code to install the files.
const char* no_dir_permissions = 0;
@@ -45,8 +58,40 @@ void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
(this->Programs
? cmInstallType_PROGRAMS
: cmInstallType_FILES),
- this->Files,
+ files,
this->Optional,
this->FilePermissions.c_str(), no_dir_permissions,
this->Rename.c_str(), 0, indent);
}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os,
+ Indent const& indent)
+{
+ if(this->ActionsPerConfig)
+ {
+ this->cmInstallGenerator::GenerateScriptActions(os, indent);
+ }
+ else
+ {
+ this->AddFilesInstallRule(os, indent, this->Files);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmInstallFilesGenerator::GenerateScriptForConfig(std::ostream& os,
+ const char* config,
+ Indent const& indent)
+{
+ std::vector<std::string> files;
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ for(std::vector<std::string>::const_iterator i = this->Files.begin();
+ i != this->Files.end(); ++i)
+ {
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*i);
+ cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config),
+ files);
+ }
+ this->AddFilesInstallRule(os, indent, files);
+}
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 02b005e..9dea296 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -34,6 +34,11 @@ public:
protected:
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
+ virtual void GenerateScriptForConfig(std::ostream& os,
+ const char* config,
+ Indent const& indent);
+ void AddFilesInstallRule(std::ostream& os, Indent const& indent,
+ std::vector<std::string> const& files);
cmMakefile* Makefile;
std::vector<std::string> Files;
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 9f2945f..54d903a 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -109,7 +109,8 @@ void cmInstallProgramsCommand::FinalPass()
std::string cmInstallProgramsCommand
::FindInstallSource(const char* name) const
{
- if(cmSystemTools::FileIsFullPath(name))
+ if(cmSystemTools::FileIsFullPath(name) ||
+ cmGeneratorExpression::Find(name) == 0)
{
// This is a full path.
return name;
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 0e2828e..febdfe6 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -23,6 +23,22 @@ add_library(testLib1 STATIC testLib1.c)
add_library(testLib2 STATIC testLib2.c)
target_link_libraries(testLib2 testLib1)
+# Test install(FILES) with generator expressions referencing testLib1.
+add_custom_command(TARGET testLib1 POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:testLib1>
+ $<TARGET_FILE:testLib1>.genex
+ )
+install(FILES $<TARGET_FILE:testLib1>.genex
+ DESTINATION lib
+ )
+set_property(TARGET testLib1 PROPERTY MY_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file1.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/testLib1file2.txt
+ )
+install(FILES $<TARGET_PROPERTY:testLib1,MY_FILES>
+ DESTINATION doc
+ )
+
# Test library with empty link interface. Link it to an implementation
# dependency that itself links to dependencies publicly.
add_library(testLib3ImpDep SHARED testLib3ImpDep.c)
diff --git a/Tests/ExportImport/Export/testLib1file1.txt b/Tests/ExportImport/Export/testLib1file1.txt
new file mode 100644
index 0000000..73601df
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib1file1.txt
@@ -0,0 +1 @@
+testLib1file1
diff --git a/Tests/ExportImport/Export/testLib1file2.txt b/Tests/ExportImport/Export/testLib1file2.txt
new file mode 100644
index 0000000..4874ed1
--- /dev/null
+++ b/Tests/ExportImport/Export/testLib1file2.txt
@@ -0,0 +1 @@
+testLib1file2
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index ebe4af2..eb0bbf8 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -68,6 +68,12 @@ target_link_libraries(imp_testExe1b
bld_testLibCycleA
)
+add_custom_target(check_testLib1_genex ALL
+ COMMAND ${CMAKE_COMMAND} -DtestLib1=$<TARGET_FILE:exp_testLib1>
+ -Dprefix=${CMAKE_INSTALL_PREFIX}
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check_testLib1_genex.cmake
+ )
+
add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp)
target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)
diff --git a/Tests/ExportImport/Import/A/check_testLib1_genex.cmake b/Tests/ExportImport/Import/A/check_testLib1_genex.cmake
new file mode 100644
index 0000000..7c02652
--- /dev/null
+++ b/Tests/ExportImport/Import/A/check_testLib1_genex.cmake
@@ -0,0 +1,11 @@
+foreach(f
+ "${testLib1}.genex"
+ "${prefix}/doc/testLib1file1.txt"
+ "${prefix}/doc/testLib1file2.txt"
+ )
+ if(EXISTS "${f}")
+ message(STATUS "'${f}' exists!")
+ else()
+ message(FATAL_ERROR "Missing file:\n ${f}")
+ endif()
+endforeach()