diff options
56 files changed, 701 insertions, 215 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b64b6a9..5f3bc66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,7 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR) -set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required +cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) if(POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif() @@ -196,15 +195,8 @@ mark_as_advanced(CMAKE_USE_FOLDERS) macro(CMAKE_SET_TARGET_FOLDER tgt folder) if(CMAKE_USE_FOLDERS) set_property(GLOBAL PROPERTY USE_FOLDERS ON) - - # Really, I just want this to be an "if(TARGET ${tgt})" ... - # but I'm not sure that our min req'd., CMake 2.4.5 can handle - # that... so I'm just activating this for now, with a version - # compare, and only for MSVC builds. - if(MSVC) - if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 2.8) - set_property(TARGET "${tgt}" PROPERTY FOLDER "${folder}") - endif() + if(MSVC AND TARGET ${tgt}) + set_property(TARGET "${tgt}" PROPERTY FOLDER "${folder}") endif() else() set_property(GLOBAL PROPERTY USE_FOLDERS OFF) @@ -326,11 +318,7 @@ macro (CMAKE_BUILD_UTILITIES) #--------------------------------------------------------------------- # Build or use system libarchive for CMake and CTest. if(CMAKE_USE_SYSTEM_LIBARCHIVE) - if(EXISTS ${CMAKE_ROOT}/Modules/FindLibArchive.cmake) # added in 2.8.3 - find_package(LibArchive) - else() - include(${CMake_SOURCE_DIR}/Modules/FindLibArchive.cmake) - endif() + find_package(LibArchive) if(NOT LibArchive_FOUND) message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBARCHIVE is ON but LibArchive is not found!") endif() diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake index fce25f0..604eb37 100644 --- a/Modules/CPackWIX.cmake +++ b/Modules/CPackWIX.cmake @@ -102,6 +102,20 @@ # If this variable is not set, the default MSI template included with CMake will be used. # ##end +##variable +# CPACK_WIX_EXTRA_SOURCES - Extra WiX source files +# +# This variable provides an optional list of extra WiX source files (.wxs) +# that should be compiled and linked. The full path to source files is required. +# +##end +##variable +# CPACK_WIX_EXTRA_OBJECTS - Extra WiX object files or libraries +# +# This variable provides an optional list of extra WiX object (.wixobj) and/or +# WiX library (.wixlib) files. The full path to objects and libraries is required. +# +##end #============================================================================= # Copyright 2012 Kitware, Inc. diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 8270ad4..2705d32 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -263,6 +263,12 @@ # Only available for CUDA version 3.2+. # CUDA_npp_LIBRARY -- NVIDIA Performance Primitives library. # Only available for CUDA version 4.0+. +# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives library (core). +# Only available for CUDA version 5.5+. +# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives library (image processing). +# Only available for CUDA version 5.5+. +# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives library (signal processing). +# Only available for CUDA version 5.5+. # CUDA_nvcuvenc_LIBRARY -- CUDA Video Encoder library. # Only available for CUDA version 3.2+. # Windows only. @@ -496,6 +502,9 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}") unset(CUDA_curand_LIBRARY CACHE) unset(CUDA_cusparse_LIBRARY CACHE) unset(CUDA_npp_LIBRARY CACHE) + unset(CUDA_nppc_LIBRARY CACHE) + unset(CUDA_nppi_LIBRARY CACHE) + unset(CUDA_npps_LIBRARY CACHE) unset(CUDA_nvcuvenc_LIBRARY CACHE) unset(CUDA_nvcuvid_LIBRARY CACHE) endif() @@ -700,7 +709,13 @@ if(NOT CUDA_VERSION VERSION_LESS "3.2") find_cuda_helper_libs(nvcuvid) endif() endif() -if(NOT CUDA_VERSION VERSION_LESS "4.0") +if(CUDA_VERSION VERSION_GREATER "5.0") + # In CUDA 5.5 NPP was splitted onto 3 separate libraries. + find_cuda_helper_libs(nppc) + find_cuda_helper_libs(nppi) + find_cuda_helper_libs(npps) + set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}") +elseif(NOT CUDA_VERSION VERSION_LESS "4.0") find_cuda_helper_libs(npp) endif() diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index 72844b5..8ab3e2c 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -268,6 +268,11 @@ set(CMAKE_C_CREATE_MACOSX_FRAMEWORK set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>") +# Set default framework search path flag for languages known to use a +# preprocessor that may find headers in frameworks. +set(CMAKE_C_FRAMEWORK_SEARCH_FLAG -F) +set(CMAKE_CXX_FRAMEWORK_SEARCH_FLAG -F) +set(CMAKE_Fortran_FRAMEWORK_SEARCH_FLAG -F) # default to searching for frameworks first if(NOT DEFINED CMAKE_FIND_FRAMEWORK) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 32ea0dc..0d10c10 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 12) -set(CMake_VERSION_TWEAK 20131011) +set(CMake_VERSION_TWEAK 20131015) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index cc9dec7..725810b 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + Copyright 2000-2013 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -14,6 +14,7 @@ #include <cmSystemTools.h> #include <cmGeneratedFileStream.h> +#include <cmCryptoHash.h> #include <CPack/cmCPackLog.h> #include <CPack/cmCPackComponentGroup.h> @@ -189,6 +190,8 @@ bool cmCPackWIXGenerator::PackageFilesImpl() return false; } + AppendUserSuppliedExtraSources(); + std::stringstream objectFiles; for(size_t i = 0; i < wixSources.size(); ++i) { @@ -205,9 +208,35 @@ bool cmCPackWIXGenerator::PackageFilesImpl() objectFiles << " " << QuotePath(objectFilename); } + AppendUserSuppliedExtraObjects(objectFiles); + return RunLightCommand(objectFiles.str()); } +void cmCPackWIXGenerator::AppendUserSuppliedExtraSources() +{ + const char *cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES"); + if(!cpackWixExtraSources) return; + + cmSystemTools::ExpandListArgument(cpackWixExtraSources, wixSources); +} + +void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream) +{ + const char *cpackWixExtraObjects = GetOption("CPACK_WIX_EXTRA_OBJECTS"); + if(!cpackWixExtraObjects) return; + + std::vector<std::string> expandedExtraObjects; + + cmSystemTools::ExpandListArgument( + cpackWixExtraObjects, expandedExtraObjects); + + for(size_t i = 0; i < expandedExtraObjects.size(); ++i) + { + stream << " " << QuotePath(expandedExtraObjects[i]); + } +} + bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile() { std::string cpackTopLevel; @@ -319,9 +348,6 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() directoryDefinitions.AddAttribute("Name", install_root[i]); } - size_t directoryCounter = 0; - size_t fileCounter = 0; - std::string fileDefinitionsFilename = cpackTopLevel + "/files.wxs"; @@ -367,7 +393,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() if (!cpackVendor || !cpackPkgName) { cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_PACKAGE_VENDOR and " - "CPACK_PACKAGE_NAME must be defined for shortcut creation" << std::endl); + "CPACK_PACKAGE_NAME must be defined for shortcut creation" + << std::endl); cpackPkgExecutables.clear(); } else @@ -380,7 +407,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() AddDirectoryAndFileDefinitons( toplevel, "INSTALL_ROOT", directoryDefinitions, fileDefinitions, featureDefinitions, - directoryCounter, fileCounter, cpackPkgExecutables, dirIdExecutables); + cpackPkgExecutables, dirIdExecutables); directoryDefinitions.EndElement(); directoryDefinitions.EndElement(); @@ -403,7 +430,10 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() std::string directoryId = *it; fileDefinitions.BeginElement("Shortcut"); - std::string shortcutName = fileName; // the iconName is mor likely to contain blanks early on + + // the iconName is more likely to contain blanks early on + std::string shortcutName = fileName; + std::string::size_type const dotPos = shortcutName.find('.'); if(std::string::npos == dotPos) { shortcutName = shortcutName.substr(0, dotPos); } @@ -531,8 +561,6 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - size_t& directoryCounter, - size_t& fileCounter, const std::vector<std::string>& pkgExecutables, std::vector<std::string>& dirIdExecutables) { @@ -550,11 +578,14 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( std::string fullPath = topdir + "/" + fileName; + std::string relativePath = cmSystemTools::RelativePath( + toplevel.c_str(), fullPath.c_str()); + + std::string id = PathToId(relativePath); + if(cmSystemTools::FileIsDirectory(fullPath.c_str())) { - std::stringstream tmp; - tmp << "DIR_ID_" << ++directoryCounter; - std::string subDirectoryId = tmp.str(); + std::string subDirectoryId = std::string("CM_D") + id; directoryDefinitions.BeginElement("Directory"); directoryDefinitions.AddAttribute("Id", subDirectoryId); @@ -565,20 +596,14 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( directoryDefinitions, fileDefinitions, featureDefinitions, - directoryCounter, - fileCounter, pkgExecutables, dirIdExecutables); directoryDefinitions.EndElement(); } else { - std::stringstream tmp; - tmp << "_ID_" << ++fileCounter; - std::string idSuffix = tmp.str(); - - std::string componentId = std::string("CMP") + idSuffix; - std::string fileId = std::string("FILE") + idSuffix; + std::string componentId = std::string("CM_C") + id; + std::string fileId = std::string("CM_F") + id; fileDefinitions.BeginElement("DirectoryRef"); fileDefinitions.AddAttribute("Id", directoryId); @@ -686,3 +711,119 @@ std::string cmCPackWIXGenerator::GetRightmostExtension( return cmSystemTools::LowerCase(extension); } + +std::string cmCPackWIXGenerator::PathToId(const std::string& path) +{ + id_map_t::const_iterator i = pathToIdMap.find(path); + if(i != pathToIdMap.end()) return i->second; + + std::string id = CreateNewIdForPath(path); + return id; +} + +std::string cmCPackWIXGenerator::CreateNewIdForPath(const std::string& path) +{ + std::vector<std::string> components; + cmSystemTools::SplitPath(path.c_str(), components, false); + + size_t replacementCount = 0; + + std::string identifier; + std::string currentComponent; + + for(size_t i = 1; i < components.size(); ++i) + { + if(i != 1) identifier += '.'; + + currentComponent = NormalizeComponentForId( + components[i], replacementCount); + + identifier += currentComponent; + } + + std::string idPrefix = "P"; + size_t replacementPercent = replacementCount * 100 / identifier.size(); + if(replacementPercent > 33 || identifier.size() > 60) + { + identifier = CreateHashedId(path, currentComponent); + idPrefix = "H"; + } + + std::stringstream result; + result << idPrefix << "_" << identifier; + + size_t ambiguityCount = ++idAmbiguityCounter[identifier]; + + if(ambiguityCount > 999) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while trying to generate a unique Id for '" << + path << "'" << std::endl); + + return std::string(); + } + else if(ambiguityCount > 1) + { + result << "_" << ambiguityCount; + } + + std::string resultString = result.str(); + + pathToIdMap[path] = resultString; + + return resultString; +} + +std::string cmCPackWIXGenerator::CreateHashedId( + const std::string& path, const std::string& normalizedFilename) +{ + cmsys::auto_ptr<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1"); + std::string hash = sha1->HashString(path.c_str()); + + std::string identifier; + identifier += hash.substr(0, 7) + "_"; + + const size_t maxFileNameLength = 52; + if(normalizedFilename.length() > maxFileNameLength) + { + identifier += normalizedFilename.substr(0, maxFileNameLength - 3); + identifier += "..."; + } + else + { + identifier += normalizedFilename; + } + + return identifier; +} + +std::string cmCPackWIXGenerator::NormalizeComponentForId( + const std::string& component, size_t& replacementCount) +{ + std::string result; + result.resize(component.size()); + + for(size_t i = 0; i < component.size(); ++i) + { + char c = component[i]; + if(IsLegalIdCharacter(c)) + { + result[i] = c; + } + else + { + result[i] = '_'; + ++ replacementCount; + } + } + + return result; +} + +bool cmCPackWIXGenerator::IsLegalIdCharacter(char c) +{ + return (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + c == '_' || c == '.'; +} diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index aaccf9d..eac69fe 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -54,6 +54,9 @@ protected: } private: + typedef std::map<std::string, std::string> id_map_t; + typedef std::map<std::string, size_t> ambiguity_map_t; + bool InitializeWiXConfiguration(); bool PackageFilesImpl(); @@ -68,6 +71,10 @@ private: bool CreateWiXSourceFiles(); + void AppendUserSuppliedExtraSources(); + + void AppendUserSuppliedExtraObjects(std::ostream& stream); + bool CreateLicenseFile(); bool RunWiXCommand(const std::string& command); @@ -82,13 +89,10 @@ private: cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - size_t& directoryCounter, - size_t& fileCounter, const std::vector<std::string>& pkgExecutables, std::vector<std::string>& dirIdExecutables ); - bool RequireOption(const std::string& name, std::string& value) const; std::string GetArchitecture() const; @@ -99,7 +103,21 @@ private: static std::string GetRightmostExtension(const std::string& filename); + std::string PathToId(const std::string& path); + + std::string CreateNewIdForPath(const std::string& path); + + static std::string CreateHashedId( + const std::string& path, const std::string& normalizedFilename); + + std::string NormalizeComponentForId( + const std::string& component, size_t& replacementCount); + + static bool IsLegalIdCharacter(char c); + std::vector<std::string> wixSources; + id_map_t pathToIdMap; + ambiguity_map_t idAmbiguityCounter; }; #endif diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 58634ea..dbe1b04 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1977,6 +1977,8 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_FLAGS_RELWITHDEBINFO_INIT", cmProperty::VARIABLE,0,0); + cm->DefineProperty("CMAKE_<LANG>_FRAMEWORK_SEARCH_FLAG", + cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_INFORMATION_LOADED", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_<LANG>_LINK_FLAGS", diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 243e5ce..50835e2 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -11,40 +11,38 @@ ============================================================================*/ #include "cmExportBuildFileGenerator.h" -#include "cmExportCommand.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" //---------------------------------------------------------------------------- cmExportBuildFileGenerator::cmExportBuildFileGenerator() { - this->ExportCommand = 0; + this->Makefile = 0; } //---------------------------------------------------------------------------- bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { - std::vector<cmTarget*> allTargets; { std::string expectedTargets; std::string sep; - for(std::vector<cmTarget*>::const_iterator - tei = this->Exports->begin(); - tei != this->Exports->end(); ++tei) + for(std::vector<std::string>::const_iterator + tei = this->Targets.begin(); + tei != this->Targets.end(); ++tei) { - expectedTargets += sep + this->Namespace + (*tei)->GetExportName(); + cmTarget *te = this->Makefile->FindTargetToUse(tei->c_str()); + expectedTargets += sep + this->Namespace + te->GetExportName(); sep = " "; - cmTarget* te = *tei; if(this->ExportedTargets.insert(te).second) { - allTargets.push_back(te); + this->Exports.push_back(te); } else { - if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty()) - { - cmOStringStream e; - e << "given target \"" << te->GetName() << "\" more than once."; - this->ExportCommand->ErrorMessage = e.str(); - } + cmOStringStream e; + e << "given target \"" << te->GetName() << "\" more than once."; + this->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), this->Backtrace); return false; } if (te->GetType() == cmTarget::INTERFACE_LIBRARY) @@ -60,8 +58,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) // Create all the imported targets. for(std::vector<cmTarget*>::const_iterator - tei = allTargets.begin(); - tei != allTargets.end(); ++tei) + tei = this->Exports.begin(); + tei != this->Exports.end(); ++tei) { cmTarget* te = *tei; this->GenerateImportTargetCode(os, te); @@ -116,8 +114,8 @@ cmExportBuildFileGenerator std::vector<std::string> &missingTargets) { for(std::vector<cmTarget*>::const_iterator - tei = this->Exports->begin(); - tei != this->Exports->end(); ++tei) + tei = this->Exports.begin(); + tei != this->Exports.end(); ++tei) { // Collect import properties for this target. cmTarget* target = *tei; @@ -198,40 +196,95 @@ cmExportBuildFileGenerator //---------------------------------------------------------------------------- void cmExportBuildFileGenerator::HandleMissingTarget( - std::string& link_libs, std::vector<std::string>&, - cmMakefile*, cmTarget* depender, cmTarget* dependee) + std::string& link_libs, std::vector<std::string>& missingTargets, + cmMakefile* mf, cmTarget* depender, cmTarget* dependee) { // The target is not in the export. if(!this->AppendMode) { - // We are not appending, so all exported targets should be - // known here. This is probably user-error. - this->ComplainAboutMissingTarget(depender, dependee); + const std::string name = dependee->GetName(); + std::vector<std::string> namespaces = this->FindNamespaces(mf, name); + + int targetOccurrences = (int)namespaces.size(); + if (targetOccurrences == 1) + { + std::string missingTarget = namespaces[0]; + + missingTarget += dependee->GetExportName(); + link_libs += missingTarget; + missingTargets.push_back(missingTarget); + return; + } + else + { + // We are not appending, so all exported targets should be + // known here. This is probably user-error. + this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + } } // Assume the target will be exported by another command. // Append it with the export namespace. link_libs += this->Namespace; link_libs += dependee->GetExportName(); +// if generate time {} +} + + +//---------------------------------------------------------------------------- +std::vector<std::string> +cmExportBuildFileGenerator +::FindNamespaces(cmMakefile* mf, const std::string& name) +{ + std::vector<std::string> namespaces; + cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); + + std::map<std::string, cmExportBuildFileGenerator*>& exportSets + = gg->GetBuildExportSets(); + + for(std::map<std::string, cmExportBuildFileGenerator*>::const_iterator + expIt = exportSets.begin(); expIt != exportSets.end(); ++expIt) + { + const cmExportBuildFileGenerator* exportSet = expIt->second; + std::vector<std::string> const& targets = exportSet->GetTargets(); + + if (std::find(targets.begin(), targets.end(), name) != targets.end()) + { + namespaces.push_back(exportSet->GetNamespace()); + } + } + + return namespaces; } //---------------------------------------------------------------------------- void cmExportBuildFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee) + cmTarget* dependee, + int occurrences) { - if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty()) + if(cmSystemTools::GetErrorOccuredFlag()) { return; } cmOStringStream e; - e << "called with target \"" << depender->GetName() - << "\" which requires target \"" << dependee->GetName() - << "\" that is not in the export list.\n" - << "If the required target is not easy to reference in this call, " + e << "export called with target \"" << depender->GetName() + << "\" which requires target \"" << dependee->GetName() << "\" "; + if (occurrences == 0) + { + e << "that is not in the export set.\n"; + } + else + { + e << "that is not in this export set, but " << occurrences + << " times in others.\n"; + } + e << "If the required target is not easy to reference in this call, " << "consider using the APPEND option with multiple separate calls."; - this->ExportCommand->ErrorMessage = e.str(); + + this->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), this->Backtrace); } std::string diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 3ffdf8b..2fbd98f 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -13,8 +13,7 @@ #define cmExportBuildFileGenerator_h #include "cmExportFileGenerator.h" - -class cmExportCommand; +#include "cmListFileCache.h" /** \class cmExportBuildFileGenerator * \brief Generate a file exporting targets from a build tree. @@ -31,14 +30,22 @@ public: cmExportBuildFileGenerator(); /** Set the list of targets to export. */ - void SetExports(std::vector<cmTarget*> const* exports) - { this->Exports = exports; } + void SetTargets(std::vector<std::string> const& targets) + { this->Targets = targets; } + std::vector<std::string> const& GetTargets() const + { return this->Targets; } + void AppendTargets(std::vector<std::string> const& targets) + { this->Targets.insert(this->Targets.end(), + targets.begin(), targets.end()); } /** Set whether to append generated code to the output file. */ void SetAppendMode(bool append) { this->AppendMode = append; } - /** Set the command instance through which errors should be reported. */ - void SetCommand(cmExportCommand* cmd) { this->ExportCommand = cmd; } + void SetMakefile(cmMakefile *mf) { + this->Makefile = mf; + this->Makefile->GetBacktrace(this->Backtrace); + } + protected: // Implement virtual methods from the superclass. virtual bool GenerateMainFile(std::ostream& os); @@ -53,7 +60,8 @@ protected: cmTarget* dependee); void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + cmTarget* dependee, + int occurrences); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const char* config, @@ -63,8 +71,13 @@ protected: std::string InstallNameDir(cmTarget* target, const std::string& config); - std::vector<cmTarget*> const* Exports; - cmExportCommand* ExportCommand; + std::vector<std::string> + FindNamespaces(cmMakefile* mf, const std::string& name); + + std::vector<std::string> Targets; + std::vector<cmTarget*> Exports; + cmMakefile* Makefile; + cmListFileBacktrace Backtrace; }; #endif diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index 422b038..86ddc3f 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -108,8 +108,6 @@ bool cmExportCommand fname += this->Filename.GetString(); } - // Collect the targets to be exported. - std::vector<cmTarget*> targets; for(std::vector<std::string>::const_iterator currentTarget = this->Targets.GetVector().begin(); currentTarget != this->Targets.GetVector().end(); @@ -128,15 +126,7 @@ bool cmExportCommand this->Makefile->GetLocalGenerator()-> GetGlobalGenerator()->FindTarget(0, currentTarget->c_str())) { - if((target->GetType() == cmTarget::EXECUTABLE) || - (target->GetType() == cmTarget::STATIC_LIBRARY) || - (target->GetType() == cmTarget::SHARED_LIBRARY) || - (target->GetType() == cmTarget::MODULE_LIBRARY) || - (target->GetType() == cmTarget::INTERFACE_LIBRARY)) - { - targets.push_back(target); - } - else if(target->GetType() == cmTarget::OBJECT_LIBRARY) + if(target->GetType() == cmTarget::OBJECT_LIBRARY) { cmOStringStream e; e << "given OBJECT library \"" << *currentTarget @@ -144,35 +134,28 @@ bool cmExportCommand this->SetError(e.str().c_str()); return false; } - else - { - cmOStringStream e; - e << "given target \"" << *currentTarget - << "\" which is not an executable or library."; - this->SetError(e.str().c_str()); - return false; - } } - else + } + + cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator(); + if (this->Append.IsEnabled()) + { + if (cmExportBuildFileGenerator *ebfg = gg->GetExportedTargetsFile(fname)) { - cmOStringStream e; - e << "given target \"" << *currentTarget - << "\" which is not built by this project."; - this->SetError(e.str().c_str()); - return false; + ebfg->AppendTargets(this->Targets.GetVector()); + return true; } } // Setup export file generation. - cmExportBuildFileGenerator ebfg; - ebfg.SetExportFile(fname.c_str()); - ebfg.SetNamespace(this->Namespace.GetCString()); - ebfg.SetAppendMode(this->Append.IsEnabled()); - ebfg.SetExports(&targets); - ebfg.SetCommand(this); - ebfg.SetExportOld(this->ExportOld.IsEnabled()); - - this->Makefile->AddExportedTargetsFile(fname); + cmExportBuildFileGenerator *ebfg = new cmExportBuildFileGenerator; + ebfg->SetExportFile(fname.c_str()); + ebfg->SetNamespace(this->Namespace.GetCString()); + ebfg->SetAppendMode(this->Append.IsEnabled()); + ebfg->SetTargets(this->Targets.GetVector()); + ebfg->SetMakefile(this->Makefile); + ebfg->SetExportOld(this->ExportOld.IsEnabled()); // Compute the set of configurations exported. std::vector<std::string> configurationTypes; @@ -183,27 +166,15 @@ bool cmExportCommand ci = configurationTypes.begin(); ci != configurationTypes.end(); ++ci) { - ebfg.AddConfiguration(ci->c_str()); + ebfg->AddConfiguration(ci->c_str()); } } else { - ebfg.AddConfiguration(""); + ebfg->AddConfiguration(""); } - // Generate the import file. - if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty()) - { - this->SetError("could not write export file."); - return false; - } - - // Report generated error message if any. - if(!this->ErrorMessage.empty()) - { - this->SetError(this->ErrorMessage.c_str()); - return false; - } + gg->AddBuildExportSet(ebfg); return true; } diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index 87c3452..38e8d9a 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -85,7 +85,9 @@ public: "should never be installed. " "See the install(EXPORT) command to export targets from an " "installation tree." - CM_LOCATION_UNDEFINED_BEHAVIOR("passing it to this command") + "\n" + "The properties set on the generated IMPORTED targets will have the " + "same values as the final values of the input TARGETS." "\n" " export(PACKAGE <name>)\n" "Store the current build directory in the CMake user package registry " diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 25c5710..b01e499 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -52,6 +52,12 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile) } //---------------------------------------------------------------------------- +const char* cmExportFileGenerator::GetMainExportFileName() const +{ + return this->MainImportFile.c_str(); +} + +//---------------------------------------------------------------------------- bool cmExportFileGenerator::GenerateImportFile() { // Open the output file to generate it. diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 9628b96..f3d0807 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -33,9 +33,11 @@ public: /** Set the full path to the export file to generate. */ void SetExportFile(const char* mainFile); + const char *GetMainExportFileName() const; /** Set the namespace in which to place exported target names. */ void SetNamespace(const char* ns) { this->Namespace = ns; } + std::string GetNamespace() const { return this->Namespace; } void SetExportOld(bool exportOld) { this->ExportOld = exportOld; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index c71008e..133944e 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -432,8 +432,8 @@ cmExportInstallFileGenerator::HandleMissingTarget( } else { - // We are not appending, so all exported targets should be - // known here. This is probably user-error. + // All exported targets should be known here and should be unique. + // This is probably user-error. this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); } } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index eacf85b..fb205be 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -27,6 +27,7 @@ #include "cmGeneratorTarget.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" +#include "cmExportBuildFileGenerator.h" #include <cmsys/Directory.hxx> @@ -77,6 +78,12 @@ cmGlobalGenerator::~cmGlobalGenerator() { delete *li; } + for(std::map<std::string, cmExportBuildFileGenerator*>::iterator + i = this->BuildExportSets.begin(); + i != this->BuildExportSets.end(); ++i) + { + delete i->second; + } this->LocalGenerators.clear(); if (this->ExtraGenerator) @@ -183,6 +190,34 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, doc.c_str(), cmCacheManager::FILEPATH); } +void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen) +{ + this->BuildExportSets[gen->GetMainExportFileName()] = gen; +} + +bool cmGlobalGenerator::GenerateImportFile(const std::string &file) +{ + std::map<std::string, cmExportBuildFileGenerator*>::iterator it + = this->BuildExportSets.find(file); + if (it != this->BuildExportSets.end()) + { + bool result = it->second->GenerateImportFile(); + delete it->second; + it->second = 0; + this->BuildExportSets.erase(it); + return result; + } + return false; +} + +bool +cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const +{ + const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it + = this->BuildExportSets.find(filename); + return it != this->BuildExportSets.end(); +} + // Find the make program for the generator, required for try compiles void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) { @@ -966,6 +1001,14 @@ void cmGlobalGenerator::Configure() } } +cmExportBuildFileGenerator* +cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const +{ + std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it + = this->BuildExportSets.find(filename); + return it == this->BuildExportSets.end() ? 0 : it->second; +} + bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { // If the property is not enabled then okay. @@ -1091,6 +1134,19 @@ void cmGlobalGenerator::Generate() } this->SetCurrentLocalGenerator(0); + for (std::map<std::string, cmExportBuildFileGenerator*>::iterator + it = this->BuildExportSets.begin(); it != this->BuildExportSets.end(); + ++it) + { + if (!it->second->GenerateImportFile() + && !cmSystemTools::GetErrorOccuredFlag()) + { + this->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, "Could not write export file.", + cmListFileBacktrace()); + return; + } + } // Update rule hashes. this->CheckRuleHashes(); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 70f6e32..c930b2b 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -31,6 +31,7 @@ class cmExternalMakefileProjectGenerator; class cmTarget; class cmInstallTargetGenerator; class cmInstallFilesGenerator; +class cmExportBuildFileGenerator; /** \class cmGlobalGenerator * \brief Responable for overseeing the generation process for the entire tree @@ -293,6 +294,13 @@ public: void ProcessEvaluationFiles(); + std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets() + {return this->BuildExportSets;} + void AddBuildExportSet(cmExportBuildFileGenerator*); + bool IsExportedTargetsFile(const std::string &filename) const; + bool GenerateImportFile(const std::string &file); + cmExportBuildFileGenerator* + GetExportedTargetsFile(const std::string &filename) const; protected: typedef std::vector<cmLocalGenerator*> GeneratorVector; // for a project collect all its targets by following depend @@ -344,6 +352,7 @@ protected: bool InstallTargetEnabled; // Sets of named target exports cmExportSetMap ExportSets; + std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; // Manifest of all targets that will be built for each configuration. // This is computed just before local generators generate. diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index a3d8b83..5b93171 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -93,7 +93,9 @@ bool cmIncludeCommand cmSystemTools::CollapseFullPath(fname.c_str(), this->Makefile->GetStartDirectory()); - if (this->Makefile->IsExportedTargetsFile(fname_abs)) + cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator(); + if (gg->IsExportedTargetsFile(fname_abs)) { const char *modal = 0; cmake::MessageType messageType = cmake::AUTHOR_WARNING; @@ -125,6 +127,7 @@ bool cmIncludeCommand return false; } } + gg->GenerateImportFile(fname_abs); } std::string fullFilePath; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 9174e26..3dde19f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1253,6 +1253,12 @@ std::string cmLocalGenerator::GetIncludeFlags( sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar.c_str()); } + std::string fwSearchFlagVar = "CMAKE_"; + fwSearchFlagVar += lang; + fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG"; + const char* fwSearchFlag = + this->Makefile->GetDefinition(fwSearchFlagVar.c_str()); + bool flagUsed = false; std::set<cmStdString> emitted; #ifdef __APPLE__ @@ -1261,7 +1267,7 @@ std::string cmLocalGenerator::GetIncludeFlags( std::vector<std::string>::const_iterator i; for(i = includes.begin(); i != includes.end(); ++i) { - if(this->Makefile->IsOn("APPLE") + if(fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") && cmSystemTools::IsPathToFramework(i->c_str())) { std::string frameworkDir = *i; @@ -1271,8 +1277,8 @@ std::string cmLocalGenerator::GetIncludeFlags( { OutputFormat format = forResponseFile? RESPONSE : SHELL; includeFlags - << "-F" << this->Convert(frameworkDir.c_str(), - START_OUTPUT, format, true) + << fwSearchFlag << this->Convert(frameworkDir.c_str(), + START_OUTPUT, format, true) << " "; } continue; @@ -1770,13 +1776,21 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, } // Append the framework search path flags. - std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths(); - for(std::vector<std::string>::const_iterator fdi = fwDirs.begin(); - fdi != fwDirs.end(); ++fdi) + std::string fwSearchFlagVar = "CMAKE_"; + fwSearchFlagVar += linkLanguage; + fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG"; + const char* fwSearchFlag = + this->Makefile->GetDefinition(fwSearchFlagVar.c_str()); + if(fwSearchFlag && *fwSearchFlag) { - frameworkPath += "-F"; - frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); - frameworkPath += " "; + std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths(); + for(std::vector<std::string>::const_iterator fdi = fwDirs.begin(); + fdi != fwDirs.end(); ++fdi) + { + frameworkPath += fwSearchFlag; + frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); + frameworkPath += " "; + } } // Append the library search path flags. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 362b066..ca82336 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -489,18 +489,6 @@ public: return this->cmCurrentListFile.c_str(); } - void AddExportedTargetsFile(const std::string &filename) - { - this->ExportedTargetsFiles.insert(filename); - } - - bool IsExportedTargetsFile(const std::string &filename) const - { - const std::set<std::string>::const_iterator it - = this->ExportedTargetsFiles.find(filename); - return it != this->ExportedTargetsFiles.end(); - } - //@} /** @@ -1053,7 +1041,6 @@ private: void EnforceDirectoryLevelRules(); bool GeneratingBuildSystem; - std::set<std::string> ExportedTargetsFiles; /** * Old version of GetSourceFileWithOutput(const char*) kept for * backward-compatibility. It implements a linear search and support diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 42091e3..9ca9149 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -291,7 +291,7 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) // Add include directory flags. this->LocalGenerator-> - AppendFlags(flags,this->GetFrameworkFlags().c_str()); + AppendFlags(flags,this->GetFrameworkFlags(l).c_str()); // Add target-specific flags. this->LocalGenerator->AddCompileOptions(flags, this->Target, @@ -1518,13 +1518,21 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(const char* main_output, } //---------------------------------------------------------------------------- -std::string cmMakefileTargetGenerator::GetFrameworkFlags() +std::string cmMakefileTargetGenerator::GetFrameworkFlags(std::string const& l) { if(!this->Makefile->IsOn("APPLE")) { return std::string(); } + std::string fwSearchFlagVar = "CMAKE_" + l + "_FRAMEWORK_SEARCH_FLAG"; + const char* fwSearchFlag = + this->Makefile->GetDefinition(fwSearchFlagVar.c_str()); + if(!(fwSearchFlag && *fwSearchFlag)) + { + return std::string(); + } + std::set<cmStdString> emitted; #ifdef __APPLE__ /* don't insert this when crosscompiling e.g. to iphone */ emitted.insert("/System/Library/Frameworks"); @@ -1559,7 +1567,7 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() { if(emitted.insert(*i).second) { - flags += "-F"; + flags += fwSearchFlag; flags += this->Convert(i->c_str(), cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL, true); diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index f7a1e2e..ec2af1c 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -124,7 +124,7 @@ protected: void DriveCustomCommands(std::vector<std::string>& depends); // Return the a string with -F flags on apple - std::string GetFrameworkFlags(); + std::string GetFrameworkFlags(std::string const& l); void AppendFortranFormatFlags(std::string& flags, cmSourceFile& source); diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 1d3469f..d07645c 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -637,6 +637,28 @@ cmPolicies::cmPolicies() "The OLD behavior for this policy is to use compiler id \"Clang\". " "The NEW behavior for this policy is to use compiler id \"AppleClang\".", 2,8,13,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0026, "CMP0026", + "Disallow use of the LOCATION target property.", + "CMake 2.8.12 and lower allowed reading the LOCATION target property to " + "determine the eventual location of build targets. This relies on the " + "assumption that all necessary information is available at " + "configure-time to determine the final location and filename of the " + "target. However, this property is not fully determined until later at " + "generate-time. At generate time, the $<TARGET_FILE> generator " + "expression can be used to determine the eventual LOCATION of a target " + "output." + "\n" + "Code which reads the LOCATION target property can be ported to use the " + "$<TARGET_FILE> generator expression together with the file(GENERATE) " + "subcommand to generate a file containing the target location." + "\n" + "The OLD behavior for this policy is to allow reading the LOCATION " + "property from build-targets. " + "The NEW behavior for this policy is to not to allow reading the " + "LOCATION property from build-targets.", + 2,8,13,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index ec8959d..e33171b 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -76,6 +76,7 @@ public: CMP0023, ///< Disallow mixing keyword and plain tll signatures CMP0024, ///< Disallow including export() result. CMP0025, ///< Compiler id for Apple Clang is now AppleClang + CMP0026, ///< Disallow use of the LOCATION target property. /** \brief Always the last entry. * diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1c04e4e..d03ed49 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -273,7 +273,10 @@ void cmTarget::DefineProperties(cmake *cm) "Additional flags to use when compiling this target's sources.", "The COMPILE_FLAGS property sets additional compiler flags used " "to build sources within the target. Use COMPILE_DEFINITIONS " - "to pass additional preprocessor definitions."); + "to pass additional preprocessor definitions." + "\n" + "This property is deprecated. Use the COMPILE_OPTIONS property or the " + "target_compile_options command instead."); cm->DefineProperty ("COMPILE_DEFINITIONS", cmProperty::TARGET, @@ -4130,6 +4133,43 @@ const char *cmTarget::GetProperty(const char* prop) } //---------------------------------------------------------------------------- +bool cmTarget::HandleLocationPropertyPolicy() +{ + if (this->IsImported()) + { + return true; + } + const char *modal = 0; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0026)) + { + case cmPolicies::WARN: + modal = "should"; + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + modal = "may"; + messageType = cmake::FATAL_ERROR; + } + + if (modal) + { + cmOStringStream e; + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0026)) << "\n"; + e << "The LOCATION property " << modal << " not be read from target \"" + << this->GetName() << "\". Use the target name directly with " + "add_custom_command, or use the generator expression $<TARGET_FILE>, " + "as appropriate.\n"; + this->Makefile->IssueMessage(messageType, e.str().c_str()); + } + + return messageType != cmake::FATAL_ERROR; +} + +//---------------------------------------------------------------------------- const char *cmTarget::GetProperty(const char* prop, cmProperty::ScopeType scope) { @@ -4154,6 +4194,11 @@ const char *cmTarget::GetProperty(const char* prop, { if(strcmp(prop,"LOCATION") == 0) { + if (!this->HandleLocationPropertyPolicy()) + { + return 0; + } + // Set the LOCATION property of the target. // // For an imported target this is the location of an arbitrary @@ -4169,6 +4214,10 @@ const char *cmTarget::GetProperty(const char* prop, // Support "LOCATION_<CONFIG>". if(strncmp(prop, "LOCATION_", 9) == 0) { + if (!this->HandleLocationPropertyPolicy()) + { + return 0; + } std::string configName = prop+9; this->SetProperty(prop, this->GetLocation(configName.c_str())); } @@ -4181,6 +4230,10 @@ const char *cmTarget::GetProperty(const char* prop, std::string configName(prop, len-9); if(configName != "IMPORTED") { + if (!this->HandleLocationPropertyPolicy()) + { + return 0; + } this->SetProperty(prop, this->GetLocation(configName.c_str())); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a88c5ec..3c36da7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -554,6 +554,8 @@ public: { return this->TargetTypeValue == STATIC_LIBRARY; } private: + bool HandleLocationPropertyPolicy(); + // The set of include directories that are marked as system include // directories. std::set<cmStdString> SystemIncludeDirectories; diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index a831e30..070c9cc 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -12,7 +12,7 @@ set(CMakeLib_TESTS testXMLSafe ) -if(WIN32 AND NOT UNIX) # Just if(WIN32) when CMake >= 2.8.4 is required +if(WIN32) list(APPEND CMakeLib_TESTS testVisualStudioSlnParser ) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f7b98da..0e0455c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1985,12 +1985,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ "Process file.*foo.py.*Total LOC:.*13.*Percentage Coverage: 84.62.*" ENVIRONMENT COVFILE=) - # Use macro, not function so that build can still be driven by CMake 2.4. - # After 2.6 is required, this could be a function without the extra 'set' - # calls. - # - macro(add_config_tests cfg) - set(cfg "${cfg}") + function(add_config_tests cfg) set(base "${CMake_BINARY_DIR}/Tests/CTestConfig") # Test -S script with a -C config arg to ctest: @@ -2014,7 +2009,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ add_test(CTestConfig.Dashboard.${cfg} ${CMAKE_CMAKE_COMMAND} -P "${base}/${cfg}-dashboard.cmake" -VV ) - endmacro() + endfunction() add_config_tests(Debug) add_config_tests(MinSizeRel) @@ -2165,15 +2160,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set_tests_properties(CTestTestTimeout PROPERTIES PASS_REGULAR_EXPRESSION "TestTimeout *\\.+ *\\*\\*\\*Timeout.*CheckChild *\\.+ *Passed") - # this test only runs correctly if WORKING_DIRECTORY is honored. - if (NOT CMAKE_VERSION VERSION_LESS "2.8.4") - add_test( - NAME CTestTestRerunFailed - COMMAND ${CMAKE_CTEST_COMMAND} --rerun-failed) - set_tests_properties(CTestTestRerunFailed PROPERTIES - PASS_REGULAR_EXPRESSION "1/1 Test #1: TestTimeout" DEPENDS CTestTestTimeout - WORKING_DIRECTORY ${CMake_BINARY_DIR}/Tests/CTestTestTimeout) - endif () + add_test( + NAME CTestTestRerunFailed + COMMAND ${CMAKE_CTEST_COMMAND} --rerun-failed) + set_tests_properties(CTestTestRerunFailed PROPERTIES + PASS_REGULAR_EXPRESSION "1/1 Test #1: TestTimeout" DEPENDS CTestTestTimeout + WORKING_DIRECTORY ${CMake_BINARY_DIR}/Tests/CTestTestTimeout) configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestZeroTimeout/test.cmake.in" @@ -2234,20 +2226,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFdSetSize/testOutput.log" ) - # Use macro, not function so that build can still be driven by CMake 2.4. - # After 2.6 is required, this could be a function without the extra 'set' - # calls. - # - macro(add_failed_submit_test name source build in out log regex) - # Have variables named source, build and drop_method because the - # configure_file call expects those variables to be defined. - # - set(source "${source}") - set(build "${build}") + function(add_failed_submit_test name source build in out log regex) configure_file("${in}" "${out}" @ONLY) add_test(${name} ${CMAKE_CTEST_COMMAND} -S "${out}" -V --output-log "${log}") set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}") - endmacro() + endfunction() set(regex "(Problems when submitting via S*CP") set(regex "${regex}|Error message was: ") diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt index 3674f0e..5d1b376 100644 --- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt +++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt @@ -19,8 +19,16 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile") configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY) # now set up the test: - get_target_property(cmakeExecutable cmake LOCATION) - + if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk" + CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n" + ) + else() + get_target_property(cmakeLocation cmake LOCATION) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk" + "CMAKE = \"${cmakeLocation}\"\n" + ) + endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY) diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in index f647901..c91d8a0 100644 --- a/Tests/FindPackageModeMakefileTest/Makefile.in +++ b/Tests/FindPackageModeMakefileTest/Makefile.in @@ -1,4 +1,6 @@ -CMAKE = "@cmakeExecutable@" + +include cmakeExecutable.mk + CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@" CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@" CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@" diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt index aec6ff9..1f5c93b 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt @@ -17,3 +17,31 @@ target_include_directories(upstream SYSTEM PUBLIC add_library(consumer consumer.cpp) target_link_libraries(consumer upstream) target_compile_options(consumer PRIVATE -Werror=unused-variable) + +add_library(iface IMPORTED INTERFACE) +set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/systemlib_header_only") + +add_library(imported_consumer imported_consumer.cpp) +target_link_libraries(imported_consumer iface) +target_compile_options(imported_consumer PRIVATE -Werror=unused-variable) + +macro(do_try_compile error_option) + set(TC_ARGS + IFACE_TRY_COMPILE_${error_option} + "${CMAKE_CURRENT_BINARY_DIR}/try_compile_iface" "${CMAKE_CURRENT_SOURCE_DIR}/imported_consumer.cpp" + LINK_LIBRARIES iface + ) + if (${error_option} STREQUAL WITH_ERROR) + list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable) + endif() + try_compile(${TC_ARGS}) +endmacro() + +do_try_compile(NO_ERROR) +if (NOT IFACE_TRY_COMPILE_NO_ERROR) + message(SEND_ERROR "try_compile failed with imported target.") +endif() +do_try_compile(WITH_ERROR) +if (NOT IFACE_TRY_COMPILE_WITH_ERROR) + message(SEND_ERROR "try_compile failed with imported target with error option.") +endif() diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp new file mode 100644 index 0000000..1dbe819 --- /dev/null +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp @@ -0,0 +1,7 @@ + +#include "systemlib.h" + +int main() +{ + return systemlib(); +} diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h new file mode 100644 index 0000000..93622c4 --- /dev/null +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib_header_only/systemlib.h @@ -0,0 +1,16 @@ + +#ifndef SYSTEMLIB_H +#define SYSTEMLIB_H + +int systemlib() +{ + return 0; +} + +int unusedFunc() +{ + int unused; + return systemlib(); +} + +#endif diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt index ae7627e..405dd8d 100644 --- a/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt +++ b/Tests/RunCMake/CMP0022/CMP0022-export-stderr.txt @@ -1,4 +1,4 @@ -CMake Error at CMP0022-export.cmake:11 \(export\): +CMake Error in CMakeLists.txt: Target "cmp0022NEW" has policy CMP0022 enabled, but also has old-style LINK_INTERFACE_LIBRARIES properties populated, but it was exported without the EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake new file mode 100644 index 0000000..650c8a5 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(someimportedlib SHARED IMPORTED) + +get_target_property(_loc someimportedlib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt new file mode 100644 index 0000000..2a05a4d --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at CMP0026-NEW.cmake:7 \(get_target_property\): + Policy CMP0026 is not set: Disallow use of the LOCATION target property. + Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy + command to set the policy and suppress this warning. + + The LOCATION property may not be read from target "somelib". Use the + target name directly with add_custom_command, or use the generator + expression \$<TARGET_FILE>, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake new file mode 100644 index 0000000..1659ffc --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake @@ -0,0 +1,7 @@ + +enable_language(CXX) + +cmake_policy(SET CMP0026 NEW) + +add_library(somelib empty.cpp) +get_target_property(_loc somelib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt new file mode 100644 index 0000000..9b88194 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt @@ -0,0 +1,12 @@ +CMake Warning \(dev\) at CMP0026-WARN.cmake:5 \(get_target_property\): + Policy CMP0026 is not set: Disallow use of the LOCATION target property. + Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy + command to set the policy and suppress this warning. + + The LOCATION property should not be read from target "somelib". Use the + target name directly with add_custom_command, or use the generator + expression \$<TARGET_FILE>, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake new file mode 100644 index 0000000..89c5a8a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_library(somelib empty.cpp) +get_target_property(_loc somelib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake new file mode 100644 index 0000000..68000a6 --- /dev/null +++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0026-WARN) +run_cmake(CMP0026-NEW) +run_cmake(CMP0026-IMPORTED) diff --git a/Tests/RunCMake/CMP0026/empty.cpp b/Tests/RunCMake/CMP0026/empty.cpp new file mode 100644 index 0000000..bfbbdde --- /dev/null +++ b/Tests/RunCMake/CMP0026/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 4fbc3b0..6d5b07b 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -53,6 +53,7 @@ endif() add_RunCMake_test(CMP0019) add_RunCMake_test(CMP0022) +add_RunCMake_test(CMP0026) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) diff --git a/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt b/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt index 67a0ae3..5658d85 100644 --- a/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt +++ b/Tests/RunCMake/ExportWithoutLanguage/NoLanguage-stderr.txt @@ -1,6 +1,4 @@ CMake Error: CMake can not determine linker language for target: NoLanguage -CMake Error at NoLanguage.cmake:2 \(export\): +CMake Error in CMakeLists.txt: Exporting the target "NoLanguage" is not allowed since its linker language cannot be determined -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExportWithoutLanguage/header.h b/Tests/RunCMake/ExportWithoutLanguage/header.h new file mode 100644 index 0000000..0c803ed --- /dev/null +++ b/Tests/RunCMake/ExportWithoutLanguage/header.h @@ -0,0 +1,2 @@ + +enum some_compilers { need_more_than_nothing }; diff --git a/Tests/RunCMake/include/CMP0024-NEW-stderr.txt b/Tests/RunCMake/include/CMP0024-NEW-stderr.txt index 182c67a..059d7e4 100644 --- a/Tests/RunCMake/include/CMP0024-NEW-stderr.txt +++ b/Tests/RunCMake/include/CMP0024-NEW-stderr.txt @@ -1,15 +1,12 @@ -CMake Error at CMP0024-NEW.cmake:9 \(include\): +CMake Error at subdir2/CMakeLists.txt:2 \(include\): Policy CMP0024 is not set: Disallow include export result. Run "cmake --help-policy CMP0024" for policy details. Use the cmake_policy command to set the policy and suppress this warning. The file - .*/Tests/RunCMake/include/CMP0024-NEW-build/theTargets.cmake + .*/Tests/RunCMake/include/CMP0024-NEW-build/subdir1/theTargets.cmake was generated by the export\(\) command. It may not be used as the argument to the include\(\) command. Use ALIAS targets instead to refer to targets by alternative names. - -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/include/CMP0024-NEW.cmake b/Tests/RunCMake/include/CMP0024-NEW.cmake index 0685d6c..0e03d2a 100644 --- a/Tests/RunCMake/include/CMP0024-NEW.cmake +++ b/Tests/RunCMake/include/CMP0024-NEW.cmake @@ -5,5 +5,5 @@ cmake_policy(SET CMP0024 NEW) add_library(foo SHARED empty.cpp) -export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") -include("${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") +add_subdirectory(subdir1) +add_subdirectory(subdir2) diff --git a/Tests/RunCMake/include/CMP0024-WARN-stderr.txt b/Tests/RunCMake/include/CMP0024-WARN-stderr.txt index 2b36f17..9c79007 100644 --- a/Tests/RunCMake/include/CMP0024-WARN-stderr.txt +++ b/Tests/RunCMake/include/CMP0024-WARN-stderr.txt @@ -1,16 +1,14 @@ -CMake Warning \(dev\) at CMP0024-WARN.cmake:7 \(include\): +CMake Warning \(dev\) at subdir2/CMakeLists.txt:2 \(include\): Policy CMP0024 is not set: Disallow include export result. Run "cmake --help-policy CMP0024" for policy details. Use the cmake_policy command to set the policy and suppress this warning. The file - .*/Tests/RunCMake/include/CMP0024-WARN-build/theTargets.cmake + .*/Tests/RunCMake/include/CMP0024-WARN-build/subdir1/theTargets.cmake was generated by the export\(\) command. It should not be used as the argument to the include\(\) command. Use ALIAS targets instead to refer to targets by alternative names. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/include/CMP0024-WARN.cmake b/Tests/RunCMake/include/CMP0024-WARN.cmake index 583c7d4..783cf78 100644 --- a/Tests/RunCMake/include/CMP0024-WARN.cmake +++ b/Tests/RunCMake/include/CMP0024-WARN.cmake @@ -3,5 +3,5 @@ enable_language(CXX) add_library(foo SHARED empty.cpp) -export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") -include("${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") +add_subdirectory(subdir1) +add_subdirectory(subdir2) diff --git a/Tests/RunCMake/include/subdir1/CMakeLists.txt b/Tests/RunCMake/include/subdir1/CMakeLists.txt new file mode 100644 index 0000000..11a76d1 --- /dev/null +++ b/Tests/RunCMake/include/subdir1/CMakeLists.txt @@ -0,0 +1,2 @@ + +export(TARGETS foo FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") diff --git a/Tests/RunCMake/include/subdir2/CMakeLists.txt b/Tests/RunCMake/include/subdir2/CMakeLists.txt new file mode 100644 index 0000000..7361f9c --- /dev/null +++ b/Tests/RunCMake/include/subdir2/CMakeLists.txt @@ -0,0 +1,2 @@ + +include("${CMAKE_CURRENT_BINARY_DIR}/../subdir1/theTargets.cmake") diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index bad8d63..31807ee 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -48,14 +48,12 @@ set(DOCBOOK_FILES ) macro(ADD_DOCS target dependency) - # Generate documentation for "ctest" executable. - get_target_property(CMD ${target} LOCATION) # only generate the documentation if the target is actually built - if(CMD) + if(${target}) add_custom_command( OUTPUT ${CMake_BINARY_DIR}/Docs/${target}.txt ${${target}-PATH} # Possibly set PATH, see below. - COMMAND ${CMD} + COMMAND $<TARGET_FILE:${target}> ARGS --help-full ${CMake_BINARY_DIR}/Docs/${target}.txt --help-full ${CMake_BINARY_DIR}/Docs/${target}.html --help-full ${CMake_BINARY_DIR}/Docs/${target}.1 @@ -92,10 +90,9 @@ ADD_DOCS(cmake-gui ${CMake_SOURCE_DIR}/Utilities/Doxygen/doxyfile.in) # add the documentation for cmake itself -get_target_property(CMD cmake LOCATION) add_custom_command( OUTPUT ${CMake_BINARY_DIR}/Docs/cmake.txt - COMMAND ${CMD} + COMMAND $<TARGET_FILE:cmake> ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt --help-full ${CMake_BINARY_DIR}/Docs/cmake.txt --help-full ${CMake_BINARY_DIR}/Docs/cmake.html |