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}
};
//----------------------------------------------------------------------------
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[] =
{
@ -166,6 +180,15 @@ static const cmDocumentationEntry cmDocumentationModulesHeader[] =
{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[] =
{
@ -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)
{
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());
}
}
}
this->CreateModuleDocsForDir(dir, this->ModulesSection);
cmDocumentationEntry e = { 0, 0, 0 };
this->ModulesSection.Append(e);
}
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,
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<std::string> dirs;
cmSystemTools::ExpandListArgument(this->CMakeModulePath, dirs);
for(std::vector<std::string>::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;
}
@ -1084,6 +1204,16 @@ bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
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)
{
@ -1141,6 +1271,7 @@ void cmDocumentation::CreateUsageDocumentation()
void cmDocumentation::CreateFullDocumentation()
{
this->ClearSections();
this->CreateCustomModulesSection();
this->CreateModulesSection();
this->AddSection(this->NameSection);
this->AddSection(this->UsageSection);
@ -1211,6 +1342,21 @@ void cmDocumentation::CreateModulesDocumentation()
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()
{

View File

@ -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<std::string> ModulesFound;
std::vector< char* > ModuleStrings;
std::vector< const char* > Names;
std::vector< const cmDocumentationEntry* > Sections;

View File

@ -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. */

View File

@ -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<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> compatCommands;
std::vector<cmDocumentationEntry> globalProperties;