2001-05-18 23:25:08 +04:00
/*=========================================================================
2002-10-24 02:03:27 +04:00
Program : CMake - Cross - Platform Makefile Generator
2001-05-18 23:25:08 +04:00
Module : $ RCSfile $
Language : C + +
Date : $ Date $
Version : $ Revision $
2002-10-24 02:03:27 +04:00
Copyright ( c ) 2002 Kitware , Inc . , Insight Consortium . All rights reserved .
See Copyright . txt or http : //www.cmake.org/HTML/Copyright.html for details.
2001-05-18 23:25:08 +04:00
2002-01-21 23:30:43 +03:00
This software is distributed WITHOUT ANY WARRANTY ; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE . See the above copyright notices for more information .
2001-05-18 23:25:08 +04:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "cmake.h"
2002-06-03 21:08:52 +04:00
# include "time.h"
2001-05-18 23:25:08 +04:00
# include "cmCacheManager.h"
2002-09-06 21:06:23 +04:00
# include "cmMakefile.h"
# include "cmLocalGenerator.h"
2002-09-11 00:51:29 +04:00
# include "cmCommands.h"
# include "cmCommand.h"
2003-01-08 20:59:52 +03:00
# include "cmVariableWatch.h"
2001-05-18 23:25:08 +04:00
// include the generator
# if defined(_WIN32) && !defined(__CYGWIN__)
2002-09-06 21:06:23 +04:00
# include "cmGlobalVisualStudio6Generator.h"
2003-08-22 00:22:23 +04:00
# if !defined(__MINGW32__)
2002-09-06 21:06:23 +04:00
# include "cmGlobalVisualStudio7Generator.h"
2003-05-09 00:59:27 +04:00
# include "cmGlobalVisualStudio71Generator.h"
2003-08-22 00:22:23 +04:00
# endif
2002-09-06 21:06:23 +04:00
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
2003-08-22 00:22:23 +04:00
# include "cmGlobalUnixMakefileGenerator.h"
2002-09-28 01:28:15 +04:00
# include "cmWin32ProcessExecution.h"
2001-05-18 23:25:08 +04:00
# else
2002-09-06 21:06:23 +04:00
# include "cmGlobalUnixMakefileGenerator.h"
2001-05-21 17:50:24 +04:00
# endif
2003-05-24 00:40:55 +04:00
# include <stdlib.h> // required for atoi
2002-09-11 01:24:25 +04:00
2002-10-24 23:39:25 +04:00
# ifdef __APPLE__
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
2003-04-16 23:40:24 +04:00
# if defined(CMAKE_BUILD_WITH_CMAKE)
2003-04-16 22:47:44 +04:00
# include "cmGlobalCodeWarriorGenerator.h"
2002-10-24 23:39:25 +04:00
# endif
2003-04-16 23:40:24 +04:00
# endif
2002-10-24 23:39:25 +04:00
2003-01-09 16:47:17 +03:00
void cmNeedBackwardsCompatibility ( const std : : string & variable ,
2003-01-10 17:02:29 +03:00
int access_type , void * )
2003-01-09 16:47:17 +03:00
{
if ( access_type = = cmVariableWatch : : UNKNOWN_VARIABLE_READ_ACCESS )
{
2003-08-08 00:11:49 +04:00
std : : string message = " An attempt was made to access a variable: " ;
2003-01-09 16:47:17 +03:00
message + = variable ;
message + = " that has not been defined. Some variables were always defined by CMake in versions prior to 1.6. To fix this you might need to set the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If you are writing a CMakeList file, (or have already set CMAKE_BACKWARDS_COMPATABILITY to 1.4 or less) then you probably need to include a CMake module to test for the feature this variable defines. " ;
cmSystemTools : : Error ( message . c_str ( ) ) ;
}
}
2001-09-07 01:28:24 +04:00
cmake : : cmake ( )
{
2003-12-23 23:01:10 +03:00
m_DebugTryCompile = false ;
2002-10-24 23:39:25 +04:00
# ifdef __APPLE__
struct rlimit rlp ;
if ( ! getrlimit ( RLIMIT_STACK , & rlp ) )
{
if ( rlp . rlim_cur ! = rlp . rlim_max )
{
rlp . rlim_cur = rlp . rlim_max ;
setrlimit ( RLIMIT_STACK , & rlp ) ;
}
}
# endif
2003-05-14 00:51:01 +04:00
// If MAKEFLAGS are given in the environment, remove the environment
// variable. This will prevent try-compile from succeeding when it
// should fail (if "-i" is an option). We cannot simply test
// whether "-i" is given and remove it because some make programs
// encode the MAKEFLAGS variable in a strange way.
if ( getenv ( " MAKEFLAGS " ) )
{
2003-05-14 16:40:16 +04:00
static char makeflags [ ] = " MAKEFLAGS= " ;
putenv ( makeflags ) ;
2003-05-14 00:51:01 +04:00
}
2002-09-12 22:37:27 +04:00
m_Local = false ;
2001-09-07 01:28:24 +04:00
m_Verbose = false ;
2002-09-12 19:08:06 +04:00
m_InTryCompile = false ;
2002-09-06 21:06:23 +04:00
m_CacheManager = new cmCacheManager ;
m_GlobalGenerator = 0 ;
2002-09-26 23:14:20 +04:00
m_ProgressCallback = 0 ;
m_ProgressCallbackClientData = 0 ;
2003-01-08 20:59:52 +03:00
m_VariableWatch = new cmVariableWatch ;
2003-10-29 17:45:26 +03:00
m_ScriptMode = false ;
2002-09-26 23:14:20 +04:00
2003-07-08 05:52:10 +04:00
this - > AddDefaultGenerators ( ) ;
2002-09-11 00:51:29 +04:00
this - > AddDefaultCommands ( ) ;
2003-01-09 16:47:17 +03:00
m_VariableWatch - > AddWatch ( " CMAKE_WORDS_BIGENDIAN " ,
cmNeedBackwardsCompatibility ) ;
m_VariableWatch - > AddWatch ( " CMAKE_SIZEOF_INT " ,
cmNeedBackwardsCompatibility ) ;
m_VariableWatch - > AddWatch ( " CMAKE_X_LIBS " ,
cmNeedBackwardsCompatibility ) ;
2001-09-07 01:28:24 +04:00
}
2002-08-23 21:46:32 +04:00
cmake : : ~ cmake ( )
{
2002-09-06 21:06:23 +04:00
delete m_CacheManager ;
if ( m_GlobalGenerator )
2002-08-28 22:51:10 +04:00
{
2002-09-06 21:06:23 +04:00
delete m_GlobalGenerator ;
m_GlobalGenerator = 0 ;
2002-08-28 22:51:10 +04:00
}
2002-09-11 00:51:29 +04:00
for ( RegisteredCommandsMap : : iterator j = m_Commands . begin ( ) ;
j ! = m_Commands . end ( ) ; + + j )
{
delete ( * j ) . second ;
}
2003-01-08 20:59:52 +03:00
delete m_VariableWatch ;
2002-09-11 00:51:29 +04:00
}
bool cmake : : CommandExists ( const char * name ) const
{
return ( m_Commands . find ( name ) ! = m_Commands . end ( ) ) ;
2002-08-23 21:46:32 +04:00
}
2002-09-11 00:51:29 +04:00
cmCommand * cmake : : GetCommand ( const char * name )
{
cmCommand * rm = 0 ;
RegisteredCommandsMap : : iterator pos = m_Commands . find ( name ) ;
if ( pos ! = m_Commands . end ( ) )
{
rm = ( * pos ) . second ;
}
return rm ;
}
void cmake : : AddCommand ( cmCommand * wg )
{
std : : string name = wg - > GetName ( ) ;
2002-09-24 21:24:10 +04:00
// if the command already exists, free the old one
RegisteredCommandsMap : : iterator pos = m_Commands . find ( name ) ;
if ( pos ! = m_Commands . end ( ) )
{
delete pos - > second ;
m_Commands . erase ( pos ) ;
}
2002-09-11 00:51:29 +04:00
m_Commands . insert ( RegisteredCommandsMap : : value_type ( name , wg ) ) ;
}
2002-08-23 21:46:32 +04:00
2001-05-18 23:25:08 +04:00
void cmake : : Usage ( const char * program )
{
2002-10-10 18:43:59 +04:00
cmOStringStream errorStream ;
2002-02-01 21:08:50 +03:00
errorStream < < " cmake version " < < cmMakefile : : GetMajorVersion ( )
< < " . " < < cmMakefile : : GetMinorVersion ( ) < < " \n " ;
errorStream < < " Usage: " < < program < < " [srcdir] [options] \n "
2001-12-04 01:00:43 +03:00
< < " 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 " ;
2002-02-01 21:08:50 +03:00
errorStream < < " Options are: \n " ;
errorStream < < " \n -i (puts cmake in wizard mode, not available for ccmake) \n " ;
errorStream < < " \n -DVAR:TYPE=VALUE (create a cache file entry) \n " ;
errorStream < < " \n -Cpath_to_initial_cache (a cmake list file that is used to pre-load the cache with values.) \n " ;
errorStream < < " \n [-GgeneratorName] (where generator name can be one of these: " ;
2001-09-07 01:28:24 +04:00
std : : vector < std : : string > names ;
2002-08-28 22:51:10 +04:00
this - > GetRegisteredGenerators ( names ) ;
2001-09-07 01:28:24 +04:00
for ( std : : vector < std : : string > : : iterator i = names . begin ( ) ;
i ! = names . end ( ) ; + + i )
{
2002-02-01 21:08:50 +03:00
errorStream < < " \" " < < i - > c_str ( ) < < " \" " ;
2001-09-07 01:28:24 +04:00
}
2002-10-09 21:37:27 +04:00
errorStream < < " ) \n " ;
2002-02-01 21:08:50 +03:00
2002-06-19 23:21:49 +04:00
cmSystemTools : : Error ( errorStream . str ( ) . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-11-21 01:51:03 +03:00
// Parse the args
2003-10-29 17:45:26 +03:00
bool cmake : : SetCacheArgs ( const std : : vector < std : : string > & args )
2001-11-21 01:51:03 +03:00
{
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 ;
2003-08-01 22:10:26 +04:00
cmCacheManager : : CacheEntryType type = cmCacheManager : : UNINITIALIZED ;
if ( cmCacheManager : : ParseEntry ( entry . c_str ( ) , var , value , type ) | |
cmCacheManager : : ParseEntry ( entry . c_str ( ) , var , value ) )
2001-11-21 01:51:03 +03:00
{
2003-08-01 22:10:26 +04:00
this - > m_CacheManager - > AddCacheEntry ( var . c_str ( ) , value . c_str ( ) ,
" No help, variable specified on the command line. " ,
type ) ;
2001-11-21 01:51:03 +03:00
}
else
{
std : : cerr < < " Parse error in command line argument: " < < arg < < " \n "
< < " Should be: VAR:type=value \n " ;
2003-10-29 17:45:26 +03:00
cmSystemTools : : Error ( " No cmake scrpt provided. " ) ;
return false ;
2001-11-21 01:51:03 +03:00
}
}
2001-12-04 01:00:43 +03:00
else if ( arg . find ( " -C " , 0 ) = = 0 )
{
std : : string path = arg . substr ( 2 ) ;
2003-10-29 17:45:26 +03:00
if ( path . size ( ) = = 0 )
{
cmSystemTools : : Error ( " No initial cache file provided. " ) ;
return false ;
}
2001-12-04 01:00:43 +03:00
std : : cerr < < " loading initial cache file " < < path . c_str ( ) < < " \n " ;
2002-09-06 21:06:23 +04:00
this - > ReadListFile ( path . c_str ( ) ) ;
}
2003-12-11 03:47:15 +03:00
else if ( arg . find ( " -P " , 0 ) = = 0 )
2003-10-29 17:45:26 +03:00
{
2003-12-11 03:47:15 +03:00
std : : string path = arg . substr ( strlen ( " -P " ) ) ;
2003-10-29 17:45:26 +03:00
if ( path . size ( ) = = 0 )
{
cmSystemTools : : Error ( " No cmake scrpt provided. " ) ;
return false ;
}
std : : cerr < < " Running cmake script file " < < path . c_str ( ) < < " \n " ;
this - > ReadListFile ( path . c_str ( ) ) ;
}
2002-09-06 21:06:23 +04:00
}
2003-10-29 17:45:26 +03:00
return true ;
2002-09-06 21:06:23 +04:00
}
void cmake : : ReadListFile ( const char * path )
{
// if a generator was not yet created, temporarily create one
cmGlobalGenerator * gg = this - > GetGlobalGenerator ( ) ;
2002-09-08 18:17:03 +04:00
bool created = false ;
2002-09-06 21:06:23 +04:00
// if a generator was not specified use a generic one
if ( ! gg )
{
gg = new cmGlobalGenerator ;
gg - > SetCMakeInstance ( this ) ;
created = true ;
}
// read in the list file to fill the cache
if ( path )
{
cmLocalGenerator * lg = gg - > CreateLocalGenerator ( ) ;
lg - > SetGlobalGenerator ( gg ) ;
2003-07-28 21:40:53 +04:00
if ( ! lg - > GetMakefile ( ) - > ReadListFile ( 0 , path ) )
2002-09-06 21:06:23 +04:00
{
std : : cerr < < " Error in reading cmake initial cache file: "
< < path < < " \n " ;
2001-12-04 01:00:43 +03:00
}
2001-11-21 01:51:03 +03:00
}
2002-09-06 21:06:23 +04:00
// free generic one if generated
if ( created )
{
delete gg ;
}
2001-11-21 01:51:03 +03:00
}
2001-05-18 23:25:08 +04:00
// Parse the args
2002-09-06 21:06:23 +04:00
void cmake : : SetArgs ( const std : : vector < std : : string > & args )
2001-05-18 23:25:08 +04:00
{
m_Local = false ;
2001-09-07 01:28:24 +04:00
bool directoriesSet = false ;
2001-06-12 16:30:12 +04:00
for ( unsigned int i = 1 ; i < args . size ( ) ; + + i )
2001-05-18 23:25:08 +04:00
{
2001-05-30 23:28:55 +04:00
std : : string arg = args [ i ] ;
2001-07-02 22:38:39 +04:00
if ( arg . find ( " -H " , 0 ) = = 0 )
2001-05-18 23:25:08 +04:00
{
2001-09-07 01:28:24 +04:00
directoriesSet = true ;
2001-05-18 23:25:08 +04:00
std : : string path = arg . substr ( 2 ) ;
2003-12-22 20:24:26 +03:00
path = cmSystemTools : : CollapseFullPath ( path . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
2002-09-06 21:06:23 +04:00
this - > SetHomeDirectory ( path . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-09-07 01:28:24 +04:00
else if ( arg . find ( " -S " , 0 ) = = 0 )
2001-05-18 23:25:08 +04:00
{
2001-09-07 01:28:24 +04:00
directoriesSet = true ;
2001-05-18 23:25:08 +04:00
m_Local = true ;
std : : string path = arg . substr ( 2 ) ;
2003-12-22 20:24:26 +03:00
path = cmSystemTools : : CollapseFullPath ( path . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
2002-09-06 21:06:23 +04:00
this - > SetStartDirectory ( path . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-09-07 01:28:24 +04:00
else if ( arg . find ( " -O " , 0 ) = = 0 )
2001-05-18 23:25:08 +04:00
{
2001-09-07 01:28:24 +04:00
directoriesSet = true ;
2001-05-18 23:25:08 +04:00
std : : string path = arg . substr ( 2 ) ;
2003-12-22 20:24:26 +03:00
path = cmSystemTools : : CollapseFullPath ( path . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
2002-09-06 21:06:23 +04:00
this - > SetStartOutputDirectory ( path . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-09-07 01:28:24 +04:00
else if ( arg . find ( " -B " , 0 ) = = 0 )
2001-05-18 23:25:08 +04:00
{
2001-09-07 01:28:24 +04:00
directoriesSet = true ;
2001-05-18 23:25:08 +04:00
std : : string path = arg . substr ( 2 ) ;
2003-12-22 20:24:26 +03:00
path = cmSystemTools : : CollapseFullPath ( path . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
2002-09-06 21:06:23 +04:00
this - > SetHomeOutputDirectory ( path . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-09-07 01:28:24 +04:00
else if ( arg . find ( " -V " , 0 ) = = 0 )
2001-05-18 23:25:08 +04:00
{
2002-10-09 21:37:27 +04:00
m_Verbose = true ;
2001-05-18 23:25:08 +04:00
}
2001-11-21 16:47:37 +03:00
else if ( arg . find ( " -D " , 0 ) = = 0 )
{
// skip for now
}
2001-12-04 01:00:43 +03:00
else if ( arg . find ( " -C " , 0 ) = = 0 )
{
// skip for now
}
2003-10-30 03:49:50 +03:00
else if ( arg . find ( " --script " , 0 ) = = 0 )
2003-10-29 17:45:26 +03:00
{
// skip for now
}
2003-12-23 23:01:10 +03:00
else if ( arg . find ( " --debug-trycompile " , 0 ) = = 0 )
{
std : : cout < < " debug trycompile on \n " ;
this - > DebugTryCompileOn ( ) ;
}
2001-09-07 01:28:24 +04:00
else if ( arg . find ( " -G " , 0 ) = = 0 )
{
std : : string value = arg . substr ( 2 ) ;
2002-09-06 21:06:23 +04:00
cmGlobalGenerator * gen =
this - > CreateGlobalGenerator ( value . c_str ( ) ) ;
2001-09-07 01:28:24 +04:00
if ( ! gen )
{
cmSystemTools : : Error ( " Could not create named generator " ,
value . c_str ( ) ) ;
}
else
{
2002-09-06 21:06:23 +04:00
this - > SetGlobalGenerator ( gen ) ;
2001-09-07 01:28:24 +04:00
}
}
2002-01-07 23:49:07 +03:00
// no option assume it is the path to the source
2001-09-07 01:28:24 +04:00
else
{
2002-01-07 23:49:07 +03:00
directoriesSet = true ;
2003-08-06 00:36:15 +04:00
this - > SetDirectoriesFromFile ( arg . c_str ( ) ) ;
2001-09-07 01:28:24 +04:00
}
}
if ( ! directoriesSet )
{
2002-09-06 21:06:23 +04:00
this - > SetHomeOutputDirectory
2002-01-07 23:49:07 +03:00
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
2002-09-06 21:06:23 +04:00
this - > SetStartOutputDirectory
2002-01-07 23:49:07 +03:00
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
2002-09-06 21:06:23 +04:00
this - > SetHomeDirectory
2002-01-07 23:49:07 +03:00
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
2002-09-06 21:06:23 +04:00
this - > SetStartDirectory
2002-01-07 23:49:07 +03:00
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
2001-05-18 23:25:08 +04:00
}
2001-05-21 17:32:11 +04:00
if ( ! m_Local )
{
2002-09-06 21:06:23 +04:00
this - > SetStartDirectory ( this - > GetHomeDirectory ( ) ) ;
this - > SetStartOutputDirectory ( this - > GetHomeOutputDirectory ( ) ) ;
2001-05-21 17:32:11 +04:00
}
2001-05-18 23:25:08 +04:00
}
2003-08-06 00:36:15 +04:00
//----------------------------------------------------------------------------
void cmake : : SetDirectoriesFromFile ( const char * arg )
{
// Check if the argument refers to a CMakeCache.txt or
// CMakeLists.txt file.
std : : string listPath ;
std : : string cachePath ;
bool argIsFile = false ;
if ( cmSystemTools : : FileIsDirectory ( arg ) )
{
std : : string path = cmSystemTools : : CollapseFullPath ( arg ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
std : : string cacheFile = path ;
cacheFile + = " /CMakeCache.txt " ;
std : : string listFile = path ;
listFile + = " /CMakeLists.txt " ;
if ( cmSystemTools : : FileExists ( cacheFile . c_str ( ) ) )
{
cachePath = path ;
}
if ( cmSystemTools : : FileExists ( listFile . c_str ( ) ) )
{
listPath = path ;
}
}
else if ( cmSystemTools : : FileExists ( arg ) )
{
argIsFile = true ;
std : : string fullPath = cmSystemTools : : CollapseFullPath ( arg ) ;
std : : string name = cmSystemTools : : GetFilenameName ( fullPath . c_str ( ) ) ;
name = cmSystemTools : : LowerCase ( name ) ;
if ( name = = " cmakecache.txt " )
{
cachePath = cmSystemTools : : GetFilenamePath ( fullPath . c_str ( ) ) ;
}
else if ( name = = " cmakelists.txt " )
{
listPath = cmSystemTools : : GetFilenamePath ( fullPath . c_str ( ) ) ;
}
}
2003-12-08 19:31:16 +03:00
else
{
// Specified file or directory does not exist. Try to set things
// up to produce a meaningful error message.
std : : string fullPath = cmSystemTools : : CollapseFullPath ( arg ) ;
std : : string name = cmSystemTools : : GetFilenameName ( fullPath . c_str ( ) ) ;
name = cmSystemTools : : LowerCase ( name ) ;
if ( name = = " cmakecache.txt " | | name = = " cmakelists.txt " )
{
argIsFile = true ;
listPath = cmSystemTools : : GetFilenamePath ( fullPath . c_str ( ) ) ;
}
else
{
listPath = fullPath ;
}
}
2003-08-06 00:36:15 +04:00
// If there is a CMakeCache.txt file, use its settings.
if ( cachePath . length ( ) > 0 )
{
cmCacheManager * cachem = this - > GetCacheManager ( ) ;
cmCacheManager : : CacheIterator it = cachem - > NewIterator ( ) ;
if ( cachem - > LoadCache ( cachePath . c_str ( ) ) & & it . Find ( " CMAKE_HOME_DIRECTORY " ) )
{
this - > SetHomeOutputDirectory ( cachePath . c_str ( ) ) ;
this - > SetStartOutputDirectory ( cachePath . c_str ( ) ) ;
this - > SetHomeDirectory ( it . GetValue ( ) ) ;
this - > SetStartDirectory ( it . GetValue ( ) ) ;
return ;
}
}
// If there is a CMakeLists.txt file, use it as the source tree.
if ( listPath . length ( ) > 0 )
{
this - > SetHomeDirectory ( listPath . c_str ( ) ) ;
this - > SetStartDirectory ( listPath . c_str ( ) ) ;
if ( argIsFile )
{
// Source CMakeLists.txt file given. It was probably dropped
// onto the executable in a GUI. Default to an in-source build.
this - > SetHomeOutputDirectory ( listPath . c_str ( ) ) ;
this - > SetStartOutputDirectory ( listPath . c_str ( ) ) ;
}
else
{
// Source directory given on command line. Use current working
// directory as build tree.
std : : string cwd = cmSystemTools : : GetCurrentWorkingDirectory ( ) ;
this - > SetHomeOutputDirectory ( cwd . c_str ( ) ) ;
this - > SetStartOutputDirectory ( cwd . c_str ( ) ) ;
}
return ;
}
// We didn't find a CMakeLists.txt or CMakeCache.txt file from the
// argument. Assume it is the path to the source tree, and use the
// current working directory as the build tree.
std : : string full = cmSystemTools : : CollapseFullPath ( arg ) ;
std : : string cwd = cmSystemTools : : GetCurrentWorkingDirectory ( ) ;
this - > SetHomeDirectory ( full . c_str ( ) ) ;
this - > SetStartDirectory ( full . c_str ( ) ) ;
this - > SetHomeOutputDirectory ( cwd . c_str ( ) ) ;
this - > SetStartOutputDirectory ( cwd . c_str ( ) ) ;
}
2001-06-22 20:18:52 +04:00
// at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the cache
2002-09-06 21:06:23 +04:00
int cmake : : AddCMakePaths ( const char * arg0 )
2001-05-18 23:25:08 +04:00
{
2002-01-07 23:49:07 +03:00
// Find our own executable.
2002-06-27 17:35:21 +04:00
std : : vector < cmStdString > failures ;
2002-09-06 21:06:23 +04:00
std : : string cMakeSelf = arg0 ;
2001-05-24 00:28:34 +04:00
cmSystemTools : : ConvertToUnixSlashes ( cMakeSelf ) ;
2002-06-27 17:35:21 +04:00
failures . push_back ( cMakeSelf ) ;
2002-01-07 23:49:07 +03:00
cMakeSelf = cmSystemTools : : FindProgram ( cMakeSelf . c_str ( ) ) ;
2001-06-22 00:34:13 +04:00
if ( ! cmSystemTools : : FileExists ( cMakeSelf . c_str ( ) ) )
{
2001-06-22 01:20:03 +04:00
# ifdef CMAKE_BUILD_DIR
2002-06-03 21:08:52 +04:00
std : : string intdir = " . " ;
# ifdef CMAKE_INTDIR
intdir = CMAKE_INTDIR ;
# endif
cMakeSelf = CMAKE_BUILD_DIR ;
2003-05-02 21:56:56 +04:00
cMakeSelf + = " /bin/ " ;
2002-06-03 21:08:52 +04:00
cMakeSelf + = intdir ;
cMakeSelf + = " /cmake " ;
cMakeSelf + = cmSystemTools : : GetExecutableExtension ( ) ;
2001-06-22 00:34:13 +04:00
# endif
2001-06-22 01:20:03 +04:00
}
2001-06-22 00:34:13 +04:00
# ifdef CMAKE_PREFIX
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( cMakeSelf . c_str ( ) ) )
2001-06-22 00:34:13 +04:00
{
2002-06-27 17:35:21 +04:00
failures . push_back ( cMakeSelf ) ;
2001-06-22 01:20:03 +04:00
cMakeSelf = CMAKE_PREFIX " /bin/cmake " ;
2001-06-22 00:34:13 +04:00
}
# endif
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( cMakeSelf . c_str ( ) ) )
2001-06-22 00:34:13 +04:00
{
2002-06-27 17:35:21 +04:00
failures . push_back ( cMakeSelf ) ;
2002-10-10 18:43:59 +04:00
cmOStringStream msg ;
2002-06-27 17:35:21 +04:00
msg < < " CMAKE can not find the command line program cmake. \n " ;
2002-09-06 21:06:23 +04:00
msg < < " argv[0] = \" " < < arg0 < < " \" \n " ;
2002-06-27 17:35:21 +04:00
msg < < " Attempted paths: \n " ;
std : : vector < cmStdString > : : iterator i ;
for ( i = failures . begin ( ) ; i ! = failures . end ( ) ; + + i )
{
msg < < " \" " < < i - > c_str ( ) < < " \" \n " ;
}
cmSystemTools : : Error ( msg . str ( ) . c_str ( ) ) ;
return 0 ;
2001-06-22 00:34:13 +04:00
}
2001-06-22 01:20:03 +04:00
// Save the value in the cache
2002-09-06 21:06:23 +04:00
this - > m_CacheManager - > AddCacheEntry
2002-03-26 01:03:54 +03:00
( " CMAKE_COMMAND " , cMakeSelf . c_str ( ) , " Path to CMake executable. " ,
2001-05-23 23:49:18 +04:00
cmCacheManager : : INTERNAL ) ;
2002-03-15 23:42:59 +03:00
2002-05-07 17:02:45 +04:00
// Find and save the command to edit the cache
std : : string editCacheCommand = cmSystemTools : : GetFilenamePath ( cMakeSelf ) +
" /ccmake " + cmSystemTools : : GetFilenameExtension ( cMakeSelf ) ;
if ( ! cmSystemTools : : FileExists ( editCacheCommand . c_str ( ) ) )
{
editCacheCommand = cmSystemTools : : GetFilenamePath ( cMakeSelf ) +
" /CMakeSetup " + cmSystemTools : : GetFilenameExtension ( cMakeSelf ) ;
}
2004-01-07 19:24:22 +03:00
std : : string ctestCommand = cmSystemTools : : GetFilenamePath ( cMakeSelf ) +
" /ctest " + cmSystemTools : : GetFilenameExtension ( cMakeSelf ) ;
if ( cmSystemTools : : FileExists ( ctestCommand . c_str ( ) ) )
{
this - > m_CacheManager - > AddCacheEntry
( " CMAKE_CTEST_COMMAND " , ctestCommand . c_str ( ) ,
" Path to ctest program executable. " , cmCacheManager : : INTERNAL ) ;
}
2002-05-07 17:02:45 +04:00
if ( cmSystemTools : : FileExists ( editCacheCommand . c_str ( ) ) )
{
2002-09-06 21:06:23 +04:00
this - > m_CacheManager - > AddCacheEntry
2002-05-07 17:02:45 +04:00
( " CMAKE_EDIT_COMMAND " , editCacheCommand . c_str ( ) ,
" Path to cache edit program executable. " , cmCacheManager : : INTERNAL ) ;
}
2001-06-22 01:20:03 +04:00
2001-05-18 23:25:08 +04:00
// do CMAKE_ROOT, look for the environment variable first
std : : string cMakeRoot ;
2001-06-22 01:20:03 +04:00
std : : string modules ;
2001-05-18 23:25:08 +04:00
if ( getenv ( " CMAKE_ROOT " ) )
{
cMakeRoot = getenv ( " CMAKE_ROOT " ) ;
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-05-18 23:25:08 +04:00
}
2001-06-22 01:20:03 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-05-18 23:25:08 +04:00
{
// 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?
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-06-22 01:20:03 +04:00
}
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-06-22 01:20:03 +04:00
{
// try exe/../share/cmake
2003-07-22 00:38:53 +04:00
cMakeRoot + = CMAKE_DATA_DIR ;
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-06-22 01:20:03 +04:00
}
2001-06-20 21:56:38 +04:00
# ifdef CMAKE_ROOT_DIR
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-06-22 01:20:03 +04:00
{
2001-06-22 01:25:35 +04:00
// try compiled in root directory
2001-06-22 01:20:03 +04:00
cMakeRoot = CMAKE_ROOT_DIR ;
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-06-22 01:20:03 +04:00
}
2001-05-18 23:25:08 +04:00
# endif
2001-06-22 01:20:03 +04:00
# ifdef CMAKE_PREFIX
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-06-22 01:20:03 +04:00
{
2001-06-22 01:25:35 +04:00
// try compiled in install prefix
2003-07-22 00:38:53 +04:00
cMakeRoot = CMAKE_PREFIX CMAKE_DATA_DIR ;
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-06-22 01:20:03 +04:00
}
# endif
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-06-22 01:20:03 +04:00
{
2001-06-22 01:25:35 +04:00
// try
cMakeRoot = cmSystemTools : : GetProgramPath ( cMakeSelf . c_str ( ) ) ;
2003-07-22 00:38:53 +04:00
cMakeRoot + = CMAKE_DATA_DIR ;
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2001-06-22 01:20:03 +04:00
}
2002-05-16 01:23:09 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
{
// next try exe
cMakeRoot = cmSystemTools : : GetProgramPath ( cMakeSelf . c_str ( ) ) ;
// is there no Modules direcory there?
2003-01-22 00:46:24 +03:00
modules = cMakeRoot + " /Modules/CMakeDefaultMakeRuleVariables.cmake " ;
2002-05-16 01:23:09 +04:00
}
2001-06-22 01:41:23 +04:00
if ( ! cmSystemTools : : FileExists ( modules . c_str ( ) ) )
2001-06-22 01:20:03 +04:00
{
// couldn't find modules
2003-08-26 23:06:52 +04:00
cmSystemTools : : Error ( " Could not find CMAKE_ROOT !!! \n "
" CMake has most likely not been installed correctly. \n "
" Modules directory not found in \n " ,
cMakeRoot . c_str ( ) ) ;
2002-06-27 17:35:21 +04:00
return 0 ;
2001-05-18 23:25:08 +04:00
}
2002-09-06 21:06:23 +04:00
this - > m_CacheManager - > AddCacheEntry
2001-05-18 23:25:08 +04:00
( " CMAKE_ROOT " , cMakeRoot . c_str ( ) ,
" Path to CMake installation. " , cmCacheManager : : INTERNAL ) ;
2002-09-28 01:28:15 +04:00
# ifdef _WIN32
2002-09-30 22:01:51 +04:00
std : : string comspec = " cmw9xcom.exe " ;
2002-09-30 19:41:53 +04:00
cmSystemTools : : SetWindows9xComspecSubstitute ( comspec . c_str ( ) ) ;
2002-09-28 01:28:15 +04:00
# endif
2002-06-27 17:35:21 +04:00
return 1 ;
2001-05-18 23:25:08 +04:00
}
2002-05-16 01:23:09 +04:00
2002-06-03 21:08:52 +04:00
void CMakeCommandUsage ( const char * program )
{
2002-10-10 18:43:59 +04:00
cmOStringStream errorStream ;
2002-06-03 21:08:52 +04:00
errorStream
< < " cmake version " < < cmMakefile : : GetMajorVersion ( )
< < " . " < < cmMakefile : : GetMinorVersion ( ) < < " \n " ;
errorStream
< < " Usage: " < < program < < " -E [command] [arguments ...] \n "
< < " Available commands: \n "
2002-07-10 22:34:38 +04:00
< < " chdir dir cmd [args]... - run command in a given directory \n "
2002-06-03 21:08:52 +04:00
< < " copy file destination - copy file to destination (either file or directory) \n "
2002-12-16 19:10:37 +03:00
< < " copy_if_different in-file out-file - copy file if input has changed \n "
2002-09-28 01:28:15 +04:00
< < " echo [string]... - displays arguments as text \n "
2002-06-03 21:08:52 +04:00
< < " remove file1 file2 ... - remove the file(s) \n "
2002-06-19 23:21:49 +04:00
< < " time command [args] ... - run command and return elapsed time \n " ;
2002-06-03 21:08:52 +04:00
# if defined(_WIN32) && !defined(__CYGWIN__)
2002-06-19 23:21:49 +04:00
errorStream
2002-06-03 21:08:52 +04:00
< < " write_regv key value - write registry value \n "
2002-09-28 01:28:15 +04:00
< < " delete_regv key - delete registry value \n "
< < " comspec - on windows 9x use this for RunCommand \n " ;
2002-06-03 21:08:52 +04:00
# endif
2002-06-19 23:21:49 +04:00
cmSystemTools : : Error ( errorStream . str ( ) . c_str ( ) ) ;
2002-06-03 21:08:52 +04:00
}
int cmake : : CMakeCommand ( std : : vector < std : : string > & args )
{
if ( args . size ( ) > 1 )
{
// Copy file
if ( args [ 1 ] = = " copy " & & args . size ( ) = = 4 )
{
cmSystemTools : : cmCopyFile ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) ;
return cmSystemTools : : GetErrorOccuredFlag ( ) ;
}
2002-12-16 19:10:37 +03:00
// Copy file if different.
if ( args [ 1 ] = = " copy_if_different " & & args . size ( ) = = 4 )
{
cmSystemTools : : CopyFileIfDifferent ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) ;
return cmSystemTools : : GetErrorOccuredFlag ( ) ;
}
2002-09-28 01:28:15 +04:00
// Echo string
else if ( args [ 1 ] = = " echo " )
{
2002-09-29 22:09:16 +04:00
unsigned int cc ;
2002-09-28 01:28:15 +04:00
for ( cc = 2 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
std : : cout < < args [ cc ] < < " " ;
}
2002-09-28 01:28:15 +04:00
std : : cout < < std : : endl ;
return 0 ;
}
2002-06-03 21:08:52 +04:00
// Remove file
else if ( args [ 1 ] = = " remove " & & args . size ( ) > 2 )
{
for ( std : : string : : size_type cc = 2 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
2002-06-03 21:08:52 +04:00
if ( args [ cc ] ! = " -f " )
{
if ( args [ cc ] = = " \\ -f " )
{
args [ cc ] = " -f " ;
}
cmSystemTools : : RemoveFile ( args [ cc ] . c_str ( ) ) ;
}
2002-10-09 21:37:27 +04:00
}
2002-06-03 21:08:52 +04:00
return 0 ;
}
// Clock command
else if ( args [ 1 ] = = " time " & & args . size ( ) > 2 )
{
std : : string command = args [ 2 ] ;
for ( std : : string : : size_type cc = 3 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
2002-06-03 21:08:52 +04:00
command + = " " ;
command + = args [ cc ] ;
2002-10-09 21:37:27 +04:00
}
2002-06-03 21:08:52 +04:00
clock_t clock_start , clock_finish ;
time_t time_start , time_finish ;
time ( & time_start ) ;
clock_start = clock ( ) ;
2003-08-04 06:35:52 +04:00
cmSystemTools : : RunSingleCommand ( command . c_str ( ) ) ;
2002-06-03 21:08:52 +04:00
clock_finish = clock ( ) ;
time ( & time_finish ) ;
double clocks_per_sec = ( double ) CLOCKS_PER_SEC ;
std : : cout < < " Elapsed time: "
< < ( long ) ( time_finish - time_start ) < < " s. (time) "
< < " , "
< < ( double ) ( clock_finish - clock_start ) / clocks_per_sec
< < " s. (clock) "
< < " \n " ;
return 0 ;
}
2002-07-10 22:34:38 +04:00
// Clock command
2002-10-01 00:46:19 +04:00
else if ( args [ 1 ] = = " chdir " & & args . size ( ) > = 4 )
2002-07-10 22:34:38 +04:00
{
std : : string directory = args [ 2 ] ;
2003-10-28 23:26:00 +03:00
std : : string command = " \" " ;
command + = args [ 3 ] ;
command + = " \" " ;
2002-07-10 22:34:38 +04:00
for ( std : : string : : size_type cc = 4 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
2003-10-28 23:26:00 +03:00
command + = " \" " ;
2002-07-10 22:34:38 +04:00
command + = args [ cc ] ;
2003-10-28 23:26:00 +03:00
command + = " \" " ;
2002-10-09 21:37:27 +04:00
}
2002-07-10 22:34:38 +04:00
2002-07-17 19:53:07 +04:00
int retval = 0 ;
2003-08-04 06:35:52 +04:00
int timeout = 0 ;
if ( cmSystemTools : : RunSingleCommand ( command . c_str ( ) , 0 , & retval ,
directory . c_str ( ) , true , timeout ) )
2002-10-09 21:37:27 +04:00
{
return retval ;
}
2002-07-10 22:34:38 +04:00
2002-07-17 19:53:07 +04:00
return 1 ;
2003-11-27 00:38:26 +03:00
}
// Internal CMake shared library support.
else if ( args [ 1 ] = = " cmake_symlink_library " & & args . size ( ) = = 5 )
{
int result = 0 ;
std : : string realName = args [ 2 ] ;
std : : string soName = args [ 3 ] ;
std : : string name = args [ 4 ] ;
if ( soName ! = realName )
{
std : : string fname = cmSystemTools : : GetFilenameName ( realName ) ;
2003-11-27 01:34:01 +03:00
if ( cmSystemTools : : FileExists ( soName . c_str ( ) ) )
{
cmSystemTools : : RemoveFile ( soName . c_str ( ) ) ;
}
2003-11-27 00:38:26 +03:00
if ( ! cmSystemTools : : CreateSymlink ( fname . c_str ( ) , soName . c_str ( ) ) )
{
result = 1 ;
}
}
if ( name ! = soName )
{
std : : string fname = cmSystemTools : : GetFilenameName ( soName ) ;
2003-11-27 01:34:01 +03:00
if ( cmSystemTools : : FileExists ( soName . c_str ( ) ) )
{
cmSystemTools : : RemoveFile ( name . c_str ( ) ) ;
}
2003-11-27 00:38:26 +03:00
if ( ! cmSystemTools : : CreateSymlink ( fname . c_str ( ) , name . c_str ( ) ) )
{
result = 1 ;
}
}
2003-11-27 18:28:50 +03:00
return result ;
2003-11-27 00:38:26 +03:00
}
2002-07-10 22:34:38 +04:00
2002-06-03 21:08:52 +04:00
# if defined(_WIN32) && !defined(__CYGWIN__)
// Write registry value
else if ( args [ 1 ] = = " write_regv " & & args . size ( ) > 3 )
{
return cmSystemTools : : WriteRegistryValue ( args [ 2 ] . c_str ( ) ,
args [ 3 ] . c_str ( ) ) ? 0 : 1 ;
}
// Delete registry value
else if ( args [ 1 ] = = " delete_regv " & & args . size ( ) > 2 )
{
return cmSystemTools : : DeleteRegistryValue ( args [ 2 ] . c_str ( ) ) ? 0 : 1 ;
}
2002-09-28 01:28:15 +04:00
// Remove file
else if ( args [ 1 ] = = " comspec " & & args . size ( ) > 2 )
{
2002-09-29 22:09:16 +04:00
unsigned int cc ;
2002-09-28 01:28:15 +04:00
std : : string command = args [ 2 ] ;
for ( cc = 3 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
command + = " " + args [ cc ] ;
}
2002-09-28 01:28:15 +04:00
return cmWin32ProcessExecution : : Windows9xHack ( command . c_str ( ) ) ;
}
2002-06-03 21:08:52 +04:00
# endif
}
: : CMakeCommandUsage ( args [ 0 ] . c_str ( ) ) ;
return 1 ;
}
2002-08-28 22:51:10 +04:00
void cmake : : GetRegisteredGenerators ( std : : vector < std : : string > & names )
{
2003-07-08 05:52:10 +04:00
for ( RegisteredGeneratorsMap : : const_iterator i = m_Generators . begin ( ) ;
i ! = m_Generators . end ( ) ; + + i )
{
names . push_back ( i - > first ) ;
}
2002-09-06 21:06:23 +04:00
}
cmGlobalGenerator * cmake : : CreateGlobalGenerator ( const char * name )
{
2003-07-08 05:52:10 +04:00
RegisteredGeneratorsMap : : const_iterator i = m_Generators . find ( name ) ;
if ( i ! = m_Generators . end ( ) )
2002-09-06 21:06:23 +04:00
{
2003-07-08 05:52:10 +04:00
cmGlobalGenerator * generator = ( i - > second ) ( ) ;
generator - > SetCMakeInstance ( this ) ;
return generator ;
2002-09-06 21:06:23 +04:00
}
2003-07-08 05:52:10 +04:00
else
2002-08-28 22:51:10 +04:00
{
2003-07-08 05:52:10 +04:00
return 0 ;
2002-08-28 22:51:10 +04:00
}
}
2002-09-06 21:06:23 +04:00
void cmake : : SetHomeDirectory ( const char * dir )
{
m_cmHomeDirectory = dir ;
cmSystemTools : : ConvertToUnixSlashes ( m_cmHomeDirectory ) ;
}
2002-08-28 22:51:10 +04:00
2002-09-06 21:06:23 +04:00
void cmake : : SetHomeOutputDirectory ( const char * lib )
2002-08-28 22:51:10 +04:00
{
2002-09-06 21:06:23 +04:00
m_HomeOutputDirectory = lib ;
cmSystemTools : : ConvertToUnixSlashes ( m_HomeOutputDirectory ) ;
}
void cmake : : SetGlobalGenerator ( cmGlobalGenerator * gg )
{
// delete the old generator
if ( m_GlobalGenerator )
2002-08-28 22:51:10 +04:00
{
2002-09-06 21:06:23 +04:00
delete m_GlobalGenerator ;
2003-01-09 20:18:22 +03:00
// restore the original environment variables CXX and CC
// Restor CC
static char envCC [ 5000 ] ;
std : : string env = " CC= " ;
if ( m_CCEnvironment )
{
env + = m_CCEnvironment ;
}
std : : string : : size_type size = env . size ( ) ;
if ( size > 4999 )
{
size = 4999 ;
}
strncpy ( envCC , env . c_str ( ) , size ) ;
2004-01-08 17:59:24 +03:00
envCC [ size ] = 0 ;
2003-01-09 20:18:22 +03:00
putenv ( envCC ) ;
// Restore CXX
static char envCXX [ 5000 ] ;
env = " CXX= " ;
if ( m_CXXEnvironment )
{
env + = m_CXXEnvironment ;
}
size = env . size ( ) ;
if ( size > 4999 )
{
size = 4999 ;
}
strncpy ( envCXX , env . c_str ( ) , size ) ;
2004-01-08 17:59:24 +03:00
envCXX [ size ] = 0 ;
2003-01-09 20:18:22 +03:00
putenv ( envCXX ) ;
2002-08-28 22:51:10 +04:00
}
2003-01-09 20:18:22 +03:00
2002-09-06 21:06:23 +04:00
// set the new
m_GlobalGenerator = gg ;
2003-08-22 00:22:23 +04:00
// set the global flag for unix style paths on cmSystemTools as
// soon as the generator is set. This allows gmake to be used
// on windows.
cmSystemTools : : SetForceUnixPaths ( m_GlobalGenerator - > GetForceUnixPaths ( ) ) ;
2003-01-09 20:18:22 +03:00
// Save the environment variables CXX and CC
m_CXXEnvironment = getenv ( " CXX " ) ;
m_CCEnvironment = getenv ( " CC " ) ;
2002-09-06 21:06:23 +04:00
// set the cmake instance just to be sure
gg - > SetCMakeInstance ( this ) ;
2002-08-28 22:51:10 +04:00
}
2003-05-29 19:14:05 +04:00
int cmake : : DoPreConfigureChecks ( )
2002-08-28 22:51:10 +04:00
{
2003-06-13 22:15:17 +04:00
// Make sure the Start directory contains a CMakeLists.txt file.
std : : string srcList = this - > GetHomeDirectory ( ) ;
srcList + = " /CMakeLists.txt " ;
if ( ! cmSystemTools : : FileExists ( srcList . c_str ( ) ) )
{
2003-10-31 00:12:09 +03:00
cmOStringStream err ;
2003-12-08 19:31:16 +03:00
if ( cmSystemTools : : FileIsDirectory ( this - > GetHomeDirectory ( ) ) )
{
err < < " The source directory \" " < < this - > GetHomeDirectory ( )
< < " \" does not appear to contain CMakeLists.txt. \n " ;
}
else if ( cmSystemTools : : FileExists ( this - > GetHomeDirectory ( ) ) )
{
err < < " The source directory \" " < < this - > GetHomeDirectory ( )
< < " \" is a file, not a directory. \n " ;
}
else
{
err < < " The source directory \" " < < this - > GetHomeDirectory ( )
< < " \" does not exist. \n " ;
}
err < < " Specify --help for usage, or press the help button on the CMake GUI. " ;
2003-10-31 00:12:09 +03:00
cmSystemTools : : Error ( err . str ( ) . c_str ( ) ) ;
2003-06-13 22:15:17 +04:00
return - 2 ;
}
2002-09-13 18:41:20 +04:00
// do a sanity check on some values
2002-09-06 21:06:23 +04:00
if ( m_CacheManager - > GetCacheValue ( " CMAKE_HOME_DIRECTORY " ) )
{
std : : string cacheStart =
m_CacheManager - > GetCacheValue ( " CMAKE_HOME_DIRECTORY " ) ;
cacheStart + = " /CMakeLists.txt " ;
std : : string currentStart = this - > GetHomeDirectory ( ) ;
currentStart + = " /CMakeLists.txt " ;
if ( ! cmSystemTools : : SameFile ( cacheStart . c_str ( ) , currentStart . c_str ( ) ) )
{
2003-08-06 00:51:00 +04:00
std : : string message = " The source \" " ;
2002-09-06 21:06:23 +04:00
message + = currentStart ;
2003-08-06 00:51:00 +04:00
message + = " \" does not match the source \" " ;
2002-09-06 21:06:23 +04:00
message + = cacheStart ;
2003-08-06 00:51:00 +04:00
message + = " \" used to generate cache. " ;
message + = " Re-run cmake with a different source directory. " ;
2002-09-06 21:06:23 +04:00
cmSystemTools : : Error ( message . c_str ( ) ) ;
return - 2 ;
}
}
else
2003-05-29 19:14:05 +04:00
{
return 0 ;
}
return 1 ;
}
int cmake : : Configure ( )
{
2003-10-29 17:45:26 +03:00
int res = 0 ;
if ( ! m_ScriptMode )
{
res = this - > DoPreConfigureChecks ( ) ;
}
2003-05-29 19:14:05 +04:00
if ( res < 0 )
{
return - 2 ;
}
if ( ! res )
2002-09-06 21:06:23 +04:00
{
m_CacheManager - > AddCacheEntry ( " CMAKE_HOME_DIRECTORY " ,
this - > GetHomeDirectory ( ) ,
" Start directory with the top level CMakeLists.txt file for this project " ,
cmCacheManager : : INTERNAL ) ;
}
2003-02-24 19:02:23 +03:00
// set the default BACKWARDS compatibility to the current version
if ( ! m_CacheManager - > GetCacheValue ( " CMAKE_BACKWARDS_COMPATIBILITY " ) )
{
char ver [ 256 ] ;
sprintf ( ver , " %i.%i " , cmMakefile : : GetMajorVersion ( ) ,
cmMakefile : : GetMinorVersion ( ) ) ;
this - > m_CacheManager - > AddCacheEntry
( " CMAKE_BACKWARDS_COMPATIBILITY " , ver ,
" For backwards compatibility, what version of CMake commands and syntax should this version of CMake allow. " ,
cmCacheManager : : STRING ) ;
}
2002-09-06 21:06:23 +04:00
// no generator specified on the command line
if ( ! m_GlobalGenerator )
{
const char * genName = m_CacheManager - > GetCacheValue ( " CMAKE_GENERATOR " ) ;
if ( genName )
{
m_GlobalGenerator = this - > CreateGlobalGenerator ( genName ) ;
2003-08-22 00:22:23 +04:00
// set the global flag for unix style paths on cmSystemTools as
// soon as the generator is set. This allows gmake to be used
// on windows.
cmSystemTools : : SetForceUnixPaths ( m_GlobalGenerator - > GetForceUnixPaths ( ) ) ;
2002-09-06 21:06:23 +04:00
}
else
{
2002-09-10 23:36:11 +04:00
# if defined(__BORLANDC__) && defined(_WIN32)
2002-09-06 21:06:23 +04:00
this - > SetGlobalGenerator ( new cmGlobalBorlandMakefileGenerator ) ;
# elif defined(_WIN32) && !defined(__CYGWIN__)
this - > SetGlobalGenerator ( new cmGlobalVisualStudio6Generator ) ;
# else
this - > SetGlobalGenerator ( new cmGlobalUnixMakefileGenerator ) ;
# endif
}
if ( ! m_GlobalGenerator )
{
cmSystemTools : : Error ( " Could not create generator " ) ;
return - 1 ;
}
}
const char * genName = m_CacheManager - > GetCacheValue ( " CMAKE_GENERATOR " ) ;
if ( genName )
2002-08-28 22:51:10 +04:00
{
2002-09-06 21:06:23 +04:00
if ( strcmp ( m_GlobalGenerator - > GetName ( ) , genName ) ! = 0 )
2002-08-28 22:51:10 +04:00
{
2002-09-06 21:06:23 +04:00
std : : string message = " Error: generator : " ;
message + = m_GlobalGenerator - > GetName ( ) ;
message + = " \n Does not match the generator used previously: " ;
message + = genName ;
message + =
" \n Either remove the CMakeCache.txt file or choose a different "
" binary directory. " ;
cmSystemTools : : Error ( message . c_str ( ) ) ;
return - 2 ;
2002-08-28 22:51:10 +04:00
}
}
2002-09-06 21:06:23 +04:00
if ( ! m_CacheManager - > GetCacheValue ( " CMAKE_GENERATOR " ) )
{
m_CacheManager - > AddCacheEntry ( " CMAKE_GENERATOR " , m_GlobalGenerator - > GetName ( ) ,
" Name of generator. " ,
cmCacheManager : : INTERNAL ) ;
}
2002-09-13 18:41:20 +04:00
// reset any system configuration information, except for when we are
// InTryCompile. With TryCompile the system info is taken from the parent's
// info to save time
if ( ! m_InTryCompile )
{
m_GlobalGenerator - > ClearEnabledLanguages ( ) ;
}
2002-09-06 21:06:23 +04:00
// actually do the configure
m_GlobalGenerator - > Configure ( ) ;
// 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 ( ! m_CacheManager - > GetCacheValue ( " LIBRARY_OUTPUT_PATH " ) )
{
m_CacheManager - > AddCacheEntry ( " LIBRARY_OUTPUT_PATH " , " " ,
" Single output directory for building all libraries. " ,
cmCacheManager : : PATH ) ;
}
if ( ! m_CacheManager - > GetCacheValue ( " EXECUTABLE_OUTPUT_PATH " ) )
{
m_CacheManager - > AddCacheEntry ( " EXECUTABLE_OUTPUT_PATH " , " " ,
" Single output directory for building all executables. " ,
cmCacheManager : : PATH ) ;
}
2003-05-14 00:11:14 +04:00
if ( cmSystemTools : : GetFatalErrorOccured ( ) & &
( ! this - > m_CacheManager - > GetCacheValue ( " CMAKE_MAKE_PROGRAM " ) | |
cmSystemTools : : IsOff ( this - > m_CacheManager - > GetCacheValue ( " CMAKE_MAKE_PROGRAM " ) ) ) )
{
// We must have a bad generator selection. Wipe the cache entry so the
// user can select another.
m_CacheManager - > RemoveCacheEntry ( " CMAKE_GENERATOR " ) ;
}
2003-10-29 17:45:26 +03:00
if ( ! m_ScriptMode )
{
this - > m_CacheManager - > SaveCache ( this - > GetHomeOutputDirectory ( ) ) ;
}
2002-09-06 21:06:23 +04:00
if ( cmSystemTools : : GetErrorOccuredFlag ( ) )
{
return - 1 ;
}
2002-08-28 22:51:10 +04:00
return 0 ;
}
2002-11-13 23:20:20 +03:00
bool cmake : : CacheVersionMatches ( )
{
const char * majv = m_CacheManager - > GetCacheValue ( " CMAKE_CACHE_MAJOR_VERSION " ) ;
const char * minv = m_CacheManager - > GetCacheValue ( " CMAKE_CACHE_MINOR_VERSION " ) ;
const char * relv = m_CacheManager - > GetCacheValue ( " CMAKE_CACHE_RELEASE_VERSION " ) ;
bool cacheSameCMake = false ;
2002-11-18 01:31:12 +03:00
if ( majv & &
atoi ( majv ) = = static_cast < int > ( cmMakefile : : GetMajorVersion ( ) )
& & minv & &
atoi ( minv ) = = static_cast < int > ( cmMakefile : : GetMinorVersion ( ) )
2002-11-13 23:20:20 +03:00
& & relv & & ( strcmp ( relv , cmMakefile : : GetReleaseVersion ( ) ) = = 0 ) )
{
cacheSameCMake = true ;
}
return cacheSameCMake ;
}
2002-09-06 21:06:23 +04:00
// handle a command line invocation
2003-04-29 18:04:05 +04:00
int cmake : : Run ( const std : : vector < std : : string > & args , bool noconfigure )
2002-09-06 21:06:23 +04:00
{
// Process the arguments
this - > SetArgs ( args ) ;
2002-09-17 21:59:58 +04:00
// set the cmake command
m_CMakeCommand = args [ 0 ] ;
2003-10-29 17:45:26 +03:00
if ( ! m_ScriptMode )
2003-01-22 18:33:34 +03:00
{
2003-10-29 17:45:26 +03:00
// load the cache
if ( this - > LoadCache ( ) < 0 )
{
cmSystemTools : : Error ( " Error executing cmake::LoadCache(). Aborting. \n " ) ;
return - 1 ;
}
2003-01-22 18:33:34 +03:00
}
2003-10-29 17:45:26 +03:00
2002-09-17 21:59:58 +04:00
// Add any cache args
2003-10-29 17:45:26 +03:00
if ( ! this - > SetCacheArgs ( args ) )
{
cmSystemTools : : Error ( " Problem processing arguments. Aborting. \n " ) ;
return - 1 ;
}
2002-11-13 23:20:20 +03:00
2002-12-16 20:13:37 +03:00
std : : string systemFile = this - > GetHomeOutputDirectory ( ) ;
systemFile + = " /CMakeSystem.cmake " ;
2003-04-29 18:04:05 +04:00
if ( noconfigure )
{
return 0 ;
}
2002-11-13 23:20:20 +03:00
int ret = 0 ;
2002-12-16 20:13:37 +03:00
// if not local or the cmake version has changed since the last run
// of cmake, or CMakeSystem.cmake file is not in the root binary
// directory, run a global generate
2003-10-29 17:45:26 +03:00
if ( m_ScriptMode | | ! m_Local | | ! this - > CacheVersionMatches ( ) | |
2002-12-16 20:13:37 +03:00
! cmSystemTools : : FileExists ( systemFile . c_str ( ) ) )
{
// If we are doing global generate, we better set start and start
// output directory to the root of the project.
2002-12-17 20:11:48 +03:00
std : : string oldstartdir = this - > GetStartDirectory ( ) ;
std : : string oldstartoutputdir = this - > GetStartOutputDirectory ( ) ;
2002-12-16 20:13:37 +03:00
this - > SetStartDirectory ( this - > GetHomeDirectory ( ) ) ;
this - > SetStartOutputDirectory ( this - > GetHomeOutputDirectory ( ) ) ;
2002-11-13 23:20:20 +03:00
bool saveLocalFlag = m_Local ;
m_Local = false ;
ret = this - > Configure ( ) ;
2003-10-29 17:45:26 +03:00
if ( ret | | m_ScriptMode )
2002-11-13 23:20:20 +03:00
{
return ret ;
}
ret = this - > Generate ( ) ;
if ( ret )
{
return ret ;
}
m_Local = saveLocalFlag ;
2002-12-17 20:11:48 +03:00
this - > SetStartDirectory ( oldstartdir . c_str ( ) ) ;
this - > SetStartOutputDirectory ( oldstartoutputdir . c_str ( ) ) ;
2002-09-06 21:06:23 +04:00
}
2002-12-17 20:11:48 +03:00
2002-11-13 23:20:20 +03:00
// if we are local do the local thing
if ( m_Local )
2002-09-06 21:06:23 +04:00
{
2002-11-13 23:20:20 +03:00
ret = this - > LocalGenerate ( ) ;
2002-09-06 21:06:23 +04:00
}
2002-11-13 23:20:20 +03:00
return ret ;
2002-09-06 21:06:23 +04:00
}
int cmake : : Generate ( )
{
2003-08-26 23:06:52 +04:00
if ( ! m_GlobalGenerator )
{
return - 1 ;
}
2002-09-06 21:06:23 +04:00
m_GlobalGenerator - > Generate ( ) ;
if ( cmSystemTools : : GetErrorOccuredFlag ( ) )
{
return - 1 ;
}
return 0 ;
}
int cmake : : LocalGenerate ( )
{
// Read in the cache
m_CacheManager - > LoadCache ( this - > GetHomeOutputDirectory ( ) ) ;
// create the generator based on the cache if it isn't already there
const char * genName = m_CacheManager - > GetCacheValue ( " CMAKE_GENERATOR " ) ;
if ( genName )
{
m_GlobalGenerator = this - > CreateGlobalGenerator ( genName ) ;
2003-08-22 00:22:23 +04:00
// set the global flag for unix style paths on cmSystemTools as
// soon as the generator is set. This allows gmake to be used
// on windows.
cmSystemTools : : SetForceUnixPaths ( m_GlobalGenerator - > GetForceUnixPaths ( ) ) ;
2002-09-06 21:06:23 +04:00
}
else
{
cmSystemTools : : Error ( " Could local Generate called without the GENERATOR being specified in the CMakeCache " ) ;
return - 1 ;
}
// do the local generate
m_GlobalGenerator - > LocalGenerate ( ) ;
if ( cmSystemTools : : GetErrorOccuredFlag ( ) )
{
return - 1 ;
}
return 0 ;
}
unsigned int cmake : : GetMajorVersion ( )
{
return cmMakefile : : GetMajorVersion ( ) ;
}
unsigned int cmake : : GetMinorVersion ( )
{
return cmMakefile : : GetMinorVersion ( ) ;
}
const char * cmake : : GetReleaseVersion ( )
{
return cmMakefile : : GetReleaseVersion ( ) ;
}
2002-12-04 18:57:22 +03:00
void cmake : : AddCacheEntry ( const char * key , const char * value ,
const char * helpString ,
int type )
{
m_CacheManager - > AddCacheEntry ( key , value ,
helpString ,
cmCacheManager : : CacheEntryType ( type ) ) ;
}
2002-09-06 21:06:23 +04:00
const char * cmake : : GetCacheDefinition ( const char * name ) const
{
return m_CacheManager - > GetCacheValue ( name ) ;
}
2002-09-11 00:51:29 +04:00
int cmake : : DumpDocumentationToFile ( std : : ostream & f )
{
// Loop over all registered commands and print out documentation
const char * name ;
const char * terse ;
const char * full ;
char tmp [ 1024 ] ;
sprintf ( tmp , " Version %d.%d " , cmake : : GetMajorVersion ( ) ,
cmake : : GetMinorVersion ( ) ) ;
f < < " <html> \n " ;
f < < " <h1>Documentation for commands of CMake " < < tmp < < " </h1> \n " ;
f < < " <ul> \n " ;
for ( RegisteredCommandsMap : : iterator j = m_Commands . begin ( ) ;
j ! = m_Commands . end ( ) ; + + j )
{
name = ( * j ) . second - > GetName ( ) ;
terse = ( * j ) . second - > GetTerseDocumentation ( ) ;
full = ( * j ) . second - > GetFullDocumentation ( ) ;
f < < " <li><b> " < < name < < " </b> - " < < terse < < std : : endl
< < " <br><i>Usage:</i> " < < full < < " </li> " < < std : : endl < < std : : endl ;
}
f < < " </ul></html> \n " ;
return 1 ;
}
void cmake : : AddDefaultCommands ( )
{
std : : list < cmCommand * > commands ;
GetPredefinedCommands ( commands ) ;
for ( std : : list < cmCommand * > : : iterator i = commands . begin ( ) ;
i ! = commands . end ( ) ; + + i )
{
this - > AddCommand ( * i ) ;
}
}
2003-07-08 05:52:10 +04:00
void cmake : : AddDefaultGenerators ( )
{
# if defined(_WIN32) && !defined(__CYGWIN__)
m_Generators [ cmGlobalVisualStudio6Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio6Generator : : New ;
2003-08-22 00:22:23 +04:00
# if !defined(__MINGW32__)
2003-07-08 05:52:10 +04:00
m_Generators [ cmGlobalVisualStudio7Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio7Generator : : New ;
m_Generators [ cmGlobalVisualStudio71Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio71Generator : : New ;
2003-08-22 00:22:23 +04:00
# endif
2003-07-08 05:52:10 +04:00
m_Generators [ cmGlobalBorlandMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalBorlandMakefileGenerator : : New ;
m_Generators [ cmGlobalNMakeMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalNMakeMakefileGenerator : : New ;
# else
# if defined(__APPLE__) && defined(CMAKE_BUILD_WITH_CMAKE)
m_Generators [ cmGlobalCodeWarriorGenerator : : GetActualName ( ) ] =
& cmGlobalCodeWarriorGenerator : : New ;
# endif
2003-08-22 00:22:23 +04:00
# endif
2003-07-08 05:52:10 +04:00
m_Generators [ cmGlobalUnixMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalUnixMakefileGenerator : : New ;
}
2002-11-07 17:04:20 +03:00
int cmake : : LoadCache ( )
2002-09-17 21:59:58 +04:00
{
m_CacheManager - > LoadCache ( this - > GetHomeOutputDirectory ( ) ) ;
if ( m_CMakeCommand . size ( ) < 2 )
{
cmSystemTools : : Error ( " cmake command was not specified prior to loading the cache in cmake.cxx " ) ;
return - 1 ;
}
// setup CMAKE_ROOT and CMAKE_COMMAND
if ( ! this - > AddCMakePaths ( m_CMakeCommand . c_str ( ) ) )
{
return - 3 ;
2002-12-04 18:44:44 +03:00
}
// set the default BACKWARDS compatibility to the current version
if ( ! m_CacheManager - > GetCacheValue ( " CMAKE_BACKWARDS_COMPATIBILITY " ) )
{
char ver [ 256 ] ;
sprintf ( ver , " %i.%i " , cmMakefile : : GetMajorVersion ( ) ,
cmMakefile : : GetMinorVersion ( ) ) ;
this - > m_CacheManager - > AddCacheEntry
( " CMAKE_BACKWARDS_COMPATIBILITY " , ver ,
" For backwards compatibility, what version of CMake commands and syntax should this version of CMake allow. " ,
cmCacheManager : : STRING ) ;
2002-09-17 21:59:58 +04:00
}
2002-12-04 18:44:44 +03:00
2002-09-17 21:59:58 +04:00
return 0 ;
}
2002-09-26 23:14:20 +04:00
void cmake : : SetProgressCallback ( ProgressCallback f , void * cd )
{
m_ProgressCallback = f ;
m_ProgressCallbackClientData = cd ;
}
void cmake : : UpdateProgress ( const char * msg , float prog )
{
if ( m_ProgressCallback & & ! m_InTryCompile )
{
( * m_ProgressCallback ) ( msg , prog , m_ProgressCallbackClientData ) ;
return ;
}
}
2003-02-14 18:53:37 +03:00
void cmake : : GetCommandDocumentation ( std : : vector < cmDocumentationEntry > & v ) const
{
for ( RegisteredCommandsMap : : const_iterator j = m_Commands . begin ( ) ;
j ! = m_Commands . end ( ) ; + + j )
{
cmDocumentationEntry e =
{
( * j ) . second - > GetName ( ) ,
( * j ) . second - > GetTerseDocumentation ( ) ,
( * j ) . second - > GetFullDocumentation ( )
} ;
v . push_back ( e ) ;
}
cmDocumentationEntry empty = { 0 , 0 , 0 } ;
v . push_back ( empty ) ;
}
2003-07-08 05:52:10 +04:00
void cmake : : GetGeneratorDocumentation ( std : : vector < cmDocumentationEntry > & v )
{
for ( RegisteredGeneratorsMap : : const_iterator i = m_Generators . begin ( ) ;
i ! = m_Generators . end ( ) ; + + i )
{
cmDocumentationEntry e ;
cmGlobalGenerator * generator = ( i - > second ) ( ) ;
generator - > GetDocumentation ( e ) ;
delete generator ;
v . push_back ( e ) ;
}
cmDocumentationEntry empty = { 0 , 0 , 0 } ;
v . push_back ( empty ) ;
}