From 6ba055bacdce1cdf7a74008b980440027f275d94 Mon Sep 17 00:00:00 2001 From: Eric NOULARD Date: Mon, 14 May 2012 20:26:15 +0200 Subject: [PATCH 1/4] CPack add easy possibility to warn about CPACK_SET_DESTDIR CPackNSIS will only warn but sooner or later it should error out --- Source/CPack/cmCPackGenerator.cxx | 32 ++++++++++++++++++++++++++- Source/CPack/cmCPackGenerator.h | 23 +++++++++++++++++++ Source/CPack/cmCPackNSISGenerator.cxx | 8 +++++++ Source/CPack/cmCPackNSISGenerator.h | 1 + 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 0f832b395..bf652718e 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -62,10 +62,31 @@ void cmCPackGenerator::DisplayVerboseOutput(const char* msg, //---------------------------------------------------------------------- int cmCPackGenerator::PrepareNames() -{ +{ cmCPackLogger(cmCPackLog::LOG_DEBUG, "Create temp directory." << std::endl); + // checks CPACK_SET_DESTDIR support + if (IsOn("CPACK_SET_DESTDIR")) + { + if (SETDESTDIR_UNSUPPORTED==SupportsSetDestdir()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPACK_SET_DESTDIR is set to ON but the '" + << Name << "' generator does NOT support it." + << std::endl); + return 0; + } + else if (SETDESTDIR_SHOULD_NOT_BE_USED==SupportsSetDestdir()) + { + cmCPackLogger(cmCPackLog::LOG_WARNING, + "CPACK_SET_DESTDIR is set to ON but it is " + << "usually a bad idea to do that with '" + << Name << "' generator. Use at your own risk." + << std::endl); + } + } + std::string tempDirectory = this->GetOption("CPACK_PACKAGE_DIRECTORY"); tempDirectory += "/_CPack_Packages/"; const char* toplevelTag = this->GetOption("CPACK_TOPLEVEL_TAG"); @@ -953,6 +974,8 @@ int cmCPackGenerator::DoPackage() cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package using " << this->Name.c_str() << std::endl); + // Prepare CPack internal name and check + // values for many CPACK_xxx vars if ( !this->PrepareNames() ) { return 0; @@ -1430,6 +1453,13 @@ std::string cmCPackGenerator::GetComponentPackageFileName( return initialPackageFileName + suffix; } +//---------------------------------------------------------------------- +enum cmCPackGenerator::CPackSetDestdirSupport +cmCPackGenerator::SupportsSetDestdir() const +{ + return cmCPackGenerator::SETDESTDIR_SUPPORTED; +} + //---------------------------------------------------------------------- bool cmCPackGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 55afb4489..68ee3f2e0 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -189,6 +189,29 @@ protected: virtual int InstallProjectViaInstallCMakeProjects( bool setDestDir, const char* tempInstallDirectory); + /** + * The various level of support of + * CPACK_SET_DESTDIR used by the generator. + */ + enum CPackSetDestdirSupport { + /* the generator works with or without it */ + SETDESTDIR_SUPPORTED, + /* the generator works best if automatically handled */ + SETDESTDIR_INTERNALLY_SUPPORTED, + /* no official support, use at your own risk */ + SETDESTDIR_SHOULD_NOT_BE_USED, + /* officially NOT supported */ + SETDESTDIR_UNSUPPORTED + }; + + /** + * Does the CPack generator support CPACK_SET_DESTDIR? + * The default legacy value is 'true' generator + * have to override it in order change this. + * @return CPackSetDestdirSupport + */ + virtual enum CPackSetDestdirSupport SupportsSetDestdir() const; + /** * Does the CPack generator support component installation?. * Some Generators requires the user to set diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 0787ef901..63189de2e 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -64,6 +64,7 @@ int cmCPackNSISGenerator::PackageFiles() << std::endl); return false; } + std::string nsisFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); std::string tmpFile = nsisFileName; tmpFile += "/NSISOutput.log"; @@ -630,6 +631,13 @@ bool cmCPackNSISGenerator::GetListOfSubdirectories(const char* topdir, return true; } +//---------------------------------------------------------------------- +enum cmCPackGenerator::CPackSetDestdirSupport +cmCPackNSISGenerator::SupportsSetDestdir() const +{ + return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED; +} + //---------------------------------------------------------------------- bool cmCPackNSISGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h index 7bccb89fb..c2987d0ba 100644 --- a/Source/CPack/cmCPackNSISGenerator.h +++ b/Source/CPack/cmCPackNSISGenerator.h @@ -44,6 +44,7 @@ protected: bool GetListOfSubdirectories(const char* dir, std::vector& dirs); + enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const; virtual bool SupportsComponentInstallation() const; /// Produce a string that contains the NSIS code to describe a From 47f0dbd70b83ccb5e314abee5feded2ed50a23fb Mon Sep 17 00:00:00 2001 From: Eric NOULARD Date: Mon, 14 May 2012 23:29:42 +0200 Subject: [PATCH 2/4] CPack add necessary check to detect/warns/error on ABSOLUTE DESTINATION The [usually] wrong usage of absolute DESTINATION in INSTALL rules keeps popping-up on the ML. We shall have some way to: 1) easily detect it. 2) forbids this for some CPack generator like NSIS In fact it should certainly be forbidden for *any* generators when used on Windows but we may implements that on top of the current patch. The patch ask the task to the generated cmake_install.cmake scripts. Those scripts are a little bit more complicated with that but iff there are absolute DESTINATION. This cost nothing if relative DESTINATION are used. Two new vars are introduced (and documented to handle that): CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION and CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION --- Source/CPack/cmCPackDocumentVariables.cxx | 16 +++++++++++++++ Source/CPack/cmCPackGenerator.cxx | 25 +++++++++++++++++++++++ Source/CPack/cmCPackGenerator.h | 11 +++++++++- Source/CPack/cmCPackNSISGenerator.cxx | 6 ++++++ Source/CPack/cmCPackNSISGenerator.h | 1 + Source/cmInstallGenerator.cxx | 9 ++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx index d2e3802c6..b5294805d 100644 --- a/Source/CPack/cmCPackDocumentVariables.cxx +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -77,4 +77,20 @@ void cmCPackDocumentVariables::DefineVariables(cmake* cm) "which is done right before packaging the files." " The script is not called by e.g.: make install.", false, "Variables common to all CPack generators"); + + cm->DefineProperty + ("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, + "Ask CPack to warn each time a file with absolute INSTALL" + " DESTINATION is encountered.", + "", false, + "Variables common to all CPack generators"); + + cm->DefineProperty + ("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, + "Ask CPack to error out as soon as a file with absolute INSTALL" + " DESTINATION is encountered", + "The fatal error is emitted before the installation of " + "the offending file takes place. Some CPack generators, like NSIS," + "enforce this internally.", false, + "Variables common to all CPack generators"); } diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index bf652718e..ca790c02c 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -849,8 +849,27 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( filesBefore = glB.GetFiles(); std::sort(filesBefore.begin(),filesBefore.end()); } + + // If CPack was asked to warn on ABSOLUTE INSTALL DESTINATION + // then forward request to cmake_install.cmake script + if (this->GetOption("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) + { + mf->AddDefinition("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", + "1"); + } + // If current CPack generator does support + // ABSOLUTE INSTALL DESTINATION or CPack has been asked for + // then ask cmake_install.cmake script to error out + // as soon as it occurs (before installing file) + if (!SupportsAbsoluteDestination() || + this->GetOption("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) + { + mf->AddDefinition("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", + "1"); + } // do installation int res = mf->ReadListFile(0, installFile.c_str()); + // Now rebuild the list of files after installation // of the current component (if we are in component install) if (componentInstall) @@ -1460,6 +1479,12 @@ cmCPackGenerator::SupportsSetDestdir() const return cmCPackGenerator::SETDESTDIR_SUPPORTED; } +//---------------------------------------------------------------------- +bool cmCPackGenerator::SupportsAbsoluteDestination() const +{ + return true; +} + //---------------------------------------------------------------------- bool cmCPackGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index 68ee3f2e0..ddde8b5d8 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -206,12 +206,21 @@ protected: /** * Does the CPack generator support CPACK_SET_DESTDIR? - * The default legacy value is 'true' generator + * The default legacy value is 'SETDESTDIR_SUPPORTED' generator * have to override it in order change this. * @return CPackSetDestdirSupport */ virtual enum CPackSetDestdirSupport SupportsSetDestdir() const; + /** + * Does the CPack generator support absolute path + * in INSTALL DESTINATION? + * The default legacy value is 'true' generator + * have to override it in order change this. + * @return true if supported false otherwise + */ + virtual bool SupportsAbsoluteDestination() const; + /** * Does the CPack generator support component installation?. * Some Generators requires the user to set diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 63189de2e..481fd2b6e 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -638,6 +638,12 @@ cmCPackNSISGenerator::SupportsSetDestdir() const return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED; } +//---------------------------------------------------------------------- +bool cmCPackNSISGenerator::SupportsAbsoluteDestination() const +{ + return false; +} + //---------------------------------------------------------------------- bool cmCPackNSISGenerator::SupportsComponentInstallation() const { diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h index c2987d0ba..82248546f 100644 --- a/Source/CPack/cmCPackNSISGenerator.h +++ b/Source/CPack/cmCPackNSISGenerator.h @@ -45,6 +45,7 @@ protected: std::vector& dirs); enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const; + virtual bool SupportsAbsoluteDestination() const; virtual bool SupportsComponentInstallation() const; /// Produce a string that contains the NSIS code to describe a diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 807168e0d..2150ec1b8 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -80,6 +80,15 @@ void cmInstallGenerator } } os << "\")\n"; + os << indent << "IF (CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + os << indent << indent << "message(WARNING \"ABSOLUTE path INSTALL " + << "DESTINATION : ${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent << "ENDIF (CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + + os << indent << "IF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + os << indent << indent << "message(FATAL_ERROR \"ABSOLUTE path INSTALL " + << "DESTINATION forbidden (by CPack): ${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent << "ENDIF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; } os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str(); if(optional) From f90223cafc4be83a1556e2d238e2af596afbd616 Mon Sep 17 00:00:00 2001 From: Eric NOULARD Date: Tue, 15 May 2012 07:54:42 +0200 Subject: [PATCH 3/4] Fix KWStyle warning --- Source/cmInstallGenerator.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 2150ec1b8..2b1db7940 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -87,7 +87,8 @@ void cmInstallGenerator os << indent << "IF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; os << indent << indent << "message(FATAL_ERROR \"ABSOLUTE path INSTALL " - << "DESTINATION forbidden (by CPack): ${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; + << "DESTINATION forbidden (by CPack): " + << "${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; os << indent << "ENDIF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; } os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str(); From 4986d525afcddcad6f8610c85cc7d2cf46701ad5 Mon Sep 17 00:00:00 2001 From: Eric NOULARD Date: Sun, 20 May 2012 17:28:54 +0200 Subject: [PATCH 4/4] Use CPACK_xxx and CMAKE_xxx in a consistent way. CMAKE_xxx vars are now used in the CMake-generated cmake_install.cmake script while CPACK_xxx equivalent vars are used from within CPack. CPack is responsible for getting/forwarding definitions of CPACK_xxxx var corresponding to CMAKE_xxxx when invoking CMake-generated install scripts. As a consequence: CMAKE_ABSOLUTE_DESTINATION_FILES CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION may be used from outside CPack as well. e.g. cmake -DCMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION=1 -P cmake_install.cmake works as expected. --- Source/CPack/cmCPackDocumentVariables.cxx | 21 +++++++++++++--- Source/CPack/cmCPackGenerator.cxx | 12 +++++++-- Source/cmDocumentVariables.cxx | 30 +++++++++++++++++++++++ Source/cmInstallGenerator.cxx | 16 ++++++------ 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx index b5294805d..edbef45ef 100644 --- a/Source/CPack/cmCPackDocumentVariables.cxx +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -78,19 +78,34 @@ void cmCPackDocumentVariables::DefineVariables(cmake* cm) " The script is not called by e.g.: make install.", false, "Variables common to all CPack generators"); + cm->DefineProperty + ("CPACK_ABSOLUTE_DESTINATION_FILES", cmProperty::VARIABLE, + "List of files which have been installed using " + " an ABSOLUTE DESTINATION path.", + "This variable is a Read-Only variable which is set internally" + " by CPack during installation and before packaging using" + " CMAKE_ABSOLUTE_DESTINATION_FILES defined in cmake_install.cmake " + "scripts. The value can be used within CPack project configuration" + " file and/or CPack.cmake file of generator.", false, + "Variables common to all CPack generators"); + cm->DefineProperty ("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, "Ask CPack to warn each time a file with absolute INSTALL" " DESTINATION is encountered.", - "", false, + "This variable triggers the definition of " + "CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs" + " cmake_install.cmake scripts.", false, "Variables common to all CPack generators"); cm->DefineProperty ("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, "Ask CPack to error out as soon as a file with absolute INSTALL" - " DESTINATION is encountered", + " DESTINATION is encountered.", "The fatal error is emitted before the installation of " "the offending file takes place. Some CPack generators, like NSIS," - "enforce this internally.", false, + "enforce this internally. " + "This variable triggers the definition of" + "CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION when CPack runs" "Variables common to all CPack generators"); } diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index ca790c02c..87a3b9e4c 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -854,7 +854,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // then forward request to cmake_install.cmake script if (this->GetOption("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION")) { - mf->AddDefinition("CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", + mf->AddDefinition("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); } // If current CPack generator does support @@ -864,11 +864,19 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( if (!SupportsAbsoluteDestination() || this->GetOption("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) { - mf->AddDefinition("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", + mf->AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); } // do installation int res = mf->ReadListFile(0, installFile.c_str()); + // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES + // to CPack (may be used by generators like CPack RPM or DEB) + // in order to transparently handle ABSOLUTE PATH + if (mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) + { + mf->AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", + mf->GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")); + } // Now rebuild the list of files after installation // of the current component (if we are in component install) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 897e516b9..fb40024ef 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -833,6 +833,36 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Default is ON.",false, "Variables That Change Behavior"); + cm->DefineProperty + ("CMAKE_ABSOLUTE_DESTINATION_FILES", cmProperty::VARIABLE, + "List of files which have been installed using " + " an ABSOLUTE DESTINATION path.", + "This variable is defined by CMake-generated cmake_install.cmake " + "scripts." + " It can be used (read-only) by program or script that source those" + " install scripts. This is used by some CPack generators (e.g. RPM).", + false, + "Variables That Change Behavior"); + + cm->DefineProperty + ("CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, + "Ask cmake_install.cmake script to warn each time a file with " + "absolute INSTALL DESTINATION is encountered.", + "This variable is used by CMake-generated cmake_install.cmake" + " scripts. If ones set this variable to ON while running the" + " script, it may get warning messages from the script.", false, + "Variables That Change Behavior"); + + cm->DefineProperty + ("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", cmProperty::VARIABLE, + "Ask cmake_install.cmake script to error out as soon as " + "a file with absolute INSTALL DESTINATION is encountered.", + "The fatal error is emitted before the installation of " + "the offending file takes place." + " This variable is used by CMake-generated cmake_install.cmake" + " scripts. If ones set this variable to ON while running the" + " script, it may get fatal error messages from the script.",false, + "Variables That Change Behavior"); // Variables defined by CMake that describe the system diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 2b1db7940..3be2c2b14 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -60,7 +60,7 @@ void cmInstallGenerator std::string dest = this->GetInstallDestination(); if (cmSystemTools::FileIsFullPath(dest.c_str())) { - os << "list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES\n"; + os << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"; os << indent << " \""; for(std::vector::const_iterator fi = files.begin(); fi != files.end(); ++fi) @@ -80,16 +80,16 @@ void cmInstallGenerator } } os << "\")\n"; - os << indent << "IF (CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + os << indent << "IF (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; os << indent << indent << "message(WARNING \"ABSOLUTE path INSTALL " - << "DESTINATION : ${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; - os << indent << "ENDIF (CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + << "DESTINATION : ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent << "ENDIF (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; - os << indent << "IF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + os << indent << "IF (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; os << indent << indent << "message(FATAL_ERROR \"ABSOLUTE path INSTALL " - << "DESTINATION forbidden (by CPack): " - << "${CPACK_ABSOLUTE_DESTINATION_FILES}\")\n"; - os << indent << "ENDIF (CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; + << "DESTINATION forbidden (by caller): " + << "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; + os << indent << "ENDIF (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"; } os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str(); if(optional)