summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2002-09-17 14:56:18 (GMT)
committerBrad King <brad.king@kitware.com>2002-09-17 14:56:18 (GMT)
commite5e0132203ab8b8c2391ad7847cf2204d1e44639 (patch)
tree30d559407bd0f6077ed040636d0d4b98400544aa
parent222b04f6d9a73d202faea473ab1c5c7991ca75e6 (diff)
downloadCMake-e5e0132203ab8b8c2391ad7847cf2204d1e44639.zip
CMake-e5e0132203ab8b8c2391ad7847cf2204d1e44639.tar.gz
CMake-e5e0132203ab8b8c2391ad7847cf2204d1e44639.tar.bz2
ENH: Improved implementation of INSTALL_FILES and INSTALL_PROGRAMS commands. Source paths can now be relative or full paths, and don't need to be in the same directory as the CMakeLists.txt file.
-rw-r--r--Source/cmInstallFilesCommand.cxx77
-rw-r--r--Source/cmInstallFilesCommand.h17
-rw-r--r--Source/cmInstallProgramsCommand.cxx47
-rw-r--r--Source/cmInstallProgramsCommand.h4
-rw-r--r--Source/cmLocalUnixMakefileGenerator.cxx74
5 files changed, 161 insertions, 58 deletions
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index 990bd47..d16354a 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -30,16 +30,30 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
// Create an INSTALL_FILES target specifically for this path.
m_TargetName = "INSTALL_FILES_"+args[0];
- cmTarget target;
+ cmTarget& target = m_Makefile->GetTargets()[m_TargetName];
target.SetInAll(false);
target.SetType(cmTarget::INSTALL_FILES);
target.SetInstallPath(args[0].c_str());
- m_Makefile->GetTargets().insert(cmTargets::value_type(m_TargetName, target));
-
- std::vector<std::string>::const_iterator s = args.begin();
- for (++s;s != args.end(); ++s)
+
+ if((args.size() > 1) && (args[1] == "FILES"))
{
- m_FinalArgs.push_back(*s);
+ m_IsFilesForm = true;
+ for(std::vector<std::string>::const_iterator s = args.begin()+2;
+ s != args.end(); ++s)
+ {
+ // Find the source location for each file listed.
+ std::string f = this->FindInstallSource(s->c_str());
+ target.GetSourceLists().push_back(f);
+ }
+ }
+ else
+ {
+ m_IsFilesForm = false;
+ std::vector<std::string>::const_iterator s = args.begin();
+ for (++s;s != args.end(); ++s)
+ {
+ m_FinalArgs.push_back(*s);
+ }
}
return true;
@@ -47,6 +61,12 @@ bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& argsIn)
void cmInstallFilesCommand::FinalPass()
{
+ // No final pass for "FILES" form of arguments.
+ if(m_IsFilesForm)
+ {
+ return;
+ }
+
std::string testf;
std::string ext = m_FinalArgs[0];
std::vector<std::string>& targetSourceLists =
@@ -72,8 +92,9 @@ void cmInstallFilesCommand::FinalPass()
{
testf = cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext;
}
+
// add to the result
- targetSourceLists.push_back(testf);
+ targetSourceLists.push_back(this->FindInstallSource(testf.c_str()));
}
}
else // reg exp list
@@ -87,9 +108,47 @@ void cmInstallFilesCommand::FinalPass()
// for each argument, get the files
for (;s != files.end(); ++s)
{
- targetSourceLists.push_back(*s);
+ targetSourceLists.push_back(this->FindInstallSource(s->c_str()));
}
}
}
-
+/**
+ * Find a file in the build or source tree for installation given a
+ * relative path from the CMakeLists.txt file. This will favor files
+ * present in the build tree. If a full path is given, it is just
+ * returned.
+ */
+std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
+{
+ if(cmSystemTools::FileIsFullPath(name))
+ {
+ // This is a full path.
+ return name;
+ }
+
+ // This is a relative path.
+ std::string tb = m_Makefile->GetCurrentOutputDirectory();
+ tb += "/";
+ tb += name;
+ std::string ts = m_Makefile->GetCurrentDirectory();
+ ts += "/";
+ ts += name;
+
+ if(cmSystemTools::FileExists(tb.c_str()))
+ {
+ // The file exists in the binary tree. Use it.
+ return tb;
+ }
+ else if(cmSystemTools::FileExists(ts.c_str()))
+ {
+ // The file exists in the source tree. Use it.
+ return ts;
+ }
+ else
+ {
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
+ }
+}
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index 7297bbc..2c78c5f 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -72,14 +72,29 @@ public:
return
"INSTALL_FILES(path extension file file ...)\n"
"INSTALL_FILES(path regexp)\n"
- "Create rules to install the listed files into the path. Path is relative to the variable CMAKE_INSTALL_PREFIX. There are two forms for this command. In the first the files can be specified explicitly. If a file specified already has an extension, that extension will be removed first. This is useful for providing lists of source files such as foo.cxx when you want the corresponding foo.h to be installed. A typical extension is .h etc... In the second form any files in the current directory that match the regular expression will be installed.";
+ "INSTALL_FILES(path FILES file file ...)\n"
+ "Create rules to install the listed files into the path. Path is\n"
+ "relative to the variable CMAKE_INSTALL_PREFIX. There are three forms for\n"
+ "this command. In the first the files can be specified explicitly. If a\n"
+ "file specified already has an extension, that extension will be\n"
+ "removed first. This is useful for providing lists of source files such\n"
+ "as foo.cxx when you want the corresponding foo.h to be installed. A\n"
+ "typical extension is .h etc... In the second form any files in the\n"
+ "current directory that match the regular expression will be installed.\n"
+ "In the third form, any files listed after the FILES keyword will be\n"
+ "installed explicitly from the names given. Full paths are allowed in\n"
+ "this form.";
}
cmTypeMacro(cmInstallFilesCommand, cmCommand);
+protected:
+ std::string FindInstallSource(const char* name) const;
+
private:
std::string m_TargetName;
std::vector<std::string> m_FinalArgs;
+ bool m_IsFilesForm;
};
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 6049bb0..6089538 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -30,11 +30,10 @@ bool cmInstallProgramsCommand::InitialPass(std::vector<std::string> const& argsI
// Create an INSTALL_PROGRAMS target specifically for this path.
m_TargetName = "INSTALL_PROGRAMS_"+args[0];
- cmTarget target;
+ cmTarget& target = m_Makefile->GetTargets()[m_TargetName];
target.SetInAll(false);
target.SetType(cmTarget::INSTALL_PROGRAMS);
target.SetInstallPath(args[0].c_str());
- m_Makefile->GetTargets().insert(cmTargets::value_type(m_TargetName, target));
std::vector<std::string>::const_iterator s = args.begin();
for (++s;s != args.end(); ++s)
@@ -58,7 +57,7 @@ void cmInstallProgramsCommand::FinalPass()
s != m_FinalArgs.end(); ++s)
{
// add to the result
- targetSourceLists.push_back(*s);
+ targetSourceLists.push_back(this->FindInstallSource(s->c_str()));
}
}
else // reg exp list
@@ -71,9 +70,47 @@ void cmInstallProgramsCommand::FinalPass()
// for each argument, get the programs
for (;s != programs.end(); ++s)
{
- targetSourceLists.push_back(*s);
+ targetSourceLists.push_back(this->FindInstallSource(s->c_str()));
}
}
}
-
+/**
+ * Find a file in the build or source tree for installation given a
+ * relative path from the CMakeLists.txt file. This will favor files
+ * present in the build tree. If a full path is given, it is just
+ * returned.
+ */
+std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const
+{
+ if(cmSystemTools::FileIsFullPath(name))
+ {
+ // This is a full path.
+ return name;
+ }
+
+ // This is a relative path.
+ std::string tb = m_Makefile->GetCurrentOutputDirectory();
+ tb += "/";
+ tb += name;
+ std::string ts = m_Makefile->GetCurrentDirectory();
+ ts += "/";
+ ts += name;
+
+ if(cmSystemTools::FileExists(tb.c_str()))
+ {
+ // The file exists in the binary tree. Use it.
+ return tb;
+ }
+ else if(cmSystemTools::FileExists(ts.c_str()))
+ {
+ // The file exists in the source tree. Use it.
+ return ts;
+ }
+ else
+ {
+ // The file doesn't exist. Assume it will be present in the
+ // binary tree when the install occurs.
+ return tb;
+ }
+}
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 7a19297..1ab5a97 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -77,7 +77,9 @@ public:
cmTypeMacro(cmInstallProgramsCommand, cmCommand);
- private:
+protected:
+ std::string FindInstallSource(const char* name) const;
+private:
std::string m_TargetName;
std::vector<std::string> m_FinalArgs;
};
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx
index 7abe109..09ccc2f 100644
--- a/Source/cmLocalUnixMakefileGenerator.cxx
+++ b/Source/cmLocalUnixMakefileGenerator.cxx
@@ -1664,81 +1664,71 @@ void cmLocalUnixMakefileGenerator::OutputInstallRules(std::ostream& fout)
break;
case cmTarget::INSTALL_FILES:
{
+ std::string sourcePath = m_Makefile->GetCurrentDirectory();
+ std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
+ sourcePath += "/";
+ binaryPath += "/";
const std::vector<std::string> &sf = l->second.GetSourceLists();
std::vector<std::string>::const_iterator i;
for (i = sf.begin(); i != sf.end(); ++i)
{
- fout << "\t@ echo \"Installing " << *i << " \"\n";
- fout << "\t@if [ -f " << *i << " ] ; then \\\n";
- // avoid using install-sh to install install-sh
- // does not work on windows....
- if(*i == "install-sh")
+ std::string f = *i;
+ if(f.substr(0, sourcePath.length()) == sourcePath)
{
- fout << "\t cp ";
+ f = f.substr(sourcePath.length());
}
- else
+ else if(f.substr(0, binaryPath.length()) == binaryPath)
{
- fout << "\t $(INSTALL_DATA) ";
+ f = f.substr(binaryPath.length());
}
- fout << *i
- << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "; \\\n";
- fout << "\t elif [ -f $(CMAKE_CURRENT_SOURCE)/" << *i << " ] ; then \\\n";
+ fout << "\t@ echo \"Installing " << f.c_str() << " \"\n";
// avoid using install-sh to install install-sh
- // does not work on windows....
- if(*i == "install-sh")
+ // does not work on windows....
+ if(*i == "install-sh")
{
- fout << "\t cp ";
+ fout << "\t @cp ";
}
else
{
- fout << "\t $(INSTALL_DATA) ";
+ fout << "\t @$(INSTALL_DATA) ";
}
- fout << "$(CMAKE_CURRENT_SOURCE)/" << *i
- << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "; \\\n";
- fout << "\telse \\\n";
- fout << "\t echo \" ERROR!!! Unable to find: " << *i
- << " \"; \\\n";
- fout << "\t fi\n";
+ fout << *i
+ << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
}
}
break;
case cmTarget::INSTALL_PROGRAMS:
{
+ std::string sourcePath = m_Makefile->GetCurrentDirectory();
+ std::string binaryPath = m_Makefile->GetCurrentOutputDirectory();
+ sourcePath += "/";
+ binaryPath += "/";
const std::vector<std::string> &sf = l->second.GetSourceLists();
std::vector<std::string>::const_iterator i;
for (i = sf.begin(); i != sf.end(); ++i)
{
- fout << "\t@ echo \"Installing " << *i << " \"\n";
- fout << "\t@if [ -f " << *i << " ] ; then \\\n";
- // avoid using install-sh to install install-sh
- // does not work on windows....
- if(*i == "install-sh")
+ std::string f = *i;
+ if(f.substr(0, sourcePath.length()) == sourcePath)
{
- fout << "\t cp ";
+ f = f.substr(sourcePath.length());
}
- else
+ else if(f.substr(0, binaryPath.length()) == binaryPath)
{
- fout << "\t $(INSTALL_PROGRAM) ";
+ f = f.substr(binaryPath.length());
}
- fout << *i
- << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "; \\\n";
- fout << "\t elif [ -f $(CMAKE_CURRENT_SOURCE)/" << *i << " ] ; then \\\n";
+ fout << "\t@ echo \"Installing " << f.c_str() << " \"\n";
// avoid using install-sh to install install-sh
- // does not work on windows....
- if(*i == "install-sh")
+ // does not work on windows....
+ if(*i == "install-sh")
{
- fout << "\t cp ";
+ fout << "\t @cp ";
}
else
{
- fout << "\t $(INSTALL_PROGRAM) ";
+ fout << "\t @$(INSTALL_DATA) ";
}
- fout << "$(CMAKE_CURRENT_SOURCE)/" << *i
- << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "; \\\n";
- fout << "\telse \\\n";
- fout << "\t echo \" ERROR!!! Unable to find: " << *i
- << " \"; \\\n";
- fout << "\t fi\n";
+ fout << *i
+ << " $(DESTDIR)" << prefix << l->second.GetInstallPath() << "\n";
}
}
break;