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
This commit is contained in:
Alexander Neundorf 2007-09-19 13:14:25 -04:00
parent a581b64330
commit 31881265c7
4 changed files with 212 additions and 28 deletions

View File

@ -61,6 +61,20 @@ static const cmDocumentationEntry cmModulesDocumentationDescription[] =
{0,0,0} {0,0,0}
}; };
//----------------------------------------------------------------------------
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[] = static const cmDocumentationEntry cmPropertiesDocumentationDescription[] =
{ {
@ -166,6 +180,15 @@ static const cmDocumentationEntry cmDocumentationModulesHeader[] =
{0,0,0} {0,0,0}
}; };
//----------------------------------------------------------------------------
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[] = static const cmDocumentationEntry cmDocumentationGeneratorsHeader[] =
{ {
@ -264,6 +287,7 @@ cmDocumentation::cmDocumentation()
,CompatCommandsSection("Compatibility Listfile Commands", ,CompatCommandsSection("Compatibility Listfile Commands",
"COMPATIBILITY COMMANDS") "COMPATIBILITY COMMANDS")
,ModulesSection ("Standard CMake Modules", "MODULES") ,ModulesSection ("Standard CMake Modules", "MODULES")
,CustomModulesSection ("Custom CMake Modules", "CUSTOM MODULES")
,GeneratorsSection ("Generators", "GENERATORS") ,GeneratorsSection ("Generators", "GENERATORS")
,SeeAlsoSection ("See Also", "SEE ALSO") ,SeeAlsoSection ("See Also", "SEE ALSO")
,CopyrightSection ("Copyright", "COPYRIGHT") ,CopyrightSection ("Copyright", "COPYRIGHT")
@ -389,6 +413,8 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
return this->PrintDocumentationFull(os); return this->PrintDocumentationFull(os);
case cmDocumentation::Modules: case cmDocumentation::Modules:
return this->PrintDocumentationModules(os); return this->PrintDocumentationModules(os);
case cmDocumentation::CustomModules:
return this->PrintDocumentationCustomModules(os);
case cmDocumentation::Properties: case cmDocumentation::Properties:
return this->PrintDocumentationProperties(os); return this->PrintDocumentationProperties(os);
case cmDocumentation::Commands: case cmDocumentation::Commands:
@ -414,30 +440,75 @@ bool cmDocumentation::CreateModulesSection()
if (dir.GetNumberOfFiles() > 0) if (dir.GetNumberOfFiles() > 0)
{ {
this->ModulesSection.Append(cmDocumentationModulesHeader[0]); this->ModulesSection.Append(cmDocumentationModulesHeader[0]);
for(unsigned int i = 0; i < dir.GetNumberOfFiles(); ++i) this->CreateModuleDocsForDir(dir, this->ModulesSection);
{
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);
std::string path = cmakeModules;
path += "/";
path += fname;
this->CreateSingleModule(path.c_str(), moduleName.c_str());
}
}
}
cmDocumentationEntry e = { 0, 0, 0 }; cmDocumentationEntry e = { 0, 0, 0 };
this->ModulesSection.Append(e); this->ModulesSection.Append(e);
} }
return true; return true;
} }
//----------------------------------------------------------------------------
bool cmDocumentation::CreateCustomModulesSection()
{
bool sectionHasHeader = false;
std::vector<std::string> dirs;
cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
dirIt != dirs.end();
++dirIt)
{
cmsys::Directory dir;
dir.Load(dirIt->c_str());
if (dir.GetNumberOfFiles() > 0)
{
if (!sectionHasHeader)
{
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())
{
this->ModulesFound.insert(moduleName);
std::string path = dir.GetPath();
path += "/";
path += fname;
this->CreateSingleModule(path.c_str(), moduleName.c_str(), moduleSection);
}
}
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmDocumentation::CreateSingleModule(const char* fname, bool cmDocumentation::CreateSingleModule(const char* fname,
const char* moduleName) const char* moduleName,
cmSection &moduleSection)
{ {
std::ifstream fin(fname); std::ifstream fin(fname);
if(!fin) if(!fin)
@ -513,7 +584,7 @@ bool cmDocumentation::CreateSingleModule(const char* fname,
char* pbrief = strcpy(new char[brief.length()+1], brief.c_str()); char* pbrief = strcpy(new char[brief.length()+1], brief.c_str());
this->ModuleStrings.push_back(pbrief); this->ModuleStrings.push_back(pbrief);
cmDocumentationEntry e = { pname, pbrief, ptext }; cmDocumentationEntry e = { pname, pbrief, ptext };
this->ModulesSection.Append(e); moduleSection.Append(e);
return true; return true;
} }
} }
@ -642,6 +713,12 @@ bool cmDocumentation::CheckOptions(int argc, const char* const* argv)
GET_OPT_ARGUMENT(help.Filename); GET_OPT_ARGUMENT(help.Filename);
help.HelpForm = this->GetFormFromFilename(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) else if(strcmp(argv[i], "--help-commands") == 0)
{ {
help.HelpType = cmDocumentation::Commands; help.HelpType = cmDocumentation::Commands;
@ -914,22 +991,51 @@ bool cmDocumentation::PrintDocumentationSingleModule(std::ostream& os)
os << "Argument --help-module needs a module name.\n"; os << "Argument --help-module needs a module name.\n";
return false; return false;
} }
std::string cmakeModules = this->CMakeRoot;
cmakeModules += "/Modules/"; std::string moduleName;
cmakeModules += this->CurrentArgument; // find the module
cmakeModules += ".cmake"; std::vector<std::string> dirs;
if(cmSystemTools::FileExists(cmakeModules.c_str()) cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
&& this->CreateSingleModule(cmakeModules.c_str(), for(std::vector<std::string>::const_iterator dirIt = dirs.begin();
this->CurrentArgument.c_str())) 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()); this->PrintDocumentationCommand(os, this->ModulesSection.GetEntries());
os << "\n Defined in: "; os << "\n Defined in: ";
os << cmakeModules << "\n"; os << moduleName << "\n";
return true; return true;
} }
// Argument was not a module. Complain. // Argument was not a module. Complain.
os << "Argument \"" << this->CurrentArgument.c_str() 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; return false;
} }
@ -1039,6 +1145,7 @@ bool cmDocumentation::PrintPropertyList(std::ostream& os)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmDocumentation::PrintModuleList(std::ostream& os) bool cmDocumentation::PrintModuleList(std::ostream& os)
{ {
this->CreateCustomModulesSection();
this->CreateModulesSection(); this->CreateModulesSection();
if(this->ModulesSection.IsEmpty()) if(this->ModulesSection.IsEmpty())
{ {
@ -1053,6 +1160,19 @@ bool cmDocumentation::PrintModuleList(std::ostream& os)
os << entry->name << std::endl; 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; return true;
} }
@ -1084,6 +1204,16 @@ bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
return true; return true;
} }
//----------------------------------------------------------------------------
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) bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
{ {
@ -1141,6 +1271,7 @@ void cmDocumentation::CreateUsageDocumentation()
void cmDocumentation::CreateFullDocumentation() void cmDocumentation::CreateFullDocumentation()
{ {
this->ClearSections(); this->ClearSections();
this->CreateCustomModulesSection();
this->CreateModulesSection(); this->CreateModulesSection();
this->AddSection(this->NameSection); this->AddSection(this->NameSection);
this->AddSection(this->UsageSection); this->AddSection(this->UsageSection);
@ -1211,6 +1342,21 @@ void cmDocumentation::CreateModulesDocumentation()
this->CurrentFormatter->GetForm()), cmDocumentationStandardSeeAlso); this->CurrentFormatter->GetForm()), cmDocumentationStandardSeeAlso);
} }
//----------------------------------------------------------------------------
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() void cmDocumentation::CreatePropertiesDocumentation()
{ {

View File

@ -26,6 +26,11 @@
#include "cmDocumentationFormatterUsage.h" #include "cmDocumentationFormatterUsage.h"
namespace cmsys
{
class Directory;
}
/** Class to generate documentation. */ /** Class to generate documentation. */
class cmDocumentation: public cmDocumentationEnums class cmDocumentation: public cmDocumentationEnums
{ {
@ -157,14 +162,21 @@ public:
/** Set cmake root so we can find installed files */ /** Set cmake root so we can find installed files */
void SetCMakeRoot(const char* root) { this->CMakeRoot = root;} 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); static Form GetFormFromFilename(const std::string& filename);
private: private:
void SetForm(Form f); 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 CreateModulesSection();
bool CreateCustomModulesSection();
bool PrintCopyright(std::ostream& os); bool PrintCopyright(std::ostream& os);
bool PrintVersion(std::ostream& os); bool PrintVersion(std::ostream& os);
bool PrintDocumentationList(std::ostream& os); bool PrintDocumentationList(std::ostream& os);
@ -176,6 +188,7 @@ private:
bool PrintDocumentationUsage(std::ostream& os); bool PrintDocumentationUsage(std::ostream& os);
bool PrintDocumentationFull(std::ostream& os); bool PrintDocumentationFull(std::ostream& os);
bool PrintDocumentationModules(std::ostream& os); bool PrintDocumentationModules(std::ostream& os);
bool PrintDocumentationCustomModules(std::ostream& os);
bool PrintDocumentationProperties(std::ostream& os); bool PrintDocumentationProperties(std::ostream& os);
bool PrintDocumentationCurrentCommands(std::ostream& os); bool PrintDocumentationCurrentCommands(std::ostream& os);
bool PrintDocumentationCompatCommands(std::ostream& os); bool PrintDocumentationCompatCommands(std::ostream& os);
@ -187,6 +200,7 @@ private:
void CreateCurrentCommandsDocumentation(); void CreateCurrentCommandsDocumentation();
void CreateCompatCommandsDocumentation(); void CreateCompatCommandsDocumentation();
void CreateModulesDocumentation(); void CreateModulesDocumentation();
void CreateCustomModulesDocumentation();
void CreatePropertiesDocumentation(); void CreatePropertiesDocumentation();
void SetSection(const cmDocumentationEntry* header, void SetSection(const cmDocumentationEntry* header,
@ -204,6 +218,7 @@ private:
cmSection CommandsSection; cmSection CommandsSection;
cmSection CompatCommandsSection; cmSection CompatCommandsSection;
cmSection ModulesSection; cmSection ModulesSection;
cmSection CustomModulesSection;
cmSection GeneratorsSection; cmSection GeneratorsSection;
cmSection SeeAlsoSection; cmSection SeeAlsoSection;
cmSection CopyrightSection; cmSection CopyrightSection;
@ -219,6 +234,8 @@ private:
std::string SeeAlsoString; std::string SeeAlsoString;
std::string CMakeRoot; std::string CMakeRoot;
std::string CMakeModulePath;
std::set<std::string> ModulesFound;
std::vector< char* > ModuleStrings; std::vector< char* > ModuleStrings;
std::vector< const char* > Names; std::vector< const char* > Names;
std::vector< const cmDocumentationEntry* > Sections; std::vector< const cmDocumentationEntry* > Sections;

View File

@ -32,7 +32,7 @@ public:
enum Type enum Type
{ None, Usage, Single, SingleModule, SingleProperty, { None, Usage, Single, SingleModule, SingleProperty,
List, ModuleList, PropertyList, List, ModuleList, PropertyList,
Full, Properties, Modules, Commands, CompatCommands, Full, Properties, Modules, CustomModules, Commands, CompatCommands,
Copyright, Version }; Copyright, Version };
/** Forms of documentation output. */ /** Forms of documentation output. */

View File

@ -138,6 +138,12 @@ static const cmDocumentationEntry cmDocumentationOptions[] =
"If a file is specified, the documentation is written into and the output " "If a file is specified, the documentation is written into and the output "
"format is determined depending on the filename suffix. Supported are man " "format is determined depending on the filename suffix. Supported are man "
"page, HTML and plain text."}, "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]", {"--help-property prop [file]",
"Print help for a single property and exit.", "Print help for a single property and exit.",
"Full documentation specific to the given module is displayed." "Full documentation specific to the given module is displayed."
@ -277,6 +283,21 @@ int do_cmake(int ac, char** av)
cmake hcm; cmake hcm;
hcm.AddCMakePaths(av[0]); hcm.AddCMakePaths(av[0]);
doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT")); 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<std::string> 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<cmDocumentationEntry> commands; std::vector<cmDocumentationEntry> commands;
std::vector<cmDocumentationEntry> compatCommands; std::vector<cmDocumentationEntry> compatCommands;
std::vector<cmDocumentationEntry> globalProperties; std::vector<cmDocumentationEntry> globalProperties;