summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 990bd471a4..d16354a56d 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 7297bbcc66..2c78c5f712 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 6049bb0cb8..6089538df7 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 7a19297a88..1ab5a97738 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 7abe109e93..09ccc2f1ac 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;