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"
2005-10-12 21:51:15 +04:00
# include "cmFileTimeComparison.h"
2006-03-03 22:24:31 +03:00
# include "cmGeneratedFileStream.h"
2001-05-18 23:25:08 +04:00
2004-10-27 18:47:14 +04:00
# if defined(CMAKE_BUILD_WITH_CMAKE)
2005-03-04 00:53:33 +03:00
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
2004-10-27 18:47:14 +04:00
# include "cmVariableWatch.h"
# include "cmVersion.h"
# endif
2004-10-26 20:55:20 +04:00
2004-10-12 17:50:36 +04:00
// only build kdevelop generator on non-windows platforms
// when not bootstrapping cmake
# if !defined(_WIN32)
# if defined(CMAKE_BUILD_WITH_CMAKE)
# define CMAKE_USE_KDEVELOP
# endif
# endif
2006-02-01 02:50:16 +03:00
# if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE)
# define CMAKE_BOOT_MINGW
# endif
2001-05-18 23:25:08 +04:00
// include the generator
# if defined(_WIN32) && !defined(__CYGWIN__)
2006-02-01 03:34:57 +03:00
# if !defined(CMAKE_BOOT_MINGW)
# include "cmGlobalVisualStudio6Generator.h"
2004-10-11 19:32:14 +04:00
# include "cmGlobalVisualStudio7Generator.h"
# include "cmGlobalVisualStudio71Generator.h"
# include "cmGlobalVisualStudio8Generator.h"
2006-02-01 02:50:16 +03:00
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
# include "cmGlobalWatcomWMakeGenerator.h"
# endif
2005-12-23 00:42:36 +03:00
# include "cmGlobalMSYSMakefileGenerator.h"
# include "cmGlobalMinGWMakefileGenerator.h"
2004-10-11 19:32:14 +04:00
# include "cmWin32ProcessExecution.h"
2001-05-18 23:25:08 +04:00
# else
2001-05-21 17:50:24 +04:00
# endif
2005-05-12 18:49:56 +04:00
# include "cmGlobalUnixMakefileGenerator3.h"
2004-10-12 17:50:36 +04:00
# ifdef CMAKE_USE_KDEVELOP
# include "cmGlobalKdevelopGenerator.h"
# endif
2001-05-21 17:50:24 +04:00
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__
2005-03-14 21:23:14 +03:00
# include "cmGlobalXCodeGenerator.h"
# define CMAKE_USE_XCODE 1
2004-10-11 19:32:14 +04:00
# include <sys / types.h>
# include <sys / time.h>
# include <sys / resource.h>
2003-04-16 23:40:24 +04:00
# endif
2002-10-24 23:39:25 +04:00
2005-07-03 06:25:43 +04:00
# include <sys/stat.h> // struct stat
2004-05-05 18:13:19 +04:00
# include <memory> // auto_ptr
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
{
2004-10-27 18:47:14 +04:00
# ifdef CMAKE_BUILD_WITH_CMAKE
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 ;
2004-05-05 18:13:19 +04:00
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. " ;
2003-01-09 16:47:17 +03:00
cmSystemTools : : Error ( message . c_str ( ) ) ;
}
2004-10-27 18:47:14 +04:00
# else
( void ) variable ;
( void ) access_type ;
# endif
2003-01-09 16:47:17 +03:00
}
2001-09-07 01:28:24 +04:00
cmake : : cmake ( )
{
2003-12-23 23:01:10 +03:00
m_DebugTryCompile = false ;
2005-06-10 18:45:08 +04:00
m_ClearBuildSystem = false ;
2005-10-12 21:51:15 +04:00
m_FileComparison = new cmFileTimeComparison ;
2005-06-10 18:45:08 +04:00
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 " ) )
{
2004-01-26 21:32:46 +03:00
cmSystemTools : : PutEnv ( " MAKEFLAGS= " ) ;
2003-05-14 00:51:01 +04:00
}
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-10-29 17:45:26 +03:00
m_ScriptMode = false ;
2002-09-26 23:14:20 +04:00
2004-10-27 18:47:14 +04:00
# ifdef CMAKE_BUILD_WITH_CMAKE
m_VariableWatch = new cmVariableWatch ;
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 ) ;
2004-10-27 18:47:14 +04:00
# endif
this - > AddDefaultGenerators ( ) ;
this - > AddDefaultCommands ( ) ;
2006-02-15 18:22:55 +03:00
// Make sure we can capture the build tool output.
cmSystemTools : : EnableVSConsoleOutput ( ) ;
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 ;
}
2004-10-27 18:47:14 +04:00
# ifdef CMAKE_BUILD_WITH_CMAKE
2003-01-08 20:59:52 +03:00
delete m_VariableWatch ;
2004-10-27 18:47:14 +04:00
# endif
2005-10-12 21:51:15 +04:00
delete m_FileComparison ;
2002-09-11 00:51:29 +04:00
}
2005-06-16 22:56:15 +04:00
void cmake : : CleanupCommandsAndMacros ( )
{
std : : vector < cmCommand * > commands ;
for ( RegisteredCommandsMap : : iterator j = m_Commands . begin ( ) ;
j ! = m_Commands . end ( ) ; + + j )
{
if ( ! j - > second - > IsA ( " cmMacroHelperCommand " ) )
{
commands . push_back ( j - > second ) ;
}
else
{
delete j - > second ;
}
}
m_Commands . erase ( m_Commands . begin ( ) , m_Commands . end ( ) ) ;
std : : vector < cmCommand * > : : iterator it ;
for ( it = commands . begin ( ) ; it ! = commands . end ( ) ;
+ + it )
{
m_Commands [ cmSystemTools : : LowerCase ( ( * it ) - > GetName ( ) ) ] = * it ;
}
}
2002-09-11 00:51:29 +04:00
bool cmake : : CommandExists ( const char * name ) const
{
2005-06-16 22:56:15 +04:00
std : : string sName = cmSystemTools : : LowerCase ( name ) ;
return ( m_Commands . find ( sName ) ! = 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 ;
2005-06-16 22:56:15 +04:00
std : : string sName = cmSystemTools : : LowerCase ( name ) ;
RegisteredCommandsMap : : iterator pos = m_Commands . find ( sName ) ;
2002-09-11 00:51:29 +04:00
if ( pos ! = m_Commands . end ( ) )
{
rm = ( * pos ) . second ;
}
return rm ;
}
2005-06-14 20:48:59 +04:00
void cmake : : RenameCommand ( const char * oldName , const char * newName )
{
// if the command already exists, free the old one
2005-06-16 22:56:15 +04:00
std : : string sOldName = cmSystemTools : : LowerCase ( oldName ) ;
std : : string sNewName = cmSystemTools : : LowerCase ( newName ) ;
RegisteredCommandsMap : : iterator pos = m_Commands . find ( sOldName ) ;
2005-06-14 20:48:59 +04:00
if ( pos = = m_Commands . end ( ) )
{
return ;
}
2005-06-16 22:56:15 +04:00
cmCommand * cmd = pos - > second ;
2005-06-14 20:48:59 +04:00
2005-06-16 22:56:15 +04:00
pos = m_Commands . find ( sNewName ) ;
if ( pos ! = m_Commands . end ( ) )
{
delete pos - > second ;
m_Commands . erase ( pos ) ;
}
m_Commands . insert ( RegisteredCommandsMap : : value_type ( sNewName , cmd ) ) ;
pos = m_Commands . find ( sOldName ) ;
2005-06-14 20:48:59 +04:00
m_Commands . erase ( pos ) ;
}
2002-09-11 00:51:29 +04:00
void cmake : : AddCommand ( cmCommand * wg )
{
2005-06-16 22:56:15 +04:00
std : : string name = cmSystemTools : : LowerCase ( 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-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 ) ;
2005-07-20 01:16:23 +04:00
if ( entry . size ( ) = = 0 )
{
entry = args [ + + i ] ;
}
2001-11-21 01:51:03 +03:00
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 )
{
2005-07-20 01:16:23 +04:00
path = args [ + + i ] ;
2003-10-29 17:45:26 +03:00
}
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
{
2004-02-20 22:46:33 +03:00
i + + ;
std : : string path = args [ i ] ;
2003-10-29 17:45:26 +03:00
if ( path . size ( ) = = 0 )
{
2005-09-23 20:50:09 +04:00
cmSystemTools : : Error ( " No cmake script provided. " ) ;
2003-10-29 17:45:26 +03:00
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 )
{
2004-05-05 18:13:19 +04:00
std : : auto_ptr < cmLocalGenerator > lg ( gg - > CreateLocalGenerator ( ) ) ;
2002-09-06 21:06:23 +04:00
lg - > SetGlobalGenerator ( gg ) ;
2005-09-23 20:50:09 +04:00
lg - > GetMakefile ( ) - > SetHomeOutputDirectory
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
lg - > GetMakefile ( ) - > SetStartOutputDirectory
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
lg - > GetMakefile ( ) - > SetHomeDirectory
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
lg - > GetMakefile ( ) - > SetStartDirectory
( cmSystemTools : : GetCurrentWorkingDirectory ( ) . c_str ( ) ) ;
2003-07-28 21:40:53 +04:00
if ( ! lg - > GetMakefile ( ) - > ReadListFile ( 0 , path ) )
2002-09-06 21:06:23 +04:00
{
2005-09-23 20:50:09 +04:00
std : : cerr < < " Error processing 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
{
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
{
2005-03-01 20:26:25 +03:00
// There is no local generate anymore. Ignore -S option.
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
{
2005-03-01 20:26:25 +03:00
// There is no local generate anymore. Ignore -O option.
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
}
2004-10-30 00:50:46 +04:00
else if ( ( i < args . size ( ) - 1 ) & & ( arg . find ( " --check-build-system " , 0 ) = = 0 ) )
2004-10-15 17:24:44 +04:00
{
2004-10-30 00:50:46 +04:00
m_CheckBuildSystem = args [ + + i ] ;
2005-06-10 18:45:08 +04:00
m_ClearBuildSystem = ( atoi ( args [ + + i ] . c_str ( ) ) > 0 ) ;
2004-10-15 17:24:44 +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
}
2005-01-28 21:00:36 +03:00
else if ( arg . find ( " -P " , 0 ) = = 0 )
2003-10-29 17:45:26 +03:00
{
// skip for now
2005-01-28 21:00:36 +03:00
i + + ;
2003-10-29 17:45:26 +03:00
}
2006-03-03 22:24:31 +03:00
else if ( arg . find ( " --graphviz= " , 0 ) = = 0 )
{
std : : string path = arg . substr ( strlen ( " --graphviz= " ) ) ;
path = cmSystemTools : : CollapseFullPath ( path . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( path ) ;
m_GraphVizFile = path ;
if ( m_GraphVizFile . empty ( ) )
{
cmSystemTools : : Error ( " No file specified for --graphviz " ) ;
}
}
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 ) ;
2005-07-20 01:16:23 +04:00
if ( value . size ( ) = = 0 )
{
value = args [ + + i ] ;
}
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
}
2005-03-10 21:39:38 +03:00
this - > SetStartDirectory ( this - > GetHomeDirectory ( ) ) ;
this - > SetStartOutputDirectory ( this - > GetHomeOutputDirectory ( ) ) ;
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 ( ) ) ;
2005-07-07 17:44:55 +04:00
cmSystemTools : : ConvertToUnixSlashes ( cMakeSelf ) ;
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 " ) ;
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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?
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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 ;
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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 ;
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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 ;
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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 ;
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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?
2004-08-26 22:55:55 +04:00
modules = cMakeRoot + " /Modules/CMake.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
2004-10-27 18:47:14 +04:00
# ifdef CMAKE_BUILD_WITH_CMAKE
2002-06-03 21:08:52 +04:00
errorStream
2004-10-22 23:44:54 +04:00
< < " cmake version " < < cmVersion : : GetCMakeVersion ( ) < < " \n " ;
2004-10-27 18:47:14 +04:00
# else
errorStream
< < " cmake bootstrap \n " ;
# endif
2002-06-03 21:08:52 +04:00
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 "
2005-02-12 00:25:30 +03:00
< < " copy_directory source destination - copy directory 'source' content to directory 'destination' \n "
2005-12-30 23:25:35 +03:00
< < " compare_files file1 file2 - check if file1 is same as file2 \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 "
2005-12-29 20:19:13 +03:00
< < " tar [cxt][vfz] file.tar file/dir1 file/dir2 ... - create a tar. \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 " ;
2005-08-19 17:38:17 +04:00
# else
errorStream
< < " create_symlink old new - create a symbolic link new -> old \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 )
{
2004-01-22 18:30:01 +03:00
if ( ! cmSystemTools : : cmCopyFile ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) )
{
std : : cerr < < " Error copying file \" " < < args [ 2 ] . c_str ( )
< < " \" to \" " < < args [ 3 ] . c_str ( ) < < " \" . \n " ;
return 1 ;
}
return 0 ;
2002-06-03 21:08:52 +04:00
}
2002-12-16 19:10:37 +03:00
// Copy file if different.
if ( args [ 1 ] = = " copy_if_different " & & args . size ( ) = = 4 )
{
2004-01-22 18:30:01 +03:00
if ( ! cmSystemTools : : CopyFileIfDifferent ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) )
{
std : : cerr < < " Error copying file (if different) from \" "
< < args [ 2 ] . c_str ( ) < < " \" to \" " < < args [ 3 ] . c_str ( )
< < " \" . \n " ;
return 1 ;
}
return 0 ;
2002-12-16 19:10:37 +03:00
}
2005-02-12 00:25:30 +03:00
// Copy directory content
if ( args [ 1 ] = = " copy_directory " & & args . size ( ) = = 4 )
{
if ( ! cmSystemTools : : CopyADirectory ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) )
{
std : : cerr < < " Error copying directory from \" "
< < args [ 2 ] . c_str ( ) < < " \" to \" " < < args [ 3 ] . c_str ( )
< < " \" . \n " ;
return 1 ;
}
return 0 ;
}
2005-12-30 23:25:35 +03:00
// Compare files
if ( args [ 1 ] = = " compare_files " & & args . size ( ) = = 4 )
{
if ( cmSystemTools : : FilesDiffer ( args [ 2 ] . c_str ( ) , args [ 3 ] . c_str ( ) ) )
{
std : : cerr < < " Files \" "
< < args [ 2 ] . c_str ( ) < < " \" to \" " < < args [ 3 ] . c_str ( )
< < " \" are different. \n " ;
return 1 ;
}
return 0 ;
}
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 ;
2006-02-10 19:41:52 +03:00
const char * space = " " ;
2002-09-28 01:28:15 +04:00
for ( cc = 2 ; cc < args . size ( ) ; cc + + )
2002-10-09 21:37:27 +04:00
{
2006-02-10 19:41:52 +03:00
std : : cout < < space < < args [ cc ] ;
space = " " ;
2002-10-09 21:37:27 +04:00
}
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 ;
}
2005-02-17 15:53:57 +03:00
// Command to change directory and run a program.
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 ] ;
2005-02-16 21:15:25 +03:00
if ( ! cmSystemTools : : FileExists ( directory . c_str ( ) ) )
{
2005-02-17 15:53:57 +03:00
cmSystemTools : : Error ( " Directory does not exist for chdir command: " ,
args [ 2 ] . c_str ( ) ) ;
return 0 ;
2005-02-16 21:15:25 +03:00
}
2005-02-17 15:53:57 +03:00
2003-10-28 23:26:00 +03:00
std : : string command = " \" " ;
2005-02-17 15:53:57 +03:00
command + = args [ 3 ] ;
2003-10-28 23:26:00 +03:00
command + = " \" " ;
2005-02-17 15:53:57 +03: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-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
}
2005-08-19 17:38:17 +04:00
// Command to create a symbolic link. Fails on platforms not
// supporting them.
else if ( args [ 1 ] = = " create_symlink " & & args . size ( ) = = 4 )
{
return cmSystemTools : : CreateSymlink ( args [ 2 ] . c_str ( ) ,
args [ 3 ] . c_str ( ) ) ? 0 : 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
}
2005-08-18 00:06:52 +04:00
// Internal CMake versioned executable support.
else if ( args [ 1 ] = = " cmake_symlink_executable " & & args . size ( ) = = 4 )
{
int result = 0 ;
std : : string realName = args [ 2 ] ;
std : : string name = args [ 3 ] ;
if ( name ! = realName )
{
std : : string fname = cmSystemTools : : GetFilenameName ( realName ) ;
if ( cmSystemTools : : FileExists ( realName . c_str ( ) ) )
{
cmSystemTools : : RemoveFile ( name . c_str ( ) ) ;
}
if ( ! cmSystemTools : : CreateSymlink ( fname . c_str ( ) , name . c_str ( ) ) )
{
result = 1 ;
}
}
return result ;
}
2002-07-10 22:34:38 +04:00
2004-10-26 20:55:20 +04:00
// Internal CMake dependency scanning support.
2005-07-27 17:49:37 +04:00
else if ( args [ 1 ] = = " cmake_depends " & & args . size ( ) > = 6 )
2004-10-26 20:55:20 +04:00
{
2005-05-12 18:49:56 +04:00
cmake cm ;
cmGlobalGenerator * ggd = cm . CreateGlobalGenerator ( args [ 2 ] . c_str ( ) ) ;
if ( ggd )
{
2005-12-23 00:42:36 +03:00
ggd - > SetCMakeInstance ( & cm ) ;
2005-05-12 18:49:56 +04:00
std : : auto_ptr < cmLocalGenerator > lgd ( ggd - > CreateLocalGenerator ( ) ) ;
lgd - > SetGlobalGenerator ( ggd ) ;
2005-06-07 18:47:28 +04:00
return lgd - > ScanDependencies ( args ) ? 0 : 2 ;
2005-05-12 18:49:56 +04:00
}
return 1 ;
2004-10-26 20:55:20 +04:00
}
2005-12-29 00:31:12 +03:00
// Tar files
else if ( args [ 1 ] = = " tar " & & args . size ( ) > 3 )
{
2005-12-29 20:19:13 +03:00
std : : string flags = args [ 2 ] ;
std : : string outFile = args [ 3 ] ;
2005-12-29 00:31:12 +03:00
std : : vector < cmStdString > files ;
2005-12-29 20:19:13 +03:00
for ( std : : string : : size_type cc = 4 ; cc < args . size ( ) ; cc + + )
2005-12-29 00:31:12 +03:00
{
files . push_back ( args [ cc ] ) ;
}
2005-12-29 20:19:13 +03:00
bool gzip = false ;
bool verbose = false ;
if ( flags . find_first_of ( ' z ' ) ! = flags . npos )
2005-12-29 00:31:12 +03:00
{
2005-12-29 20:19:13 +03:00
gzip = true ;
}
if ( flags . find_first_of ( ' v ' ) ! = flags . npos )
{
verbose = true ;
2005-12-29 00:31:12 +03:00
}
2005-12-29 20:19:13 +03:00
if ( flags . find_first_of ( ' t ' ) ! = flags . npos )
2005-12-29 18:43:12 +03:00
{
2005-12-29 20:19:13 +03:00
if ( ! cmSystemTools : : ListTar ( outFile . c_str ( ) , files , gzip , verbose ) )
{
cmSystemTools : : Error ( " Problem creating tar: " , outFile . c_str ( ) ) ;
return 1 ;
}
2005-12-29 18:43:12 +03:00
}
2005-12-29 20:19:13 +03:00
else if ( flags . find_first_of ( ' c ' ) ! = flags . npos )
2005-12-29 18:43:12 +03:00
{
2005-12-29 20:19:13 +03:00
if ( ! cmSystemTools : : CreateTar ( outFile . c_str ( ) , files , gzip , verbose ) )
{
cmSystemTools : : Error ( " Problem creating tar: " , outFile . c_str ( ) ) ;
return 1 ;
}
}
else if ( flags . find_first_of ( ' x ' ) ! = flags . npos )
{
if ( ! cmSystemTools : : ExtractTar ( outFile . c_str ( ) , files , gzip , verbose ) )
{
cmSystemTools : : Error ( " Problem extracting tar: " , outFile . c_str ( ) ) ;
return 1 ;
}
2005-12-29 18:43:12 +03:00
}
return 0 ;
}
2005-03-04 00:53:33 +03:00
# if defined(CMAKE_BUILD_WITH_CMAKE)
// Internal CMake Fortran module support.
else if ( args [ 1 ] = = " cmake_copy_f90_mod " & & args . size ( ) > = 4 )
{
return cmDependsFortran : : CopyModule ( args ) ? 0 : 1 ;
}
# endif
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
std : : string env = " CC= " ;
2004-01-26 21:32:46 +03:00
if ( m_CCEnvironment . size ( ) )
2003-01-09 20:18:22 +03:00
{
env + = m_CCEnvironment ;
}
2004-01-26 21:32:46 +03:00
cmSystemTools : : PutEnv ( env . c_str ( ) ) ;
2003-01-09 20:18:22 +03:00
env = " CXX= " ;
2004-01-26 21:32:46 +03:00
if ( m_CXXEnvironment . size ( ) )
2003-01-09 20:18:22 +03:00
{
env + = m_CXXEnvironment ;
}
2004-01-26 21:32:46 +03:00
cmSystemTools : : PutEnv ( env . c_str ( ) ) ;
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
2004-01-26 21:32:46 +03:00
const char * cxx = getenv ( " CXX " ) ;
const char * cc = getenv ( " CC " ) ;
if ( cxx )
{
m_CXXEnvironment = cxx ;
}
else
{
m_CXXEnvironment = " " ;
}
if ( cc )
{
m_CCEnvironment = cc ;
}
else
{
m_CCEnvironment = " " ;
}
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 ( )
{
2004-10-04 20:31:09 +04:00
// Construct right now our path conversion table before it's too late:
this - > UpdateConversionPathTable ( ) ;
2005-06-16 22:56:15 +04:00
this - > CleanupCommandsAndMacros ( ) ;
2004-10-04 20:31:09 +04:00
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 ) ;
2004-04-29 18:26:22 +04:00
}
if ( m_GlobalGenerator )
{
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 ) ;
2006-02-01 02:50:16 +03:00
# elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
2004-07-27 21:40:47 +04:00
std : : string installedCompiler ;
2004-08-04 18:00:39 +04:00
std : : string mp = " [HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ VisualStudio \\ 8.0 \\ Setup;Dbghelp_path] " ;
2004-07-27 21:40:47 +04:00
cmSystemTools : : ExpandRegistryValues ( mp ) ;
if ( ! ( mp = = " /registry " ) )
{
installedCompiler = " Visual Studio 8 2005 " ;
}
else
{
mp = " [HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ VisualStudio \\ 7.1;InstallDir] " ;
cmSystemTools : : ExpandRegistryValues ( mp ) ;
if ( ! ( mp = = " /registry " ) )
{
installedCompiler = " Visual Studio 7 .NET 2003 " ;
}
else
{
mp = " [HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ VisualStudio \\ 7.0;InstallDir] " ;
cmSystemTools : : ExpandRegistryValues ( mp ) ;
if ( ! ( mp = = " /registry " ) )
{
installedCompiler = " Visual Studio 7 " ;
}
else
{
installedCompiler = " Visual Studio 6 " ;
}
}
}
cmGlobalGenerator * gen = this - > CreateGlobalGenerator ( installedCompiler . c_str ( ) ) ;
if ( ! gen )
{
gen = new cmGlobalNMakeMakefileGenerator ;
}
this - > SetGlobalGenerator ( gen ) ;
2002-09-06 21:06:23 +04:00
# else
2005-05-25 19:18:41 +04:00
this - > SetGlobalGenerator ( new cmGlobalUnixMakefileGenerator3 ) ;
2002-09-06 21:06:23 +04:00
# 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 ( ) ;
}
2004-04-26 19:23:06 +04:00
this - > CleanupWrittenFiles ( ) ;
2005-07-03 20:06:40 +04:00
// Truncate log files
if ( ! m_InTryCompile )
{
this - > TruncateOutputLog ( " CMakeOutput.log " ) ;
this - > TruncateOutputLog ( " CMakeError.log " ) ;
}
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 ) ;
}
2004-03-31 19:01:52 +04:00
if ( ! m_CacheManager - > GetCacheValue ( " CMAKE_USE_RELATIVE_PATHS " ) )
{
m_CacheManager - > AddCacheEntry ( " CMAKE_USE_RELATIVE_PATHS " , false ,
" If true, cmake will use relative paths in makefiles and projects. " ) ;
cmCacheManager : : CacheIterator it =
m_CacheManager - > GetCacheIterator ( " CMAKE_USE_RELATIVE_PATHS " ) ;
if ( ! it . PropertyExists ( " ADVANCED " ) )
{
it . SetProperty ( " ADVANCED " , " 1 " ) ;
}
}
2002-09-06 21:06:23 +04:00
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 " ) ;
}
2006-02-15 06:03:16 +03:00
// only save the cache if there were no fatal errors
if ( ! m_ScriptMode & & ! cmSystemTools : : GetFatalErrorOccured ( ) )
2003-10-29 17:45:26 +03:00
{
this - > m_CacheManager - > SaveCache ( this - > GetHomeOutputDirectory ( ) ) ;
}
2006-03-03 22:24:31 +03:00
if ( ! m_GraphVizFile . empty ( ) )
{
std : : cout < < " Generate graphviz: " < < m_GraphVizFile < < std : : endl ;
this - > GenerateGraphViz ( m_GraphVizFile . c_str ( ) ) ;
}
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 ;
}
2004-08-17 23:36:08 +04:00
void cmake : : PreLoadCMakeFiles ( )
{
std : : string pre_load = this - > GetHomeDirectory ( ) ;
2004-08-23 22:33:22 +04:00
if ( pre_load . size ( ) > 0 )
2004-08-17 23:36:08 +04:00
{
2004-08-23 22:33:22 +04:00
pre_load + = " /PreLoad.cmake " ;
if ( cmSystemTools : : FileExists ( pre_load . c_str ( ) ) )
{
this - > ReadListFile ( pre_load . c_str ( ) ) ;
}
2004-08-17 23:36:08 +04:00
}
pre_load = this - > GetHomeOutputDirectory ( ) ;
2004-08-23 22:33:22 +04:00
if ( pre_load . size ( ) > 0 )
2004-08-17 23:36:08 +04:00
{
2004-08-23 22:33:22 +04:00
pre_load + = " /PreLoad.cmake " ;
if ( cmSystemTools : : FileExists ( pre_load . c_str ( ) ) )
{
this - > ReadListFile ( pre_load . c_str ( ) ) ;
}
2004-08-17 23:36:08 +04:00
}
}
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 ) ;
2005-04-05 19:23:08 +04:00
if ( cmSystemTools : : GetErrorOccuredFlag ( ) )
{
CMakeCommandUsage ( args [ 0 ] . c_str ( ) ) ;
return - 1 ;
}
2002-09-06 21:06:23 +04:00
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
}
2006-03-07 22:46:50 +03:00
else
{
this - > AddCMakePaths ( m_CMakeCommand . c_str ( ) ) ;
}
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 ;
}
2004-04-28 18:52:20 +04:00
2005-02-22 17:08:02 +03:00
// In script mode we terminate after running the script.
if ( m_ScriptMode )
{
2005-08-08 17:37:29 +04:00
if ( cmSystemTools : : GetErrorOccuredFlag ( ) )
{
return - 1 ;
}
else
{
return 0 ;
}
2005-02-22 17:08:02 +03:00
}
2004-08-17 23:36:08 +04:00
this - > PreLoadCMakeFiles ( ) ;
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 ;
}
2005-03-10 21:39:38 +03:00
// now run the global generate
// Check the state of the build system to see if we need to regenerate.
if ( ! this - > CheckBuildSystem ( ) )
{
return 0 ;
2002-09-06 21:06:23 +04:00
}
2005-03-10 21:39:38 +03:00
// If we are doing global generate, we better set start and start
// output directory to the root of the project.
std : : string oldstartdir = this - > GetStartDirectory ( ) ;
std : : string oldstartoutputdir = this - > GetStartOutputDirectory ( ) ;
this - > SetStartDirectory ( this - > GetHomeDirectory ( ) ) ;
this - > SetStartOutputDirectory ( this - > GetHomeOutputDirectory ( ) ) ;
2005-03-11 16:38:15 +03:00
int ret = this - > Configure ( ) ;
2005-03-10 21:39:38 +03:00
if ( ret | | m_ScriptMode )
2002-09-06 21:06:23 +04:00
{
2005-03-10 21:39:38 +03:00
return ret ;
2002-09-06 21:06:23 +04:00
}
2005-03-10 21:39:38 +03:00
ret = this - > Generate ( ) ;
std : : string message = " Build files have been written to: " ;
message + = this - > GetHomeOutputDirectory ( ) ;
this - > UpdateProgress ( message . c_str ( ) , - 1 ) ;
if ( ret )
{
return ret ;
}
this - > SetStartDirectory ( oldstartdir . c_str ( ) ) ;
this - > SetStartOutputDirectory ( oldstartoutputdir . c_str ( ) ) ;
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 ;
}
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 )
{
2004-10-27 18:47:14 +04:00
# ifdef CMAKE_BUILD_WITH_CMAKE
2002-09-11 00:51:29 +04:00
// Loop over all registered commands and print out documentation
const char * name ;
const char * terse ;
const char * full ;
char tmp [ 1024 ] ;
2004-10-22 23:44:54 +04:00
sprintf ( tmp , " Version %d.%d (%s) " , cmake : : GetMajorVersion ( ) ,
cmake : : GetMinorVersion ( ) , cmVersion : : GetReleaseVersion ( ) . c_str ( ) ) ;
2002-09-11 00:51:29 +04:00
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 " ;
2004-10-27 18:47:14 +04:00
# else
( void ) f ;
# endif
2002-09-11 00:51:29 +04:00
return 1 ;
}
void cmake : : AddDefaultCommands ( )
{
std : : list < cmCommand * > commands ;
2005-01-21 18:27:51 +03:00
GetBootstrapCommands ( commands ) ;
2002-09-11 00:51:29 +04:00
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__)
2006-02-01 03:34:57 +03:00
# if !defined(CMAKE_BOOT_MINGW)
m_Generators [ cmGlobalVisualStudio6Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio6Generator : : New ;
2003-07-08 05:52:10 +04:00
m_Generators [ cmGlobalVisualStudio7Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio7Generator : : New ;
m_Generators [ cmGlobalVisualStudio71Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio71Generator : : New ;
2004-07-05 20:16:33 +04:00
m_Generators [ cmGlobalVisualStudio8Generator : : GetActualName ( ) ] =
& cmGlobalVisualStudio8Generator : : New ;
2003-07-08 05:52:10 +04:00
m_Generators [ cmGlobalBorlandMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalBorlandMakefileGenerator : : New ;
m_Generators [ cmGlobalNMakeMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalNMakeMakefileGenerator : : New ;
2006-01-17 18:21:45 +03:00
m_Generators [ cmGlobalWatcomWMakeGenerator : : GetActualName ( ) ] =
& cmGlobalWatcomWMakeGenerator : : New ;
2006-02-01 03:34:57 +03:00
# endif
2005-12-23 00:42:36 +03:00
m_Generators [ cmGlobalMSYSMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalMSYSMakefileGenerator : : New ;
m_Generators [ cmGlobalMinGWMakefileGenerator : : GetActualName ( ) ] =
& cmGlobalMinGWMakefileGenerator : : New ;
2003-08-22 00:22:23 +04:00
# endif
2005-05-12 18:49:56 +04:00
m_Generators [ cmGlobalUnixMakefileGenerator3 : : GetActualName ( ) ] =
& cmGlobalUnixMakefileGenerator3 : : New ;
2005-03-14 21:23:14 +03:00
# ifdef CMAKE_USE_XCODE
2005-01-25 23:26:57 +03:00
m_Generators [ cmGlobalXCodeGenerator : : GetActualName ( ) ] =
& cmGlobalXCodeGenerator : : New ;
2005-03-14 21:23:14 +03:00
# endif
2004-10-12 17:50:36 +04:00
# ifdef CMAKE_USE_KDEVELOP
2004-10-11 19:32:14 +04:00
m_Generators [ cmGlobalKdevelopGenerator : : GetActualName ( ) ] =
& cmGlobalKdevelopGenerator : : New ;
# endif
2003-07-08 05:52:10 +04:00
}
2002-11-07 17:04:20 +03:00
int cmake : : LoadCache ( )
2002-09-17 21:59:58 +04:00
{
2005-08-11 21:20:23 +04:00
// could we not read the cache
if ( ! m_CacheManager - > LoadCache ( this - > GetHomeOutputDirectory ( ) ) )
{
// if it does exist, but isn;t readable then warn the user
std : : string cacheFile = this - > GetHomeOutputDirectory ( ) ;
cacheFile + = " /CMakeCache.txt " ;
if ( cmSystemTools : : FileExists ( cacheFile . c_str ( ) ) )
{
cmSystemTools : : Error ( " There is a CMakeCache.txt file for the current binary tree but cmake does not have permission to read it. Please check the permissions of the directory you are trying to run CMake on. " ) ;
return - 1 ;
}
}
2002-09-17 21:59:58 +04:00
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 ) ;
}
2004-04-18 22:41:46 +04:00
void cmake : : AddWrittenFile ( const char * file )
{
m_WrittenFiles . insert ( file ) ;
}
bool cmake : : HasWrittenFile ( const char * file )
{
return m_WrittenFiles . find ( file ) ! = m_WrittenFiles . end ( ) ;
}
2004-04-26 19:23:06 +04:00
void cmake : : CleanupWrittenFiles ( )
{
m_WrittenFiles . clear ( ) ;
}
2004-10-04 20:31:09 +04:00
void cmake : : UpdateConversionPathTable ( )
{
// Update the path conversion table with any specified file:
const char * tablepath =
m_CacheManager - > GetCacheValue ( " CMAKE_PATH_TRANSLATION_FILE " ) ;
if ( tablepath )
{
std : : ifstream table ( tablepath ) ;
2004-10-05 19:37:03 +04:00
if ( ! table )
2004-10-04 20:31:09 +04:00
{
2004-10-05 19:37:03 +04:00
cmSystemTools : : Error ( " CMAKE_PATH_TRANSLATION_FILE set to " , tablepath , " . CMake can not open file. " ) ;
cmSystemTools : : ReportLastSystemError ( " CMake can not open file. " ) ;
}
else
{
std : : string a , b ;
2004-10-04 20:31:09 +04:00
while ( ! table . eof ( ) )
{
// two entries per line
table > > a ; table > > b ;
cmSystemTools : : AddTranslationPath ( a . c_str ( ) , b . c_str ( ) ) ;
}
}
}
}
2004-10-15 17:24:44 +04:00
2004-10-30 00:50:46 +04:00
//----------------------------------------------------------------------------
int cmake : : CheckBuildSystem ( )
2004-10-15 17:24:44 +04:00
{
2004-10-30 00:50:46 +04:00
// This method will check the integrity of the build system if the
// option was given on the command line. It reads the given file to
// determine whether CMake should rerun. If it does rerun then the
// generation step will check the integrity of dependencies. If it
// does not then we need to check the integrity here.
2004-10-15 17:24:44 +04:00
// If no file is provided for the check, we have to rerun.
2004-10-30 00:50:46 +04:00
if ( m_CheckBuildSystem . size ( ) = = 0 )
2004-10-15 17:24:44 +04:00
{
return 1 ;
}
// If the file provided does not exist, we have to rerun.
2004-10-30 00:50:46 +04:00
if ( ! cmSystemTools : : FileExists ( m_CheckBuildSystem . c_str ( ) ) )
2004-10-15 17:24:44 +04:00
{
return 1 ;
}
// Read the rerun check file and use it to decide whether to do the
// global generate.
cmake cm ;
cmGlobalGenerator gg ;
gg . SetCMakeInstance ( & cm ) ;
std : : auto_ptr < cmLocalGenerator > lg ( gg . CreateLocalGenerator ( ) ) ;
lg - > SetGlobalGenerator ( & gg ) ;
cmMakefile * mf = lg - > GetMakefile ( ) ;
2004-10-30 00:50:46 +04:00
if ( ! mf - > ReadListFile ( 0 , m_CheckBuildSystem . c_str ( ) ) | |
2004-10-15 17:24:44 +04:00
cmSystemTools : : GetErrorOccuredFlag ( ) )
{
// There was an error reading the file. Just rerun.
return 1 ;
}
// Get the set of dependencies and outputs.
const char * dependsStr = mf - > GetDefinition ( " CMAKE_MAKEFILE_DEPENDS " ) ;
const char * outputsStr = mf - > GetDefinition ( " CMAKE_MAKEFILE_OUTPUTS " ) ;
if ( ! dependsStr | | ! outputsStr )
{
// Not enough information was provided to do the test. Just rerun.
return 1 ;
}
std : : vector < std : : string > depends ;
std : : vector < std : : string > outputs ;
cmSystemTools : : ExpandListArgument ( dependsStr , depends ) ;
cmSystemTools : : ExpandListArgument ( outputsStr , outputs ) ;
// If any output is older than any dependency then rerun.
for ( std : : vector < std : : string > : : iterator dep = depends . begin ( ) ;
dep ! = depends . end ( ) ; + + dep )
{
for ( std : : vector < std : : string > : : iterator out = outputs . begin ( ) ;
out ! = outputs . end ( ) ; + + out )
{
int result = 0 ;
2005-10-21 00:37:14 +04:00
if ( ! m_FileComparison - > FileTimeCompare ( out - > c_str ( ) ,
dep - > c_str ( ) , & result ) | |
2004-10-15 17:24:44 +04:00
result < 0 )
{
return 1 ;
}
}
}
2005-05-06 17:58:58 +04:00
// We do not need to rerun CMake. Check dependency integrity. Use
// the make system's VERBOSE environment variable to enable verbose
// output.
2005-05-06 20:38:23 +04:00
bool verbose = cmSystemTools : : GetEnv ( " VERBOSE " ) ! = 0 ;
2005-05-12 18:49:56 +04:00
// compute depends based on the generator specified
const char * genName = mf - > GetDefinition ( " CMAKE_DEPENDS_GENERATOR " ) ;
if ( ! genName | | genName [ 0 ] = = ' \0 ' )
{
genName = " Unix Makefiles " ;
}
cmGlobalGenerator * ggd = this - > CreateGlobalGenerator ( genName ) ;
if ( ggd )
{
std : : auto_ptr < cmLocalGenerator > lgd ( ggd - > CreateLocalGenerator ( ) ) ;
lgd - > SetGlobalGenerator ( ggd ) ;
2005-06-10 18:45:08 +04:00
lgd - > CheckDependencies ( mf , verbose , m_ClearBuildSystem ) ;
2005-05-12 18:49:56 +04:00
}
2004-10-30 00:50:46 +04:00
2004-10-15 17:24:44 +04:00
// No need to rerun.
return 0 ;
}
2005-07-03 06:25:43 +04:00
//----------------------------------------------------------------------------
void cmake : : TruncateOutputLog ( const char * fname )
{
std : : string fullPath = this - > GetHomeOutputDirectory ( ) ;
fullPath + = " / " ;
fullPath + = fname ;
struct stat st ;
if ( : : stat ( fullPath . c_str ( ) , & st ) )
{
return ;
}
if ( ! m_CacheManager - > GetCacheValue ( " CMAKE_CACHEFILE_DIR " ) )
{
cmSystemTools : : RemoveFile ( fullPath . c_str ( ) ) ;
return ;
}
size_t fsize = st . st_size ;
const size_t maxFileSize = 50 * 1024 ;
if ( fsize < maxFileSize )
{
//TODO: truncate file
return ;
}
}
2006-02-23 18:00:44 +03:00
inline std : : string removeQuotes ( const std : : string & s )
{
if ( s [ 0 ] = = ' \" ' & & s [ s . size ( ) - 1 ] = = ' \" ' )
{
return s . substr ( 1 , s . size ( ) - 2 ) ;
}
return s ;
}
const char * cmake : : GetCTestCommand ( )
{
if ( ! m_CTestCommand . empty ( ) )
{
return m_CTestCommand . c_str ( ) ;
}
cmMakefile * mf = this - > GetGlobalGenerator ( ) - > GetLocalGenerator ( 0 ) - > GetMakefile ( ) ;
2006-02-24 16:57:05 +03:00
# ifdef CMAKE_BUILD_WITH_CMAKE
2006-02-23 18:00:44 +03:00
m_CTestCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CTestCommand = removeQuotes ( m_CTestCommand ) ;
m_CTestCommand = cmSystemTools : : GetFilenamePath ( m_CTestCommand . c_str ( ) ) ;
m_CTestCommand + = " / " ;
m_CTestCommand + = " ctest " ;
m_CTestCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
if ( ! cmSystemTools : : FileExists ( m_CTestCommand . c_str ( ) ) )
{
m_CTestCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CTestCommand = cmSystemTools : : GetFilenamePath ( m_CTestCommand . c_str ( ) ) ;
m_CTestCommand + = " /Debug/ " ;
m_CTestCommand + = " ctest " ;
m_CTestCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
}
if ( ! cmSystemTools : : FileExists ( m_CTestCommand . c_str ( ) ) )
{
m_CTestCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CTestCommand = cmSystemTools : : GetFilenamePath ( m_CTestCommand . c_str ( ) ) ;
m_CTestCommand + = " /Release/ " ;
m_CTestCommand + = " ctest " ;
m_CTestCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
}
2006-02-24 16:57:05 +03:00
# else
// Only for bootstrap
m_CTestCommand + = mf - > GetSafeDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
m_CTestCommand + = " /ctest " ;
m_CTestCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
# endif
2006-02-23 18:00:44 +03:00
if ( m_CTestCommand . empty ( ) )
{
cmSystemTools : : Error ( " Cannot find the CTest executable " ) ;
m_CTestCommand = " CTEST-COMMAND-NOT-FOUND " ;
}
return m_CTestCommand . c_str ( ) ;
}
const char * cmake : : GetCPackCommand ( )
{
if ( ! m_CPackCommand . empty ( ) )
{
return m_CPackCommand . c_str ( ) ;
}
cmMakefile * mf = this - > GetGlobalGenerator ( ) - > GetLocalGenerator ( 0 ) - > GetMakefile ( ) ;
# ifdef CMAKE_BUILD_WITH_CMAKE
m_CPackCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CPackCommand = removeQuotes ( m_CPackCommand ) ;
m_CPackCommand = cmSystemTools : : GetFilenamePath ( m_CPackCommand . c_str ( ) ) ;
m_CPackCommand + = " / " ;
m_CPackCommand + = " cpack " ;
m_CPackCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
if ( ! cmSystemTools : : FileExists ( m_CPackCommand . c_str ( ) ) )
{
m_CPackCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CPackCommand = cmSystemTools : : GetFilenamePath ( m_CPackCommand . c_str ( ) ) ;
m_CPackCommand + = " /Debug/ " ;
m_CPackCommand + = " cpack " ;
m_CPackCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
}
if ( ! cmSystemTools : : FileExists ( m_CPackCommand . c_str ( ) ) )
{
m_CPackCommand = mf - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
m_CPackCommand = cmSystemTools : : GetFilenamePath ( m_CPackCommand . c_str ( ) ) ;
m_CPackCommand + = " /Release/ " ;
m_CPackCommand + = " cpack " ;
m_CPackCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
}
if ( ! cmSystemTools : : FileExists ( m_CPackCommand . c_str ( ) ) )
{
cmSystemTools : : Error ( " Cannot find the CPack executable " ) ;
m_CPackCommand = " CPACK-COMMAND-NOT-FOUND " ;
}
# else
// Only for bootstrap
m_CPackCommand + = mf - > GetSafeDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
m_CPackCommand + = " /cpack " ;
m_CPackCommand + = cmSystemTools : : GetExecutableExtension ( ) ;
# endif
return m_CPackCommand . c_str ( ) ;
}
2006-03-03 22:24:31 +03:00
void cmake : : GenerateGraphViz ( const char * fileName )
{
cmGeneratedFileStream str ( fileName ) ;
if ( ! str )
{
return ;
}
2006-03-07 23:31:05 +03:00
cmake cm ;
cmGlobalGenerator ggi ;
ggi . SetCMakeInstance ( & cm ) ;
std : : auto_ptr < cmLocalGenerator > lg ( ggi . CreateLocalGenerator ( ) ) ;
lg - > SetGlobalGenerator ( & ggi ) ;
cmMakefile * mf = lg - > GetMakefile ( ) ;
std : : string infile = this - > GetHomeOutputDirectory ( ) ;
infile + = " /CMakeGraphVizOptions.cmake " ;
if ( ! cmSystemTools : : FileExists ( infile . c_str ( ) ) )
{
infile = this - > GetHomeDirectory ( ) ;
infile + = " /CMakeGraphVizOptions.cmake " ;
if ( ! cmSystemTools : : FileExists ( infile . c_str ( ) ) )
{
infile = " " ;
}
}
if ( ! infile . empty ( ) )
{
if ( ! mf - > ReadListFile ( 0 , infile . c_str ( ) ) )
{
cmSystemTools : : Error ( " Problem opening GraphViz options file: " , infile . c_str ( ) ) ;
return ;
}
std : : cout < < " Read GraphViz options file: " < < infile . c_str ( ) < < std : : endl ;
}
# define __set_if_not_set(var, value, cmakeDefinition) \
const char * var = mf - > GetDefinition ( cmakeDefinition ) ; \
if ( ! var ) \
{ \
var = value ; \
}
__set_if_not_set ( graphType , " digraph " , " GRAPHVIZ_GRAPH_TYPE " ) ;
__set_if_not_set ( graphName , " GG " , " GRAPHVIZ_GRAPH_NAME " ) ;
__set_if_not_set ( graphHeader , " node [ \n fontsize = \" 12 \" \n ]; " , " GRAPHVIZ_GRAPH_HEADER " ) ;
__set_if_not_set ( graphNodePrefix , " node " , " GRAPHVIZ_NODE_PREFIX " ) ;
const char * ignoreTargets = mf - > GetDefinition ( " GRAPHVIZ_IGNORE_TARGETS " ) ;
std : : set < cmStdString > ignoreTargetsSet ;
if ( ignoreTargets )
{
std : : vector < std : : string > ignoreTargetsVector ;
cmSystemTools : : ExpandListArgument ( ignoreTargets , ignoreTargetsVector ) ;
std : : vector < std : : string > : : iterator itvIt ;
for ( itvIt = ignoreTargetsVector . begin ( ) ; itvIt ! = ignoreTargetsVector . end ( ) ; + + itvIt )
{
ignoreTargetsSet . insert ( itvIt - > c_str ( ) ) ;
}
}
str < < graphType < < " " < < graphName < < " { " < < std : : endl ;
str < < graphHeader < < std : : endl ;
2006-03-03 22:24:31 +03:00
cmGlobalGenerator * gg = this - > GetGlobalGenerator ( ) ;
std : : vector < cmLocalGenerator * > localGenerators ;
gg - > GetLocalGenerators ( localGenerators ) ;
std : : vector < cmLocalGenerator * > : : iterator lit ;
// for target deps
// 1 - cmake target
// 2 - external target
// 0 - no deps
std : : map < cmStdString , int > targetDeps ;
std : : map < cmStdString , cmTarget * > targetPtrs ;
std : : map < cmStdString , cmStdString > targetNamesNodes ;
char tgtName [ 100 ] ;
int cnt = 0 ;
// First pass get the list of all cmake targets
for ( lit = localGenerators . begin ( ) ; lit ! = localGenerators . end ( ) ; + + lit )
{
cmTargets * targets = & ( ( * lit ) - > GetMakefile ( ) - > GetTargets ( ) ) ;
cmTargets : : iterator tit ;
for ( tit = targets - > begin ( ) ; tit ! = targets - > end ( ) ; + + tit )
{
2006-03-07 23:31:05 +03:00
const char * realTargetName = tit - > first . c_str ( ) ;
if ( ignoreTargetsSet . find ( realTargetName ) ! = ignoreTargetsSet . end ( ) )
{
// Skip ignored targets
continue ;
}
2006-03-03 22:24:31 +03:00
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
2006-03-07 23:31:05 +03:00
sprintf ( tgtName , " %s%d " , graphNodePrefix , cnt + + ) ;
targetNamesNodes [ realTargetName ] = tgtName ;
targetPtrs [ realTargetName ] = & tit - > second ;
2006-03-03 22:24:31 +03:00
//str << " \"" << tgtName << "\" [ label=\"" << tit->first.c_str() << "\" shape=\"box\"];" << std::endl;
}
}
// Ok, now find all the stuff we link to that is not in cmake
for ( lit = localGenerators . begin ( ) ; lit ! = localGenerators . end ( ) ; + + lit )
{
cmTargets * targets = & ( ( * lit ) - > GetMakefile ( ) - > GetTargets ( ) ) ;
cmTargets : : iterator tit ;
for ( tit = targets - > begin ( ) ; tit ! = targets - > end ( ) ; + + tit )
{
const cmTarget : : LinkLibraries * ll = & ( tit - > second . GetOriginalLinkLibraries ( ) ) ;
cmTarget : : LinkLibraries : : const_iterator llit ;
2006-03-07 23:31:05 +03:00
const char * realTargetName = tit - > first . c_str ( ) ;
if ( ignoreTargetsSet . find ( realTargetName ) ! = ignoreTargetsSet . end ( ) )
{
// Skip ignored targets
continue ;
}
2006-03-03 22:24:31 +03:00
if ( ll - > size ( ) > 0 )
{
2006-03-07 23:31:05 +03:00
targetDeps [ realTargetName ] = 1 ;
2006-03-03 22:24:31 +03:00
}
for ( llit = ll - > begin ( ) ; llit ! = ll - > end ( ) ; + + llit )
{
const char * libName = llit - > first . c_str ( ) ;
std : : map < cmStdString , cmStdString > : : iterator tarIt = targetNamesNodes . find ( libName ) ;
2006-03-07 23:31:05 +03:00
if ( ignoreTargetsSet . find ( libName ) ! = ignoreTargetsSet . end ( ) )
{
// Skip ignored targets
continue ;
}
2006-03-03 22:24:31 +03:00
if ( tarIt = = targetNamesNodes . end ( ) )
{
2006-03-07 23:31:05 +03:00
sprintf ( tgtName , " %s%d " , graphNodePrefix , cnt + + ) ;
2006-03-03 22:24:31 +03:00
targetDeps [ libName ] = 2 ;
targetNamesNodes [ libName ] = tgtName ;
//str << " \"" << tgtName << "\" [ label=\"" << libName << "\" shape=\"ellipse\"];" << std::endl;
}
else
{
std : : map < cmStdString , int > : : iterator depIt = targetDeps . find ( libName ) ;
if ( depIt = = targetDeps . end ( ) )
{
targetDeps [ libName ] = 1 ;
}
}
}
}
}
// Write out nodes
std : : map < cmStdString , int > : : iterator depIt ;
for ( depIt = targetDeps . begin ( ) ; depIt ! = targetDeps . end ( ) ; + + depIt )
{
2006-03-07 20:03:11 +03:00
const char * newTargetName = depIt - > first . c_str ( ) ;
std : : map < cmStdString , cmStdString > : : iterator tarIt = targetNamesNodes . find ( newTargetName ) ;
2006-03-03 22:24:31 +03:00
if ( tarIt = = targetNamesNodes . end ( ) )
{
// We should not be here.
2006-03-07 23:31:05 +03:00
std : : cout < < __LINE__ < < " Cannot find library: " < < newTargetName < < " even though it was added in the previous pass " < < std : : endl ;
2006-03-03 22:24:31 +03:00
abort ( ) ;
}
2006-03-07 20:03:11 +03:00
str < < " \" " < < tarIt - > second . c_str ( ) < < " \" [ label= \" " < < newTargetName < < " \" shape= \" " ;
2006-03-03 22:24:31 +03:00
if ( depIt - > second = = 1 )
{
2006-03-07 20:03:11 +03:00
std : : map < cmStdString , cmTarget * > : : iterator tarTypeIt = targetPtrs . find ( newTargetName ) ;
2006-03-03 22:28:28 +03:00
if ( tarTypeIt = = targetPtrs . end ( ) )
2006-03-03 22:24:31 +03:00
{
// We should not be here.
2006-03-07 23:31:05 +03:00
std : : cout < < __LINE__ < < " Cannot find library: " < < newTargetName < < " even though it was added in the previous pass " < < std : : endl ;
2006-03-03 22:24:31 +03:00
abort ( ) ;
}
cmTarget * tg = tarTypeIt - > second ;
switch ( tg - > GetType ( ) )
{
case cmTarget : : EXECUTABLE :
str < < " house " ;
break ;
case cmTarget : : STATIC_LIBRARY :
str < < " diamond " ;
break ;
case cmTarget : : SHARED_LIBRARY :
str < < " polygon " ;
break ;
case cmTarget : : MODULE_LIBRARY :
str < < " octagon " ;
break ;
default :
str < < " box " ;
}
}
else
{
str < < " ellipse " ;
}
str < < " \" ]; " < < std : : endl ;
}
// Now generate the connectivity
for ( lit = localGenerators . begin ( ) ; lit ! = localGenerators . end ( ) ; + + lit )
{
cmTargets * targets = & ( ( * lit ) - > GetMakefile ( ) - > GetTargets ( ) ) ;
cmTargets : : iterator tit ;
for ( tit = targets - > begin ( ) ; tit ! = targets - > end ( ) ; + + tit )
{
2006-03-07 20:03:11 +03:00
std : : map < cmStdString , int > : : iterator dependIt = targetDeps . find ( tit - > first . c_str ( ) ) ;
if ( dependIt = = targetDeps . end ( ) )
2006-03-03 22:24:31 +03:00
{
continue ;
}
std : : map < cmStdString , cmStdString > : : iterator cmakeTarIt = targetNamesNodes . find ( tit - > first . c_str ( ) ) ;
const cmTarget : : LinkLibraries * ll = & ( tit - > second . GetOriginalLinkLibraries ( ) ) ;
cmTarget : : LinkLibraries : : const_iterator llit ;
for ( llit = ll - > begin ( ) ; llit ! = ll - > end ( ) ; + + llit )
{
const char * libName = llit - > first . c_str ( ) ;
std : : map < cmStdString , cmStdString > : : iterator tarIt = targetNamesNodes . find ( libName ) ;
if ( tarIt = = targetNamesNodes . end ( ) )
{
// We should not be here.
2006-03-07 23:31:05 +03:00
std : : cout < < __LINE__ < < " Cannot find library: " < < libName < < " even though it was added in the previous pass " < < std : : endl ;
2006-03-03 22:24:31 +03:00
abort ( ) ;
}
str < < " \" " < < cmakeTarIt - > second . c_str ( ) < < " \" -> \" " < < tarIt - > second . c_str ( ) < < " \" " < < std : : endl ;
}
}
}
// TODO: Use dotted or something for external libraries
//str << " \"node0\":f4 -> \"node12\"[color=\"#0000ff\" style=dotted]" << std::endl;
//
str < < " } " < < std : : endl ;
}