ENH: add new subdirectory exclude from top option

This commit is contained in:
Bill Hoffman 2004-03-09 16:28:44 -05:00
parent bf699505bc
commit ddb815c125
17 changed files with 147 additions and 52 deletions

View File

@ -550,6 +550,17 @@ IF(BUILD_TESTING)
--test-command test1
)
ADD_TEST(SubDir ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/SubDir"
"${CMake_BINARY_DIR}/Tests/SubDir"
--build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${MAKEPROGRAM}
--build-project SUBDIR
--test-command test "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
)
IF (APPLE)
ADD_TEST(objc++ ${CMAKE_CTEST_COMMAND}
--build-and-test

View File

@ -63,13 +63,13 @@ void cmEnableTestingCommand::FinalPass()
if (!m_Makefile->GetSubDirectories().empty())
{
fout << "SUBDIRS(";
const std::vector<std::string>& subdirs = m_Makefile->GetSubDirectories();
std::vector<std::string>::const_iterator i = subdirs.begin();
fout << (*i).c_str();
const std::vector<std::pair<cmStdString, bool> >& subdirs = m_Makefile->GetSubDirectories();
std::vector<std::pair<cmStdString, bool> >::const_iterator i = subdirs.begin();
fout << (*i).first.c_str();
++i;
for(; i != subdirs.end(); ++i)
{
fout << " " << (*i).c_str();
fout << " " << i->first.c_str();
}
fout << ")" << std::endl << std::endl;;
}

View File

@ -367,7 +367,7 @@ void cmGlobalGenerator::RecursiveConfigure(cmLocalGenerator *lg,
lg->Configure();
// get all the subdirectories
std::vector<std::string> subdirs = lg->GetMakefile()->GetSubDirectories();
std::vector<std::pair<cmStdString, bool> > subdirs = lg->GetMakefile()->GetSubDirectories();
float progressPiece = (endProgress - startProgress)/(1.0f+subdirs.size());
m_CMakeInstance->UpdateProgress("Configuring",
startProgress + progressPiece);
@ -377,18 +377,19 @@ void cmGlobalGenerator::RecursiveConfigure(cmLocalGenerator *lg,
for (i = 0; i < subdirs.size(); ++i)
{
cmLocalGenerator *lg2 = this->CreateLocalGenerator();
lg2->SetParent(lg);
m_LocalGenerators.push_back(lg2);
// add the subdir to the start output directory
std::string outdir = lg->GetMakefile()->GetStartOutputDirectory();
outdir += "/";
outdir += subdirs[i];
outdir += subdirs[i].first;
lg2->GetMakefile()->SetStartOutputDirectory(outdir.c_str());
lg2->SetExcludeAll(!subdirs[i].second);
// add the subdir to the start source directory
std::string currentDir = lg->GetMakefile()->GetStartDirectory();
currentDir += "/";
currentDir += subdirs[i];
currentDir += subdirs[i].first;
lg2->GetMakefile()->SetStartDirectory(currentDir.c_str());
lg2->GetMakefile()->MakeStartDirectoriesCurrent();
@ -537,3 +538,20 @@ void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
entry.brief = "";
entry.full = "";
}
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
cmLocalGenerator* gen)
{
cmLocalGenerator* cur = gen->GetParent();
while(cur && cur != root)
{
if(cur->GetExcludeAll())
{
return true;
}
cur = cur->GetParent();
}
return false;
}

View File

@ -106,6 +106,8 @@ public:
bool GetForceUnixPaths() {return m_ForceUnixPaths;}
protected:
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
bool m_ForceUnixPaths;
cmStdString m_FindMakeProgramFile;
cmStdString m_ConfiguredFilesPath;

View File

@ -201,8 +201,10 @@ void cmGlobalVisualStudio6Generator::CollectSubprojects()
}
}
// Write a DSW file to the stream
void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
// Write out the header for a DSW file
@ -215,8 +217,13 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout,
unsigned int i;
bool doneAllBuild = false;
bool doneRunTests = false;
for(i = 0; i < generators.size(); ++i)
{
if(this->IsExcluded(root, generators[i]))
{
continue;
}
cmMakefile* mf = generators[i]->GetMakefile();
// Get the source directory from the makefile
@ -324,15 +331,16 @@ void cmGlobalVisualStudio6Generator::WriteDSWFile(std::ostream& fout,
this->WriteDSWFooter(fout);
}
void cmGlobalVisualStudio6Generator::OutputDSWFile(std::vector<cmLocalGenerator*>& generators)
void cmGlobalVisualStudio6Generator::OutputDSWFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
if(generators.size() == 0)
{
return;
}
std::string fname = generators[0]->GetMakefile()->GetStartOutputDirectory();
std::string fname = root->GetMakefile()->GetStartOutputDirectory();
fname += "/";
fname += generators[0]->GetMakefile()->GetProjectName();
fname += root->GetMakefile()->GetProjectName();
fname += ".dsw";
std::ofstream fout(fname.c_str());
if(!fout)
@ -341,7 +349,7 @@ void cmGlobalVisualStudio6Generator::OutputDSWFile(std::vector<cmLocalGenerator*
fname.c_str());
return;
}
this->WriteDSWFile(fout, generators);
this->WriteDSWFile(fout, root, generators);
}
// output the DSW file
@ -350,7 +358,7 @@ void cmGlobalVisualStudio6Generator::OutputDSWFile()
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_SubProjectMap.begin(); it!= m_SubProjectMap.end(); ++it)
{
this->OutputDSWFile(it->second);
this->OutputDSWFile(it->second[0], it->second);
}
}

