| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- /*=========================================================================
- Program: Insight Segmentation & Registration Toolkit
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2001 Insight Consortium
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * The name of the Insight Consortium, nor the names of any consortium members,
- nor of any contributors, may be used to endorse or promote products derived
- from this software without specific prior written permission.
- * Modified source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- =========================================================================*/
- #include "cmake.h"
- #include "cmCacheManager.h"
- // include the generator
- #if defined(_WIN32) && !defined(__CYGWIN__)
- #include "cmMSProjectGenerator.h"
- #include "cmBorlandMakefileGenerator.h"
- #include "cmNMakeMakefileGenerator.h"
- #else
- #include "cmUnixMakefileGenerator.h"
- #endif
- cmake::cmake()
- {
- m_Verbose = false;
- m_UsePathTranslation = false;
- #if defined(_WIN32) && !defined(__CYGWIN__)
- cmMakefileGenerator::RegisterGenerator(new cmMSProjectGenerator);
- cmMakefileGenerator::RegisterGenerator(new cmNMakeMakefileGenerator);
- cmMakefileGenerator::RegisterGenerator(new cmBorlandMakefileGenerator);
- #else
- cmMakefileGenerator::RegisterGenerator(new cmUnixMakefileGenerator);
- #endif
- }
- void cmake::Usage(const char* program)
- {
- std::cerr << "cmake version " << cmMakefile::GetMajorVersion()
- << "." << cmMakefile::GetMinorVersion() << " - "
- << cmMakefile::GetReleaseVersion() << "\n";
- std::cerr << "Usage: " << program << " [srcdir] [outdir] [options]\n"
- << "Where cmake is run from the directory where you want the object files written. If srcdir is not specified, the current directory is used for both source and object files.\n";
- std::cerr << "If outdir is specified, pathname translation is enabled, and srcdir and outdir are used as given to access the roots of source and output directories.\n";
- std::cerr << "Options are:\n";
- std::cerr << "\n-i (puts cmake in wizard mode, not available for ccmake)\n";
- std::cerr << "\n-DVAR:TYPE=VALUE (create a cache file entry)\n";
- std::cerr << "\n-Cpath_to_initial_cache (a cmake list file that is used to pre-load the cache with values.)\n";
- std::cerr << "\n[-GgeneratorName] (where generator name can be one of these: ";
- std::vector<std::string> names;
- cmMakefileGenerator::GetRegisteredGenerators(names);
- for(std::vector<std::string>::iterator i =names.begin();
- i != names.end(); ++i)
- {
- std::cerr << "\"" << i->c_str() << "\" ";
- }
- std::cerr << ")\n";
- }
- // Parse the args
- void cmake::SetCacheArgs(cmMakefile& builder,
- const std::vector<std::string>& args)
- {
- for(unsigned int i=1; i < args.size(); ++i)
- {
- std::string arg = args[i];
- if(arg.find("-D",0) == 0)
- {
- std::string entry = arg.substr(2);
- std::string var, value;
- cmCacheManager::CacheEntryType type;
- if(cmCacheManager::ParseEntry(entry.c_str(), var, value, type))
- {
- cmCacheManager::GetInstance()->AddCacheEntry(
- var.c_str(),
- cmSystemTools::EscapeSpaces(value.c_str()).c_str(),
- "No help, variable specified on the command line.",
- type);
- }
- else
- {
- std::cerr << "Parse error in command line argument: " << arg << "\n"
- << "Should be: VAR:type=value\n";
- }
- }
- else if(arg.find("-C",0) == 0)
- {
- std::string path = arg.substr(2);
- std::cerr << "loading initial cache file " << path.c_str() << "\n";
- if(!builder.ReadListFile(path.c_str()))
- {
- std::cerr << "Error in reading cmake initial cache file:"
- << path.c_str() << "\n";
- }
- }
- }
- }
- // Parse the args
- void cmake::SetArgs(cmMakefile& builder, const std::vector<std::string>& args)
- {
- m_Local = false;
- bool directoriesSet = false;
- std::string srcdir;
- std::string outdir;
- for(unsigned int i=1; i < args.size(); ++i)
- {
- std::string arg = args[i];
- if(arg.find("-H",0) == 0)
- {
- directoriesSet = true;
- std::string path = arg.substr(2);
- if( cmSystemTools::CollapseFullPath(path.c_str()) != path &&
- path.size() > 0 && path[0] != '.' )
- {
- cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(path.c_str()), path );
- m_UsePathTranslation = true;
- }
- builder.SetHomeDirectory(path.c_str());
- }
- else if(arg.find("-S",0) == 0)
- {
- directoriesSet = true;
- m_Local = true;
- std::string path = arg.substr(2);
- builder.SetStartDirectory(path.c_str());
- }
- else if(arg.find("-O",0) == 0)
- {
- directoriesSet = true;
- std::string path = arg.substr(2);
- builder.SetStartOutputDirectory(path.c_str());
- }
- else if(arg.find("-B",0) == 0)
- {
- directoriesSet = true;
- std::string path = arg.substr(2);
- if( cmSystemTools::CollapseFullPath(path.c_str()) != path &&
- path.size() > 0 && path[0] != '.' )
- {
- cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(path.c_str()), path );
- m_UsePathTranslation = true;
- }
- builder.SetHomeOutputDirectory(path.c_str());
- }
- else if(arg.find("-V",0) == 0)
- {
- m_Verbose = true;
- }
- else if(arg.find("-D",0) == 0)
- {
- // skip for now
- }
- else if(arg.find("-C",0) == 0)
- {
- // skip for now
- }
- else if(arg.find("-G",0) == 0)
- {
- std::string value = arg.substr(2);
- cmMakefileGenerator* gen =
- cmMakefileGenerator::CreateGenerator(value.c_str());
- if(!gen)
- {
- cmSystemTools::Error("Could not create named generator ",
- value.c_str());
- }
- else
- {
- builder.SetMakefileGenerator(gen);
- }
- }
- // no option assume it is the path to the source or to the output
- else
- {
- if( srcdir.size() == 0 )
- {
- srcdir = arg;
- }
- else if( outdir.size() == 0 )
- {
- // Make sure the symbolic output directory specified matches
- // the current directory, and that the symbolic path is
- // absolute. Even if not, set the outdir variable so that
- // further attempts to set the output directory (with
- // another command line argument) fails.
- if( cmSystemTools::CollapseFullPath( arg.c_str() ) == cmSystemTools::GetCurrentWorkingDirectory() )
- {
- outdir = arg;
- if( srcdir.size() > 0 && srcdir[0] != '.' && outdir.size() > 0 && outdir[0] != '.' )
- {
- cmSystemTools::AddPathTranslation( cmSystemTools::GetCurrentWorkingDirectory(), outdir );
- cmSystemTools::AddPathTranslation( cmSystemTools::CollapseFullPath(srcdir.c_str()), srcdir );
- m_UsePathTranslation = true;
- }
- else
- {
- std::cerr << "Symbolic paths must be absolute for path translation. One of \"" << srcdir
- << "\" or \"" << outdir << "\" is not.\n"
- << "Not performing path name translation." << std::endl;
- outdir = cmSystemTools::GetCurrentWorkingDirectory();
- }
- }
- else
- {
- std::cerr << "The current working directory (" << cmSystemTools::GetCurrentWorkingDirectory() << ")\n"
- << "does not match the binary directory (" << (cmSystemTools::CollapseFullPath(arg.c_str())) << ")\n"
- << "[ given as " << arg << " ].\n"
- << "Not performing path name translation." << std::endl;
- outdir = cmSystemTools::GetCurrentWorkingDirectory();
- }
- }
- else
- {
- std::cerr << "Ignoring parameter " << arg << std::endl;
- }
- }
- }
- if(!directoriesSet)
- {
- if( srcdir.size() == 0 ) srcdir = cmSystemTools::GetCurrentWorkingDirectory();
- outdir = cmSystemTools::GetCurrentWorkingDirectory();
- srcdir = cmSystemTools::CollapseFullPath( srcdir.c_str() );
- builder.SetHomeOutputDirectory( outdir.c_str() );
- builder.SetStartOutputDirectory( outdir.c_str() );
- builder.SetHomeDirectory( srcdir.c_str() );
- builder.SetStartDirectory( srcdir.c_str() );
- }
- if (!m_Local)
- {
- builder.SetStartDirectory(builder.GetHomeDirectory());
- builder.SetStartOutputDirectory(builder.GetHomeOutputDirectory());
- }
- }
- // at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
- void cmake::AddCMakePaths(const std::vector<std::string>& args)
- {
- // Find our own executable. If path translations are enabled and the
- // user supplies the full path to cmake, use it as the canonical
- // name (i.e. don't translate to a local disk path).
- std::string cMakeSelf = args[0];
- cmSystemTools::ConvertToUnixSlashes(cMakeSelf);
- if(!(m_UsePathTranslation && cmSystemTools::FileExists(cMakeSelf.c_str()) && cMakeSelf[0]!='.'))
- cMakeSelf = cmSystemTools::FindProgram(cMakeSelf.c_str());
- if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
- {
- #ifdef CMAKE_BUILD_DIR
- cMakeSelf = CMAKE_BUILD_DIR;
- cMakeSelf += "/Source/cmake";
- #endif
- }
- #ifdef CMAKE_PREFIX
- if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
- {
- cMakeSelf = CMAKE_PREFIX "/bin/cmake";
- }
- #endif
- if(!cmSystemTools::FileExists(cMakeSelf.c_str()))
- {
- cmSystemTools::Error("CMAKE can not find the command line program cmake. "
- "Attempted path: ", cMakeSelf.c_str());
- return;
- }
- // Save the value in the cache
- cmCacheManager::GetInstance()->AddCacheEntry
- ("CMAKE_COMMAND",
- cmSystemTools::EscapeSpaces(cMakeSelf.c_str()).c_str(),
- "Path to CMake executable.",
- cmCacheManager::INTERNAL);
-
- // do CMAKE_ROOT, look for the environment variable first
- std::string cMakeRoot;
- std::string modules;
- if (getenv("CMAKE_ROOT"))
- {
- cMakeRoot = getenv("CMAKE_ROOT");
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
- if(!cmSystemTools::FileExists(modules.c_str()))
- {
- // next try exe/..
- cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
- std::string::size_type slashPos = cMakeRoot.rfind("/");
- if(slashPos != std::string::npos)
- {
- cMakeRoot = cMakeRoot.substr(0, slashPos);
- }
- // is there no Modules direcory there?
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
-
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try exe/../share/cmake
- cMakeRoot += "/share/CMake";
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
- #ifdef CMAKE_ROOT_DIR
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try compiled in root directory
- cMakeRoot = CMAKE_ROOT_DIR;
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
- #endif
- #ifdef CMAKE_PREFIX
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try compiled in install prefix
- cMakeRoot = CMAKE_PREFIX "/share/CMake";
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
- #endif
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // try
- cMakeRoot = cmSystemTools::GetProgramPath(cMakeSelf.c_str());
- cMakeRoot += "/share/CMake";
- modules = cMakeRoot + "/Modules/FindVTK.cmake";
- }
- if (!cmSystemTools::FileExists(modules.c_str()))
- {
- // couldn't find modules
- cmSystemTools::Error("Could not find CMAKE_ROOT !!!\n",
- "Modules directory not in directory:\n",
- modules.c_str());
- return;
- }
- cmCacheManager::GetInstance()->AddCacheEntry
- ("CMAKE_ROOT", cMakeRoot.c_str(),
- "Path to CMake installation.", cmCacheManager::INTERNAL);
- }
-
- int cmake::Generate(const std::vector<std::string>& args, bool buildMakefiles)
- {
- if(args.size() == 1 && !cmSystemTools::FileExists("CMakeLists.txt"))
- {
- this->Usage(args[0].c_str());
- return -1;
- }
- // look for obvious request for help
- for(unsigned int i=1; i < args.size(); ++i)
- {
- std::string arg = args[i];
- if(arg.find("-help",0) != std::string::npos ||
- arg.find("--help",0) != std::string::npos ||
- arg.find("/?",0) != std::string::npos ||
- arg.find("-usage",0) != std::string::npos)
- {
- this->Usage(args[0].c_str());
- return -1;
- }
- }
- // Create a makefile
- cmMakefile mf;
- // extract the directory arguments, could create a Generator
- this->SetArgs(mf, args);
- // Read and parse the input makefile
- mf.MakeStartDirectoriesCurrent();
- cmCacheManager::GetInstance()->LoadCache(&mf);
- // extract command line arguments that might add cache entries
- this->SetCacheArgs(mf, args);
- // no generator specified on the command line
- if(!mf.GetMakefileGenerator())
- {
- cmMakefileGenerator* gen;
- const char* genName = mf.GetDefinition("CMAKE_GENERATOR");
- if(genName)
- {
- gen = cmMakefileGenerator::CreateGenerator(genName);
- }
- else
- {
- #if defined(__BORLANDC__)
- gen = new cmBorlandMakefileGenerator;
- #elif defined(_WIN32) && !defined(__CYGWIN__)
- gen = new cmMSProjectGenerator;
- #else
- gen = new cmUnixMakefileGenerator;
- #endif
- }
- if(!gen)
- {
- cmSystemTools::Error("Could not create generator");
- return -1;
- }
- mf.SetMakefileGenerator(gen);
- // add the
- }
- cmMakefileGenerator* gen = mf.GetMakefileGenerator();
- gen->SetLocal(m_Local);
- if(!mf.GetDefinition("CMAKE_GENERATOR"))
- {
- mf.AddCacheDefinition("CMAKE_GENERATOR",
- gen->GetName(),
- "Name of generator.",
- cmCacheManager::INTERNAL);
- }
-
- // setup CMAKE_ROOT and CMAKE_COMMAND
- this->AddCMakePaths(args);
- // compute system info
- gen->ComputeSystemInfo();
- // Transfer the cache into the makefile's definitions.
- cmCacheManager::GetInstance()->DefineCache(&mf);
- std::string lf = mf.GetStartDirectory();
- lf += "/CMakeLists.txt";
- if(!mf.ReadListFile(lf.c_str()))
- {
- this->Usage(args[0].c_str());
- return -1;
- }
- // if buildMakefiles, then call GenerateMakefile
- if(buildMakefiles)
- {
- mf.GenerateMakefile();
- }
- else // do not build, but let the commands finalize
- {
- std::vector<cmMakefile*> makefiles;
- mf.FindSubDirectoryCMakeListsFiles(makefiles);
- for(std::vector<cmMakefile*>::iterator i = makefiles.begin();
- i != makefiles.end(); ++i)
- {
- cmMakefile* mf = *i;
- mf->FinalPass();
- delete mf;
- }
- mf.FinalPass();
- }
-
-
- // Before saving the cache
- // if the project did not define one of the entries below, add them now
- // so users can edit the values in the cache:
- // LIBRARY_OUTPUT_PATH
- // EXECUTABLE_OUTPUT_PATH
- if(!cmCacheManager::GetInstance()->GetCacheValue("LIBRARY_OUTPUT_PATH"))
- {
- cmCacheManager::GetInstance()->AddCacheEntry("LIBRARY_OUTPUT_PATH", "",
- "Single output directory for building all libraries.",
- cmCacheManager::PATH);
- }
- if(!cmCacheManager::GetInstance()->GetCacheValue("EXECUTABLE_OUTPUT_PATH"))
- {
- cmCacheManager::GetInstance()->AddCacheEntry("EXECUTABLE_OUTPUT_PATH", "",
- "Single output directory for building all executables.",
- cmCacheManager::PATH);
- }
-
- cmCacheManager::GetInstance()->SaveCache(&mf);
-
- if(m_Verbose)
- {
- cmCacheManager::GetInstance()->PrintCache(std::cout);
- }
-
- if(cmSystemTools::GetErrorOccuredFlag())
- {
- return -1;
- }
- return 0;
- }
|