From 31881265c7651af289e1ebbe20946ae78f067222 Mon Sep 17 00:00:00 2001 From: Alexander Neundorf Date: Wed, 19 Sep 2007 13:14:25 -0400 Subject: ENH: add new help option --help-custom-modules, which generates documentation for all modules found in CMAKE_MODULE_PATH, which currently has to be specified via -D, this can later on be improved e.g. by reading a special (to-be-created) file like CMakeFiles/ModulePath.cmake in the build tree so that running cmake help in the build tree of a project will always give you the current module path. (This could actually also help IDEs which would like to support cmake for projects...) Alex --- Source/cmDocumentation.cxx | 190 +++++++++++++++++++++++++++++++++----- Source/cmDocumentation.h | 19 +++- Source/cmDocumentationFormatter.h | 2 +- Source/cmakemain.cxx | 21 +++++ 4 files changed, 208 insertions(+), 24 deletions(-) diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 455d60e..7f8c101 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -62,6 +62,20 @@ static const cmDocumentationEntry cmModulesDocumentationDescription[] = }; //---------------------------------------------------------------------------- +static const cmDocumentationEntry cmCustomModulesDocumentationDescription[] = +{ + {0, + " Custom CMake Modules - Additional Modules for CMake.", 0}, +// CMAKE_DOCUMENTATION_OVERVIEW, + {0, + "This is the documentation for additional modules and scripts for CMake. " + "Using these modules you can check the computer system for " + "installed software packages, features of the compiler and the " + "existance of headers to name just a few.", 0}, + {0,0,0} +}; + +//---------------------------------------------------------------------------- static const cmDocumentationEntry cmPropertiesDocumentationDescription[] = { {0, @@ -167,6 +181,15 @@ static const cmDocumentationEntry cmDocumentationModulesHeader[] = }; //---------------------------------------------------------------------------- +static const cmDocumentationEntry cmDocumentationCustomModulesHeader[] = +{ + {0, + "The following modules are also available for CMake. " + "They can be used with INCLUDE(ModuleName).", 0}, + {0,0,0} +}; + +//---------------------------------------------------------------------------- static const cmDocumentationEntry cmDocumentationGeneratorsHeader[] = { {0, @@ -264,6 +287,7 @@ cmDocumentation::cmDocumentation() ,CompatCommandsSection("Compatibility Listfile Commands", "COMPATIBILITY COMMANDS") ,ModulesSection ("Standard CMake Modules", "MODULES") +,CustomModulesSection ("Custom CMake Modules", "CUSTOM MODULES") ,GeneratorsSection ("Generators", "GENERATORS") ,SeeAlsoSection ("See Also", "SEE ALSO") ,CopyrightSection ("Copyright", "COPYRIGHT") @@ -389,6 +413,8 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) return this->PrintDocumentationFull(os); case cmDocumentation::Modules: return this->PrintDocumentationModules(os); + case cmDocumentation::CustomModules: + return this->PrintDocumentationCustomModules(os); case cmDocumentation::Properties: return this->PrintDocumentationProperties(os); case cmDocumentation::Commands: @@ -414,30 +440,75 @@ bool cmDocumentation::CreateModulesSection() if (dir.GetNumberOfFiles() > 0) { this->ModulesSection.Append(cmDocumentationModulesHeader[0]); - for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i) + this->CreateModuleDocsForDir(dir, this->ModulesSection); + cmDocumentationEntry e = { 0, 0, 0 }; + this->ModulesSection.Append(e); + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmDocumentation::CreateCustomModulesSection() +{ + bool sectionHasHeader = false; + + std::vector dirs; + cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs); + + for(std::vector::const_iterator dirIt = dirs.begin(); + dirIt != dirs.end(); + ++dirIt) + { + cmsys::Directory dir; + dir.Load(dirIt->c_str()); + if (dir.GetNumberOfFiles() > 0) { - std::string fname = dir.GetFile(i); - if(fname.length() > 6) + if (!sectionHasHeader) { - if(fname.substr(fname.length()-6, 6) == ".cmake") + this->CustomModulesSection.Append(cmDocumentationCustomModulesHeader[0]); + sectionHasHeader = true; + } + this->CreateModuleDocsForDir(dir, this->CustomModulesSection); + } + } + + if(sectionHasHeader) + { + cmDocumentationEntry e = { 0, 0, 0 }; + this->CustomModulesSection.Append(e); + } + return true; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::CreateModuleDocsForDir(cmsys::Directory& dir, + cmSection &moduleSection) +{ + for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i) + { + std::string fname = dir.GetFile(i); + if(fname.length() > 6) + { + if(fname.substr(fname.length()-6, 6) == ".cmake") + { + std::string moduleName = fname.substr(0, fname.length()-6); + if (this->ModulesFound.find(moduleName) == this->ModulesFound.end()) { - std::string moduleName = fname.substr(0, fname.length()-6); - std::string path = cmakeModules; + this->ModulesFound.insert(moduleName); + std::string path = dir.GetPath(); path += "/"; path += fname; - this->CreateSingleModule(path.c_str(), moduleName.c_str()); + this->CreateSingleModule(path.c_str(), moduleName.c_str(), moduleSection); } } - } - cmDocumentationEntry e = { 0, 0, 0 }; - this->ModulesSection.Append(e); + } } - return true; } //---------------------------------------------------------------------------- bool cmDocumentation::CreateSingleModule(const char* fname, - const char* moduleName) + const char* moduleName, + cmSection &moduleSection) { std::ifstream fin(fname); if(!fin) @@ -513,7 +584,7 @@ bool cmDocumentation::CreateSingleModule(const char* fname, char* pbrief = strcpy(new char[brief.length()+1], brief.c_str()); this->ModuleStrings.push_back(pbrief); cmDocumentationEntry e = { pname, pbrief, ptext }; - this->ModulesSection.Append(e); + moduleSection.Append(e); return true; } } @@ -642,6 +713,12 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv) GET_OPT_ARGUMENT(help.Filename); help.HelpForm = this->GetFormFromFilename(help.Filename); } + else if(strcmp(argv[i], "--help-custom-modules") == 0) + { + help.HelpType = cmDocumentation::CustomModules; + GET_OPT_ARGUMENT(help.Filename); + help.HelpForm = this->GetFormFromFilename(help.Filename); + } else if(strcmp(argv[i], "--help-commands") == 0) { help.HelpType = cmDocumentation::Commands; @@ -914,22 +991,51 @@ bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os) os << "Argument --help-module needs a module name.\n"; return false; } - std::string cmakeModules = this->CMakeRoot; - cmakeModules += "/Modules/"; - cmakeModules += this->CurrentArgument; - cmakeModules += ".cmake"; - if(cmSystemTools::FileExists(cmakeModules.c_str()) - && this->CreateSingleModule(cmakeModules.c_str(), - this->CurrentArgument.c_str())) + + std::string moduleName; + // find the module + std::vector dirs; + cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs); + for(std::vector::const_iterator dirIt = dirs.begin(); + dirIt != dirs.end(); + ++dirIt) + { + moduleName = *dirIt; + moduleName += "/"; + moduleName += this->CurrentArgument; + moduleName += ".cmake"; + if(cmSystemTools::FileExists(moduleName.c_str())) + { + break; + } + moduleName = ""; + } + + if (moduleName.empty()) + { + moduleName = this->CMakeRoot; + moduleName += "/Modules/"; + moduleName += this->CurrentArgument; + moduleName += ".cmake"; + if(!cmSystemTools::FileExists(moduleName.c_str())) + { + moduleName = ""; + } + } + + if(!moduleName.empty() + && this->CreateSingleModule(moduleName.c_str(), + this->CurrentArgument.c_str(), + this->ModulesSection)) { this->PrintDocumentationCommand(os, this->ModulesSection.GetEntries()); os << "\n Defined in: "; - os << cmakeModules << "\n"; + os << moduleName << "\n"; return true; } // Argument was not a module. Complain. os << "Argument \"" << this->CurrentArgument.c_str() - << "\" to --help-module is not a CMake module."; + << "\" to --help-module is not a CMake module.\n"; return false; } @@ -1039,6 +1145,7 @@ bool cmDocumentation::PrintPropertyList(std::ostream& os) //---------------------------------------------------------------------------- bool cmDocumentation::PrintModuleList(std::ostream& os) { + this->CreateCustomModulesSection(); this->CreateModulesSection(); if(this->ModulesSection.IsEmpty()) { @@ -1053,6 +1160,19 @@ bool cmDocumentation::PrintModuleList(std::ostream& os) os << entry->name << std::endl; } } + + if(!this->CustomModulesSection.IsEmpty()) + { + os << "\nCUSTOM MODULES\n" << std::endl; + for(const cmDocumentationEntry* + entry = this->CustomModulesSection.GetEntries(); entry->brief; ++entry) + { + if(entry->name) + { + os << entry->name << std::endl; + } + } + } return true; } @@ -1085,6 +1205,16 @@ bool cmDocumentation::PrintDocumentationModules(std::ostream& os) } //---------------------------------------------------------------------------- +bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os) +{ + this->CreateCustomModulesDocumentation(); + this->CurrentFormatter->PrintHeader(GetNameString(), os); + this->Print(os); + this->CurrentFormatter->PrintFooter(os); + return true; +} + +//---------------------------------------------------------------------------- bool cmDocumentation::PrintDocumentationProperties(std::ostream& os) { this->CreatePropertiesDocumentation(); @@ -1141,6 +1271,7 @@ void cmDocumentation::CreateUsageDocumentation() void cmDocumentation::CreateFullDocumentation() { this->ClearSections(); + this->CreateCustomModulesSection(); this->CreateModulesSection(); this->AddSection(this->NameSection); this->AddSection(this->UsageSection); @@ -1212,6 +1343,21 @@ void cmDocumentation::CreateModulesDocumentation() } //---------------------------------------------------------------------------- +void cmDocumentation::CreateCustomModulesDocumentation() +{ + this->ClearSections(); + this->CreateCustomModulesSection(); + this->AddSection(this->DescriptionSection.GetName( + this->CurrentFormatter->GetForm()), + cmCustomModulesDocumentationDescription); + this->AddSection(this->CustomModulesSection); + this->AddSection(this->CopyrightSection.GetName( + this->CurrentFormatter->GetForm()), cmDocumentationCopyright); + this->AddSection(this->SeeAlsoSection.GetName( + this->CurrentFormatter->GetForm()), cmDocumentationStandardSeeAlso); +} + +//---------------------------------------------------------------------------- void cmDocumentation::CreatePropertiesDocumentation() { this->ClearSections(); diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 90e6e69..c6f5444 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -26,6 +26,11 @@ #include "cmDocumentationFormatterUsage.h" +namespace cmsys +{ + class Directory; +} + /** Class to generate documentation. */ class cmDocumentation: public cmDocumentationEnums { @@ -157,14 +162,21 @@ public: /** Set cmake root so we can find installed files */ void SetCMakeRoot(const char* root) { this->CMakeRoot = root;} + + /** Set CMAKE_MODULE_PATH so we can find additional cmake modules */ + void SetCMakeModulePath(const char* path) { this->CMakeModulePath = path;} static Form GetFormFromFilename(const std::string& filename); private: void SetForm(Form f); - bool CreateSingleModule(const char* fname, const char* moduleName); + bool CreateSingleModule(const char* fname, + const char* moduleName, + cmSection &moduleSection); + void CreateModuleDocsForDir(cmsys::Directory& dir, cmSection &moduleSection); bool CreateModulesSection(); + bool CreateCustomModulesSection(); bool PrintCopyright(std::ostream& os); bool PrintVersion(std::ostream& os); bool PrintDocumentationList(std::ostream& os); @@ -176,6 +188,7 @@ private: bool PrintDocumentationUsage(std::ostream& os); bool PrintDocumentationFull(std::ostream& os); bool PrintDocumentationModules(std::ostream& os); + bool PrintDocumentationCustomModules(std::ostream& os); bool PrintDocumentationProperties(std::ostream& os); bool PrintDocumentationCurrentCommands(std::ostream& os); bool PrintDocumentationCompatCommands(std::ostream& os); @@ -187,6 +200,7 @@ private: void CreateCurrentCommandsDocumentation(); void CreateCompatCommandsDocumentation(); void CreateModulesDocumentation(); + void CreateCustomModulesDocumentation(); void CreatePropertiesDocumentation(); void SetSection(const cmDocumentationEntry* header, @@ -204,6 +218,7 @@ private: cmSection CommandsSection; cmSection CompatCommandsSection; cmSection ModulesSection; + cmSection CustomModulesSection; cmSection GeneratorsSection; cmSection SeeAlsoSection; cmSection CopyrightSection; @@ -219,6 +234,8 @@ private: std::string SeeAlsoString; std::string CMakeRoot; + std::string CMakeModulePath; + std::set ModulesFound; std::vector< char* > ModuleStrings; std::vector< const char* > Names; std::vector< const cmDocumentationEntry* > Sections; diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h index a2e7801..c0bc646 100644 --- a/Source/cmDocumentationFormatter.h +++ b/Source/cmDocumentationFormatter.h @@ -32,7 +32,7 @@ public: enum Type { None, Usage, Single, SingleModule, SingleProperty, List, ModuleList, PropertyList, - Full, Properties, Modules, Commands, CompatCommands, + Full, Properties, Modules, CustomModules, Commands, CompatCommands, Copyright, Version }; /** Forms of documentation output. */ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 5413013..0717cf5 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -138,6 +138,12 @@ static const cmDocumentationEntry cmDocumentationOptions[] = "If a file is specified, the documentation is written into and the output " "format is determined depending on the filename suffix. Supported are man " "page, HTML and plain text."}, + {"--help-custom-modules [file]" , "Print help for all custom modules and " + "exit.", + "Full documentation for all custom modules is displayed. " + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML and plain text."}, {"--help-property prop [file]", "Print help for a single property and exit.", "Full documentation specific to the given module is displayed." @@ -277,6 +283,21 @@ int do_cmake(int ac, char** av) cmake hcm; hcm.AddCMakePaths(av[0]); doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT")); + + // the command line args are processed here so that you can do + // -DCMAKE_MODULE_PATH=/some/path and have this value accessible here + std::vector args; + for(int i =0; i < ac; ++i) + { + args.push_back(av[i]); + } + hcm.SetCacheArgs(args); + const char* modulePath = hcm.GetCacheDefinition("CMAKE_MODULE_PATH"); + if (modulePath) + { + doc.SetCMakeModulePath(modulePath); + } + std::vector commands; std::vector compatCommands; std::vector globalProperties; -- cgit v0.12