View File

@ -68,8 +68,10 @@ public:
* Generate the DSW workspace file.
*/
virtual void OutputDSWFile();
virtual void OutputDSWFile(std::vector<cmLocalGenerator*>& generators);
virtual void OutputDSWFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteDSWFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
private:
void CollectSubprojects();

View File

@ -269,15 +269,16 @@ void cmGlobalVisualStudio7Generator::Generate()
this->OutputSLNFile();
}
void cmGlobalVisualStudio7Generator::OutputSLNFile(std::vector<cmLocalGenerator*>& generators)
void cmGlobalVisualStudio7Generator::OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
if(generators.size() == 0)
{
return;
}
std::string fname = generators[0]->GetMakefile()->GetStartOutputDirectory();
std::string fname = root->GetMakefile()->GetStartOutputDirectory();
fname += "/";
fname += generators[0]->GetMakefile()->GetProjectName();
fname += root->GetMakefile()->GetProjectName();
fname += ".sln";
std::ofstream fout(fname.c_str());
if(!fout)
@ -286,7 +287,7 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile(std::vector<cmLocalGenerator*
fname.c_str());
return;
}
this->WriteSLNFile(fout, generators);
this->WriteSLNFile(fout, root, generators);
}
// output the SLN file
@ -295,13 +296,14 @@ void cmGlobalVisualStudio7Generator::OutputSLNFile()
std::map<cmStdString, std::vector<cmLocalGenerator*> >::iterator it;
for(it = m_SubProjectMap.begin(); it!= m_SubProjectMap.end(); ++it)
{
this->OutputSLNFile(it->second);
this->OutputSLNFile(it->second[0], it->second);
}
}
// Write a SLN file to the stream
void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
// Write out the header for a SLN file
@ -318,6 +320,10 @@ void cmGlobalVisualStudio7Generator::WriteSLNFile(std::ostream& fout,
unsigned int i;
for(i = 0; i < generators.size(); ++i)
{
if(this->IsExcluded(root, generators[i]))
{
continue;
}
cmMakefile* mf = generators[i]->GetMakefile();
// Get the source directory from the makefile

View File

@ -83,8 +83,10 @@ public:
protected:
void CollectSubprojects();
virtual void OutputSLNFile(std::vector<cmLocalGenerator*>& generators);
virtual void WriteSLNFile(std::ostream& fout, std::vector<cmLocalGenerator*>& generators);
virtual void OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteProject(std::ostream& fout,
const char* name, const char* path,
const cmTarget &t);

View File

@ -24,6 +24,8 @@ cmLocalGenerator::cmLocalGenerator()
{
m_Makefile = new cmMakefile;
m_Makefile->SetLocalGenerator(this);
m_ExcludeFromAll = false;
m_Parent = 0;
}
cmLocalGenerator::~cmLocalGenerator()
@ -229,12 +231,12 @@ void cmLocalGenerator::GenerateInstallRules()
cmMakefile* mf = this->GetMakefile();
if ( !mf->GetSubDirectories().empty() )
{
const std::vector<std::string>& subdirs = mf->GetSubDirectories();
std::vector<std::string>::const_iterator i = subdirs.begin();
const std::vector<std::pair<cmStdString, bool> >& subdirs = mf->GetSubDirectories();
std::vector<std::pair<cmStdString, bool> >::const_iterator i = subdirs.begin();
for(; i != subdirs.end(); ++i)
{
std::string odir = mf->GetCurrentOutputDirectory();
odir += "/" + (*i);
odir += "/" + (*i).first;
cmSystemTools::ConvertToUnixSlashes(odir);
fout << "INCLUDE(" << odir.c_str()
<< "/cmake_install.cmake)" << std::endl;

View File

@ -78,6 +78,20 @@ public:
virtual const char* GetSafeDefinition(const char*);
std::string ConvertToRelativeOutputPath(const char* p);
// flag to determine if this project should be included in a parent project
bool GetExcludeAll()
{
return m_ExcludeFromAll;
}
void SetExcludeAll(bool b)
{
m_ExcludeFromAll = b;
}
///! set/get the parent generator
cmLocalGenerator* GetParent(){return m_Parent;}
void SetParent(cmLocalGenerator* g) { m_Parent = g;}
protected:
virtual void AddInstallRule(std::ostream& fout, const char* dest, int type,
const char* files, bool optional = false);
@ -92,7 +106,8 @@ protected:
std::string m_HomeOutputDirectory;
std::string m_HomeDirectory;
std::string m_HomeOutputDirectoryNoSlash;
bool m_ExcludeFromAll;
cmLocalGenerator* m_Parent;
};
#endif

View File

@ -1996,7 +1996,7 @@ OutputSubDirectoryVars(std::ostream& fout,
const char* target1,
const char* target2,
const char* depend,
const std::vector<std::string>& SubDirectories,
const std::vector<std::pair<cmStdString, bool> >& SubDirectories,
bool silent)
{
if(!depend)
@ -2008,26 +2008,29 @@ OutputSubDirectoryVars(std::ostream& fout,
return;
}
fout << "# Variable for making " << target << " in subdirectories.\n";
fout << var << " = \\\n";
fout << var << " = ";
unsigned int ii;
for(ii =0; ii < SubDirectories.size(); ii++)
{
std::string subdir = FixDirectoryName(SubDirectories[ii].c_str());
if(!SubDirectories[ii].second)
{
continue;
}
fout << " \\\n";
std::string subdir = FixDirectoryName(SubDirectories[ii].first.c_str());
fout << target << "_" << subdir.c_str();
if(ii == SubDirectories.size()-1)
{
fout << " \n\n";
}
else
{
fout << " \\\n";
}
}
fout << " \n\n";
fout << "# Targets for making " << target << " in subdirectories.\n";
std::string last = "";
for(unsigned int cc =0; cc < SubDirectories.size(); cc++)
{
std::string subdir = FixDirectoryName(SubDirectories[cc].c_str());
if(!SubDirectories[cc].second)
{
continue;
}
std::string subdir = FixDirectoryName(SubDirectories[cc].first.c_str());
fout << target << "_" << subdir.c_str() << ": " << depend;
// Make each subdirectory depend on previous one. This forces
@ -2042,7 +2045,7 @@ OutputSubDirectoryVars(std::ostream& fout,
last = subdir;
std::string dir = m_Makefile->GetCurrentOutputDirectory();
dir += "/";
dir += SubDirectories[cc];
dir += SubDirectories[cc].first;
this->BuildInSubDirectory(fout, dir.c_str(),
target1, target2, silent);
}
@ -2054,7 +2057,7 @@ OutputSubDirectoryVars(std::ostream& fout,
void cmLocalUnixMakefileGenerator::OutputSubDirectoryRules(std::ostream& fout)
{
// Output Sub directory build rules
const std::vector<std::string>& SubDirectories
const std::vector<std::pair<cmStdString, bool> >& SubDirectories
= m_Makefile->GetSubDirectories();
if( SubDirectories.size() == 0)

View File

@ -159,7 +159,7 @@ protected:
const char* target1,
const char* target2,
const char* depend,
const std::vector<std::string>&
const std::vector<std::pair<cmStdString, bool> >&
SubDirectories,
bool silent = false);

View File

@ -142,6 +142,17 @@ void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>
std::cout << " )\n";
}
void cmMakefile::PrintStringVector(const char* s, const std::vector<std::pair<cmStdString, bool> >& v) const
{
std::cout << s << ": ( \n";
for(std::vector<std::pair<cmStdString, bool> >::const_iterator i = v.begin();
i != v.end(); ++i)
{
std::cout << i->first.c_str() << " " << i->second;
}
std::cout << " )\n";
}
// call print on all the classes in the makefile
void cmMakefile::Print() const
@ -824,13 +835,14 @@ void cmMakefile::AddLinkDirectory(const char* dir)
}
}
void cmMakefile::AddSubDirectory(const char* sub)
void cmMakefile::AddSubDirectory(const char* sub, bool topLevel)
{
std::pair<cmStdString, bool> p(sub, topLevel);
// make sure it isn't already there
if (std::find(m_SubDirectories.begin(),
m_SubDirectories.end(), sub) == m_SubDirectories.end())
m_SubDirectories.end(), p) == m_SubDirectories.end())
{
m_SubDirectories.push_back(sub);
m_SubDirectories.push_back(p);
}
}

View File

@ -203,7 +203,7 @@ public:
/**
* Add a subdirectory to the build.
*/
void AddSubDirectory(const char*);
void AddSubDirectory(const char*, bool includeTopLevel=true);
/**
* Add an include directory to the build.
@ -409,7 +409,7 @@ public:
/**
* Get a list of the build subdirectories.
*/
const std::vector<std::string>& GetSubDirectories()
const std::vector<std::pair<cmStdString, bool> >& GetSubDirectories()
{
return m_SubDirectories;
}
@ -658,7 +658,7 @@ protected:
cmTargets m_Targets;
std::vector<cmSourceFile*> m_SourceFiles;
std::vector<std::string> m_SubDirectories; // list of sub directories
std::vector<std::pair<cmStdString, bool> > m_SubDirectories; // list of sub directories
struct StringSet : public std::set<cmStdString>
{
};
@ -695,6 +695,7 @@ private:
void ReadSources(std::ifstream& fin, bool t);
friend class cmMakeDepend; // make depend needs direct access
// to the m_Sources array
void PrintStringVector(const char* s, const std::vector<std::pair<cmStdString, bool> >& v) const;
void PrintStringVector(const char* s, const std::vector<std::string>& v) const;
void AddDefaultDefinitions();
std::list<cmFunctionBlocker *> m_FunctionBlockers;

View File

@ -25,15 +25,21 @@ bool cmSubdirCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
bool res = true;
bool intoplevel = true;
for(std::vector<std::string>::const_iterator i = args.begin();
i != args.end(); ++i)
{
if(*i == "EXCLUDE_FROM_ALL")
{
intoplevel = false;
continue;
}
std::string directory = std::string(m_Makefile->GetCurrentDirectory()) +
"/" + i->c_str();
if ( cmSystemTools::FileIsDirectory(directory.c_str()) )
{
m_Makefile->AddSubDirectory(i->c_str());
m_Makefile->AddSubDirectory(i->c_str(), intoplevel);
}
else
{

View File

@ -62,10 +62,15 @@ public:
virtual const char* GetFullDocumentation()
{
return
" SUBDIRS(dir1 dir2 ...)\n"
" SUBDIRS(dir1 dir2 ...[EXCLUDE_FROM_ALL exclude_dir1 exclude_dir2 ...])\n"
"Add a list of subdirectories to the build. "
"This will cause any CMakeLists.txt files in the sub directories "
"to be processed by CMake.";
"to be processed by CMake. Any directories after the EXCLUDE_FROM_ALL marker "
"will not be included in the top level makefile or project file. This is useful"
" for having cmake create makefiles or projects for a set of examples in a project."
"You would want cmake to generated makefiles or project files for all the examples at"
" the same time, but you would not want them to show up in the top level project or be built"
" each time make is run from the top.";
}
cmTypeMacro(cmSubdirCommand, cmCommand);

View File

@ -1,8 +1,10 @@
#include <stdio.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
// return true if the file exists
int FileExists(const char* filename)