summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2008-04-20 20:44:59 -0400
committerBill Hoffman <bill.hoffman@kitware.com>2008-04-20 20:44:59 -0400
commitb855e7defc42a210e7908c2abc54535de9265acc (patch)
tree35c38fbdcd4f2b9346949f401ea9ddc716ca0abc
parent0d98aada943e23dbf3165fc97d71be3b57310e55 (diff)
downloadcmake-b855e7defc42a210e7908c2abc54535de9265acc.tar.gz
ENH: merge in from main tree
-rw-r--r--CMakeLists.txt2
-rw-r--r--ChangeLog.manual15
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake10
-rwxr-xr-xModules/CPack.RuntimeScript.in21
-rw-r--r--Modules/CPack.cmake53
-rw-r--r--Modules/FindMPI.cmake12
-rw-r--r--Modules/FindwxWidgets.cmake12
-rw-r--r--Source/CPack/cpack.cxx3
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx26
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h3
-rw-r--r--Source/cmELF.cxx88
-rw-r--r--Source/cmELF.h14
-rw-r--r--Source/cmFileCommand.cxx162
-rw-r--r--Source/cmFileCommand.h4
-rw-r--r--Source/cmInstallCommand.cxx48
-rw-r--r--Source/cmInstallCommand.h19
-rw-r--r--Source/cmInstallTargetGenerator.cxx105
-rw-r--r--Source/cmInstallTargetGenerator.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx23
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx5
-rw-r--r--Source/cmMakefileTargetGenerator.cxx12
-rw-r--r--Source/cmMessageCommand.cxx2
-rw-r--r--Source/cmPolicies.cxx18
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmSystemTools.cxx243
-rw-r--r--Source/cmSystemTools.h16
-rw-r--r--Source/cmTarget.cxx10
-rw-r--r--Tests/Framework/CMakeLists.txt1
-rw-r--r--Tests/Tutorial/Step7/CMakeLists.txt1
-rw-r--r--Tests/X11/CMakeLists.txt11
-rw-r--r--Tests/X11/HelloWorldX11.cxx145
31 files changed, 974 insertions, 114 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2298ff210a..6badd627ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -354,7 +354,7 @@ ENDMACRO (CMAKE_BUILD_UTILITIES)
SET(CMake_VERSION_MAJOR 2)
SET(CMake_VERSION_MINOR 6)
SET(CMake_VERSION_PATCH 0)
-SET(CMake_VERSION_RC 8)
+SET(CMake_VERSION_RC 81)
# CVS versions are odd, if this is an odd minor version
# then set the CMake_VERSION_DATE variable
IF("${CMake_VERSION_MINOR}" MATCHES "[13579]$")
diff --git a/ChangeLog.manual b/ChangeLog.manual
index 37b4ff1456..2a640bfe5c 100644
--- a/ChangeLog.manual
+++ b/ChangeLog.manual
@@ -1,3 +1,18 @@
+Changes in CMake 2.6.0 RC 9
+
+- Better message in compiler ABI detect
+- Fixes for cpack x11 packages on leopard
+- Changes to cpack options names
+- Fixes for FindMPI on 64 bit MS MPI
+- Fix for -isystem for wxWidgets
+- Some fixes to chrpath during installation
+- Fix compatibility with CMake 2.4 for installation of MACOSX_BUNDLE (CMP0006)
+- Do not use debug postfix when building frameworks on the Mac
+- Fix exception handling off/on issue with visual studio IDE generators
+- Fix <OBJECT_DIR> to be native path style
+- Fix leak in cpack
+- Some Qt GUI style changes
+
Changes in CMake 2.6.0 RC 8
- Fix sun make very poor performance
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 0571dc664f..3fd06a9577 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -5,7 +5,7 @@
FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
IF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
- MESSAGE(STATUS "Detecting ${lang} compiler info")
+ MESSAGE(STATUS "Detecting ${lang} compiler ABI info")
# Compile the ABI identification source.
SET(BIN "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeDetermineCompilerABI_${lang}.bin")
@@ -17,9 +17,9 @@ FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
# Load the resulting information strings.
IF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
- MESSAGE(STATUS "Detecting ${lang} compiler info - done")
+ MESSAGE(STATUS "Detecting ${lang} compiler ABI info - done")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "Detecting ${lang} compiler info compiled with the following output:\n${OUTPUT}\n\n")
+ "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
FILE(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[^[]*\\[")
FOREACH(info ${ABI_STRINGS})
IF("${info}" MATCHES ".*INFO:sizeof_dptr\\[0*([^]]*)\\].*")
@@ -41,9 +41,9 @@ FUNCTION(CMAKE_DETERMINE_COMPILER_ABI lang src)
ENDIF(ABI_NAME)
ELSE(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
- MESSAGE(STATUS "Detecting ${lang} compiler info - failed")
+ MESSAGE(STATUS "Detecting ${lang} compiler ABI info - failed")
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "Detecting ${lang} compiler info failed to compile with the following output:\n${OUTPUT}\n\n")
+ "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n\n")
ENDIF(CMAKE_DETERMINE_${lang}_ABI_COMPILED)
ENDIF(NOT DEFINED CMAKE_DETERMINE_${lang}_ABI_COMPILED)
ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ABI)
diff --git a/Modules/CPack.RuntimeScript.in b/Modules/CPack.RuntimeScript.in
index 1ce43bc777..fc3444abfd 100755
--- a/Modules/CPack.RuntimeScript.in
+++ b/Modules/CPack.RuntimeScript.in
@@ -5,6 +5,26 @@
CWD="`dirname \"$0\"`"
TMP=/tmp/$UID/TemporaryItems
+version=`sw_vers -productVersion`
+if [ "$?" == "0" ]; then
+ major=${version%%\.*}
+ rest=${version#*\.}
+ minor=${rest%%\.*}
+ build=${rest#*\.}
+else
+ major=10
+ minor=4
+ build=0
+fi
+
+echo $version
+echo "Major = $major"
+echo "Minor = $minor"
+echo "Build = $build"
+
+
+# if 10.5 or greater, then all the open-x11 stuff need not occur
+if ((( $major < 10 )) || ((( $major == 10)) && (( $minor < 5 )))); then
ps -wx -ocommand | grep -e '[X]11.app' > /dev/null
if [ "$?" != "0" -a ! -f ~/.xinitrc ]; then
echo "rm -f ~/.xinitrc" > ~/.xinitrc
@@ -42,4 +62,5 @@ echo "$@" > /tmp/arguments.log
if echo $1 | grep -- "^-psn_"; then
shift
fi
+fi
exec "$CWD/bin/@CPACK_EXECUTABLE_NAME@" "$@" > /tmp/slicer.output 2>&1
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 15f46fbba4..59e409fb11 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -111,37 +111,37 @@ endmacro(cpack_optional_append _list _cond _item)
if(NOT CPACK_GENERATOR)
if(UNIX)
if(CYGWIN)
- option(CPACK_CYGWIN_BINARY "Enable to build Cygwin binary packages" ON)
+ option(CPACK_BINARY_CYGWIN "Enable to build Cygwin binary packages" ON)
else(CYGWIN)
if(APPLE)
- option(CPACK_PACKAGEMAKER "Enable to build PackageMaker packages" ON)
- option(CPACK_OSXX11 "Enable to build OSX X11 packages" OFF)
+ option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" ON)
+ option(CPACK_BINARY_OSXX11 "Enable to build OSX X11 packages" OFF)
else(APPLE)
- option(CPACK_TZ "Enable to build TZ packages" ON)
+ option(CPACK_BINARY_TZ "Enable to build TZ packages" ON)
endif(APPLE)
- option(CPACK_STGZ "Enable to build STGZ packages" ON)
- option(CPACK_TGZ "Enable to build TGZ packages" ON)
- option(CPACK_TBZ2 "Enable to build TBZ2 packages" ON)
- option(CPACK_DEB "Enable to build Debian packages" OFF)
- option(CPACK_RPM "Enable to build RPM packages" OFF)
- option(CPACK_NSIS "Enable to build NSIS packages" OFF)
+ option(CPACK_BINARY_STGZ "Enable to build STGZ packages" ON)
+ option(CPACK_BINARY_TGZ "Enable to build TGZ packages" ON)
+ option(CPACK_BINARY_TBZ2 "Enable to build TBZ2 packages" ON)
+ option(CPACK_BINARY_DEB "Enable to build Debian packages" OFF)
+ option(CPACK_BINARY_RPM "Enable to build RPM packages" OFF)
+ option(CPACK_BINARY_NSIS "Enable to build NSIS packages" OFF)
endif(CYGWIN)
else(UNIX)
- option(CPACK_NSIS "Enable to build NSIS packages" ON)
- option(CPACK_ZIP "Enable to build ZIP packages" ON)
+ option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
+ option(CPACK_BINARY_ZIP "Enable to build ZIP packages" ON)
endif(UNIX)
- cpack_optional_append(CPACK_GENERATOR CPACK_PACKAGEMAKER PackageMaker)
- cpack_optional_append(CPACK_GENERATOR CPACK_OSXX11 OSXX11)
- cpack_optional_append(CPACK_GENERATOR CPACK_CYGWIN_BINARY CygwinBinary)
- cpack_optional_append(CPACK_GENERATOR CPACK_DEB DEB)
- cpack_optional_append(CPACK_GENERATOR CPACK_RPM RPM)
- cpack_optional_append(CPACK_GENERATOR CPACK_NSIS NSIS)
- cpack_optional_append(CPACK_GENERATOR CPACK_STGZ STGZ)
- cpack_optional_append(CPACK_GENERATOR CPACK_TGZ TGZ)
- cpack_optional_append(CPACK_GENERATOR CPACK_TBZ2 TBZ2)
- cpack_optional_append(CPACK_GENERATOR CPACK_TZ TZ)
- cpack_optional_append(CPACK_GENERATOR CPACK_ZIP ZIP)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PACKAGEMAKER PackageMaker)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_OSXX11 OSXX11)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_CYGWIN CygwinBinary)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DEB DEB)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_RPM RPM)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NSIS NSIS)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_STGZ STGZ)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TGZ TGZ)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TBZ2 TBZ2)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TZ TZ)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP)
endif(NOT CPACK_GENERATOR)
@@ -168,9 +168,10 @@ if(NOT CPACK_SOURCE_GENERATOR)
endif(NOT CPACK_SOURCE_GENERATOR)
# mark the above options as advanced
-mark_as_advanced(CPACK_CYGWIN_BINARY CPACK_PACKAGEMAKER CPACK_OSXX11
- CPACK_STGZ CPACK_TGZ CPACK_TBZ2 CPACK_DEB CPACK_RPM
- CPACK_TZ CPACK_NSIS CPACK_ZIP
+mark_as_advanced(CPACK_BINARY_CYGWIN CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_OSXX11
+ CPACK_BINARY_STGZ CPACK_BINARY_TGZ CPACK_BINARY_TBZ2
+ CPACK_BINARY_DEB CPACK_BINARY_RPM CPACK_BINARY_TZ
+ CPACK_BINARY_NSIS CPACK_BINARY_ZIP
CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ
CPACK_SOURCE_TZ CPACK_SOURCE_ZIP)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 5e218e7074..0923c00b82 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -216,13 +216,19 @@ else (MPI_COMPILE_CMDLINE)
"$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Include"
)
- # TODO: How do we know whether we're building 32-bit vs. 64-bit for MS-MPI?
+ # Decide between 32-bit and 64-bit libraries for Microsoft's MPI
+ if (CMAKE_CL_64)
+ set(MS_MPI_ARCH_DIR amd64)
+ else (CMAKE_CL_64)
+ set(MS_MPI_ARCH_DIR i386)
+ endif (CMAKE_CL_64)
+
find_library(MPI_LIBRARY
- NAMES mpi mpich
+ NAMES mpi mpich msmpi
PATHS /usr/lib /usr/local/lib /usr/local/mpi/lib
"C:/Program Files/MPICH/SDK/Lib"
"$ENV{SystemDrive}/Program Files/MPICH/SDK/Lib"
- "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Lib/i386"
+ "$ENV{SystemDrive}/Program Files/Microsoft Compute Cluster Pack/Lib/${MS_MPI_ARCH_DIR}"
)
find_library(MPI_LIBRARY
NAMES mpich2
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index 07dd29f69b..0007ee3cc5 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -132,6 +132,18 @@ SET(wxWidgets_LIBRARIES "")
SET(wxWidgets_LIBRARY_DIRS "")
SET(wxWidgets_CXX_FLAGS "")
+# Using SYSTEM with INCLUDE_DIRECTORIES in conjunction with wxWidgets on
+# the Mac produces compiler errors. Set wxWidgets_INCLUDE_DIRS_NO_SYSTEM
+# to prevent UsewxWidgets.cmake from using SYSTEM.
+#
+# See cmake mailing list discussions for more info:
+# http://www.cmake.org/pipermail/cmake/2008-April/021115.html
+# http://www.cmake.org/pipermail/cmake/2008-April/021146.html
+#
+IF(APPLE)
+ SET(wxWidgets_INCLUDE_DIRS_NO_SYSTEM 1)
+ENDIF(APPLE)
+
# DEPRECATED: This is a patch to support the DEPRECATED use of
# wxWidgets_USE_LIBS.
#
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index b36e2303bd..ba91a089c6 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -29,6 +29,7 @@
#include "cmCPackLog.h"
#include <cmsys/CommandLineArguments.hxx>
+#include <memory> // auto_ptr
//----------------------------------------------------------------------------
static const char * cmDocumentationName[][3] =
@@ -222,7 +223,7 @@ int main (int argc, char *argv[])
cminst.RemoveUnscriptableCommands();
cmGlobalGenerator cmgg;
cmgg.SetCMakeInstance(&cminst);
- cmLocalGenerator* cmlg = cmgg.CreateLocalGenerator();
+ std::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
cmMakefile* globalMF = cmlg->GetMakefile();
bool cpackConfigFileSpecified = true;
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 1c5e25d475..56ee7ac730 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -138,6 +138,7 @@ CMakeSetupDialog::CMakeSetupDialog()
// fixed pitch font in output window
QFont outputFont("Courier");
this->Output->setFont(outputFont);
+ this->ErrorFormat.setForeground(QBrush(Qt::red));
// start the cmake worker thread
this->CMakeThread = new QCMakeThread(this);
@@ -512,32 +513,17 @@ void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent)
{
this->ProgressBar->setValue(qRound(percent * 100));
}
-
+
void CMakeSetupDialog::error(const QString& message)
{
- QStringList messages = message.split('\n');
- foreach(QString m, messages)
- {
- // make sure we escape html tags in the cmake messages
- m.replace(QString("&"), QString("&amp;"));
- m.replace(QString("<"), QString("&lt;"));
- m.replace(QString(">"), QString("&gt;"));
- m.replace(QString(" "), QString("&nbsp;"));
- this->Output->append(QString("<b><font color=red>%1</font></b>").arg(m));
- }
+ this->Output->setCurrentCharFormat(this->ErrorFormat);
+ this->Output->append(message);
}
void CMakeSetupDialog::message(const QString& message)
{
- QStringList messages = message.split('\n');
- foreach(QString m, messages)
- {
- // make sure we escape html tags in the cmake messages
- m.replace(QString("&"), QString("&amp;"));
- m.replace(QString("<"), QString("&lt;"));
- m.replace(QString(">"), QString("&gt;"));
- this->Output->append(m);
- }
+ this->Output->setCurrentCharFormat(this->MessageFormat);
+ this->Output->append(message);
}
void CMakeSetupDialog::setEnabledState(bool enabled)
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 211dfcb023..c942d154e1 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -99,6 +99,9 @@ protected:
QAction* InstallForCommandLineAction;
State CurrentState;
+ QTextCharFormat ErrorFormat;
+ QTextCharFormat MessageFormat;
+
};
// QCMake instance on a thread
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index a6440ed083..2cf6b965d2 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -98,9 +98,18 @@ public:
// Forward to the per-class implementation.
virtual unsigned int GetNumberOfSections() const = 0;
+ virtual unsigned int GetDynamicEntryCount() = 0;
+ virtual unsigned long GetDynamicEntryPosition(int j) = 0;
virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
virtual void PrintInfo(std::ostream& os) const = 0;
+ bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
+ {
+ this->Stream.seekg(pos);
+ this->Stream.read(buf, size);
+ return this->Stream?true:false;
+ }
+
// Lookup the SONAME in the DYNAMIC section.
StringEntry const* GetSOName()
{
@@ -201,6 +210,10 @@ public:
return static_cast<unsigned int>(this->ELFHeader.e_shnum);
}
+ // Get the file position and size of a dynamic section entry.
+ virtual unsigned int GetDynamicEntryCount();
+ virtual unsigned long GetDynamicEntryPosition(int j);
+
// Lookup a string from the dynamic section with the given tag.
virtual StringEntry const* GetDynamicSectionString(int tag);
@@ -552,6 +565,40 @@ bool cmELFInternalImpl<Types>::LoadDynamicSection()
//----------------------------------------------------------------------------
template <class Types>
+unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount()
+{
+ if(!this->LoadDynamicSection())
+ {
+ return 0;
+ }
+ for(unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i)
+ {
+ if(this->DynamicSectionEntries[i].d_tag == DT_NULL)
+ {
+ return i;
+ }
+ }
+ return this->DynamicSectionEntries.size();
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
+unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
+{
+ if(!this->LoadDynamicSection())
+ {
+ return 0;
+ }
+ if(j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size()))
+ {
+ return 0;
+ }
+ ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+ return sec.sh_offset + sec.sh_entsize*j;
+}
+
+//----------------------------------------------------------------------------
+template <class Types>
cmELF::StringEntry const*
cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
{
@@ -571,6 +618,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
StringEntry& se = this->DynamicSectionStrings[tag];
se.Position = 0;
se.Size = 0;
+ se.IndexInSection = -1;
// Try reading the dynamic section.
if(!this->LoadDynamicSection())
@@ -641,6 +689,7 @@ cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
// The value has been read successfully. Report it.
se.Position = static_cast<unsigned long>(strtab.sh_offset + first);
se.Size = last - first;
+ se.IndexInSection = di - this->DynamicSectionEntries.begin();
return &se;
}
}
@@ -762,6 +811,45 @@ unsigned int cmELF::GetNumberOfSections() const
}
//----------------------------------------------------------------------------
+unsigned int cmELF::GetDynamicEntryCount() const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetDynamicEntryCount();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+unsigned long cmELF::GetDynamicEntryPosition(int index) const
+{
+ if(this->Valid())
+ {
+ return this->Internal->GetDynamicEntryPosition(index);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const
+{
+ if(this->Valid())
+ {
+ return this->Internal->ReadBytes(pos, size, buf);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
bool cmELF::GetSOName(std::string& soname)
{
if(StringEntry const* se = this->GetSOName())
diff --git a/Source/cmELF.h b/Source/cmELF.h
index 9e4575b5ad..aeb409633a 100644
--- a/Source/cmELF.h
+++ b/Source/cmELF.h
@@ -68,6 +68,9 @@ public:
// The size of the string table entry. This includes the space
// allocated for one or more null terminators.
unsigned long Size;
+
+ // The index of the section entry referencing the string.
+ int IndexInSection;
};
/** Get the type of the file opened. */
@@ -76,6 +79,17 @@ public:
/** Get the number of ELF sections present. */
unsigned int GetNumberOfSections() const;
+ /** Get the number of DYNAMIC section entries before the first
+ DT_NULL. Returns zero on error. */
+ unsigned int GetDynamicEntryCount() const;
+
+ /** Get the position of a DYNAMIC section header entry. Returns
+ zero on error. */
+ unsigned long GetDynamicEntryPosition(int index) const;
+
+ /** Read bytes from the file. */
+ bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const;
+
/** Get the SONAME field if any. */
bool GetSOName(std::string& soname);
StringEntry const* GetSOName();
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 68ccbb28f9..3cf6c0be68 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -112,9 +112,17 @@ bool cmFileCommand
{
return this->HandleInstallCommand(args);
}
- else if ( subCommand == "CHRPATH" )
+ else if ( subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH" )
{
- return this->HandleChrpathCommand(args);
+ return this->HandleRPathChangeCommand(args);
+ }
+ else if ( subCommand == "RPATH_CHECK" )
+ {
+ return this->HandleRPathCheckCommand(args);
+ }
+ else if ( subCommand == "RPATH_REMOVE" )
+ {
+ return this->HandleRPathRemoveCommand(args);
}
else if ( subCommand == "RELATIVE_PATH" )
{
@@ -1332,7 +1340,8 @@ bool cmFileCommand::HandleInstallDestination(cmFileInstaller& installer,
}
//----------------------------------------------------------------------------
-bool cmFileCommand::HandleChrpathCommand(std::vector<std::string> const& args)
+bool
+cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
{
// Evaluate arguments.
const char* file = 0;
@@ -1372,49 +1381,174 @@ bool cmFileCommand::HandleChrpathCommand(std::vector<std::string> const& args)
else
{
cmOStringStream e;
- e << "CHRPATH given unknown argument " << args[i];
+ e << "RPATH_CHANGE given unknown argument " << args[i];
this->SetError(e.str().c_str());
return false;
}
}
if(!file)
{
- this->SetError("CHRPATH not given FILE option.");
+ this->SetError("RPATH_CHANGE not given FILE option.");
return false;
}
if(!oldRPath)
{
- this->SetError("CHRPATH not given OLD_RPATH option.");
+ this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
return false;
}
if(!newRPath)
{
- this->SetError("CHRPATH not given NEW_RPATH option.");
+ this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
return false;
}
if(!cmSystemTools::FileExists(file, true))
{
cmOStringStream e;
- e << "CHRPATH given FILE \"" << file << "\" that does not exist.";
+ e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
this->SetError(e.str().c_str());
return false;
}
+ bool success = true;
+ cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+ bool have_ft = cmSystemTools::FileTimeGet(file, ft);
std::string emsg;
- if(cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg))
- {
- return true;
- }
- else
+ if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg))
{
cmOStringStream e;
- e << "CHRPATH could not write new RPATH:\n"
+ e << "RPATH_CHANGE could not write new RPATH:\n"
<< " " << newRPath << "\n"
<< "to the file:\n"
<< " " << file << "\n"
<< emsg;
this->SetError(e.str().c_str());
+ success = false;
+ }
+ if(success && have_ft)
+ {
+ cmSystemTools::FileTimeSet(file, ft);
+ }
+ cmSystemTools::FileTimeDelete(ft);
+ return success;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
+{
+ // Evaluate arguments.
+ const char* file = 0;
+ enum Doing { DoingNone, DoingFile };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "FILE")
+ {
+ doing = DoingFile;
+ }
+ else if(doing == DoingFile)
+ {
+ file = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!file)
+ {
+ this->SetError("RPATH_REMOVE not given FILE option.");
+ return false;
+ }
+ if(!cmSystemTools::FileExists(file, true))
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ bool success = true;
+ cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+ bool have_ft = cmSystemTools::FileTimeGet(file, ft);
+ std::string emsg;
+ if(!cmSystemTools::RemoveRPath(file, &emsg))
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE could not remove RPATH from file:\n"
+ << " " << file << "\n"
+ << emsg;
+ this->SetError(e.str().c_str());
+ success = false;
+ }
+ if(success && have_ft)
+ {
+ cmSystemTools::FileTimeSet(file, ft);
+ }
+ cmSystemTools::FileTimeDelete(ft);
+ return success;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
+{
+ // Evaluate arguments.
+ const char* file = 0;
+ const char* rpath = 0;
+ enum Doing { DoingNone, DoingFile, DoingRPath };
+ Doing doing = DoingNone;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(args[i] == "RPATH")
+ {
+ doing = DoingRPath;
+ }
+ else if(args[i] == "FILE")
+ {
+ doing = DoingFile;
+ }
+ else if(doing == DoingFile)
+ {
+ file = args[i].c_str();
+ doing = DoingNone;
+ }
+ else if(doing == DoingRPath)
+ {
+ rpath = args[i].c_str();
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "RPATH_CHECK given unknown argument " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+ if(!file)
+ {
+ this->SetError("RPATH_CHECK not given FILE option.");
+ return false;
+ }
+ if(!rpath)
+ {
+ this->SetError("RPATH_CHECK not given RPATH option.");
return false;
}
+
+ // If the file exists but does not have the desired RPath then
+ // delete it. This is used during installation to re-install a file
+ // if its RPath will change.
+ if(cmSystemTools::FileExists(file, true) &&
+ !cmSystemTools::CheckRPath(file, rpath))
+ {
+ cmSystemTools::RemoveFile(file);
+ }
+
+ return true;
}
//----------------------------------------------------------------------------
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index 85bdc32484..3f72cd2867 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -171,7 +171,9 @@ protected:
bool HandleRelativePathCommand(std::vector<std::string> const& args);
bool HandleCMakePathCommand(std::vector<std::string> const& args,
bool nativePath);
- bool HandleChrpathCommand(std::vector<std::string> const& args);
+ bool HandleRPathChangeCommand(std::vector<std::string> const& args);
+ bool HandleRPathCheckCommand(std::vector<std::string> const& args);
+ bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
// file(INSTALL ...) related functions
bool HandleInstallCommand(std::vector<std::string> const& args);
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 80dcdfc666..03bd15928d 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -536,7 +536,22 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
bundleGenerator = CreateInstallTargetGenerator(target, bundleArgs,
false);
}
- else
+ if(!runtimeArgs.GetDestination().empty())
+ {
+ bool failure = false;
+ if(this->CheckCMP0006(failure))
+ {
+ // For CMake 2.4 compatibility fallback to the RUNTIME
+ // properties.
+ bundleGenerator =
+ CreateInstallTargetGenerator(target, runtimeArgs, false);
+ }
+ else if(failure)
+ {
+ return false;
+ }
+ }
+ if(!bundleGenerator)
{
cmOStringStream e;
e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE "
@@ -1284,3 +1299,34 @@ bool cmInstallCommand::MakeFilesFullPath(const char* modeName,
}
return true;
}
+
+//----------------------------------------------------------------------------
+bool cmInstallCommand::CheckCMP0006(bool& failure)
+{
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0006))
+ {
+ case cmPolicies::WARN:
+ {
+ this->Makefile->IssueMessage(
+ cmake::AUTHOR_WARNING,
+ this->Makefile->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0006)
+ );
+ }
+ case cmPolicies::OLD:
+ // OLD behavior is to allow compatibility
+ return true;
+ case cmPolicies::NEW:
+ // NEW behavior is to disallow compatibility
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ failure = true;
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ this->Makefile->GetPolicies()
+ ->GetRequiredPolicyError(cmPolicies::CMP0006)
+ );
+ break;
+ }
+ return false;
+}
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 4978059b15..0b7ae7a3e8 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -109,19 +109,19 @@ public:
" ] [...])\n"
"The TARGETS form specifies rules for installing targets from a "
"project. There are five kinds of target files that may be "
- "installed: archive, library, runtime, framework, and bundle. "
+ "installed: ARCHIVE, LIBRARY, RUNTIME, FRAMEWORK, and BUNDLE. "
- "Executables are treated as runtime targets, except that those "
- "marked with the MACOSX_BUNDLE property are treated as bundle "
+ "Executables are treated as RUNTIME targets, except that those "
+ "marked with the MACOSX_BUNDLE property are treated as BUNDLE "
"targets on OS X. "
- "Static libraries are always treated as archive targets. "
- "Module libraries are always treated as library targets. "
- "For non-DLL platforms shared libraries are treated as library "
+ "Static libraries are always treated as ARCHIVE targets. "
+ "Module libraries are always treated as LIBRARY targets. "
+ "For non-DLL platforms shared libraries are treated as LIBRARY "
"targets, except that those marked with the FRAMEWORK property "
- "are treated as framework targets on OS X. "
+ "are treated as FRAMEWORK targets on OS X. "
"For DLL platforms the DLL part of a shared library is treated as "
- "a runtime target and the corresponding import library is treated as "
- "an archive target. "
+ "a RUNTIME target and the corresponding import library is treated as "
+ "an ARCHIVE target. "
"All Windows-based systems including Cygwin are DLL platforms. "
"The ARCHIVE, LIBRARY, RUNTIME, and FRAMEWORK "
"arguments change the type of target to which the subsequent "
@@ -346,6 +346,7 @@ private:
bool MakeFilesFullPath(const char* modeName,
const std::vector<std::string>& relFiles,
std::vector<std::string>& absFiles);
+ bool CheckCMP0006(bool& failure);
};
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 5fd408e366..8db09575a2 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -333,6 +333,32 @@ cmInstallTargetGenerator
return;
}
+ // Construct the path of the file on disk after installation on
+ // which tweaks may be performed.
+ std::string toDestDirPath = "$ENV{DESTDIR}";
+ if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
+ {
+ toDestDirPath += "/";
+ }
+ toDestDirPath += toInstallPath;
+
+ // Add pre-installation tweaks.
+ if(tweakInstalledFile)
+ {
+ // Collect tweaking rules.
+ cmOStringStream tw;
+ this->AddRPathCheckRule(tw, indent.Next(), config, toDestDirPath);
+ std::string tws = tw.str();
+
+ // Add the rules, if any.
+ if(!tws.empty())
+ {
+ os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
+ os << tws;
+ os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
+ }
+ }
+
// Write code to install the target file.
const char* no_dir_permissions = 0;
const char* no_rename = 0;
@@ -344,25 +370,24 @@ cmInstallTargetGenerator
no_rename, literal_args.c_str(),
indent);
- // Construct the path of the file on disk after installation on
- // which tweaks may be performed.
- std::string toDestDirPath = "$ENV{DESTDIR}";
- if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
- {
- toDestDirPath += "/";
- }
- toDestDirPath += toInstallPath;
-
- // TODO:
- // - Skip IF(EXISTS) checks if nothing is done with the installed file
+ // Add post-installation tweaks.
if(tweakInstalledFile)
{
- os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
- this->AddInstallNamePatchRule(os, indent.Next(), config, toDestDirPath);
- this->AddChrpathPatchRule(os, indent.Next(), config, toDestDirPath);
- this->AddRanlibRule(os, indent.Next(), type, toDestDirPath);
- this->AddStripRule(os, indent.Next(), type, toDestDirPath);
- os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
+ // Collect tweaking rules.
+ cmOStringStream tw;
+ this->AddInstallNamePatchRule(tw, indent.Next(), config, toDestDirPath);
+ this->AddChrpathPatchRule(tw, indent.Next(), config, toDestDirPath);
+ this->AddRanlibRule(tw, indent.Next(), type, toDestDirPath);
+ this->AddStripRule(tw, indent.Next(), type, toDestDirPath);
+ std::string tws = tw.str();
+
+ // Add the rules, if any.
+ if(!tws.empty())
+ {
+ os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
+ os << tws;
+ os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
+ }
}
}
@@ -550,6 +575,37 @@ cmInstallTargetGenerator
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
+::AddRPathCheckRule(std::ostream& os, Indent const& indent,
+ const char* config, std::string const& toDestDirPath)
+{
+ // Skip the chrpath if the target does not need it.
+ if(this->ImportLibrary || !this->Target->IsChrpathUsed())
+ {
+ return;
+ }
+
+ // Get the link information for this target.
+ // It can provide the RPATH.
+ cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
+ if(!cli)
+ {
+ return;
+ }
+
+ // Get the install RPATH from the link information.
+ std::string newRpath = cli->GetChrpathString();
+
+ // Write a rule to remove the installed file if its rpath is not the
+ // new rpath. This is needed for existing build/install trees when
+ // the installed rpath changes but the file is not rebuilt.
+ os << indent << "FILE(RPATH_CHECK\n"
+ << indent << " FILE \"" << toDestDirPath << "\"\n"
+ << indent << " RPATH \"" << newRpath << "\")\n";
+}
+
+//----------------------------------------------------------------------------
+void
+cmInstallTargetGenerator
::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
const char* config, std::string const& toDestDirPath)
{
@@ -580,9 +636,18 @@ cmInstallTargetGenerator
}
// Write a rule to run chrpath to set the install-tree RPATH
- os << indent << "FILE(CHRPATH FILE \"" << toDestDirPath << "\"\n"
- << indent << " OLD_RPATH \"" << oldRpath << "\"\n"
- << indent << " NEW_RPATH \"" << newRpath << "\")\n";
+ if(newRpath.empty())
+ {
+ os << indent << "FILE(RPATH_REMOVE\n"
+ << indent << " FILE \"" << toDestDirPath << "\")\n";
+ }
+ else
+ {
+ os << indent << "FILE(RPATH_CHANGE\n"
+ << indent << " FILE \"" << toDestDirPath << "\"\n"
+ << indent << " OLD_RPATH \"" << oldRpath << "\"\n"
+ << indent << " NEW_RPATH \"" << newRpath << "\")\n";
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 95c255d223..61357b3825 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -80,6 +80,9 @@ protected:
void AddChrpathPatchRule(std::ostream& os, Indent const& indent,
const char* config,
std::string const& toDestDirPath);
+ void AddRPathCheckRule(std::ostream& os, Indent const& indent,
+ const char* config,
+ std::string const& toDestDirPath);
void AddStripRule(std::ostream& os, Indent const& indent,
cmTarget::TargetType type,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e16af18e4c..8c5b87f874 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -407,6 +407,7 @@ public:
Linker
};
cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg,
+ int version,
Tool tool,
cmVS7FlagTable const* extraTable = 0);
@@ -439,6 +440,7 @@ public:
private:
cmLocalVisualStudio7Generator* LocalGenerator;
+ int Version;
// create a map of xml tags to the values they should have in the output
// for example, "BufferSecurityCheck" = "TRUE"
@@ -551,7 +553,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
std::string defineFlags = this->Makefile->GetDefineFlags();
// Construct a set of build options for this target.
- Options targetOptions(this, Options::Compiler, this->ExtraFlagTable);
+ Options targetOptions(this, this->Version, Options::Compiler, this->ExtraFlagTable);
targetOptions.FixExceptionHandlingDefault();
targetOptions.Parse(flags.c_str());
targetOptions.Parse(defineFlags.c_str());
@@ -745,7 +747,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
extraLinkOptions += " ";
extraLinkOptions += targetLinkFlags;
}
- Options linkOptions(this, Options::Linker);
+ Options linkOptions(this, this->Version, Options::Linker);
linkOptions.Parse(extraLinkOptions.c_str());
switch(target.GetType())
{
@@ -1289,7 +1291,7 @@ void cmLocalVisualStudio7Generator
!fc.CompileDefs.empty() ||
!fc.CompileDefsConfig.empty())
{
- Options fileOptions(this, Options::Compiler,
+ Options fileOptions(this, this->Version, Options::Compiler,
this->ExtraFlagTable);
fileOptions.Parse(fc.CompileFlags.c_str());
fileOptions.AddDefines(fc.CompileDefs.c_str());
@@ -1762,9 +1764,10 @@ std::string cmLocalVisualStudio7Generator
//----------------------------------------------------------------------------
cmLocalVisualStudio7GeneratorOptions
::cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg,
+ int version,
Tool tool,
cmVS7FlagTable const* extraTable):
- LocalGenerator(lg), CurrentTool(tool),
+ LocalGenerator(lg), Version(version), CurrentTool(tool),
DoingDefine(false), FlagTable(0), ExtraFlagTable(extraTable)
{
// Choose the flag table for the requested tool.
@@ -1786,7 +1789,17 @@ void cmLocalVisualStudio7GeneratorOptions::FixExceptionHandlingDefault()
// initialization to off, but the user has the option of removing
// the flag to disable exception handling. When the user does
// remove the flag we need to override the IDE default of on.
- this->FlagMap["ExceptionHandling"] = "FALSE";
+ switch (this->Version)
+ {
+ case 7:
+ case 71:
+ this->FlagMap["ExceptionHandling"] = "FALSE";
+ break;
+
+ default:
+ this->FlagMap["ExceptionHandling"] = "0";
+ break;
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 70978c3272..a881391c4e 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -724,7 +724,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash();
objdir += this->Target->GetName();
objdir += ".dir";
- vars.ObjectDir = objdir.c_str();
+ objdir = this->Convert(objdir.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
+ vars.ObjectDir = objdir.c_str();
vars.Target = targetOutPathReal.c_str();
std::string linkString = linklibs.str();
vars.LinkLibraries = linkString.c_str();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index cd08bdb1e9..28a6105f2c 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -334,8 +334,13 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
macdir += pkgloc;
cmSystemTools::MakeDirectory(macdir.c_str());
- // Record use of this content location.
- this->MacContentFolders.insert(pkgloc);
+ // Record use of this content location. Only the first level
+ // directory is needed.
+ {
+ std::string loc = pkgloc;
+ loc = loc.substr(0, loc.find('/'));
+ this->MacContentFolders.insert(loc);
+ }
// Get the input file location.
std::string input = source.GetFullPath();
@@ -614,6 +619,9 @@ cmMakefileTargetGenerator
cmLocalGenerator::SHELL).c_str();
vars.Object = shellObj.c_str();
std::string objectDir = cmSystemTools::GetFilenamePath(obj);
+ objectDir = this->Convert(objectDir.c_str(),
+ cmLocalGenerator::START_OUTPUT,
+ cmLocalGenerator::SHELL);
vars.ObjectDir = objectDir.c_str();
vars.Flags = flags.c_str();
vars.Defines = defines.c_str();
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 26d9012b89..a6f5808b6f 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -60,7 +60,7 @@ bool cmMessageCommand
if (send_error || fatal_error)
{
- cmSystemTools::Error(message.c_str());
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, message.c_str());
}
else
{
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index b69a7198e5..4e1b857d92 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -251,6 +251,24 @@ cmPolicies::cmPolicies()
"See documentation of the COMPILE_DEFINITIONS target property for "
"limitations of the escaping implementation.",
2,6,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0006, "CMP0006",
+ "Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.",
+ "This policy determines whether the install(TARGETS) command must be "
+ "given a BUNDLE DESTINATION when asked to install a target with the "
+ "MACOSX_BUNDLE property set. "
+ "CMake 2.4 and below did not distinguish application bundles from "
+ "normal executables when installing targets. "
+ "CMake 2.6 provides a BUNDLE option to the install(TARGETS) command "
+ "that specifies rules specific to application bundles on the Mac. "
+ "Projects should use this option when installing a target with the "
+ "MACOSX_BUNDLE property set.\n"
+ "The OLD behavior for this policy is to fall back to the RUNTIME "
+ "DESTINATION if a BUNDLE DESTINATION is not given. "
+ "The NEW behavior for this policy is to produce an error if a bundle "
+ "target is installed without a BUNDLE DESTINATION.",
+ 2,6,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5adfbfa28a..fed9d3194a 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -46,6 +46,7 @@ public:
CMP0003, // Linking does not include extra -L paths
CMP0004, // Libraries linked may not have leading or trailing whitespace
CMP0005, // Definition value escaping
+ CMP0006, // BUNDLE install rules needed for MACOSX_BUNDLE targets
// Always the last entry. Useful mostly to avoid adding a comma
// the last policy when adding a new one.
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 6091ab546d..4d25944d4a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -56,6 +56,18 @@
# include "cmELF.h"
#endif
+class cmSystemToolsFileTime
+{
+public:
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ FILETIME timeCreation;
+ FILETIME timeLastAccess;
+ FILETIME timeLastWrite;
+#else
+ struct utimbuf timeBuf;
+#endif
+};
+
#if defined(__sgi) && !defined(__GNUC__)
# pragma set woff 1375 /* base class destructor not virtual */
#endif
@@ -2111,6 +2123,67 @@ bool cmSystemTools::CopyFileTime(const char* fromFile, const char* toFile)
}
//----------------------------------------------------------------------------
+cmSystemToolsFileTime* cmSystemTools::FileTimeNew()
+{
+ return new cmSystemToolsFileTime;
+}
+
+//----------------------------------------------------------------------------
+void cmSystemTools::FileTimeDelete(cmSystemToolsFileTime* t)
+{
+ delete t;
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ cmSystemToolsWindowsHandle h =
+ CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if(!h)
+ {
+ return false;
+ }
+ if(!GetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+ {
+ return false;
+ }
+#else
+ struct stat st;
+ if(stat(fname, &st) < 0)
+ {
+ return false;
+ }
+ t->timeBuf.actime = st.st_atime;
+ t->timeBuf.modtime = st.st_mtime;
+#endif
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ cmSystemToolsWindowsHandle h =
+ CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+ if(!h)
+ {
+ return false;
+ }
+ if(!SetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+ {
+ return false;
+ }
+#else
+ if(utime(fname, &t->timeBuf) < 0)
+ {
+ return false;
+ }
+#endif
+ return true;
+}
+
+//----------------------------------------------------------------------------
static std::string cmSystemToolsExecutableDirectory;
void cmSystemTools::FindExecutableDirectory(const char* argv0)
{
@@ -2390,3 +2463,173 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return false;
#endif
}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ unsigned long rpathPosition = 0;
+ unsigned long rpathSize = 0;
+ unsigned long rpathEntryPosition = 0;
+ std::vector<char> bytes;
+ {
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
+ if(!se)
+ {
+ se = elf.GetRunPath();
+ }
+
+ if(se)
+ {
+ // Store information about the entry.
+ rpathPosition = se->Position;
+ rpathSize = se->Size;
+ rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
+
+ // Get the file range containing the rest of the DYNAMIC table
+ // after the RPATH entry.
+ unsigned long nextEntryPosition =
+ elf.GetDynamicEntryPosition(se->IndexInSection+1);
+ unsigned int count = elf.GetDynamicEntryCount();
+ if(count == 0)
+ {
+ // This should happen only for invalid ELF files where a DT_NULL
+ // appears before the end of the table.
+ if(emsg)
+ {
+ *emsg = "DYNAMIC section contains a DT_NULL before the end.";
+ }
+ return false;
+ }
+ unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
+
+ // Allocate and fill a buffer with zeros.
+ bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
+
+ // Read the part of the DYNAMIC section header that will move.
+ // The remainder of the buffer will be left with zeros which
+ // represent a DT_NULL entry.
+ if(!elf.ReadBytes(nextEntryPosition,
+ nullEntryPosition - nextEntryPosition,
+ &bytes[0]))
+ {
+ if(emsg)
+ {
+ *emsg = "Failed to read DYNAMIC section header.";
+ }
+ return false;
+ }
+ }
+ else
+ {
+ // There is no RPATH or RUNPATH anyway.
+ return true;
+ }
+ }
+
+ // Open the file for update.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+ {
+ if(emsg)
+ {
+ *emsg = "Error opening file for update.";
+ }
+ return false;
+ }
+
+ // Write the new DYNAMIC table header.
+ if(!f.seekp(rpathEntryPosition))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to DYNAMIC table header for RPATH.";
+ }
+ return false;
+ }
+ if(!f.write(&bytes[0], bytes.size()))
+ {
+ if(emsg)
+ {
+ *emsg = "Error replacing DYNAMIC table header.";
+ }
+ return false;
+ }
+
+ // Fill the RPATH string with zero bytes.
+ if(!f.seekp(rpathPosition))
+ {
+ if(emsg)
+ {
+ *emsg = "Error seeking to RPATH position.";
+ }
+ return false;
+ }
+ for(unsigned long i=0; i < rpathSize; ++i)
+ {
+ f << '\0';
+ }
+
+ // Make sure everything was okay.
+ if(f)
+ {
+ return true;
+ }
+ else
+ {
+ if(emsg)
+ {
+ *emsg = "Error writing the empty rpath to the file.";
+ }
+ return false;
+ }
+#else
+ (void)file;
+ (void)emsg;
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+bool cmSystemTools::CheckRPath(std::string const& file,
+ std::string const& newRPath)
+{
+#if defined(CMAKE_USE_ELF_PARSER)
+ // Parse the ELF binary.
+ cmELF elf(file.c_str());
+
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
+ if(!se)
+ {
+ se = elf.GetRunPath();
+ }
+
+ // Make sure the current rpath contains the new rpath.
+ if(newRPath.empty())
+ {
+ if(!se)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if(se &&
+ cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
+ {
+ return true;
+ }
+ }
+ return false;
+#else
+ (void)file;
+ (void)newRPath;
+ return false;
+#endif
+}
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index a7abc5f108..89cf407a2d 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -22,7 +22,7 @@
#include <cmsys/SystemTools.hxx>
#include <cmsys/Process.h>
-
+class cmSystemToolsFileTime;
/** \class cmSystemTools
* \brief A collection of useful functions for CMake.
@@ -363,6 +363,12 @@ public:
the first argument to that named by the second. */
static bool CopyFileTime(const char* fromFile, const char* toFile);
+ /** Save and restore file times. */
+ static cmSystemToolsFileTime* FileTimeNew();
+ static void FileTimeDelete(cmSystemToolsFileTime*);
+ static bool FileTimeGet(const char* fname, cmSystemToolsFileTime* t);
+ static bool FileTimeSet(const char* fname, cmSystemToolsFileTime* t);
+
/** Find the directory containing the running executable. Save it
in a global location to be queried by GetExecutableDirectory
later. */
@@ -387,6 +393,14 @@ public:
std::string const& newRPath,
std::string* emsg = 0);
+ /** Try to remove the RPATH from an ELF binary. */
+ static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
+
+ /** Check whether the RPATH in an ELF binary contains the path
+ given. */
+ static bool CheckRPath(std::string const& file,
+ std::string const& newRPath);
+
private:
static bool s_ForceUnixPaths;
static bool s_RunCommandHideConsole;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e7bf4eca22..1bf306124c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -134,8 +134,8 @@ void cmTarget::DefineProperties(cmake *cm)
("DEBUG_POSTFIX", cmProperty::TARGET,
"A postfix that will be applied to this target when build debug.",
"A property on a target that specifies a postfix to add to the "
- "target name when built in debug mode. For example foo.dll "
- "versus fooD.dll");
+ "target name when built in debug mode. For example \"foo.dll\" "
+ "versus \"fooD.dll\". Ignored for Mac Frameworks and App Bundles.");
cm->DefineProperty
("EchoString", cmProperty::TARGET,
@@ -2311,6 +2311,12 @@ void cmTarget::GetFullNameInternal(TargetType type,
std::string configProp = cmSystemTools::UpperCase(config);
configProp += "_POSTFIX";
configPostfix = this->GetProperty(configProp.c_str());
+ // Mac application bundles and frameworks have no postfix.
+ if(configPostfix &&
+ (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
+ {
+ configPostfix = 0;
+ }
}
const char* prefixVar = this->GetPrefixVariableInternal(type, implib);
const char* suffixVar = this->GetSuffixVariableInternal(type, implib);
diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt
index 3eb0dbc32d..397e970f5c 100644
--- a/Tests/Framework/CMakeLists.txt
+++ b/Tests/Framework/CMakeLists.txt
@@ -24,6 +24,7 @@ set_target_properties(foo PROPERTIES
PUBLIC_HEADER "foo.h;foo2.h;fooPublic.h;fooBoth.h"
RESOURCE "test.lua"
INSTALL_NAME_DIR "@executable_path/../../../Library/Frameworks"
+ DEBUG_POSTFIX -d
)
# fooBoth.h is listed as both public and private... (private wins...)
# fooNeither.h is listed as neither public nor private...
diff --git a/Tests/Tutorial/Step7/CMakeLists.txt b/Tests/Tutorial/Step7/CMakeLists.txt
index 826599b9f5..42f73f221b 100644
--- a/Tests/Tutorial/Step7/CMakeLists.txt
+++ b/Tests/Tutorial/Step7/CMakeLists.txt
@@ -75,6 +75,7 @@ include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
+set (CPACK_PACKAGE_CONTACT "foo@bar.org")
include (CPack)
# enable dashboard scripting
diff --git a/Tests/X11/CMakeLists.txt b/Tests/X11/CMakeLists.txt
index 28b41edc9a..52f4a6fe9e 100644
--- a/Tests/X11/CMakeLists.txt
+++ b/Tests/X11/CMakeLists.txt
@@ -1,6 +1,6 @@
# a simple C only test case
cmake_minimum_required (VERSION 2.6)
-PROJECT (UseX11 C)
+PROJECT (UseX11 CXX C)
INCLUDE (${CMAKE_ROOT}/Modules/FindX11.cmake)
MESSAGE("X11_FOUND: ${X11_FOUND}")
@@ -23,4 +23,13 @@ IF(X11_FOUND)
ADD_DEFINITIONS(-DCMAKE_HAS_X)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(UseX11 ${X11_LIBRARIES})
+ IF(APPLE)
+ ADD_EXECUTABLE(HelloWorldX11 HelloWorldX11.cxx)
+ TARGET_LINK_LIBRARIES(HelloWorldX11 ${X11_LIBRARIES})
+ install( TARGETS HelloWorldX11 DESTINATION bin)
+ # build a CPack driven installer package
+ set(CPACK_PACKAGE_NAME HelloWorldX11Package)
+ set(CPACK_PACKAGE_EXECUTABLES HelloWorldX11 HelloWorldX11)
+ include(CPack)
+ ENDIF(APPLE)
ENDIF(X11_FOUND)
diff --git a/Tests/X11/HelloWorldX11.cxx b/Tests/X11/HelloWorldX11.cxx
new file mode 100644
index 0000000000..5bbc19a4aa
--- /dev/null
+++ b/Tests/X11/HelloWorldX11.cxx
@@ -0,0 +1,145 @@
+
+/*** START MAIN.H ***/
+/* http://www.geocities.com/jeff_louie/x11/helloworld.htm* */
+/*
+ * main.h
+ * TestX
+ *
+ * Created by Jeff Louie on Tue Feb 03 2004.
+ * Copyright (c) 2004 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+
+#ifndef MAIN_H
+#define MAIN_H 1
+
+#include <iostream>
+
+/* include the X library headers */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+
+class Main {
+
+public:
+ // constructor
+ Main(int argc, char * const argv[]);
+ //virtual ~Main();
+
+
+private:
+
+
+ /* here are our X variables */
+ Display *dis;
+ int screen;
+ Window win;
+ GC gc;
+
+ /* here are our X routines declared! */
+ void init_x();
+ void close_x();
+ void redraw();
+ int delay(int i);
+
+};
+
+#endif
+
+/*** END MAIN.H ***/
+
+/*** START MAIN.CPP ***/
+
+// modified from Brian Hammond's Howdy program at
+// http://www.insanityengine.com/doc/x11/xintro.html
+// jeff louie 02.05.2004
+
+
+
+int main (int argc, char * const argv[]) {
+ Main m(argc, argv);
+ return 0;
+}
+
+//Main::~Main() {;};
+Main::Main (int argc, char * const argv[]) {
+ XEvent event; // XEvent declaration
+ KeySym key; // KeyPress Events
+ char text[255]; // char buffer for KeyPress Events
+
+ init_x();
+
+ // event loop
+ while(1) {
+ // get the next event and stuff it into our event variable.
+ // Note: only events we set the mask for are detected!
+ XNextEvent(dis, &event);
+
+
+ switch (event.type) {
+ int x;
+ int y;
+ case Expose:
+ if (event.xexpose.count==0) {
+ redraw();
+ }
+ break;
+ case KeyPress:
+ if (XLookupString(&event.xkey,text,255,&key,0)==1) {
+ // use the XLookupString routine to convert the invent
+ // KeyPress data into regular text. Weird but necessary...
+ if ((text[0]=='q') || (text[0]=='Q')) {
+ close_x();
+ }
+ else {
+ // echo key press
+ printf("You pressed the %c key!\n",text[0]);
+ }
+ }
+ break;
+ case ButtonPress:
+ // get cursor position
+ x= event.xbutton.x;
+ y= event.xbutton.y;
+ strcpy(text,"X is FUN!");
+ XSetForeground(dis,gc,rand()%event.xbutton.x%255);
+ // draw text at cursor
+ XDrawString(dis,win,gc,x,y, text, strlen(text));
+ break;
+ default:
+ printf("Unhandled event.\n");
+ }
+ }
+}
+
+void Main::init_x() {
+ unsigned long black,white;
+
+ dis=XOpenDisplay(NULL);
+ screen=DefaultScreen(dis);
+ black=BlackPixel(dis,screen),
+ white=WhitePixel(dis, screen);
+ win=XCreateSimpleWindow(dis,DefaultRootWindow(dis),0,0,
+ 300, 300, 5,black, white);
+ XSetStandardProperties(dis,win,"Hello World","Hi",None,NULL,0,NULL);
+ XSelectInput(dis, win, ExposureMask|ButtonPressMask|KeyPressMask);
+ // get Graphics Context
+ gc=XCreateGC(dis, win, 0,0);
+ XSetBackground(dis,gc,white);
+ XSetForeground(dis,gc,black);
+ XClearWindow(dis, win);
+ XMapRaised(dis, win);
+};
+
+void Main::close_x() {
+ XFreeGC(dis, gc);
+ XDestroyWindow(dis,win);
+ XCloseDisplay(dis);
+ exit(1);
+};
+
+void Main::redraw() {
+ XClearWindow(dis, win);
+};