summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/CMakeLists.txt11
-rw-r--r--Source/cmEnableTestingCommand.cxx8
-rw-r--r--Source/cmGlobalGenerator.cxx26
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx18
-rw-r--r--Source/cmGlobalVisualStudio6Generator.h4
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx16
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h6
-rw-r--r--Source/cmLocalGenerator.cxx8
-rw-r--r--Source/cmLocalGenerator.h17
-rw-r--r--Source/cmLocalUnixMakefileGenerator.cxx29
-rw-r--r--Source/cmLocalUnixMakefileGenerator.h2
-rw-r--r--Source/cmMakefile.cxx18
-rw-r--r--Source/cmMakefile.h7
-rw-r--r--Source/cmSubdirCommand.cxx8
-rw-r--r--Source/cmSubdirCommand.h9
-rw-r--r--Tests/SubDir/Executable/test.cxx8
17 files changed, 146 insertions, 51 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 86e8627734..bff099f183 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -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
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
index 7381df8c92..05a65456b5 100644
--- a/Source/cmEnableTestingCommand.cxx
+++ b/Source/cmEnableTestingCommand.cxx
@@ -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;;
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index e22b82fcbe..b09ab9da04 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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;
+}
+
+
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 3f4b1e3f23..a22bc4c44f 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -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;
diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx
index 97789ea11a..13bfad6124 100644
--- a/Source/cmGlobalVisualStudio6Generator.cxx
+++ b/Source/cmGlobalVisualStudio6Generator.cxx
@@ -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);
}
}
diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h
index 0bf0cc2005..4aaa619e8b 100644
--- a/Source/cmGlobalVisualStudio6Generator.h
+++ b/Source/cmGlobalVisualStudio6Generator.h
@@ -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();
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index e302718862..9feb3b8c61 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -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
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 4cd5bc274f..d934ebe43a 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -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);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a108b13877..eea1b17e37 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index c7e1e203bd..a3017552c0 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -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
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx
index 936555ec80..3ca70d81d2 100644
--- a/Source/cmLocalUnixMakefileGenerator.cxx
+++ b/Source/cmLocalUnixMakefileGenerator.cxx
@@ -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());
- fout << target << "_" << subdir.c_str();
- if(ii == SubDirectories.size()-1)
+ if(!SubDirectories[ii].second)
{
- fout << " \n\n";
- }
- else
- {
- fout << " \\\n";
+ continue;
}
+ fout << " \\\n";
+ std::string subdir = FixDirectoryName(SubDirectories[ii].first.c_str());
+ fout << target << "_" << subdir.c_str();
}
+ 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)
diff --git a/Source/cmLocalUnixMakefileGenerator.h b/Source/cmLocalUnixMakefileGenerator.h
index 4cdb8b0957..ec44e54dc5 100644
--- a/Source/cmLocalUnixMakefileGenerator.h
+++ b/Source/cmLocalUnixMakefileGenerator.h
@@ -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);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f53b3bb108..cc1721c3e1 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -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);
}
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index faa49869e6..dbfe6a652c 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -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;
diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx
index 7fcf81417e..3bcd1a0e68 100644
--- a/Source/cmSubdirCommand.cxx
+++ b/Source/cmSubdirCommand.cxx
@@ -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
{
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index c5fda341fc..fce1985c6d 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -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);
diff --git a/Tests/SubDir/Executable/test.cxx b/Tests/SubDir/Executable/test.cxx
index 12913e8a22..f351521794 100644
--- a/Tests/SubDir/Executable/test.cxx
+++ b/Tests/SubDir/Executable/test.cxx
@@ -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)