summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2007-06-29 12:58:18 -0400
committerBill Hoffman <bill.hoffman@kitware.com>2007-06-29 12:58:18 -0400
commit4e38cf0d4ce9a275d358c87dc784d2ca827f03d2 (patch)
tree951f7d1938bc92de04b1d0e6b8d5b8735c316674
parentff323cb9a11637f1c3d4dafaf31c2c20adc533c1 (diff)
downloadcmake-4e38cf0d4ce9a275d358c87dc784d2ca827f03d2.tar.gz
ENH: RC 11
-rw-r--r--CMakeLists.txt2
-rw-r--r--ChangeLog.manual8
-rw-r--r--Modules/Platform/Linux.cmake27
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx25
-rw-r--r--Source/cmCommandArgumentParserHelper.h2
-rw-r--r--Source/cmFileCommand.cxx69
-rw-r--r--Source/cmFileCommand.h3
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmMakefile.cxx138
-rw-r--r--Source/cmMakefile.h10
-rw-r--r--Source/cmake.cxx14
-rw-r--r--Tests/StringFileTest/InputFile.h.in4
-rw-r--r--Tests/StringFileTest/StringFile.cxx2
13 files changed, 213 insertions, 103 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af11eb7e73..78245ae671 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ SET(CMake_VERSION_MAJOR 2)
SET(CMake_VERSION_MINOR 4)
SET(CMake_VERSION_PATCH 7)
# for an actual release this should not be defined
-SET(CMake_VERSION_RC 10)
+SET(CMake_VERSION_RC 11)
SET(CMake_VERSION "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}")
SET(CMake_VERSION_FULL "${CMake_VERSION}.${CMake_VERSION_PATCH}")
diff --git a/ChangeLog.manual b/ChangeLog.manual
index 5f17004810..d9b5786280 100644
--- a/ChangeLog.manual
+++ b/ChangeLog.manual
@@ -1,4 +1,12 @@
Changes in CMake 2.4.7
+--- RC 11 ----
+* Fix bug 5238 for cygwin versioned executables
+
+* Allow for platform choice of executable shared libs install
+
+* Fix @ONLY issues with RC 10
+
+* Add -E make_directory to cmake executable
--- RC 10 ----
* Fix rebuild problem with makefiles and cmake vs CMakeSetup
--- RC 9 ---
diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake
index 498e49126a..4db08f8f87 100644
--- a/Modules/Platform/Linux.cmake
+++ b/Modules/Platform/Linux.cmake
@@ -18,4 +18,31 @@ FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic")
ENDFOREACH(type)
+# Debian policy requires that shared libraries be installed without
+# executable permission. Fedora policy requires that shared libraries
+# be installed with the executable permission. Since the native tools
+# create shared libraries with execute permission in the first place a
+# reasonable policy seems to be to install with execute permission by
+# default. In order to support debian packages we provide an option
+# here. The option default is based on the current distribution, but
+# packagers can set it explicitly on the command line.
+IF(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+ # Store the decision variable in the cache. This preserves any
+ # setting the user provides on the command line.
+ SET(CMAKE_INSTALL_SO_NO_EXE "${CMAKE_INSTALL_SO_NO_EXE}" CACHE INTERNAL
+ "Install .so files without execute permission.")
+ELSE(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+ # Store the decision variable as an internal cache entry to avoid
+ # checking the platform every time. This option is advanced enough
+ # that only package maintainers should need to adjust it. They are
+ # capable of providing a setting on the command line.
+ IF(EXISTS "/etc/debian_version")
+ SET(CMAKE_INSTALL_SO_NO_EXE 1 CACHE INTERNAL
+ "Install .so files without execute permission.")
+ ELSE(EXISTS "/etc/debian_version")
+ SET(CMAKE_INSTALL_SO_NO_EXE 0 CACHE INTERNAL
+ "Install .so files without execute permission.")
+ ENDIF(EXISTS "/etc/debian_version")
+ENDIF(DEFINED CMAKE_INSTALL_SO_NO_EXE)
+
INCLUDE(Platform/UnixPaths)
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 0f595ac5d7..4c13def836 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -38,7 +38,6 @@ cmCommandArgumentParserHelper::cmCommandArgumentParserHelper()
this->NoEscapeMode = false;
this->ReplaceAtSyntax = false;
- this->AtOnly = false;
}
@@ -72,18 +71,6 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
{
return this->ExpandVariable(var);
}
- if(this->AtOnly)
- {
- std::string ref = "$";
- ref += key;
- ref += "{";
- if(var)
- {
- ref += var;
- }
- ref += "}";
- return this->AddString(ref.c_str());
- }
if ( strcmp(key, "ENV") == 0 )
{
char *ptr = getenv(var);
@@ -108,18 +95,6 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key,
char* cmCommandArgumentParserHelper::ExpandVariable(const char* var,
bool doingAt)
{
- // if we are in AtOnly mode, and we are not expanding an @ variable
- // then put back the ${var} unexpanded
- if(!doingAt && this->AtOnly)
- {
- std::string ref = "${";
- if(var)
- {
- ref += var;
- }
- ref += "}";
- return this->AddString(ref.c_str());
- }
if(!var)
{
return 0;
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 5a225caf2a..2254d60dae 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -71,7 +71,6 @@ public:
void SetNoEscapeMode(bool b) { this->NoEscapeMode = b; }
void SetReplaceAtSyntax(bool b) { this->ReplaceAtSyntax = b; }
void SetRemoveEmpty(bool b) { this->RemoveEmpty = b; }
- void SetAtOnly(bool b) { this->AtOnly = b; }
const char* GetError() { return this->ErrorString.c_str(); }
char EmptyVariable[1];
@@ -107,7 +106,6 @@ private:
bool NoEscapeMode;
bool ReplaceAtSyntax;
bool RemoveEmpty;
- bool AtOnly;
};
#endif
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 3dc673837c..3e9bf668bc 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -1162,6 +1162,9 @@ bool cmFileCommand::HandleInstallCommand(
}
}
+ // Choose a default for shared library permissions.
+ bool install_so_no_exe = this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE");
+
// If file permissions were not specified set default permissions
// for this target type.
if(!use_given_permissions_file && !use_source_permissions)
@@ -1170,15 +1173,16 @@ bool cmFileCommand::HandleInstallCommand(
{
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
-#if defined(__linux__)
- // Use read/write permissions.
- permissions_file = 0;
- permissions_file |= mode_owner_read;
- permissions_file |= mode_owner_write;
- permissions_file |= mode_group_read;
- permissions_file |= mode_world_read;
- break;
-#endif
+ if(install_so_no_exe)
+ {
+ // Use read/write permissions.
+ permissions_file = 0;
+ permissions_file |= mode_owner_read;
+ permissions_file |= mode_owner_write;
+ permissions_file |= mode_group_read;
+ permissions_file |= mode_world_read;
+ break;
+ }
case cmTarget::EXECUTABLE:
case cmTarget::INSTALL_PROGRAMS:
// Use read/write/executable permissions.
@@ -1275,10 +1279,10 @@ bool cmFileCommand::HandleInstallCommand(
std::string libname = toFile;
std::string soname = toFile;
std::string soname_nopath = fromName;
- this->ComputeVersionedName(soname, lib_soversion);
- this->ComputeVersionedName(soname_nopath, lib_soversion);
- this->ComputeVersionedName(fromName, lib_version);
- this->ComputeVersionedName(toFile, lib_version);
+ this->ComputeVersionedLibName(soname, lib_soversion);
+ this->ComputeVersionedLibName(soname_nopath, lib_soversion);
+ this->ComputeVersionedLibName(fromName, lib_version);
+ this->ComputeVersionedLibName(toFile, lib_version);
cmSystemTools::RemoveFile(soname.c_str());
cmSystemTools::RemoveFile(libname.c_str());
@@ -1318,22 +1322,14 @@ bool cmFileCommand::HandleInstallCommand(
if ( exe_version )
{
std::string exename = toFile;
- std::string exename_nopath = fromName;
- exename_nopath += "-";
- exename_nopath += exe_version;
-
- fromName += "-";
- fromName += exe_version;
- toFile += "-";
- toFile += exe_version;
-
+ this->ComputeVersionedExeName(fromName, exe_version);
+ this->ComputeVersionedExeName(toFile, exe_version);
cmSystemTools::RemoveFile(exename.c_str());
-
- if (!cmSystemTools::CreateSymlink(exename_nopath.c_str(),
- exename.c_str()) )
+ if(!cmSystemTools::CreateSymlink(fromName.c_str(),
+ exename.c_str()))
{
- std::string errstring = "error when creating symlink from: "
- + exename + " to " + exename_nopath;
+ std::string errstring = "error when creating symlink from: "
+ + exename + " to " + fromName;
this->SetError(errstring.c_str());
return false;
}
@@ -1408,8 +1404,8 @@ bool cmFileCommand::HandleInstallCommand(
}
//----------------------------------------------------------------------------
-void cmFileCommand::ComputeVersionedName(std::string& name,
- const char* version)
+void cmFileCommand::ComputeVersionedLibName(std::string& name,
+ const char* version)
{
#if defined(__APPLE__)
std::string ext;
@@ -1428,6 +1424,21 @@ void cmFileCommand::ComputeVersionedName(std::string& name,
}
//----------------------------------------------------------------------------
+void cmFileCommand::ComputeVersionedExeName(std::string& name,
+ const char* version)
+{
+ std::string ext;
+ if(name.size() > 4 && name.substr(name.size()-4) == ".exe")
+ {
+ ext = ".exe";
+ name = name.substr(0, name.size()-4);
+ }
+ name += "-";
+ name += version;
+ name += ext;
+}
+
+//----------------------------------------------------------------------------
bool cmFileCommand::HandleRelativePathCommand(
std::vector<std::string> const& args)
{
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 73323a6880..4053e930ac 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -125,7 +125,8 @@ protected:
bool HandleRelativePathCommand(std::vector<std::string> const& args);
bool HandleCMakePathCommand(std::vector<std::string> const& args,
bool nativePath);
- void ComputeVersionedName(std::string& name, const char* version);
+ void ComputeVersionedLibName(std::string& name, const char* version);
+ void ComputeVersionedExeName(std::string& name, const char* version);
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 6b1fc20d75..0f9b1a6d2c 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -386,6 +386,18 @@ void cmLocalGenerator::GenerateInstallRules()
"ENDIF(NOT CMAKE_INSTALL_COMPONENT)\n"
"\n";
+ // Copy user-specified install options to the install code.
+ if(const char* so_no_exe =
+ this->Makefile->GetDefinition("CMAKE_INSTALL_SO_NO_EXE"))
+ {
+ fout <<
+ "# Install shared libraries without execute permission?\n"
+ "IF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n"
+ " SET(CMAKE_INSTALL_SO_NO_EXE \"" << so_no_exe << "\")\n"
+ "ENDIF(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n"
+ "\n";
+ }
+
// Ask each install generator to write its code.
std::vector<cmInstallGenerator*> const& installers =
this->Makefile->GetInstallGenerators();
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 24f00c0964..a4976c2964 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -85,9 +85,7 @@ cmMakefile::cmMakefile()
this->AddSourceGroup("Resources", "\\.plist$");
#endif
this->AddDefaultDefinitions();
- this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
- this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
-
+ this->Initialize();
this->PreOrder = false;
}
@@ -131,6 +129,15 @@ cmMakefile::cmMakefile(const cmMakefile& mf)
this->Properties = mf.Properties;
this->PreOrder = mf.PreOrder;
this->ListFileStack = mf.ListFileStack;
+ this->Initialize();
+}
+
+//----------------------------------------------------------------------------
+void cmMakefile::Initialize()
+{
+ this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
+ this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
+ this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
}
const char* cmMakefile::GetReleaseVersion()
@@ -1698,7 +1705,7 @@ std::vector<std::string> cmMakefile
}
-const char *cmMakefile::ExpandVariablesInString(std::string& source) const
+const char *cmMakefile::ExpandVariablesInString(std::string& source)
{
return this->ExpandVariablesInString(source, false, false);
}
@@ -1710,57 +1717,108 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
const char* filename,
long line,
bool removeEmpty,
- bool replaceAt) const
+ bool replaceAt)
{
if ( source.empty() || source.find_first_of("$@\\") == source.npos)
{
return source.c_str();
}
+ // Special-case the @ONLY mode.
+ if(atOnly)
+ {
+ if(!noEscapes || !removeEmpty || !replaceAt)
+ {
+ // This case should never be called. At-only is for
+ // configure-file/string which always does no escapes.
+ abort();
+ }
+
+ // Store an original copy of the input.
+ std::string input = source;
+
+ // Start with empty output.
+ source = "";
+
+ // Look for one @VAR@ at a time.
+ const char* in = input.c_str();
+ while(this->cmAtVarRegex.find(in))
+ {
+ // Get the range of the string to replace.
+ const char* first = in + this->cmAtVarRegex.start();
+ const char* last = in + this->cmAtVarRegex.end();
+
+ // Store the unchanged part of the string now.
+ source.append(in, first-in);
+
+ // Lookup the definition of VAR.
+ std::string var(first+1, last-first-2);
+ if(const char* val = this->GetDefinition(var.c_str()))
+ {
+ // Store the value in the output escaping as requested.
+ if(escapeQuotes)
+ {
+ source.append(cmSystemTools::EscapeQuotes(val));
+ }
+ else
+ {
+ source.append(val);
+ }
+ }
+
+ // Continue looking for @VAR@ further along the string.
+ in = last;
+ }
+
+ // Append the rest of the unchanged part of the string.
+ source.append(in);
+
+ return source.c_str();
+ }
+
// This method replaces ${VAR} and @VAR@ where VAR is looked up
// with GetDefinition(), if not found in the map, nothing is expanded.
// It also supports the $ENV{VAR} syntax where VAR is looked up in
// the current environment variables.
-
- cmCommandArgumentParserHelper parser;
- parser.SetMakefile(this);
- parser.SetLineFile(line, filename);
- parser.SetEscapeQuotes(escapeQuotes);
- parser.SetNoEscapeMode(noEscapes);
- parser.SetReplaceAtSyntax(replaceAt);
+
+ cmCommandArgumentParserHelper parser;
+ parser.SetMakefile(this);
+ parser.SetLineFile(line, filename);
+ parser.SetEscapeQuotes(escapeQuotes);
+ parser.SetNoEscapeMode(noEscapes);
+ parser.SetReplaceAtSyntax(replaceAt);
parser.SetRemoveEmpty(removeEmpty);
- parser.SetAtOnly(atOnly);
- int res = parser.ParseString(source.c_str(), 0);
- if ( res )
+ int res = parser.ParseString(source.c_str(), 0);
+ if ( res )
+ {
+ source = parser.GetResult();
+ }
+ else
+ {
+ cmOStringStream error;
+ error << "Syntax error in cmake code at\n"
+ << (filename?filename:"(no filename given)")
+ << ":" << line << ":\n"
+ << parser.GetError() << ", when parsing string \""
+ << source.c_str() << "\"";
+ const char* versionValue
+ = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
+ int major = 0;
+ int minor = 0;
+ if ( versionValue )
+ {
+ sscanf(versionValue, "%d.%d", &major, &minor);
+ }
+ if ( major < 2 || major == 2 && minor < 1 )
{
- source = parser.GetResult();
+ cmSystemTools::Error(error.str().c_str());
+ cmSystemTools::SetFatalErrorOccured();
+ return source.c_str();
}
else
{
- cmOStringStream error;
- error << "Syntax error in cmake code at\n"
- << (filename?filename:"(no filename given)")
- << ":" << line << ":\n"
- << parser.GetError() << ", when parsing string \""
- << source.c_str() << "\"";
- const char* versionValue
- = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
- int major = 0;
- int minor = 0;
- if ( versionValue )
- {
- sscanf(versionValue, "%d.%d", &major, &minor);
- }
- if ( major < 2 || major == 2 && minor < 1 )
- {
- cmSystemTools::Error(error.str().c_str());
- cmSystemTools::SetFatalErrorOccured();
- return source.c_str();
- }
- else
- {
- cmSystemTools::Message(error.str().c_str());
- }
+ cmSystemTools::Message(error.str().c_str());
}
+ }
return source.c_str();
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 815e9f289d..b4456ef74e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -571,14 +571,14 @@ public:
* entry in the this->Definitions map. Also @var@ is
* expanded to match autoconf style expansions.
*/
- const char *ExpandVariablesInString(std::string& source) const;
+ const char *ExpandVariablesInString(std::string& source);
const char *ExpandVariablesInString(std::string& source, bool escapeQuotes,
bool noEscapes,
bool atOnly = false,
const char* filename = 0,
long line = -1,
bool removeEmpty = false,
- bool replaceAt = true) const;
+ bool replaceAt = true);
/**
* Remove any remaining variables in the string. Anything with ${var} or
@@ -774,7 +774,8 @@ protected:
bool IsFunctionBlocked(const cmListFileFunction& lff);
private:
-
+ void Initialize();
+
void ReadSources(std::ifstream& fin, bool t);
friend class cmMakeDepend; // make depend needs direct access
// to the Sources array
@@ -798,7 +799,8 @@ private:
cmsys::RegularExpression cmDefineRegex;
cmsys::RegularExpression cmDefine01Regex;
-
+ cmsys::RegularExpression cmAtVarRegex;
+
std::map<cmStdString,cmStdString> Properties;
// should this makefile be processed before or after processing the parent
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index c98664cc95..a2d889aabc 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -790,7 +790,8 @@ void CMakeCommandUsage(const char* program)
<< " echo_append [string]... - displays arguments as text but no new"
" line\n"
<< " environment - display the current enviroment\n"
- << " remove file1 file2 ... - remove the file(s)\n"
+ << " make_directory dir - create a directory\n"
+ << " remeove file1 file2 ... - remove the file(s)\n"
<< " tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar.\n"
<< " time command [args] ... - run command and return elapsed time\n"
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -902,6 +903,17 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0;
}
#endif
+
+ if (args[1] == "make_directory" && args.size() == 3)
+ {
+ if(!cmSystemTools::MakeDirectory(args[2].c_str()))
+ {
+ std::cerr << "Error making directory \"" << args[2].c_str()
+ << "\".\n";
+ return 1;
+ }
+ return 0;
+ }
// Remove file
else if (args[1] == "remove" && args.size() > 2)
diff --git a/Tests/StringFileTest/InputFile.h.in b/Tests/StringFileTest/InputFile.h.in
index c7c1995531..3e70a36e86 100644
--- a/Tests/StringFileTest/InputFile.h.in
+++ b/Tests/StringFileTest/InputFile.h.in
@@ -5,6 +5,10 @@
/* This should be configured to a commented undef with the curlies in place */
#cmakedefine TEST_NOT_DEFINED ${TEST_NOT_DEFINED}
+/* This complicated line should be configured unchanged: */
+static const char* configvar =
+"@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@";
+
int CheckMethod(const char* var, const char* val )
{
if ( !var )
diff --git a/Tests/StringFileTest/StringFile.cxx b/Tests/StringFileTest/StringFile.cxx
index 0601aa0313..609ebaf20c 100644
--- a/Tests/StringFileTest/StringFile.cxx
+++ b/Tests/StringFileTest/StringFile.cxx
@@ -24,6 +24,8 @@ int main(int, char*[])
res += CheckMethod(tuvar, "CMAKE");
res += CheckMethod(tlvar, "cmake");
res += CheckMethod(relpath, "../../X11R6/bin/xnest");
+ res += CheckMethod(configvar,
+ "@$@$junk =~ s/#$xyz#/$foo_bar{$wibble}->{$xyz}/;@@");
return res;
}