2001-01-11 22:55:47 +03:00
/*=========================================================================
2002-10-24 02:03:27 +04:00
Program : CMake - Cross - Platform Makefile Generator
2001-01-11 22:55:47 +03: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-01-11 22:55:47 +03: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-01-11 22:55:47 +03:00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2000-08-29 23:26:29 +04:00
# include "cmMakefile.h"
2001-01-18 19:20:24 +03:00
# include "cmCommand.h"
2001-04-25 00:49:12 +04:00
# include "cmSourceFile.h"
2000-09-12 13:30:35 +04:00
# include "cmSystemTools.h"
2002-09-06 21:06:23 +04:00
# include "cmGlobalGenerator.h"
# include "cmLocalGenerator.h"
2001-02-13 03:49:52 +03:00
# include "cmCommands.h"
2001-02-19 23:13:48 +03:00
# include "cmCacheManager.h"
2001-04-20 01:39:03 +04:00
# include "cmFunctionBlocker.h"
2001-08-29 02:28:31 +04:00
# include "cmListFileCache.h"
2003-01-08 20:59:52 +03:00
# include "cmVariableWatch.h"
2002-08-28 22:51:10 +04:00
# include "cmake.h"
2003-05-24 00:40:55 +04:00
# include <stdlib.h> // required for atoi
2003-06-23 22:10:12 +04:00
# include <cmsys/RegularExpression.hxx>
2000-08-29 23:26:29 +04:00
// default is not to be building executables
cmMakefile : : cmMakefile ( )
{
2001-06-21 23:02:52 +04:00
// Setup the default include file regular expression (match everything).
m_IncludeFileRegularExpression = " ^.*$ " ;
// Setup the default include complaint regular expression (match nothing).
m_ComplainFileRegularExpression = " ^$ " ;
2001-07-17 02:40:42 +04:00
// Source and header file extensions that we can handle
2003-03-14 18:54:53 +03:00
2004-09-03 20:03:41 +04:00
// Set up a list of source and header extensions
// these are used to find files when the extension
// is not given
2003-03-14 18:54:53 +03:00
// The "c" extension MUST precede the "C" extension.
m_SourceFileExtensions . push_back ( " c " ) ;
2003-03-13 20:24:16 +03:00
m_SourceFileExtensions . push_back ( " C " ) ;
2003-03-14 18:54:53 +03:00
2003-03-13 20:24:16 +03:00
m_SourceFileExtensions . push_back ( " c++ " ) ;
m_SourceFileExtensions . push_back ( " cc " ) ;
m_SourceFileExtensions . push_back ( " cpp " ) ;
m_SourceFileExtensions . push_back ( " cxx " ) ;
2001-07-17 02:40:42 +04:00
m_SourceFileExtensions . push_back ( " m " ) ;
2003-03-14 19:58:56 +03:00
m_SourceFileExtensions . push_back ( " M " ) ;
2001-08-21 19:04:38 +04:00
m_SourceFileExtensions . push_back ( " mm " ) ;
2001-07-17 02:40:42 +04:00
m_HeaderFileExtensions . push_back ( " h " ) ;
2003-03-13 20:24:16 +03:00
m_HeaderFileExtensions . push_back ( " h++ " ) ;
m_HeaderFileExtensions . push_back ( " hm " ) ;
m_HeaderFileExtensions . push_back ( " hpp " ) ;
m_HeaderFileExtensions . push_back ( " hxx " ) ;
2002-03-15 00:04:02 +03:00
m_HeaderFileExtensions . push_back ( " in " ) ;
2003-03-13 20:24:16 +03:00
m_HeaderFileExtensions . push_back ( " txx " ) ;
2001-03-16 02:09:16 +03:00
2001-01-05 19:41:20 +03:00
m_DefineFlags = " " ;
2002-09-06 21:06:23 +04:00
m_LocalGenerator = 0 ;
2001-03-20 21:20:59 +03:00
this - > AddSourceGroup ( " " , " ^.*$ " ) ;
2003-03-13 20:24:16 +03:00
this - > AddSourceGroup ( " Source Files " ,
2003-03-13 20:48:52 +03:00
" \\ .(C|M|c|c \\ + \\ +|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat)$ " ) ;
this - > AddSourceGroup ( " Header Files " , " \\ .(h|h \\ + \\ +|hm|hpp|hxx|in|txx|inl)$ " ) ;
2003-06-03 18:30:23 +04:00
this - > AddSourceGroup ( " CMake Rules " , " \\ .rule$ " ) ;
2001-03-08 18:30:18 +03:00
this - > AddDefaultDefinitions ( ) ;
2004-03-04 02:18:47 +03:00
m_cmDefineRegex . compile ( " #cmakedefine[ \t ]*([A-Za-z_0-9]*) " ) ;
}
2001-01-05 19:41:20 +03:00
2003-02-14 05:57:05 +03:00
const char * cmMakefile : : GetReleaseVersion ( )
{
# if CMake_VERSION_MINOR & 1
return " development " ;
# else
2003-08-11 22:45:16 +04:00
# if CMake_VERSION_PATCH == 0
return " beta " ;
# else
2003-02-14 05:57:05 +03:00
return " patch " CMAKE_TO_STRING ( CMake_VERSION_PATCH ) ;
2003-08-11 22:45:16 +04:00
# endif
2003-02-14 05:57:05 +03:00
# endif
}
2001-06-07 22:52:29 +04:00
unsigned int cmMakefile : : GetCacheMajorVersion ( )
{
2002-09-06 21:06:23 +04:00
if ( ! this - > GetCacheManager ( ) - > GetCacheValue ( " CMAKE_CACHE_MAJOR_VERSION " ) )
2001-06-07 22:52:29 +04:00
{
return 0 ;
}
2002-09-06 21:06:23 +04:00
return atoi ( this - > GetCacheManager ( ) - > GetCacheValue ( " CMAKE_CACHE_MAJOR_VERSION " ) ) ;
2001-06-07 22:52:29 +04:00
}
unsigned int cmMakefile : : GetCacheMinorVersion ( )
{
2002-09-06 21:06:23 +04:00
if ( ! this - > GetCacheManager ( ) - > GetCacheValue ( " Cmake_Cache_MINOR_VERSION " ) )
2001-06-07 22:52:29 +04:00
{
return 0 ;
}
2002-09-06 21:06:23 +04:00
return atoi ( this - > GetCacheManager ( ) - > GetCacheValue ( " CMAKE_CACHE_MINOR_VERSION " ) ) ;
2001-06-07 22:52:29 +04:00
}
2001-01-05 19:41:20 +03:00
cmMakefile : : ~ cmMakefile ( )
{
2002-03-29 18:06:30 +03:00
for ( std : : vector < cmSourceFile * > : : iterator i = m_SourceFiles . begin ( ) ;
i ! = m_SourceFiles . end ( ) ; + + i )
{
delete * i ;
}
2001-02-23 18:40:13 +03:00
for ( unsigned int i = 0 ; i < m_UsedCommands . size ( ) ; i + + )
2001-01-05 19:41:20 +03:00
{
2001-01-18 19:20:24 +03:00
delete m_UsedCommands [ i ] ;
2001-01-05 19:41:20 +03:00
}
2001-05-16 17:19:46 +04:00
for ( DataMap : : const_iterator d = m_DataMap . begin ( ) ;
d ! = m_DataMap . end ( ) ; + + d )
{
if ( d - > second )
{
delete d - > second ;
}
}
2002-07-11 22:20:39 +04:00
std : : list < cmFunctionBlocker * > : : iterator pos ;
2001-06-04 18:18:03 +04:00
for ( pos = m_FunctionBlockers . begin ( ) ;
2002-09-26 21:52:12 +04:00
pos ! = m_FunctionBlockers . end ( ) ; + + pos )
2001-06-04 18:18:03 +04:00
{
cmFunctionBlocker * b = * pos ;
delete b ;
}
2002-09-26 21:52:12 +04:00
m_FunctionBlockers . clear ( ) ;
2001-01-05 19:41:20 +03:00
}
2001-04-20 01:39:03 +04:00
void cmMakefile : : PrintStringVector ( const char * s , const std : : vector < std : : string > & v ) const
2001-01-05 19:41:20 +03:00
{
std : : cout < < s < < " : ( \n " ;
2001-04-20 01:39:03 +04:00
for ( std : : vector < std : : string > : : const_iterator i = v . begin ( ) ;
2001-01-05 19:41:20 +03:00
i ! = v . end ( ) ; + + i )
{
std : : cout < < ( * i ) . c_str ( ) < < " " ;
}
std : : cout < < " ) \n " ;
2000-08-29 23:26:29 +04:00
}
2004-03-10 00:28:44 +03:00
void cmMakefile : : PrintStringVector ( const char * s , const std : : vector < std : : pair < cmStdString , bool > > & v ) const
{
std : : cout < < s < < " : ( \n " ;
for ( std : : vector < std : : pair < cmStdString , bool > > : : const_iterator i = v . begin ( ) ;
i ! = v . end ( ) ; + + i )
{
std : : cout < < i - > first . c_str ( ) < < " " < < i - > second ;
}
std : : cout < < " ) \n " ;
}
2000-08-29 23:26:29 +04:00
// call print on all the classes in the makefile
2001-04-20 01:39:03 +04:00
void cmMakefile : : Print ( ) const
2000-08-29 23:26:29 +04:00
{
2001-04-11 22:59:02 +04:00
// print the class lists
2001-01-05 19:41:20 +03:00
std : : cout < < " classes: \n " ;
2001-06-22 17:47:02 +04:00
2001-04-11 22:59:02 +04:00
std : : cout < < " m_Targets: " ;
for ( cmTargets : : const_iterator l = m_Targets . begin ( ) ;
l ! = m_Targets . end ( ) ; l + + )
{
std : : cout < < l - > first < < std : : endl ;
}
2001-02-15 21:30:13 +03:00
std : : cout < < " m_CurrentOutputDirectory; " < <
m_CurrentOutputDirectory . c_str ( ) < < std : : endl ;
std : : cout < < " m_StartOutputDirectory; " < <
m_StartOutputDirectory . c_str ( ) < < std : : endl ;
std : : cout < < " m_HomeOutputDirectory; " < <
m_HomeOutputDirectory . c_str ( ) < < std : : endl ;
2001-01-05 19:41:20 +03:00
std : : cout < < " m_cmCurrentDirectory; " < <
m_cmCurrentDirectory . c_str ( ) < < std : : endl ;
2001-02-15 21:30:13 +03:00
std : : cout < < " m_cmStartDirectory; " < <
m_cmStartDirectory . c_str ( ) < < std : : endl ;
std : : cout < < " m_cmHomeDirectory; " < <
m_cmHomeDirectory . c_str ( ) < < std : : endl ;
2002-10-05 02:16:13 +04:00
std : : cout < < " m_ProjectName; " < < m_ProjectName . c_str ( ) < < std : : endl ;
2001-01-05 19:41:20 +03:00
this - > PrintStringVector ( " m_SubDirectories " , m_SubDirectories ) ;
this - > PrintStringVector ( " m_IncludeDirectories; " , m_IncludeDirectories ) ;
this - > PrintStringVector ( " m_LinkDirectories " , m_LinkDirectories ) ;
2001-05-04 19:30:46 +04:00
for ( std : : vector < cmSourceGroup > : : const_iterator i = m_SourceGroups . begin ( ) ;
i ! = m_SourceGroups . end ( ) ; + + i )
{
2003-06-03 18:30:23 +04:00
std : : cout < < " Source Group: " < < i - > GetName ( ) < < std : : endl ;
2001-05-04 19:30:46 +04:00
}
2000-08-29 23:26:29 +04:00
}
2001-12-18 17:39:26 +03:00
bool cmMakefile : : CommandExists ( const char * name ) const
{
2003-01-14 17:53:13 +03:00
return this - > GetCMakeInstance ( ) - > CommandExists ( name ) ;
2001-12-18 17:39:26 +03:00
}
2002-12-12 19:36:28 +03:00
bool cmMakefile : : ExecuteCommand ( const cmListFileFunction & lff )
2001-07-26 00:53:13 +04:00
{
2002-12-12 19:36:28 +03:00
bool result = true ;
2002-07-17 18:48:39 +04:00
// quick return if blocked
2002-12-12 02:13:33 +03:00
if ( this - > IsFunctionBlocked ( lff ) )
2002-07-17 18:48:39 +04:00
{
2002-12-12 19:36:28 +03:00
// No error.
return result ;
2002-07-17 18:48:39 +04:00
}
2002-12-12 02:13:33 +03:00
std : : string name = lff . m_Name ;
2002-07-17 18:48:39 +04:00
// execute the command
2002-09-11 00:52:39 +04:00
cmCommand * rm =
2003-01-14 17:53:13 +03:00
this - > GetCMakeInstance ( ) - > GetCommand ( name . c_str ( ) ) ;
2002-09-11 00:52:39 +04:00
if ( rm )
2001-07-26 00:53:13 +04:00
{
2003-07-21 22:44:00 +04:00
const char * versionValue
= this - > GetDefinition ( " CMAKE_BACKWARDS_COMPATIBILITY " ) ;
int major = 0 ;
int minor = 0 ;
if ( versionValue )
{
sscanf ( versionValue , " %d.%d " , & major , & minor ) ;
}
if ( rm - > IsDeprecated ( major , minor ) )
{
cmOStringStream error ;
error < < " Error in cmake code at \n "
< < lff . m_FilePath < < " : " < < lff . m_Line < < " : \n "
< < rm - > GetError ( ) ;
cmSystemTools : : Error ( error . str ( ) . c_str ( ) ) ;
return false ;
}
2001-07-26 00:53:13 +04:00
cmCommand * usedCommand = rm - > Clone ( ) ;
usedCommand - > SetMakefile ( this ) ;
bool keepCommand = false ;
2003-10-29 17:45:26 +03:00
if ( usedCommand - > GetEnabled ( ) & & ! cmSystemTools : : GetFatalErrorOccured ( ) & &
( ! this - > GetCMakeInstance ( ) - > GetScriptMode ( ) | |
usedCommand - > IsScriptable ( ) ) )
2001-07-26 00:53:13 +04:00
{
// if not running in inherit mode or
// if the command is inherited then InitialPass it.
if ( ! m_Inheriting | | usedCommand - > IsInherited ( ) )
{
2002-12-12 02:13:33 +03:00
if ( ! usedCommand - > InvokeInitialPass ( lff . m_Arguments ) )
2002-03-06 02:41:24 +03:00
{
2002-12-12 02:13:33 +03:00
cmOStringStream error ;
error < < " Error in cmake code at \n "
2003-07-21 22:44:00 +04:00
< < lff . m_FilePath < < " : " < < lff . m_Line < < " : \n "
< < usedCommand - > GetError ( ) ;
2002-12-12 02:13:33 +03:00
cmSystemTools : : Error ( error . str ( ) . c_str ( ) ) ;
2002-12-12 19:36:28 +03:00
result = false ;
2003-10-29 17:45:26 +03:00
if ( this - > GetCMakeInstance ( ) - > GetScriptMode ( ) )
{
cmSystemTools : : SetFatalErrorOccured ( ) ;
}
2001-07-26 00:53:13 +04:00
}
else
{
// use the command
keepCommand = true ;
m_UsedCommands . push_back ( usedCommand ) ;
}
}
}
2003-10-29 17:45:26 +03:00
else if ( this - > GetCMakeInstance ( ) - > GetScriptMode ( ) & & ! usedCommand - > IsScriptable ( ) )
{
cmOStringStream error ;
error < < " Error in cmake code at \n "
< < lff . m_FilePath < < " : " < < lff . m_Line < < " : \n "
< < " Command " < < usedCommand - > GetName ( ) < < " not scriptable " < < std : : endl ;
cmSystemTools : : Error ( error . str ( ) . c_str ( ) ) ;
result = false ;
cmSystemTools : : SetFatalErrorOccured ( ) ;
}
2001-07-26 00:53:13 +04:00
// if the Cloned command was not used
// then delete it
if ( ! keepCommand )
{
delete usedCommand ;
}
}
else
{
2003-01-21 20:50:48 +03:00
if ( ! cmSystemTools : : GetFatalErrorOccured ( ) )
{
cmOStringStream error ;
error < < " Error in cmake code at \n "
< < lff . m_FilePath < < " : " < < lff . m_Line < < " : \n "
< < " Unknown CMake command \" " < < lff . m_Name . c_str ( ) < < " \" . " ;
cmSystemTools : : Error ( error . str ( ) . c_str ( ) ) ;
result = false ;
}
2001-07-26 00:53:13 +04:00
}
2002-12-12 19:36:28 +03:00
return result ;
2001-07-26 00:53:13 +04:00
}
2000-08-30 21:35:41 +04:00
// Parse the given CMakeLists.txt file into a list of classes.
2001-02-15 21:30:13 +03:00
// Reads in current CMakeLists file and all parent CMakeLists files
// executing all inherited commands in the parents
2001-04-30 18:52:58 +04:00
//
// if external is non-zero, this means that we have branched to grab some
// commands from a remote list-file (that is, the equivalent of a
// #include has been called). We DO NOT look at the parents of this
// list-file, and for all other purposes, the name of this list-file
// is "filename" and not "external".
2003-02-07 22:04:16 +03:00
bool cmMakefile : : ReadListFile ( const char * filename_in , const char * external_in )
2000-08-29 23:26:29 +04:00
{
2002-07-10 19:38:38 +04:00
// used to watch for blockers going out of scope
// e.g. mismatched IF statement
std : : set < cmFunctionBlocker * > originalBlockers ;
2003-02-07 22:04:16 +03:00
const char * external = 0 ;
std : : string external_abs ;
const char * filename = filename_in ;
std : : string filename_abs ;
if ( external_in )
{
external_abs =
cmSystemTools : : CollapseFullPath ( external_in ,
m_cmCurrentDirectory . c_str ( ) ) ;
external = external_abs . c_str ( ) ;
if ( filename_in )
{
filename_abs =
cmSystemTools : : CollapseFullPath ( filename_in ,
m_cmCurrentDirectory . c_str ( ) ) ;
filename = filename_abs . c_str ( ) ;
}
}
2002-07-10 19:38:38 +04:00
// keep track of the current file being read
2001-05-03 16:52:32 +04:00
if ( filename )
{
2001-06-04 18:18:03 +04:00
if ( m_cmCurrentListFile ! = filename )
{
m_cmCurrentListFile = filename ;
}
2002-07-10 19:38:38 +04:00
// loop over current function blockers and record them
2002-07-11 22:20:39 +04:00
std : : list < cmFunctionBlocker * > : : iterator pos ;
2002-07-10 19:38:38 +04:00
for ( pos = m_FunctionBlockers . begin ( ) ;
pos ! = m_FunctionBlockers . end ( ) ; + + pos )
{
originalBlockers . insert ( * pos ) ;
}
2001-05-03 16:52:32 +04:00
}
2002-07-10 19:38:38 +04:00
2001-04-30 18:52:58 +04:00
// if this is not a remote makefile
// (if it were, this would be called from the "filename" call,
// rather than the "external" call)
if ( ! external )
2001-01-05 19:41:20 +03:00
{
2001-04-30 18:52:58 +04:00
// is there a parent CMakeLists file that does not go beyond the
// Home directory? if so recurse and read in that List file
std : : string parentList = this - > GetParentListFileName ( filename ) ;
if ( parentList ! = " " )
2002-10-05 02:16:13 +04:00
{
2003-07-08 21:27:34 +04:00
std : : string srcdir = this - > GetCurrentDirectory ( ) ;
std : : string bindir = this - > GetCurrentOutputDirectory ( ) ;
2002-02-25 23:06:18 +03:00
2002-10-05 02:16:13 +04:00
std : : string : : size_type pos = parentList . rfind ( ' / ' ) ;
2002-02-25 23:06:18 +03:00
2003-07-08 21:27:34 +04:00
this - > SetCurrentDirectory ( parentList . substr ( 0 , pos ) . c_str ( ) ) ;
this - > SetCurrentOutputDirectory ( ( m_HomeOutputDirectory +
parentList . substr ( m_cmHomeDirectory . size ( ) ,
pos - m_cmHomeDirectory . size ( ) ) ) . c_str ( ) ) ;
2002-02-25 23:06:18 +03:00
2002-10-05 02:16:13 +04:00
// if not found, oops
if ( pos = = std : : string : : npos )
{
2002-02-25 23:06:18 +03:00
cmSystemTools : : Error ( " Trailing slash not found " ) ;
2002-10-05 02:16:13 +04:00
}
2002-02-25 23:06:18 +03:00
2002-10-05 02:16:13 +04:00
this - > ReadListFile ( parentList . c_str ( ) ) ;
2002-02-25 23:06:18 +03:00
2002-10-05 02:16:13 +04:00
// restore the current directory
2003-07-08 21:27:34 +04:00
this - > SetCurrentDirectory ( srcdir . c_str ( ) ) ;
this - > SetCurrentOutputDirectory ( bindir . c_str ( ) ) ;
2002-10-05 02:16:13 +04:00
}
2001-01-05 19:41:20 +03:00
}
2001-02-15 21:30:13 +03:00
// are we at the start CMakeLists file or are we processing a parent
// lists file
2001-04-30 18:52:58 +04:00
//
// this might, or might not be true, irrespective if we are
// off looking at an external makefile.
2001-07-26 00:53:13 +04:00
m_Inheriting = ( m_cmCurrentDirectory ! = m_cmStartDirectory ) ;
2001-02-15 21:30:13 +03:00
2001-01-05 19:41:20 +03:00
// Now read the input file
2001-04-30 18:52:58 +04:00
const char * filenametoread = filename ;
if ( external )
2001-05-03 16:52:32 +04:00
{
2001-04-30 18:52:58 +04:00
filenametoread = external ;
2001-05-03 16:52:32 +04:00
}
2002-12-02 23:30:59 +03:00
// try to see if the list file is the top most
// list file for a project, and if it is, then it
// must have a project command. If there is not
// one, then cmake will provide one via the
// cmListFileCache class.
bool requireProjectCommand = false ;
2002-12-03 00:15:36 +03:00
if ( ! external & & m_cmCurrentDirectory = = m_cmHomeDirectory )
2002-12-02 23:30:59 +03:00
{
if ( cmSystemTools : : LowerCase (
cmSystemTools : : GetFilenameName ( filename ) ) = = " cmakelists.txt " )
{
requireProjectCommand = true ;
}
}
2001-08-29 02:28:31 +04:00
cmListFile * lf =
2002-12-02 23:30:59 +03:00
cmListFileCache : : GetInstance ( ) - > GetFileCache ( filenametoread ,
requireProjectCommand ) ;
2001-08-29 02:28:31 +04:00
if ( ! lf )
2000-08-29 23:26:29 +04:00
{
return false ;
}
2001-08-29 02:28:31 +04:00
// add this list file to the list of dependencies
m_ListFiles . push_back ( filenametoread ) ;
2002-03-13 18:25:11 +03:00
const size_t numberFunctions = lf - > m_Functions . size ( ) ;
for ( size_t i = 0 ; i < numberFunctions ; + + i )
2000-08-29 23:26:29 +04:00
{
2002-12-12 02:13:33 +03:00
this - > ExecuteCommand ( lf - > m_Functions [ i ] ) ;
2000-08-29 23:26:29 +04:00
}
2001-05-04 16:46:05 +04:00
2004-07-27 00:59:55 +04:00
// send scope ended to and function blockers
2001-05-04 16:46:05 +04:00
if ( filename )
{
// loop over all function blockers to see if any block this command
2002-07-11 22:20:39 +04:00
std : : list < cmFunctionBlocker * > : : iterator pos ;
2001-05-04 16:46:05 +04:00
for ( pos = m_FunctionBlockers . begin ( ) ;
pos ! = m_FunctionBlockers . end ( ) ; + + pos )
{
2002-07-10 19:38:38 +04:00
// if this blocker was not in the original then send a
// scope ended message
if ( originalBlockers . find ( * pos ) = = originalBlockers . end ( ) )
{
( * pos ) - > ScopeEnded ( * this ) ;
}
2001-05-04 16:46:05 +04:00
}
}
2000-08-29 23:26:29 +04:00
return true ;
}
2001-02-13 03:49:52 +03:00
2001-04-11 22:59:02 +04:00
2001-01-18 19:20:24 +03:00
void cmMakefile : : AddCommand ( cmCommand * wg )
2001-01-05 19:41:20 +03:00
{
2003-01-14 17:53:13 +03:00
this - > GetCMakeInstance ( ) - > AddCommand ( wg ) ;
2001-01-05 19:41:20 +03:00
}
// Set the make file
2002-09-06 21:06:23 +04:00
void cmMakefile : : SetLocalGenerator ( cmLocalGenerator * lg )
2001-01-05 19:41:20 +03:00
{
2002-09-06 21:06:23 +04:00
m_LocalGenerator = lg ;
2001-01-05 19:41:20 +03:00
}
2001-07-26 02:30:27 +04:00
void cmMakefile : : FinalPass ( )
2001-01-05 19:41:20 +03:00
{
// do all the variable expansions here
2001-02-16 19:34:23 +03:00
this - > ExpandVariables ( ) ;
2001-07-27 21:06:05 +04:00
2001-01-18 19:20:24 +03:00
// give all the commands a chance to do something
2001-01-05 19:41:20 +03:00
// after the file has been parsed before generation
2001-01-18 19:20:24 +03:00
for ( std : : vector < cmCommand * > : : iterator i = m_UsedCommands . begin ( ) ;
i ! = m_UsedCommands . end ( ) ; + + i )
2001-01-05 19:41:20 +03:00
{
( * i ) - > FinalPass ( ) ;
2000-08-29 23:26:29 +04:00
}
2001-07-26 02:30:27 +04:00
}
// Generate the output file
2002-09-15 16:52:24 +04:00
void cmMakefile : : ConfigureFinalPass ( )
2001-07-26 02:30:27 +04:00
{
this - > FinalPass ( ) ;
2002-05-02 23:56:13 +04:00
const char * versionValue
= this - > GetDefinition ( " CMAKE_MINIMUM_REQUIRED_VERSION " ) ;
bool oldVersion = ( ! versionValue | | atof ( versionValue ) < 1.4 ) ;
2001-04-30 18:44:00 +04:00
// merge libraries
2002-05-02 23:56:13 +04:00
2001-04-30 18:44:00 +04:00
for ( cmTargets : : iterator l = m_Targets . begin ( ) ;
l ! = m_Targets . end ( ) ; l + + )
{
2001-05-16 23:15:21 +04:00
l - > second . GenerateSourceFilesFromSourceLists ( * this ) ;
2002-05-02 23:56:13 +04:00
// pick up any LINK_LIBRARIES that were added after the target
if ( oldVersion )
{
this - > AddGlobalLinkInformation ( l - > first . c_str ( ) , l - > second ) ;
}
2002-05-01 22:00:21 +04:00
l - > second . AnalyzeLibDependencies ( * this ) ;
2001-04-30 18:44:00 +04:00
}
2001-06-06 04:34:01 +04:00
}
2000-08-29 23:26:29 +04:00
2003-06-03 18:30:23 +04:00
// this is the old style signature, we convert to new style
2001-03-20 21:20:59 +03:00
void cmMakefile : : AddCustomCommand ( const char * source ,
const char * command ,
2001-09-10 23:11:15 +04:00
const std : : vector < std : : string > & commandArgs ,
2001-03-20 21:20:59 +03:00
const std : : vector < std : : string > & depends ,
2001-04-11 22:59:02 +04:00
const std : : vector < std : : string > & outputs ,
2002-12-11 00:47:37 +03:00
const char * target ,
const char * comment )
2003-06-03 18:30:23 +04:00
{
if ( strcmp ( source , target ) )
{
// what a pain, for backwards compatibility we will try to
// convert this to an output based rule... so for each output..
for ( std : : vector < std : : string > : : const_iterator d = outputs . begin ( ) ;
d ! = outputs . end ( ) ; + + d )
{
2003-06-05 03:04:35 +04:00
// if this looks like a real file then use is as the main depend
2003-06-23 22:10:12 +04:00
cmsys : : RegularExpression SourceFiles ( " \\ .(C|M|c|c \\ + \\ +|cc|cpp|cxx|m|mm|rc|def|r|odl|idl|hpj|bat|h|h \\ + \\ +|hm|hpp|hxx|in|txx|inl)$ " ) ;
2003-06-05 03:04:35 +04:00
if ( SourceFiles . find ( source ) )
{
this - > AddCustomCommandToOutput ( d - > c_str ( ) , command , commandArgs ,
source , depends , comment ) ;
}
// otherwise do not use a main depend
else
{
std : : vector < std : : string > depends2 = depends ;
depends2 . push_back ( source ) ;
this - > AddCustomCommandToOutput ( d - > c_str ( ) , command , commandArgs ,
0 , depends2 , comment ) ;
}
2003-06-03 18:30:23 +04:00
// add the output to the target?
std : : string sname = * d ;
sname + = " .rule " ;
2003-06-21 04:33:43 +04:00
this - > ExpandVariablesInString ( sname ) ;
2003-06-05 03:04:35 +04:00
// if the rule was added to the source,
// then add the source to the target
2003-06-03 18:30:23 +04:00
if ( ! this - > GetSource ( sname . c_str ( ) ) )
{
2003-06-04 22:01:46 +04:00
if ( m_Targets . find ( target ) ! = m_Targets . end ( ) )
{
m_Targets [ target ] . GetSourceLists ( ) . push_back ( source ) ;
}
else
{
cmSystemTools : : Error ( " Attempt to add a custom rule to a target that does not exist yet for target " , target ) ;
return ;
}
2003-06-03 18:30:23 +04:00
}
}
}
else
{
this - > AddCustomCommandToTarget ( target , command , commandArgs ,
2003-06-06 00:45:06 +04:00
cmTarget : : POST_BUILD , comment , depends ) ;
2003-06-03 18:30:23 +04:00
}
}
void cmMakefile : : AddCustomCommand ( const char * source ,
const char * command ,
const std : : vector < std : : string > & commandArgs ,
const std : : vector < std : : string > & depends ,
const char * output ,
const char * target )
{
std : : vector < std : : string > outputs ;
outputs . push_back ( output ) ;
this - > AddCustomCommand ( source , command , commandArgs , depends ,
outputs , target ) ;
}
void cmMakefile : :
2003-07-31 22:46:17 +04:00
AddCustomCommandToOutput ( const char * outputIn ,
2003-07-14 18:33:09 +04:00
const char * inCommand ,
2003-06-03 18:30:23 +04:00
const std : : vector < std : : string > & commandArgs ,
const char * main_dependency ,
const std : : vector < std : : string > & depends ,
const char * comment ,
bool replace )
{
2003-06-04 21:42:42 +04:00
std : : string expandC ;
std : : string combinedArgs ;
2003-07-14 18:33:09 +04:00
std : : string command = inCommand ;
// process the command's string
this - > ExpandVariablesInString ( command ) ;
command = cmSystemTools : : EscapeSpaces ( command . c_str ( ) ) ;
2003-06-04 21:42:42 +04:00
unsigned int i ;
2003-11-03 23:57:56 +03:00
bool escapeSpaces = true ;
2003-06-04 21:42:42 +04:00
for ( i = 0 ; i < commandArgs . size ( ) ; + + i )
{
expandC = commandArgs [ i ] . c_str ( ) ;
2003-11-03 23:57:56 +03:00
// This is a hack to fix a problem with cmCustomCommand
// The cmCustomCommand should store the arguments as a vector
// and not a string, and the cmAddCustomTargetCommand should
// not EscapeSpaces.
if ( expandC = = " This is really a single argument do not escape spaces " )
{
escapeSpaces = false ;
}
else
{
this - > ExpandVariablesInString ( expandC ) ;
if ( escapeSpaces )
{
combinedArgs + = cmSystemTools : : EscapeSpaces ( expandC . c_str ( ) ) ;
}
else
{
combinedArgs + = expandC ;
}
combinedArgs + = " " ;
}
2003-06-04 21:42:42 +04:00
}
2003-06-03 18:30:23 +04:00
cmSourceFile * file = 0 ;
2003-06-21 04:33:43 +04:00
// setup the output name and make sure we expand any variables
2003-07-31 22:46:17 +04:00
std : : string output = outputIn ;
this - > ExpandVariablesInString ( output ) ;
2003-06-03 18:30:23 +04:00
std : : string outName = output ;
outName + = " .rule " ;
2003-06-21 04:33:43 +04:00
// setup the main dependency name and expand vars of course
std : : string mainDepend ;
if ( main_dependency & & main_dependency [ 0 ] ! = ' \0 ' )
{
mainDepend = main_dependency ;
this - > ExpandVariablesInString ( mainDepend ) ;
}
2003-06-03 18:30:23 +04:00
// OK this rule will be placed on a generated output file unless the main
// depednency was specified.
if ( main_dependency & & main_dependency [ 0 ] ! = ' \0 ' )
{
2003-06-21 04:33:43 +04:00
file = this - > GetSource ( mainDepend . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
if ( file & & file - > GetCustomCommand ( ) & & ! replace )
2003-06-04 22:00:30 +04:00
{
cmCustomCommand * cc = file - > GetCustomCommand ( ) ;
// if the command and args are the same
// as the command already there, then silently skip
// this add command
2003-07-14 18:33:09 +04:00
if ( cc - > IsEquivalent ( command . c_str ( ) , combinedArgs . c_str ( ) ) )
2003-06-04 22:00:30 +04:00
{
return ;
}
2003-06-03 18:30:23 +04:00
// generate a source instead
file = 0 ;
}
else
{
2003-06-21 04:33:43 +04:00
file = this - > GetOrCreateSource ( mainDepend . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
}
}
if ( ! file )
{
file = this - > GetSource ( outName . c_str ( ) ) ;
if ( file & & file - > GetCustomCommand ( ) & & ! replace )
{
2003-06-04 21:42:42 +04:00
cmCustomCommand * cc = file - > GetCustomCommand ( ) ;
// if the command and args are the same
// as the command already there, then silently skip
// this add command
2003-07-14 18:33:09 +04:00
if ( cc - > IsEquivalent ( command . c_str ( ) , combinedArgs . c_str ( ) ) )
2003-06-04 21:42:42 +04:00
{
return ;
}
// produce error if two different commands are given to produce
// the same output
cmSystemTools : : Error ( " Attempt to add a custom rule to an output that already "
2003-07-31 22:46:17 +04:00
" has a custom rule. For output: " , outputIn ) ;
2003-06-03 18:30:23 +04:00
return ;
}
// create a cmSourceFile for the output
file = this - > GetOrCreateSource ( outName . c_str ( ) , true ) ;
2004-08-05 01:24:21 +04:00
if ( file )
{
// always mark as generated
file - > SetProperty ( " GENERATED " , " 1 " ) ;
}
2003-06-03 18:30:23 +04:00
}
// always create the output and mark it generated
2004-08-05 01:24:21 +04:00
if ( cmSourceFile * out = this - > GetOrCreateSource ( output . c_str ( ) , true ) )
{
out - > SetProperty ( " GENERATED " , " 1 " ) ;
}
2003-06-03 18:30:23 +04:00
std : : vector < std : : string > depends2 ( depends ) ;
if ( main_dependency & & main_dependency [ 0 ] ! = ' \0 ' )
{
2003-06-21 04:33:43 +04:00
depends2 . push_back ( mainDepend . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
}
cmCustomCommand * cc =
2003-07-31 22:46:17 +04:00
new cmCustomCommand ( command . c_str ( ) , combinedArgs . c_str ( ) , depends2 ,
output . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
if ( comment & & comment [ 0 ] )
{
cc - > SetComment ( comment ) ;
}
2004-08-05 01:24:21 +04:00
if ( file )
2003-06-03 18:30:23 +04:00
{
2004-08-05 01:24:21 +04:00
if ( file - > GetCustomCommand ( ) )
{
delete file - > GetCustomCommand ( ) ;
}
file - > SetCustomCommand ( cc ) ;
2003-06-03 18:30:23 +04:00
}
}
void cmMakefile : :
AddCustomCommandToTarget ( const char * target , const char * command ,
const std : : vector < std : : string > & commandArgs ,
cmTarget : : CustomCommandType type ,
const char * comment )
2003-06-06 00:45:06 +04:00
{
std : : vector < std : : string > empty ;
this - > AddCustomCommandToTarget ( target , command , commandArgs , type ,
comment , empty ) ;
}
void cmMakefile : :
AddCustomCommandToTarget ( const char * target , const char * command ,
const std : : vector < std : : string > & commandArgs ,
cmTarget : : CustomCommandType type ,
const char * comment ,
const std : : vector < std : : string > & depends )
2001-03-20 21:20:59 +03:00
{
2001-04-11 22:59:02 +04:00
// find the target,
if ( m_Targets . find ( target ) ! = m_Targets . end ( ) )
{
2001-11-28 01:32:33 +03:00
std : : string expandC = command ;
this - > ExpandVariablesInString ( expandC ) ;
std : : string c = cmSystemTools : : EscapeSpaces ( expandC . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
2001-09-10 23:11:15 +04:00
std : : string combinedArgs ;
2001-11-13 20:38:53 +03:00
unsigned int i ;
2001-09-10 23:11:15 +04:00
for ( i = 0 ; i < commandArgs . size ( ) ; + + i )
{
2003-01-21 03:17:17 +03:00
expandC = commandArgs [ i ] . c_str ( ) ;
this - > ExpandVariablesInString ( expandC ) ;
combinedArgs + = cmSystemTools : : EscapeSpaces ( expandC . c_str ( ) ) ;
2001-09-10 23:11:15 +04:00
combinedArgs + = " " ;
}
2003-06-06 00:45:06 +04:00
cmCustomCommand cc ( c . c_str ( ) , combinedArgs . c_str ( ) , depends , 0 ) ;
2002-12-11 00:47:37 +03:00
if ( comment & & comment [ 0 ] )
{
cc . SetComment ( comment ) ;
}
2003-06-03 18:30:23 +04:00
switch ( type )
{
case cmTarget : : PRE_BUILD :
m_Targets [ target ] . GetPreBuildCommands ( ) . push_back ( cc ) ;
break ;
case cmTarget : : PRE_LINK :
m_Targets [ target ] . GetPreLinkCommands ( ) . push_back ( cc ) ;
break ;
case cmTarget : : POST_BUILD :
m_Targets [ target ] . GetPostBuildCommands ( ) . push_back ( cc ) ;
break ;
}
2001-06-07 22:52:29 +04:00
std : : string cacheCommand = command ;
this - > ExpandVariablesInString ( cacheCommand ) ;
2002-09-06 21:06:23 +04:00
if ( this - > GetCacheManager ( ) - > GetCacheValue ( cacheCommand . c_str ( ) ) )
2001-06-07 22:52:29 +04:00
{
m_Targets [ target ] . AddUtility (
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - > GetCacheValue ( cacheCommand . c_str ( ) ) ) ;
2001-06-07 22:52:29 +04:00
}
2001-04-11 22:59:02 +04:00
}
2001-03-20 21:20:59 +03:00
}
2001-01-05 19:41:20 +03:00
void cmMakefile : : AddDefineFlag ( const char * flag )
{
m_DefineFlags + = " " ;
m_DefineFlags + = flag ;
}
2001-03-09 18:53:32 +03:00
2004-04-15 21:58:10 +04:00
void cmMakefile : : RemoveDefineFlag ( const char * flag )
{
cmSystemTools : : ReplaceString ( m_DefineFlags , flag , " " ) ;
}
2001-04-30 18:44:00 +04:00
void cmMakefile : : AddLinkLibrary ( const char * lib , cmTarget : : LinkLibraryType llt )
2001-04-27 00:22:53 +04:00
{
m_LinkLibraries . push_back (
2002-10-05 02:16:13 +04:00
std : : pair < std : : string , cmTarget : : LinkLibraryType > ( lib , llt ) ) ;
2001-04-30 18:44:00 +04:00
}
void cmMakefile : : AddLinkLibraryForTarget ( const char * target ,
const char * lib ,
cmTarget : : LinkLibraryType llt )
2002-05-02 21:17:10 +04:00
{
cmTargets : : iterator i = m_Targets . find ( target ) ;
if ( i ! = m_Targets . end ( ) )
2001-04-30 18:44:00 +04:00
{
2002-05-02 21:17:10 +04:00
i - > second . AddLinkLibrary ( * this , target , lib , llt ) ;
2001-04-30 18:44:00 +04:00
}
2001-07-11 00:20:24 +04:00
else
{
cmSystemTools : : Error ( " Attempt to add link libraries to non-existant target: " , target , " for lib " , lib ) ;
}
2001-04-27 00:22:53 +04:00
}
2002-05-02 21:17:10 +04:00
void cmMakefile : : AddLinkDirectoryForTarget ( const char * target ,
const char * d )
{
cmTargets : : iterator i = m_Targets . find ( target ) ;
if ( i ! = m_Targets . end ( ) )
{
i - > second . AddLinkDirectory ( d ) ;
}
else
{
cmSystemTools : : Error ( " Attempt to add link directories to non-existant target: " ,
target , " for directory " , d ) ;
}
}
2001-01-05 19:41:20 +03:00
void cmMakefile : : AddLinkLibrary ( const char * lib )
{
2001-04-30 18:44:00 +04:00
this - > AddLinkLibrary ( lib , cmTarget : : GENERAL ) ;
2001-01-05 19:41:20 +03:00
}
void cmMakefile : : AddLinkDirectory ( const char * dir )
{
2001-07-30 19:34:03 +04:00
// Don't add a link directory that is already present. Yes, this
// linear search results in n^2 behavior, but n won't be getting
// much bigger than 20. We cannot use a set because of order
// dependency of the link search path.
2002-04-29 18:23:29 +04:00
// remove trailing slashes
if ( dir & & dir [ strlen ( dir ) - 1 ] = = ' / ' )
{
std : : string newdir = dir ;
newdir = newdir . substr ( 0 , newdir . size ( ) - 1 ) ;
if ( std : : find ( m_LinkDirectories . begin ( ) ,
m_LinkDirectories . end ( ) , newdir . c_str ( ) ) = = m_LinkDirectories . end ( ) )
{
m_LinkDirectories . push_back ( newdir ) ;
}
}
else
2001-07-30 19:34:03 +04:00
{
2002-04-29 18:23:29 +04:00
if ( std : : find ( m_LinkDirectories . begin ( ) ,
m_LinkDirectories . end ( ) , dir ) = = m_LinkDirectories . end ( ) )
{
m_LinkDirectories . push_back ( dir ) ;
}
2001-07-30 19:34:03 +04:00
}
2001-01-05 19:41:20 +03:00
}
2004-04-23 20:52:48 +04:00
bool cmMakefile : : IsDirectoryPreOrder ( const char * dir )
2001-01-05 19:41:20 +03:00
{
2004-04-23 20:52:48 +04:00
return ( m_SubDirectoryOrder . find ( dir ) ! = m_SubDirectoryOrder . end ( ) ) ;
}
void cmMakefile : : AddSubDirectory ( const char * sub , bool topLevel , bool preorder )
{
if ( preorder )
{
m_SubDirectoryOrder [ sub ] = preorder ;
}
2004-03-10 00:28:44 +03:00
std : : pair < cmStdString , bool > p ( sub , topLevel ) ;
2003-03-13 20:59:46 +03:00
// make sure it isn't already there
if ( std : : find ( m_SubDirectories . begin ( ) ,
2004-03-10 00:28:44 +03:00
m_SubDirectories . end ( ) , p ) = = m_SubDirectories . end ( ) )
2003-03-13 20:59:46 +03:00
{
2004-03-10 00:28:44 +03:00
m_SubDirectories . push_back ( p ) ;
2003-03-13 20:59:46 +03:00
}
2001-01-05 19:41:20 +03:00
}
2001-11-03 06:32:39 +03:00
void cmMakefile : : AddIncludeDirectory ( const char * inc , bool before )
2001-01-05 19:41:20 +03:00
{
2001-07-30 19:34:03 +04:00
// Don't add an include directory that is already present. Yes,
// this linear search results in n^2 behavior, but n won't be
// getting much bigger than 20. We cannot use a set because of
// order dependency of the include path.
if ( std : : find ( m_IncludeDirectories . begin ( ) ,
m_IncludeDirectories . end ( ) , inc ) = = m_IncludeDirectories . end ( ) )
{
2001-11-03 06:32:39 +03:00
if ( before )
{
// WARNING: this *is* expensive (linear time) since it's a vector
m_IncludeDirectories . insert ( m_IncludeDirectories . begin ( ) , inc ) ;
}
else
{
m_IncludeDirectories . push_back ( inc ) ;
}
2001-07-30 19:34:03 +04:00
}
2001-01-05 19:41:20 +03:00
}
void cmMakefile : : AddDefinition ( const char * name , const char * value )
{
2002-09-11 22:05:45 +04:00
if ( ! value )
{
return ;
}
2003-06-24 23:23:34 +04:00
m_TemporaryDefinitionKey = name ;
m_Definitions [ m_TemporaryDefinitionKey ] = value ;
2003-01-08 20:59:52 +03:00
cmVariableWatch * vv = this - > GetVariableWatch ( ) ;
if ( vv )
{
2003-06-24 23:23:34 +04:00
vv - > VariableAccessed ( m_TemporaryDefinitionKey ,
cmVariableWatch : : VARIABLE_MODIFIED_ACCESS ) ;
2003-01-08 20:59:52 +03:00
}
2001-01-05 19:41:20 +03:00
}
2001-05-11 00:21:45 +04:00
2001-08-08 19:54:46 +04:00
void cmMakefile : : AddCacheDefinition ( const char * name , const char * value ,
const char * doc ,
cmCacheManager : : CacheEntryType type )
{
2003-08-01 22:10:26 +04:00
const char * val = value ;
cmCacheManager : : CacheIterator it =
this - > GetCacheManager ( ) - > GetCacheIterator ( name ) ;
2003-08-02 17:33:23 +04:00
if ( ! it . IsAtEnd ( ) & & ( it . GetType ( ) = = cmCacheManager : : UNINITIALIZED ) & &
it . Initialized ( ) )
2003-08-01 22:10:26 +04:00
{
val = it . GetValue ( ) ;
2003-08-08 18:07:09 +04:00
if ( type = = cmCacheManager : : PATH | | type = = cmCacheManager : : FILEPATH )
{
std : : vector < std : : string > : : size_type cc ;
std : : vector < std : : string > files ;
std : : string nvalue = " " ;
cmSystemTools : : ExpandListArgument ( val , files ) ;
for ( cc = 0 ; cc < files . size ( ) ; cc + + )
{
files [ cc ] = cmSystemTools : : CollapseFullPath ( files [ cc ] . c_str ( ) ) ;
if ( cc > 0 )
{
nvalue + = " ; " ;
}
nvalue + = files [ cc ] ;
}
this - > GetCacheManager ( ) - > AddCacheEntry ( name , nvalue . c_str ( ) , doc , type ) ;
val = it . GetValue ( ) ;
}
2003-08-01 22:10:26 +04:00
}
this - > GetCacheManager ( ) - > AddCacheEntry ( name , val , doc , type ) ;
this - > AddDefinition ( name , val ) ;
2001-08-08 19:54:46 +04:00
}
2001-04-24 20:40:37 +04:00
void cmMakefile : : AddDefinition ( const char * name , bool value )
{
if ( value )
{
2001-05-11 00:21:45 +04:00
m_Definitions . erase ( DefinitionMap : : key_type ( name ) ) ;
2001-04-24 20:40:37 +04:00
m_Definitions . insert ( DefinitionMap : : value_type ( name , " ON " ) ) ;
}
else
{
2001-05-11 00:21:45 +04:00
m_Definitions . erase ( DefinitionMap : : key_type ( name ) ) ;
2001-04-24 20:40:37 +04:00
m_Definitions . insert ( DefinitionMap : : value_type ( name , " OFF " ) ) ;
}
2003-01-08 20:59:52 +03:00
cmVariableWatch * vv = this - > GetVariableWatch ( ) ;
if ( vv )
{
vv - > VariableAccessed ( name , cmVariableWatch : : VARIABLE_MODIFIED_ACCESS ) ;
}
2001-04-24 20:40:37 +04:00
}
2001-01-05 19:41:20 +03:00
2001-08-08 19:54:46 +04:00
void cmMakefile : : AddCacheDefinition ( const char * name , bool value , const char * doc )
{
2003-08-08 17:26:55 +04:00
bool val = value ;
cmCacheManager : : CacheIterator it =
this - > GetCacheManager ( ) - > GetCacheIterator ( name ) ;
if ( ! it . IsAtEnd ( ) & & ( it . GetType ( ) = = cmCacheManager : : UNINITIALIZED ) & &
it . Initialized ( ) )
{
val = it . GetValueAsBool ( ) ;
}
this - > GetCacheManager ( ) - > AddCacheEntry ( name , val , doc ) ;
this - > AddDefinition ( name , val ) ;
2001-08-08 19:54:46 +04:00
}
2002-09-18 18:39:41 +04:00
void cmMakefile : : RemoveDefinition ( const char * name )
{
m_Definitions . erase ( DefinitionMap : : key_type ( name ) ) ;
2003-01-08 20:59:52 +03:00
cmVariableWatch * vv = this - > GetVariableWatch ( ) ;
if ( vv )
{
vv - > VariableAccessed ( name , cmVariableWatch : : VARIABLE_REMOVED_ACCESS ) ;
}
2002-09-18 18:39:41 +04:00
}
2001-01-05 19:41:20 +03:00
void cmMakefile : : SetProjectName ( const char * p )
{
2003-11-26 22:29:53 +03:00
if ( m_ProjectName . size ( ) )
{
m_ParentProjects . push_back ( m_ProjectName ) ;
}
2001-01-05 19:41:20 +03:00
m_ProjectName = p ;
}
2002-05-02 23:56:13 +04:00
void cmMakefile : : AddGlobalLinkInformation ( const char * name , cmTarget & target )
{
2002-06-03 18:25:55 +04:00
// for these targets do not add anything
switch ( target . GetType ( ) )
{
2002-10-24 18:23:11 +04:00
case cmTarget : : UTILITY :
case cmTarget : : INSTALL_FILES :
case cmTarget : : INSTALL_PROGRAMS :
return ;
2002-06-19 01:20:27 +04:00
default : ;
2002-06-03 18:25:55 +04:00
}
2002-05-02 23:56:13 +04:00
std : : vector < std : : string > : : iterator j ;
for ( j = m_LinkDirectories . begin ( ) ;
j ! = m_LinkDirectories . end ( ) ; + + j )
{
target . AddLinkDirectory ( j - > c_str ( ) ) ;
}
2002-05-04 00:34:05 +04:00
target . MergeLinkLibraries ( * this , name , m_LinkLibraries ) ;
2002-05-02 23:56:13 +04:00
}
2001-08-29 02:02:59 +04:00
void cmMakefile : : AddLibrary ( const char * lname , int shared ,
2001-07-02 23:38:02 +04:00
const std : : vector < std : : string > & srcs )
2001-04-11 22:59:02 +04:00
{
cmTarget target ;
2001-08-29 02:02:59 +04:00
switch ( shared )
{
case 0 :
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : STATIC_LIBRARY , lname ) ;
2001-08-29 02:02:59 +04:00
break ;
case 1 :
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : SHARED_LIBRARY , lname ) ;
2001-08-29 02:02:59 +04:00
break ;
case 2 :
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : MODULE_LIBRARY , lname ) ;
2001-08-29 02:02:59 +04:00
break ;
default :
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : STATIC_LIBRARY , lname ) ;
2001-08-29 02:02:59 +04:00
}
2002-11-20 02:01:05 +03:00
2002-05-02 23:10:19 +04:00
// Clear its dependencies. Otherwise, dependencies might persist
// over changes in CMakeLists.txt, making the information stale and
// hence useless.
2002-11-20 02:01:05 +03:00
target . ClearDependencyInformation ( * this , lname ) ;
2001-05-05 01:00:22 +04:00
target . SetInAll ( true ) ;
2001-04-19 21:28:46 +04:00
target . GetSourceLists ( ) = srcs ;
2002-05-02 23:56:13 +04:00
this - > AddGlobalLinkInformation ( lname , target ) ;
2002-05-04 00:34:05 +04:00
m_Targets . insert ( cmTargets : : value_type ( lname , target ) ) ;
2001-05-08 02:14:13 +04:00
// Add an entry into the cache
2002-06-27 23:57:09 +04:00
std : : string libPath = lname ;
libPath + = " _CMAKE_PATH " ;
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - >
2002-06-27 23:57:09 +04:00
AddCacheEntry ( libPath . c_str ( ) ,
2001-05-08 02:14:13 +04:00
this - > GetCurrentOutputDirectory ( ) ,
" Path to a library " , cmCacheManager : : INTERNAL ) ;
2001-07-02 23:38:02 +04:00
// Add an entry into the cache
std : : string ltname = lname ;
ltname + = " _LIBRARY_TYPE " ;
2001-08-29 02:02:59 +04:00
switch ( shared )
{
case 0 :
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - > AddCacheEntry ( ltname . c_str ( ) , " STATIC " ,
2002-10-05 02:16:13 +04:00
" Whether a library is static, shared or module. " ,
cmCacheManager : : INTERNAL ) ;
2001-08-29 02:02:59 +04:00
break ;
case 1 :
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - >
2002-10-05 02:16:13 +04:00
AddCacheEntry ( ltname . c_str ( ) ,
" SHARED " ,
" Whether a library is static, shared or module. " ,
cmCacheManager : : INTERNAL ) ;
2001-08-29 02:02:59 +04:00
break ;
case 2 :
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - >
2002-10-05 02:16:13 +04:00
AddCacheEntry ( ltname . c_str ( ) ,
" MODULE " ,
" Whether a library is static, shared or module. " ,
cmCacheManager : : INTERNAL ) ;
2001-08-29 02:02:59 +04:00
break ;
default :
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - >
2002-10-05 02:16:13 +04:00
AddCacheEntry ( ltname . c_str ( ) ,
" STATIC " ,
" Whether a library is static, shared or module. " ,
cmCacheManager : : INTERNAL ) ;
2001-08-29 02:02:59 +04:00
}
2001-04-11 22:59:02 +04:00
}
2004-02-29 02:59:19 +03:00
cmTarget * cmMakefile : : AddExecutable ( const char * exeName ,
2001-04-11 22:59:02 +04:00
const std : : vector < std : : string > & srcs )
2001-01-05 19:41:20 +03:00
{
2001-04-11 22:59:02 +04:00
cmTarget target ;
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : EXECUTABLE , exeName ) ;
2001-05-05 01:00:22 +04:00
target . SetInAll ( true ) ;
2001-04-19 21:28:46 +04:00
target . GetSourceLists ( ) = srcs ;
2002-05-02 23:56:13 +04:00
this - > AddGlobalLinkInformation ( exeName , target ) ;
2004-02-29 02:59:19 +03:00
cmTargets : : iterator it =
m_Targets . insert ( cmTargets : : value_type ( exeName , target ) ) . first ;
2002-05-04 00:34:05 +04:00
2001-05-08 02:14:13 +04:00
// Add an entry into the cache
2002-06-27 23:57:09 +04:00
std : : string exePath = exeName ;
exePath + = " _CMAKE_PATH " ;
2002-09-06 21:06:23 +04:00
this - > GetCacheManager ( ) - >
2002-06-27 23:57:09 +04:00
AddCacheEntry ( exePath . c_str ( ) ,
2001-05-08 02:14:13 +04:00
this - > GetCurrentOutputDirectory ( ) ,
" Path to an executable " , cmCacheManager : : INTERNAL ) ;
2004-02-29 02:59:19 +03:00
return & it - > second ;
2001-01-05 19:41:20 +03:00
}
2001-04-11 22:59:02 +04:00
2001-05-02 00:55:32 +04:00
void cmMakefile : : AddUtilityCommand ( const char * utilityName ,
2001-05-04 23:50:26 +04:00
const char * command ,
2001-09-05 00:07:54 +04:00
const char * arguments ,
2003-06-03 18:30:23 +04:00
bool all ,
const std : : vector < std : : string > & depends )
2001-05-04 23:50:26 +04:00
{
std : : vector < std : : string > empty ;
2001-09-05 00:07:54 +04:00
this - > AddUtilityCommand ( utilityName , command , arguments , all ,
2003-06-03 18:30:23 +04:00
depends , empty ) ;
2001-05-04 23:50:26 +04:00
}
void cmMakefile : : AddUtilityCommand ( const char * utilityName ,
const char * command ,
2001-09-05 00:07:54 +04:00
const char * arguments ,
2001-05-04 23:50:26 +04:00
bool all ,
const std : : vector < std : : string > & dep ,
const std : : vector < std : : string > & out )
2001-05-02 00:55:32 +04:00
{
cmTarget target ;
2004-09-22 22:42:05 +04:00
target . SetType ( cmTarget : : UTILITY , utilityName ) ;
2001-05-04 23:50:26 +04:00
target . SetInAll ( all ) ;
2003-06-03 18:30:23 +04:00
if ( out . size ( ) > 1 )
{
cmSystemTools : : Error (
" Utility targets can only have one output. For utilityNamed: " ,
utilityName ) ;
return ;
}
if ( out . size ( ) )
{
cmCustomCommand cc ( command , arguments , dep , out [ 0 ] . c_str ( ) ) ;
target . GetPostBuildCommands ( ) . push_back ( cc ) ;
}
else
{
2003-06-04 16:40:09 +04:00
cmCustomCommand cc ( command , arguments , dep , ( const char * ) 0 ) ;
2003-06-03 18:30:23 +04:00
target . GetPostBuildCommands ( ) . push_back ( cc ) ;
}
2001-05-02 00:55:32 +04:00
m_Targets . insert ( cmTargets : : value_type ( utilityName , target ) ) ;
}
2003-06-03 18:30:23 +04:00
cmSourceFile * cmMakefile : : GetSourceFileWithOutput ( const char * cname )
{
std : : string name = cname ;
2003-06-20 19:23:47 +04:00
2003-06-03 18:30:23 +04:00
// look through all the source files that have custom commands
// and see if the custom command has the passed source file as an output
// keep in mind the possible .rule extension that may be tacked on
for ( std : : vector < cmSourceFile * > : : const_iterator i = m_SourceFiles . begin ( ) ;
i ! = m_SourceFiles . end ( ) ; + + i )
{
// does this source file have a custom command?
if ( ( * i ) - > GetCustomCommand ( ) )
{
// is the output of the custom command match the source files name
2003-06-24 23:23:34 +04:00
const std : : string & out = ( * i ) - > GetCustomCommand ( ) - > GetOutput ( ) ;
2003-06-03 18:30:23 +04:00
if ( out . rfind ( name ) ! = out . npos & &
out . rfind ( name ) = = out . size ( ) - name . size ( ) )
{
return * i ;
}
}
}
// otherwise return NULL
2003-06-04 16:40:09 +04:00
return 0 ;
2003-06-03 18:30:23 +04:00
}
2002-10-05 02:16:13 +04:00
cmSourceGroup * cmMakefile : : GetSourceGroup ( const char * name )
{
// First see if the group exists. If so, replace its regular expression.
for ( std : : vector < cmSourceGroup > : : iterator sg = m_SourceGroups . begin ( ) ;
sg ! = m_SourceGroups . end ( ) ; + + sg )
{
std : : string sgName = sg - > GetName ( ) ;
if ( sgName = = name )
{
return & ( * sg ) ;
}
}
return 0 ;
}
2001-05-02 00:55:32 +04:00
2001-03-20 21:20:59 +03:00
void cmMakefile : : AddSourceGroup ( const char * name , const char * regex )
{
// First see if the group exists. If so, replace its regular expression.
for ( std : : vector < cmSourceGroup > : : iterator sg = m_SourceGroups . begin ( ) ;
sg ! = m_SourceGroups . end ( ) ; + + sg )
{
std : : string sgName = sg - > GetName ( ) ;
if ( sgName = = name )
{
2002-10-05 02:16:13 +04:00
if ( regex )
{
// We only want to set the regular expression. If there are already
// source files in the group, we don't want to remove them.
sg - > SetGroupRegex ( regex ) ;
}
2001-03-20 21:20:59 +03:00
return ;
}
}
// The group doesn't exist. Add it.
m_SourceGroups . push_back ( cmSourceGroup ( name , regex ) ) ;
}
2001-01-05 19:41:20 +03:00
void cmMakefile : : AddExtraDirectory ( const char * dir )
{
m_AuxSourceDirectories . push_back ( dir ) ;
}
2000-08-29 23:26:29 +04:00
2001-01-05 19:41:20 +03:00
2001-02-15 21:30:13 +03:00
// return the file name for the parent CMakeLists file to the
// one passed in. Zero is returned if the CMakeLists file is the
// one in the home directory or if for some reason a parent cmake lists
// file cannot be found.
std : : string cmMakefile : : GetParentListFileName ( const char * currentFileName )
2000-08-30 21:35:41 +04:00
{
2001-02-15 21:30:13 +03:00
// extract the directory name
std : : string parentFile ;
std : : string listsDir = currentFileName ;
std : : string : : size_type pos = listsDir . rfind ( ' / ' ) ;
// if we could not find the directory return 0
if ( pos = = std : : string : : npos )
2000-08-30 21:35:41 +04:00
{
2001-02-15 21:30:13 +03:00
return parentFile ;
2001-01-05 19:41:20 +03:00
}
2001-02-15 21:30:13 +03:00
listsDir = listsDir . substr ( 0 , pos ) ;
// if we are in the home directory then stop, return 0
if ( m_cmHomeDirectory = = listsDir )
2001-01-05 19:41:20 +03:00
{
2001-02-15 21:30:13 +03:00
return parentFile ;
2001-01-05 19:41:20 +03:00
}
2001-02-15 21:30:13 +03:00
// is there a parent directory we can check
pos = listsDir . rfind ( ' / ' ) ;
// if we could not find the directory return 0
if ( pos = = std : : string : : npos )
{
return parentFile ;
}
listsDir = listsDir . substr ( 0 , pos ) ;
// is there a CMakeLists.txt file in the parent directory ?
parentFile = listsDir ;
parentFile + = " /CMakeLists.txt " ;
2001-12-10 19:03:44 +03:00
while ( ! cmSystemTools : : FileExists ( parentFile . c_str ( ) ) )
2001-01-05 19:41:20 +03:00
{
2001-12-10 19:03:44 +03:00
// There is no CMakeLists.txt file in the parent directory. This
// can occur when coming out of a subdirectory resulting from a
// SUBDIRS(Foo/Bar) command (coming out of Bar into Foo). Try
// walking up until a CMakeLists.txt is found or the home
// directory is hit.
// if we are in the home directory then stop, return 0
if ( m_cmHomeDirectory = = listsDir ) { return " " ; }
// is there a parent directory we can check
pos = listsDir . rfind ( ' / ' ) ;
// if we could not find the directory return 0
if ( pos = = std : : string : : npos ) { return " " ; }
listsDir = listsDir . substr ( 0 , pos ) ;
parentFile = listsDir ;
parentFile + = " /CMakeLists.txt " ;
2000-08-30 21:35:41 +04:00
}
2002-02-25 23:06:18 +03:00
2001-02-15 21:30:13 +03:00
return parentFile ;
2000-08-30 21:35:41 +04:00
}
2001-01-05 19:41:20 +03:00
// expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the
// include and library directories.
2001-02-16 19:34:23 +03:00
void cmMakefile : : ExpandVariables ( )
2001-01-05 19:41:20 +03:00
{
2003-01-08 20:59:52 +03:00
// Now expand variables in the include and link strings
2001-07-30 19:34:03 +04:00
for ( std : : vector < std : : string > : : iterator d = m_IncludeDirectories . begin ( ) ;
d ! = m_IncludeDirectories . end ( ) ; + + d )
2001-01-05 19:41:20 +03:00
{
2001-07-30 19:34:03 +04:00
this - > ExpandVariablesInString ( * d ) ;
2001-01-05 19:41:20 +03:00
}
2001-07-30 19:34:03 +04:00
for ( std : : vector < std : : string > : : iterator d = m_LinkDirectories . begin ( ) ;
d ! = m_LinkDirectories . end ( ) ; + + d )
2001-01-05 19:41:20 +03:00
{
2001-07-30 19:34:03 +04:00
this - > ExpandVariablesInString ( * d ) ;
2001-02-16 19:34:23 +03:00
}
2001-07-30 19:34:03 +04:00
for ( cmTarget : : LinkLibraries : : iterator l = m_LinkLibraries . begin ( ) ;
l ! = m_LinkLibraries . end ( ) ; + + l )
2001-02-16 19:34:23 +03:00
{
2001-07-30 19:34:03 +04:00
this - > ExpandVariablesInString ( l - > first ) ;
2001-01-05 19:41:20 +03:00
}
}
2003-06-03 18:30:23 +04:00
void cmMakefile : : ExpandVariablesInCustomCommands ( )
{
2003-06-20 21:56:51 +04:00
// do source files
2003-06-03 18:30:23 +04:00
for ( std : : vector < cmSourceFile * > : : iterator i = m_SourceFiles . begin ( ) ;
i ! = m_SourceFiles . end ( ) ; + + i )
{
cmCustomCommand * cc = ( * i ) - > GetCustomCommand ( ) ;
if ( cc )
{
cc - > ExpandVariables ( * this ) ;
}
}
2003-06-20 21:56:51 +04:00
// now do targets
std : : vector < cmCustomCommand > : : iterator ic ;
for ( cmTargets : : iterator l = m_Targets . begin ( ) ;
l ! = m_Targets . end ( ) ; l + + )
{
for ( ic = l - > second . GetPreBuildCommands ( ) . begin ( ) ;
ic ! = l - > second . GetPreBuildCommands ( ) . end ( ) ; + + ic )
{
ic - > ExpandVariables ( * this ) ;
}
for ( ic = l - > second . GetPreLinkCommands ( ) . begin ( ) ;
ic ! = l - > second . GetPreLinkCommands ( ) . end ( ) ; + + ic )
{
ic - > ExpandVariables ( * this ) ;
}
for ( ic = l - > second . GetPostBuildCommands ( ) . begin ( ) ;
ic ! = l - > second . GetPostBuildCommands ( ) . end ( ) ; + + ic )
{
ic - > ExpandVariables ( * this ) ;
}
}
2003-06-03 18:30:23 +04:00
}
2002-05-01 22:00:21 +04:00
bool cmMakefile : : IsOn ( const char * name ) const
2001-08-08 19:54:46 +04:00
{
const char * value = this - > GetDefinition ( name ) ;
return cmSystemTools : : IsOn ( value ) ;
}
2004-08-06 22:51:41 +04:00
const char * cmMakefile : : GetRequiredDefinition ( const char * name ) const
{
const char * ret = this - > GetDefinition ( name ) ;
if ( ! ret )
{
cmSystemTools : : Error ( " Error required internal CMake variable not set, cmake may be not be built correctly. \n " ,
" Missing variable is: \n " ,
name ) ;
return " " ;
}
return ret ;
}
2001-08-27 22:44:15 +04:00
const char * cmMakefile : : GetDefinition ( const char * name ) const
2001-01-05 19:41:20 +03:00
{
2003-01-08 20:59:52 +03:00
const char * def = 0 ;
2001-08-27 22:44:15 +04:00
DefinitionMap : : const_iterator pos = m_Definitions . find ( name ) ;
2001-01-05 19:41:20 +03:00
if ( pos ! = m_Definitions . end ( ) )
{
2003-01-08 20:59:52 +03:00
def = ( * pos ) . second . c_str ( ) ;
}
else
{
def = this - > GetCacheManager ( ) - > GetCacheValue ( name ) ;
2001-01-05 19:41:20 +03:00
}
2003-01-08 20:59:52 +03:00
cmVariableWatch * vv = this - > GetVariableWatch ( ) ;
if ( vv )
{
if ( def )
{
vv - > VariableAccessed ( name , cmVariableWatch : : VARIABLE_READ_ACCESS ) ;
}
else
{
2003-01-09 19:35:27 +03:00
// are unknown access allowed
DefinitionMap : : const_iterator pos2 =
m_Definitions . find ( " CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS " ) ;
if ( pos2 ! = m_Definitions . end ( ) & &
cmSystemTools : : IsOn ( ( * pos2 ) . second . c_str ( ) ) )
{
vv - > VariableAccessed ( name ,
cmVariableWatch : : ALLOWED_UNKNOWN_VARIABLE_READ_ACCESS ) ;
}
else
{
vv - > VariableAccessed ( name , cmVariableWatch : :
UNKNOWN_VARIABLE_READ_ACCESS ) ;
}
2003-01-08 20:59:52 +03:00
}
}
return def ;
2001-01-05 19:41:20 +03:00
}
2001-01-12 20:43:00 +03:00
2004-04-27 19:30:31 +04:00
const char * cmMakefile : : GetSafeDefinition ( const char * def ) const
{
const char * ret = this - > GetDefinition ( def ) ;
if ( ! ret )
{
return " " ;
}
return ret ;
}
2003-03-06 19:19:28 +03:00
std : : vector < std : : string > cmMakefile : : GetDefinitions ( int cacheonly /* = 0 */ ) const
{
std : : map < std : : string , int > definitions ;
if ( ! cacheonly )
{
DefinitionMap : : const_iterator it ;
for ( it = m_Definitions . begin ( ) ; it ! = m_Definitions . end ( ) ; it + + )
{
definitions [ it - > first ] = 1 ;
}
}
cmCacheManager : : CacheIterator cit = this - > GetCacheManager ( ) - > GetCacheIterator ( ) ;
for ( cit . Begin ( ) ; ! cit . IsAtEnd ( ) ; cit . Next ( ) )
{
definitions [ cit . GetName ( ) ] = 1 ;
}
std : : vector < std : : string > res ;
std : : map < std : : string , int > : : iterator fit ;
for ( fit = definitions . begin ( ) ; fit ! = definitions . end ( ) ; fit + + )
{
res . push_back ( fit - > first ) ;
}
return res ;
}
2001-01-12 20:43:00 +03:00
2001-02-13 03:49:52 +03:00
2001-09-02 00:12:52 +04:00
const char * cmMakefile : : ExpandVariablesInString ( std : : string & source ) const
2001-06-22 19:14:32 +04:00
{
2001-09-02 00:12:52 +04:00
return this - > ExpandVariablesInString ( source , false ) ;
2001-06-22 19:14:32 +04:00
}
2001-09-02 00:12:52 +04:00
const char * cmMakefile : : ExpandVariablesInString ( std : : string & source ,
2001-10-30 22:05:07 +03:00
bool escapeQuotes ,
2004-08-04 18:45:11 +04:00
bool atOnly ,
2004-08-04 22:34:03 +04:00
const char * filename ,
long line ) const
2001-02-13 03:49:52 +03:00
{
2001-07-28 00:29:50 +04:00
// This method replaces ${VAR} and @VAR@ where VAR is looked up
2002-01-22 18:17:37 +03:00
// with GetDefinition(), if not found in the map, nothing is expanded.
2001-08-18 20:52:19 +04:00
// It also supports the $ENV{VAR} syntax where VAR is looked up in
// the current environment variables.
2001-09-02 00:12:52 +04:00
2001-07-28 00:29:50 +04:00
// start by look for $ or @ in the string
2001-10-30 22:05:07 +03:00
std : : string : : size_type markerPos ;
if ( atOnly )
{
markerPos = source . find_first_of ( " @ " ) ;
}
else
{
markerPos = source . find_first_of ( " $@ " ) ;
}
2001-08-02 22:10:19 +04:00
// if not found, or found as the last character, then leave quickly as
// nothing needs to be expanded
if ( ( markerPos = = std : : string : : npos ) | | ( markerPos > = source . size ( ) - 1 ) )
2001-02-13 03:49:52 +03:00
{
2001-09-02 00:12:52 +04:00
return source . c_str ( ) ;
2001-07-28 00:29:50 +04:00
}
// current position
2001-09-02 00:12:52 +04:00
std : : string : : size_type currentPos = 0 ; // start at 0
2001-07-28 00:29:50 +04:00
std : : string result ; // string with replacements
// go until the the end of the string
2001-08-02 22:10:19 +04:00
while ( ( markerPos ! = std : : string : : npos ) & & ( markerPos < source . size ( ) - 1 ) )
2001-07-28 00:29:50 +04:00
{
// grab string from currentPos to the start of the variable
// and add it to the result
result + = source . substr ( currentPos , markerPos - currentPos ) ;
char endVariableMarker ; // what is the end of the variable @ or }
2001-08-18 20:52:19 +04:00
int markerStartSize = 1 ; // size of the start marker 1 or 2 or 5
2001-10-30 22:05:07 +03:00
if ( ! atOnly & & source [ markerPos ] = = ' $ ' )
2001-06-22 19:14:32 +04:00
{
2001-07-28 00:29:50 +04:00
// ${var} case
if ( source [ markerPos + 1 ] = = ' { ' )
{
endVariableMarker = ' } ' ;
markerStartSize = 2 ;
}
2001-08-18 20:52:19 +04:00
// $ENV{var} case
2001-09-02 00:12:52 +04:00
else if ( markerPos + 4 < source . size ( ) & &
2001-08-18 20:52:19 +04:00
source [ markerPos + 4 ] = = ' { ' & &
2001-08-19 20:14:24 +04:00
! source . substr ( markerPos + 1 , 3 ) . compare ( " ENV " ) )
2001-08-18 20:52:19 +04:00
{
endVariableMarker = ' } ' ;
markerStartSize = 5 ;
}
2001-07-28 00:29:50 +04:00
else
{
// bogus $ with no { so add $ to result and move on
result + = ' $ ' ; // add bogus $ back into string
currentPos = markerPos + 1 ; // move on
endVariableMarker = ' ' ; // set end var to space so we can tell bogus
}
2001-06-22 19:14:32 +04:00
}
2001-07-28 00:29:50 +04:00
else
{
// @VAR case
endVariableMarker = ' @ ' ;
}
2001-08-18 20:52:19 +04:00
// if it was a valid variable (started with @ or ${ or $ENV{ )
2001-07-28 00:29:50 +04:00
if ( endVariableMarker ! = ' ' )
{
markerPos + = markerStartSize ; // move past marker
// find the end variable marker starting at the markerPos
2001-09-02 00:12:52 +04:00
std : : string : : size_type endVariablePos =
2001-07-28 00:29:50 +04:00
source . find ( endVariableMarker , markerPos ) ;
if ( endVariablePos = = std : : string : : npos )
{
// no end marker found so add the bogus start
if ( endVariableMarker = = ' @ ' )
{
result + = ' @ ' ;
}
else
{
2001-08-18 20:52:19 +04:00
result + = ( markerStartSize = = 5 ? " $ENV{ " : " ${ " ) ;
2001-07-28 00:29:50 +04:00
}
currentPos = markerPos ;
}
else
{
// good variable remove it
std : : string var = source . substr ( markerPos , endVariablePos - markerPos ) ;
2001-08-18 20:52:19 +04:00
bool found = false ;
if ( markerStartSize = = 5 ) // $ENV{
2001-07-28 00:29:50 +04:00
{
2001-08-18 20:52:19 +04:00
char * ptr = getenv ( var . c_str ( ) ) ;
2001-09-02 00:12:52 +04:00
if ( ptr )
2001-07-28 00:29:50 +04:00
{
2001-08-18 20:52:19 +04:00
if ( escapeQuotes )
{
result + = cmSystemTools : : EscapeQuotes ( ptr ) ;
}
else
{
result + = ptr ;
}
found = true ;
2001-07-28 00:29:50 +04:00
}
2001-08-18 20:52:19 +04:00
}
else
{
2001-08-27 22:44:15 +04:00
const char * lookup = this - > GetDefinition ( var . c_str ( ) ) ;
if ( lookup )
2001-07-28 00:29:50 +04:00
{
2001-08-18 20:52:19 +04:00
if ( escapeQuotes )
{
2001-08-27 22:44:15 +04:00
result + = cmSystemTools : : EscapeQuotes ( lookup ) ;
2001-08-18 20:52:19 +04:00
}
else
{
2001-08-27 22:44:15 +04:00
result + = lookup ;
2001-08-18 20:52:19 +04:00
}
found = true ;
2001-07-28 00:29:50 +04:00
}
2004-08-04 18:45:11 +04:00
else if ( filename & & ( var = = " CMAKE_CURRENT_LIST_FILE " ) )
{
result + = filename ;
found = true ;
}
else if ( line > = 0 & & ( var = = " CMAKE_CURRENT_LIST_LINE " ) )
{
cmOStringStream ostr ;
ostr < < line ;
result + = ostr . str ( ) ;
found = true ;
}
2001-07-28 00:29:50 +04:00
}
2001-08-18 20:52:19 +04:00
// if found add to result, if not, then it gets blanked
2001-09-02 00:12:52 +04:00
if ( ! found )
2001-07-28 00:29:50 +04:00
{
// if no definition is found then add the var back
if ( endVariableMarker = = ' @ ' )
{
result + = " @ " ;
result + = var ;
result + = " @ " ;
}
}
// lookup var, and replace it
currentPos = endVariablePos + 1 ;
}
}
2001-10-30 22:05:07 +03:00
if ( atOnly )
{
markerPos = source . find_first_of ( " @ " , currentPos ) ;
}
else
{
markerPos = source . find_first_of ( " $@ " , currentPos ) ;
}
2001-09-02 00:12:52 +04:00
}
2001-07-28 00:29:50 +04:00
result + = source . substr ( currentPos ) ; // pick up the rest of the string
source = result ;
2001-09-02 00:12:52 +04:00
return source . c_str ( ) ;
2001-02-13 03:49:52 +03:00
}
2001-10-30 22:05:07 +03:00
void cmMakefile : : RemoveVariablesInString ( std : : string & source ,
bool atOnly ) const
2001-04-30 18:44:00 +04:00
{
2001-10-30 22:05:07 +03:00
if ( ! atOnly )
2001-04-30 18:44:00 +04:00
{
2003-06-23 22:10:12 +04:00
cmsys : : RegularExpression var ( " ( \\ ${[A-Za-z_0-9]*}) " ) ;
2001-10-30 22:05:07 +03:00
while ( var . find ( source ) )
{
source . erase ( var . start ( ) , var . end ( ) - var . start ( ) ) ;
}
2001-04-30 18:44:00 +04:00
}
2001-10-30 22:05:07 +03:00
if ( ! atOnly )
2001-08-18 20:52:19 +04:00
{
2003-06-23 22:10:12 +04:00
cmsys : : RegularExpression varb ( " ( \\ $ENV{[A-Za-z_0-9]*}) " ) ;
2001-10-30 22:05:07 +03:00
while ( varb . find ( source ) )
{
source . erase ( varb . start ( ) , varb . end ( ) - varb . start ( ) ) ;
}
2001-08-18 20:52:19 +04:00
}
2003-06-23 22:10:12 +04:00
cmsys : : RegularExpression var2 ( " (@[A-Za-z_0-9]*@) " ) ;
2001-04-30 18:44:00 +04:00
while ( var2 . find ( source ) )
{
2001-05-04 19:30:46 +04:00
source . erase ( var2 . start ( ) , var2 . end ( ) - var2 . start ( ) ) ;
2001-04-30 18:44:00 +04:00
}
}
2001-02-23 03:24:43 +03:00
2001-03-08 18:30:18 +03:00
/**
* Add the default definitions to the makefile . These values must not
* be dependent on anything that isn ' t known when this cmMakefile instance
* is constructed .
*/
void cmMakefile : : AddDefaultDefinitions ( )
{
2002-09-11 00:52:39 +04:00
# if defined(_WIN32) || defined(__CYGWIN__)
this - > AddDefinition ( " WIN32 " , " 1 " ) ;
# else
this - > AddDefinition ( " UNIX " , " 1 " ) ;
# endif
// Cygwin is more like unix so enable the unix commands
# if defined(__CYGWIN__)
this - > AddDefinition ( " UNIX " , " 1 " ) ;
this - > AddDefinition ( " CYGWIN " , " 1 " ) ;
# endif
# if defined(__APPLE__)
this - > AddDefinition ( " APPLE " , " 1 " ) ;
# endif
2001-06-07 22:52:29 +04:00
char temp [ 1024 ] ;
sprintf ( temp , " %d " , cmMakefile : : GetMinorVersion ( ) ) ;
this - > AddDefinition ( " CMAKE_MINOR_VERSION " , temp ) ;
sprintf ( temp , " %d " , cmMakefile : : GetMajorVersion ( ) ) ;
this - > AddDefinition ( " CMAKE_MAJOR_VERSION " , temp ) ;
2001-03-08 18:30:18 +03:00
}
2001-03-20 21:20:59 +03:00
/**
* Find a source group whose regular expression matches the filename
* part of the given source name . Search backward through the list of
* source groups , and take the first matching group found . This way
* non - inherited SOURCE_GROUP commands will have precedence over
* inherited ones .
*/
2001-04-11 22:59:02 +04:00
cmSourceGroup &
cmMakefile : : FindSourceGroup ( const char * source ,
std : : vector < cmSourceGroup > & groups )
2001-03-20 21:20:59 +03:00
{
2003-07-23 23:32:54 +04:00
// First search for a group that lists the file explicitly.
for ( std : : vector < cmSourceGroup > : : reverse_iterator sg = groups . rbegin ( ) ;
sg ! = groups . rend ( ) ; + + sg )
2001-03-20 21:20:59 +03:00
{
2003-07-23 23:32:54 +04:00
if ( sg - > MatchesFiles ( source ) )
{
return * sg ;
}
2001-03-20 21:20:59 +03:00
}
2003-07-23 23:32:54 +04:00
// Now search for a group whose regex matches the file.
2001-04-11 22:59:02 +04:00
for ( std : : vector < cmSourceGroup > : : reverse_iterator sg = groups . rbegin ( ) ;
sg ! = groups . rend ( ) ; + + sg )
2001-03-20 21:20:59 +03:00
{
2003-07-23 23:32:54 +04:00
if ( sg - > MatchesRegex ( source ) )
2001-03-20 21:20:59 +03:00
{
return * sg ;
}
}
// Shouldn't get here, but just in case, return the default group.
2001-04-11 22:59:02 +04:00
return groups . front ( ) ;
2001-03-20 21:20:59 +03:00
}
2001-04-11 22:59:02 +04:00
2002-12-12 02:13:33 +03:00
bool cmMakefile : : IsFunctionBlocked ( const cmListFileFunction & lff )
2001-04-20 01:39:03 +04:00
{
2002-06-28 05:17:25 +04:00
// if there are no blockers get out of here
if ( m_FunctionBlockers . begin ( ) = = m_FunctionBlockers . end ( ) )
{
return false ;
}
2001-04-20 01:39:03 +04:00
// loop over all function blockers to see if any block this command
2002-08-09 20:00:49 +04:00
// evaluate in reverse, this is critical for balanced IF statements etc
std : : list < cmFunctionBlocker * > : : reverse_iterator pos ;
for ( pos = m_FunctionBlockers . rbegin ( ) ;
pos ! = m_FunctionBlockers . rend ( ) ; + + pos )
2001-04-20 01:39:03 +04:00
{
2002-12-12 02:13:33 +03:00
if ( ( * pos ) - > IsFunctionBlocked ( lff , * this ) )
2001-04-20 01:39:03 +04:00
{
2002-12-12 02:13:33 +03:00
return true ;
}
}
return false ;
}
void cmMakefile : : ExpandArguments (
std : : vector < cmListFileArgument > const & inArgs ,
std : : vector < std : : string > & outArgs )
{
std : : vector < cmListFileArgument > : : const_iterator i ;
2003-06-24 23:23:34 +04:00
std : : string value ;
outArgs . reserve ( inArgs . size ( ) ) ;
2002-12-12 02:13:33 +03:00
for ( i = inArgs . begin ( ) ; i ! = inArgs . end ( ) ; + + i )
{
// Expand the variables in the argument.
2003-06-24 23:23:34 +04:00
value = i - > Value ;
2004-08-04 18:45:11 +04:00
this - > ExpandVariablesInString ( value , false , false , i - > FilePath , i - > Line ) ;
2002-12-12 02:13:33 +03:00
// If the argument is quoted, it should be one argument.
// Otherwise, it may be a list of arguments.
if ( i - > Quoted )
{
outArgs . push_back ( value ) ;
2002-03-27 00:45:52 +03:00
}
else
{
2002-12-12 02:13:33 +03:00
cmSystemTools : : ExpandListArgument ( value , outArgs ) ;
2001-04-20 01:39:03 +04:00
}
}
}
2002-12-12 02:13:33 +03:00
void cmMakefile : : RemoveFunctionBlocker ( const cmListFileFunction & lff )
2001-04-20 01:39:03 +04:00
{
// loop over all function blockers to see if any block this command
2002-07-10 19:38:38 +04:00
std : : list < cmFunctionBlocker * > : : reverse_iterator pos ;
for ( pos = m_FunctionBlockers . rbegin ( ) ;
pos ! = m_FunctionBlockers . rend ( ) ; + + pos )
2001-04-20 01:39:03 +04:00
{
2002-12-12 02:13:33 +03:00
if ( ( * pos ) - > ShouldRemove ( lff , * this ) )
2001-04-20 01:39:03 +04:00
{
2001-06-04 18:18:03 +04:00
cmFunctionBlocker * b = * pos ;
2002-12-03 20:59:40 +03:00
m_FunctionBlockers . remove ( b ) ;
2001-06-04 18:18:03 +04:00
delete b ;
2002-10-24 18:23:11 +04:00
break ;
2001-04-20 01:39:03 +04:00
}
}
return ;
}
2001-04-30 18:44:00 +04:00
void cmMakefile : : SetHomeDirectory ( const char * dir )
{
m_cmHomeDirectory = dir ;
cmSystemTools : : ConvertToUnixSlashes ( m_cmHomeDirectory ) ;
this - > AddDefinition ( " CMAKE_SOURCE_DIR " , this - > GetHomeDirectory ( ) ) ;
2004-07-20 19:07:37 +04:00
if ( ! this - > GetDefinition ( " CMAKE_CURRENT_SOURCE_DIR " ) )
{
this - > AddDefinition ( " CMAKE_CURRENT_SOURCE_DIR " , this - > GetHomeDirectory ( ) ) ;
}
2001-04-30 18:44:00 +04:00
}
void cmMakefile : : SetHomeOutputDirectory ( const char * lib )
{
m_HomeOutputDirectory = lib ;
cmSystemTools : : ConvertToUnixSlashes ( m_HomeOutputDirectory ) ;
this - > AddDefinition ( " CMAKE_BINARY_DIR " , this - > GetHomeOutputDirectory ( ) ) ;
2004-07-20 19:07:37 +04:00
if ( ! this - > GetDefinition ( " CMAKE_CURRENT_BINARY_DIR " ) )
{
this - > AddDefinition ( " CMAKE_CURRENT_BINARY_DIR " , this - > GetHomeOutputDirectory ( ) ) ;
}
2001-04-30 18:44:00 +04:00
}
2001-05-16 17:19:46 +04:00
/**
* Register the given cmData instance with its own name .
*/
void cmMakefile : : RegisterData ( cmData * data )
{
std : : string name = data - > GetName ( ) ;
DataMap : : const_iterator d = m_DataMap . find ( name ) ;
2002-09-10 23:37:28 +04:00
if ( ( d ! = m_DataMap . end ( ) ) & & ( d - > second ! = 0 ) & & ( d - > second ! = data ) )
2001-05-16 17:19:46 +04:00
{
delete d - > second ;
}
m_DataMap [ name ] = data ;
}
/**
* Register the given cmData instance with the given name . This can be used
* to register a NULL pointer .
*/
void cmMakefile : : RegisterData ( const char * name , cmData * data )
{
DataMap : : const_iterator d = m_DataMap . find ( name ) ;
2002-09-10 23:37:28 +04:00
if ( ( d ! = m_DataMap . end ( ) ) & & ( d - > second ! = 0 ) & & ( d - > second ! = data ) )
2001-05-16 17:19:46 +04:00
{
delete d - > second ;
}
m_DataMap [ name ] = data ;
}
/**
* Lookup a cmData instance previously registered with the given name . If
* the instance cannot be found , return NULL .
*/
cmData * cmMakefile : : LookupData ( const char * name ) const
{
DataMap : : const_iterator d = m_DataMap . find ( name ) ;
if ( d ! = m_DataMap . end ( ) )
{
return d - > second ;
}
else
{
2002-09-10 23:37:28 +04:00
return 0 ;
2001-05-16 17:19:46 +04:00
}
}
2002-06-27 23:57:09 +04:00
cmSourceFile * cmMakefile : : GetSource ( const char * sourceName ) const
2002-03-29 18:06:30 +03:00
{
2003-06-05 22:40:25 +04:00
// if the source is provided with a full path use it, otherwise
// by default it is in the current source dir
std : : string path = cmSystemTools : : GetFilenamePath ( sourceName ) ;
if ( path . empty ( ) )
{
path = this - > GetCurrentDirectory ( ) ;
}
2003-06-24 23:23:34 +04:00
2003-06-05 22:40:25 +04:00
std : : string sname =
2003-06-24 23:23:34 +04:00
cmSystemTools : : GetFilenameWithoutLastExtension ( sourceName ) ;
2003-06-05 22:40:25 +04:00
// compute the extension
2003-06-24 23:23:34 +04:00
std : : string ext
= cmSystemTools : : GetFilenameLastExtension ( sourceName ) ;
2003-06-03 18:30:23 +04:00
if ( ext . length ( ) & & ext [ 0 ] = = ' . ' )
2002-04-30 20:58:57 +04:00
{
2003-06-03 18:30:23 +04:00
ext = ext . substr ( 1 ) ;
2002-04-30 20:58:57 +04:00
}
2003-06-05 22:40:25 +04:00
2002-06-27 23:57:09 +04:00
for ( std : : vector < cmSourceFile * > : : const_iterator i = m_SourceFiles . begin ( ) ;
2002-03-29 18:06:30 +03:00
i ! = m_SourceFiles . end ( ) ; + + i )
{
2003-06-05 23:28:51 +04:00
if ( ( * i ) - > GetSourceName ( ) = = sname & &
cmSystemTools : : GetFilenamePath ( ( * i ) - > GetFullPath ( ) ) = = path & &
2003-06-05 22:40:25 +04:00
( ext . size ( ) = = 0 | | ( ext = = ( * i ) - > GetSourceExtension ( ) ) ) )
2002-03-29 18:06:30 +03:00
{
2003-06-05 22:40:25 +04:00
return * i ;
2002-03-29 18:06:30 +03:00
}
}
2003-06-06 00:12:25 +04:00
// geeze, if it wasn't found maybe it is listed under the output dir
if ( ! cmSystemTools : : GetFilenamePath ( sourceName ) . empty ( ) )
{
return 0 ;
}
path = this - > GetCurrentOutputDirectory ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator i = m_SourceFiles . begin ( ) ;
i ! = m_SourceFiles . end ( ) ; + + i )
{
if ( ( * i ) - > GetSourceName ( ) = = sname & &
cmSystemTools : : GetFilenamePath ( ( * i ) - > GetFullPath ( ) ) = = path & &
( ext . size ( ) = = 0 | | ( ext = = ( * i ) - > GetSourceExtension ( ) ) ) )
{
return * i ;
}
}
2002-03-29 18:06:30 +03:00
return 0 ;
}
2003-06-03 18:30:23 +04:00
cmSourceFile * cmMakefile : : GetOrCreateSource ( const char * sourceName ,
bool generated )
{
2003-06-05 22:40:25 +04:00
// make it a full path first
std : : string src = sourceName ;
2003-06-14 00:59:42 +04:00
bool relative = ! cmSystemTools : : FileIsFullPath ( sourceName ) ;
2003-06-19 22:27:39 +04:00
std : : string srcTreeFile = this - > GetCurrentDirectory ( ) ;
srcTreeFile + = " / " ;
srcTreeFile + = sourceName ;
2003-06-14 00:59:42 +04:00
if ( relative )
2003-06-05 22:40:25 +04:00
{
2003-06-19 22:27:39 +04:00
src = srcTreeFile ;
2003-06-05 22:40:25 +04:00
}
2003-06-03 18:30:23 +04:00
// check to see if it exists
2003-06-05 22:40:25 +04:00
cmSourceFile * ret = this - > GetSource ( src . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
if ( ret )
{
return ret ;
}
2003-06-06 00:12:25 +04:00
// OK a source file object doesn't exist for the source
// maybe we made a bad call on assuming it was in the src tree
2003-06-19 22:27:39 +04:00
std : : string buildTreeFile = this - > GetCurrentOutputDirectory ( ) ;
buildTreeFile + = " / " ;
buildTreeFile + = sourceName ;
2003-06-18 17:13:39 +04:00
if ( relative )
2003-06-06 00:12:25 +04:00
{
2003-06-19 22:27:39 +04:00
src = buildTreeFile ;
ret = this - > GetSource ( src . c_str ( ) ) ;
if ( ret )
{
return ret ;
}
// if it has not been marked generated check to see if it exists in the
// src tree
if ( ! generated )
{
// see if the file is in the source tree, otherwise assume it
// is in the binary tree
if ( cmSystemTools : : FileExists ( srcTreeFile . c_str ( ) ) & &
! cmSystemTools : : FileIsDirectory ( srcTreeFile . c_str ( ) ) )
{
src = srcTreeFile ;
}
else
{
if ( cmSystemTools : : GetFilenameLastExtension ( srcTreeFile . c_str ( ) ) . size ( ) = = 0 )
{
if ( cmSystemTools : : DoesFileExistWithExtensions (
srcTreeFile . c_str ( ) , this - > GetSourceExtensions ( ) ) )
{
src = srcTreeFile ;
}
else if ( cmSystemTools : : DoesFileExistWithExtensions (
srcTreeFile . c_str ( ) , this - > GetHeaderExtensions ( ) ) )
{
src = srcTreeFile ;
}
}
}
}
2003-06-06 00:12:25 +04:00
}
2003-06-19 22:27:39 +04:00
// a cmSourceFile instance does not exist yet so we must create one
2003-06-18 17:13:39 +04:00
// go back to looking in the source directory for it
2003-06-19 22:27:39 +04:00
2003-06-03 18:30:23 +04:00
// we must create one
cmSourceFile file ;
2003-06-14 00:59:42 +04:00
std : : string path = cmSystemTools : : GetFilenamePath ( src ) ;
2003-06-03 18:30:23 +04:00
if ( generated )
{
2003-06-05 22:40:25 +04:00
std : : string ext = cmSystemTools : : GetFilenameLastExtension ( src ) ;
std : : string name_no_ext = cmSystemTools : : GetFilenameName ( src . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
name_no_ext = name_no_ext . substr ( 0 , name_no_ext . length ( ) - ext . length ( ) ) ;
if ( ext . length ( ) & & ext [ 0 ] = = ' . ' )
{
ext = ext . substr ( 1 ) ;
2004-08-09 21:03:41 +04:00
}
bool headerFile = ! ( std : : find ( m_HeaderFileExtensions . begin ( ) , m_HeaderFileExtensions . end ( ) , ext ) = =
m_HeaderFileExtensions . end ( ) ) ;
file . SetName ( name_no_ext . c_str ( ) , path . c_str ( ) , ext . c_str ( ) , headerFile ) ;
2003-06-03 18:30:23 +04:00
}
else
{
2003-06-05 22:40:25 +04:00
file . SetName ( cmSystemTools : : GetFilenameName ( src . c_str ( ) ) . c_str ( ) ,
path . c_str ( ) ,
this - > GetSourceExtensions ( ) ,
this - > GetHeaderExtensions ( ) ) ;
2003-06-03 18:30:23 +04:00
}
// add the source file to the makefile
this - > AddSource ( file ) ;
2003-06-05 22:40:25 +04:00
src = file . GetFullPath ( ) ;
ret = this - > GetSource ( src . c_str ( ) ) ;
2003-06-03 18:30:23 +04:00
if ( ! ret )
{
cmSystemTools : : Error (
" CMake failed to properly look up cmSourceFile: " , sourceName ) ;
}
return ret ;
}
2002-03-29 18:06:30 +03:00
cmSourceFile * cmMakefile : : AddSource ( cmSourceFile const & sf )
{
// check to see if it exists
2003-06-05 23:18:16 +04:00
cmSourceFile * ret = this - > GetSource ( sf . GetFullPath ( ) . c_str ( ) ) ;
if ( ret )
2002-03-29 18:06:30 +03:00
{
return ret ;
}
ret = new cmSourceFile ( sf ) ;
m_SourceFiles . push_back ( ret ) ;
return ret ;
}
2004-08-27 16:41:07 +04:00
void cmMakefile : : EnableLanguage ( std : : vector < std : : string > const & lang )
2002-04-03 00:43:23 +04:00
{
2002-09-06 21:06:23 +04:00
m_LocalGenerator - > GetGlobalGenerator ( ) - > EnableLanguage ( lang , this ) ;
2002-04-03 00:43:23 +04:00
}
2002-05-02 00:33:27 +04:00
2002-06-27 23:57:09 +04:00
void cmMakefile : : ExpandSourceListArguments (
std : : vector < std : : string > const & arguments ,
2002-07-02 16:24:36 +04:00
std : : vector < std : : string > & newargs , unsigned int start )
2002-06-27 23:57:09 +04:00
{
// first figure out if we need to handle version 1.2 style source lists
int oldVersion = 1 ;
const char * versionValue
= this - > GetDefinition ( " CMAKE_MINIMUM_REQUIRED_VERSION " ) ;
if ( versionValue & & atof ( versionValue ) > 1.2 )
{
oldVersion = 0 ;
}
// now expand the args
2002-06-28 00:47:38 +04:00
unsigned int i ;
2002-06-27 23:57:09 +04:00
for ( i = 0 ; i < arguments . size ( ) ; + + i )
{
// is the arg defined ?, if so use the def
const char * def = this - > GetDefinition ( arguments [ i ] . c_str ( ) ) ;
if ( def & & oldVersion & & i > = start )
{
2002-12-12 02:13:33 +03:00
// Definition lookup could result in a list that needs to be
// expanded.
cmSystemTools : : ExpandListArgument ( def , newargs ) ;
2002-06-27 23:57:09 +04:00
}
else
{
2002-12-12 02:13:33 +03:00
// List expansion will have been done already.
newargs . push_back ( arguments [ i ] ) ;
2002-06-27 23:57:09 +04:00
}
}
}
2002-08-28 22:51:10 +04:00
int cmMakefile : : TryCompile ( const char * srcdir , const char * bindir ,
2002-09-18 19:37:40 +04:00
const char * projectName , const char * targetName ,
2002-09-20 21:15:56 +04:00
const std : : vector < std : : string > * cmakeArgs ,
std : : string * output )
2002-08-28 22:51:10 +04:00
{
// does the binary directory exist ? If not create it...
if ( ! cmSystemTools : : FileIsDirectory ( bindir ) )
{
cmSystemTools : : MakeDirectory ( bindir ) ;
}
// change to the tests directory and run cmake
// use the cmake object instead of calling cmake
std : : string cwd = cmSystemTools : : GetCurrentWorkingDirectory ( ) ;
cmSystemTools : : ChangeDirectory ( bindir ) ;
// make sure the same generator is used
// use this program as the cmake to be run, it should not
// be run that way but the cmake object requires a vailid path
std : : string cmakeCommand = this - > GetDefinition ( " CMAKE_COMMAND " ) ;
2002-09-06 21:06:23 +04:00
cmake cm ;
2002-09-12 19:08:06 +04:00
cm . SetIsInTryCompile ( true ) ;
2002-09-06 21:06:23 +04:00
cmGlobalGenerator * gg =
2002-09-13 18:42:50 +04:00
cm . CreateGlobalGenerator ( m_LocalGenerator - > GetGlobalGenerator ( ) - > GetName ( ) ) ;
2002-09-06 21:06:23 +04:00
if ( ! gg )
{
cmSystemTools : : Error (
" Internal CMake error, TryCompile bad GlobalGenerator " ) ;
// return to the original directory
cmSystemTools : : ChangeDirectory ( cwd . c_str ( ) ) ;
return 1 ;
}
2002-09-11 20:52:11 +04:00
cm . SetGlobalGenerator ( gg ) ;
2002-08-28 22:51:10 +04:00
2002-09-06 21:06:23 +04:00
// do a configure
cm . SetHomeDirectory ( srcdir ) ;
cm . SetHomeOutputDirectory ( bindir ) ;
cm . SetStartDirectory ( srcdir ) ;
cm . SetStartOutputDirectory ( bindir ) ;
2002-09-17 21:59:58 +04:00
cm . SetCMakeCommand ( cmakeCommand . c_str ( ) ) ;
cm . LoadCache ( ) ;
2002-09-18 19:37:40 +04:00
// if cmake args were provided then pass them in
if ( cmakeArgs )
{
cm . SetCacheArgs ( * cmakeArgs ) ;
}
2002-09-13 18:42:50 +04:00
// to save time we pass the EnableLanguage info directly
2002-11-08 23:46:08 +03:00
gg - > EnableLanguagesFromGenerator ( m_LocalGenerator - > GetGlobalGenerator ( ) ) ;
2002-09-13 18:42:50 +04:00
2002-09-17 21:59:58 +04:00
if ( cm . Configure ( ) ! = 0 )
2002-08-28 22:51:10 +04:00
{
cmSystemTools : : Error (
2002-09-06 21:06:23 +04:00
" Internal CMake error, TryCompile configure of cmake failed " ) ;
2002-08-28 22:51:10 +04:00
// return to the original directory
cmSystemTools : : ChangeDirectory ( cwd . c_str ( ) ) ;
return 1 ;
}
2002-09-06 21:06:23 +04:00
if ( cm . Generate ( ) ! = 0 )
2002-08-28 22:51:10 +04:00
{
cmSystemTools : : Error (
2002-09-06 21:06:23 +04:00
" Internal CMake error, TryCompile generation of cmake failed " ) ;
2002-08-28 22:51:10 +04:00
// return to the original directory
cmSystemTools : : ChangeDirectory ( cwd . c_str ( ) ) ;
return 1 ;
}
// finally call the generator to actually build the resulting project
2002-09-13 18:42:50 +04:00
int ret =
m_LocalGenerator - > GetGlobalGenerator ( ) - > TryCompile ( srcdir , bindir ,
projectName ,
2002-09-20 21:15:56 +04:00
targetName ,
2004-08-05 00:33:10 +04:00
output ,
this ) ;
2002-08-28 22:51:10 +04:00
2002-09-06 21:06:23 +04:00
cmSystemTools : : ChangeDirectory ( cwd . c_str ( ) ) ;
2002-09-11 00:52:39 +04:00
return ret ;
2002-08-28 22:51:10 +04:00
}
2003-01-08 20:59:52 +03:00
cmake * cmMakefile : : GetCMakeInstance ( ) const
{
if ( m_LocalGenerator & & m_LocalGenerator - > GetGlobalGenerator ( ) )
{
return m_LocalGenerator - > GetGlobalGenerator ( ) - > GetCMakeInstance ( ) ;
}
return 0 ;
}
cmVariableWatch * cmMakefile : : GetVariableWatch ( ) const
{
if ( this - > GetCMakeInstance ( ) & &
this - > GetCMakeInstance ( ) - > GetVariableWatch ( ) )
{
return this - > GetCMakeInstance ( ) - > GetVariableWatch ( ) ;
}
return 0 ;
}
2003-08-07 02:54:13 +04:00
void cmMakefile : : AddMacro ( const char * name , const char * signature )
{
if ( ! name | | ! signature )
{
return ;
}
m_MacrosMap [ name ] = signature ;
}
void cmMakefile : : GetListOfMacros ( std : : string & macros )
{
StringStringMap : : iterator it ;
macros = " " ;
2003-08-07 03:19:17 +04:00
int cc = 0 ;
2003-08-07 02:54:13 +04:00
for ( it = m_MacrosMap . begin ( ) ; it ! = m_MacrosMap . end ( ) ; + + it )
{
if ( cc > 0 )
{
macros + = " ; " ;
}
macros + = it - > first ;
cc + + ;
}
}
2002-09-06 21:06:23 +04:00
cmCacheManager * cmMakefile : : GetCacheManager ( ) const
{
2003-01-14 17:53:13 +03:00
return this - > GetCMakeInstance ( ) - > GetCacheManager ( ) ;
2002-09-06 21:06:23 +04:00
}
2002-09-20 23:01:00 +04:00
bool cmMakefile : : GetLocal ( ) const
{
2003-01-14 17:53:13 +03:00
return this - > GetCMakeInstance ( ) - > GetLocal ( ) ;
2002-09-20 23:01:00 +04:00
}
2002-11-13 23:59:40 +03:00
void cmMakefile : : DisplayStatus ( const char * message , float s )
{
this - > GetLocalGenerator ( ) - > GetGlobalGenerator ( )
- > GetCMakeInstance ( ) - > UpdateProgress ( message , s ) ;
}
2002-12-02 23:59:59 +03:00
/**
* Find the library with the given name . Searches the given path and then
* the system search path . Returns the full path to the library if it is
* found . Otherwise , the empty string is returned .
*/
std : : string cmMakefile : : FindLibrary ( const char * name ,
const std : : vector < std : : string > & userPaths )
{
// See if the executable exists as written.
if ( cmSystemTools : : FileExists ( name ) )
{
return cmSystemTools : : CollapseFullPath ( name ) ;
}
// Add the system search path to our path.
2004-06-30 19:31:41 +04:00
std : : vector < std : : string > path ;
2004-04-22 21:24:20 +04:00
cmSystemTools : : GetPath ( path , " CMAKE_LIBRARY_PATH " ) ;
2002-12-02 23:59:59 +03:00
cmSystemTools : : GetPath ( path ) ;
2004-06-30 19:31:41 +04:00
// now add the path
path . insert ( path . end ( ) , userPaths . begin ( ) , userPaths . end ( ) ) ;
2002-12-02 23:59:59 +03:00
// Add some lib directories specific to compilers, depending on the
// current generator, so that library that might have been stored here
// can be found too.
// i.e. Microsoft Visual Studio or .Net: path to compiler/../Lib
// Borland: path to compiler/../Lib
const char * genName = this - > GetDefinition ( " CMAKE_GENERATOR " ) ;
if ( genName )
{
if ( ! strcmp ( genName , " NMake Makefiles " ) | |
! strcmp ( genName , " Visual Studio 6 " ) )
{
const char * compiler = this - > GetDefinition ( " CMAKE_CXX_COMPILER " ) ;
if ( compiler )
{
std : : string compiler_path = cmSystemTools : : FindProgram ( compiler ) ;
if ( compiler_path . size ( ) )
{
std : : string lib_path =
cmSystemTools : : GetFilenamePath (
cmSystemTools : : GetFilenamePath ( compiler_path ) ) + " /Lib " ;
path . push_back ( lib_path ) ;
}
}
}
else if ( ! strcmp ( genName , " Visual Studio 7 " ) )
{
// It is likely that the compiler won't be in the path for .Net, but
// we know where devenv is.
const char * devenv = this - > GetDefinition ( " MICROSOFT_DEVENV " ) ;
if ( devenv )
{
std : : string devenv_path = cmSystemTools : : FindProgram ( devenv ) ;
if ( devenv_path . size ( ) )
{
std : : string vc7_path =
cmSystemTools : : GetFilenamePath (
cmSystemTools : : GetFilenamePath (
cmSystemTools : : GetFilenamePath ( devenv_path ) ) ) + " /Vc7 " ;
path . push_back ( vc7_path + " /lib " ) ;
path . push_back ( vc7_path + " /PlatformSDK/lib " ) ;
}
}
}
else if ( ! strcmp ( genName , " Borland Makefiles " ) )
{
const char * bcb_bin_path = this - > GetDefinition ( " BCB_BIN_PATH " ) ;
if ( bcb_bin_path )
{
std : : string lib_path =
cmSystemTools : : GetFilenamePath ( bcb_bin_path ) + " /Lib " ;
path . push_back ( lib_path ) ;
}
}
}
return cmSystemTools : : FindLibrary ( name , path ) ;
}
2004-02-29 02:59:19 +03:00
std : : string cmMakefile : : GetModulesFile ( const char * filename )
{
std : : vector < std : : string > modulePath ;
const char * def = this - > GetDefinition ( " CMAKE_MODULE_PATH " ) ;
if ( def )
{
cmSystemTools : : ExpandListArgument ( def , modulePath ) ;
}
// Also search in the standard modules location.
def = this - > GetDefinition ( " CMAKE_ROOT " ) ;
if ( def )
{
std : : string rootModules = def ;
rootModules + = " /Modules " ;
modulePath . push_back ( rootModules ) ;
}
//std::string Look through the possible module directories.
for ( std : : vector < std : : string > : : iterator i = modulePath . begin ( ) ;
i ! = modulePath . end ( ) ; + + i )
{
std : : string itempl = * i ;
cmSystemTools : : ConvertToUnixSlashes ( itempl ) ;
2004-02-29 23:13:01 +03:00
itempl + = " / " ;
2004-02-29 02:59:19 +03:00
itempl + = filename ;
if ( cmSystemTools : : FileExists ( itempl . c_str ( ) ) )
{
return itempl ;
}
}
return " " ;
}
2004-03-04 02:18:47 +03:00
void cmMakefile : : ConfigureString ( const std : : string & input ,
std : : string & output , bool atOnly ,
bool escapeQuotes )
{
// Split input to handle one line at a time.
std : : string : : const_iterator lineStart = input . begin ( ) ;
while ( lineStart ! = input . end ( ) )
{
// Find the end of this line.
std : : string : : const_iterator lineEnd = lineStart ;
while ( lineEnd ! = input . end ( ) & & * lineEnd ! = ' \n ' )
{
+ + lineEnd ;
}
// Copy the line.
std : : string line ( lineStart , lineEnd ) ;
// Skip the newline character.
bool haveNewline = ( lineEnd ! = input . end ( ) ) ;
if ( haveNewline )
{
+ + lineEnd ;
}
// Replace #cmakedefine instances.
if ( m_cmDefineRegex . find ( line ) )
{
const char * def = this - > GetDefinition ( m_cmDefineRegex . match ( 1 ) . c_str ( ) ) ;
if ( ! cmSystemTools : : IsOff ( def ) )
{
cmSystemTools : : ReplaceString ( line , " #cmakedefine " , " #define " ) ;
output + = line ;
}
else
{
cmSystemTools : : ReplaceString ( line , " #cmakedefine " , " #undef " ) ;
output + = " /* " ;
output + = line ;
output + = " */ " ;
}
}
else
{
output + = line ;
}
if ( haveNewline )
{
output + = " \n " ;
}
// Move to the next line.
lineStart = lineEnd ;
}
// Perform variable replacements.
this - > ExpandVariablesInString ( output , escapeQuotes , atOnly ) ;
this - > RemoveVariablesInString ( output , atOnly ) ;
}
2004-03-09 03:05:04 +03:00
int cmMakefile : : ConfigureFile ( const char * infile , const char * outfile ,
2004-03-09 15:50:45 +03:00
bool copyonly , bool atOnly , bool escapeQuotes )
2004-03-09 03:05:04 +03:00
{
2004-05-27 20:53:15 +04:00
int res = 1 ;
2004-03-29 01:00:57 +04:00
if ( ! cmSystemTools : : FileExists ( infile ) )
{
cmSystemTools : : Error ( " File " , infile , " does not exist. " ) ;
return 0 ;
}
2004-03-09 03:05:04 +03:00
std : : string soutfile = outfile ;
std : : string sinfile = infile ;
this - > AddCMakeDependFile ( infile ) ;
cmSystemTools : : ConvertToUnixSlashes ( soutfile ) ;
mode_t perm = 0 ;
cmSystemTools : : GetPermissions ( sinfile . c_str ( ) , perm ) ;
std : : string : : size_type pos = soutfile . rfind ( ' / ' ) ;
if ( pos ! = std : : string : : npos )
{
std : : string path = soutfile . substr ( 0 , pos ) ;
cmSystemTools : : MakeDirectory ( path . c_str ( ) ) ;
}
if ( copyonly )
{
if ( ! cmSystemTools : : CopyFileIfDifferent ( sinfile . c_str ( ) ,
soutfile . c_str ( ) ) )
{
return 0 ;
}
}
else
{
std : : string tempOutputFile = soutfile ;
tempOutputFile + = " .tmp " ;
std : : ofstream fout ( tempOutputFile . c_str ( ) ) ;
if ( ! fout )
{
cmSystemTools : : Error (
2004-07-09 22:18:44 +04:00
" Could not open file for write in copy operation " ,
2004-03-09 03:05:04 +03:00
tempOutputFile . c_str ( ) ) ;
2004-09-08 00:55:25 +04:00
cmSystemTools : : ReportLastSystemError ( " " ) ;
2004-03-09 03:05:04 +03:00
return 0 ;
}
std : : ifstream fin ( sinfile . c_str ( ) ) ;
if ( ! fin )
{
2004-07-09 22:18:44 +04:00
cmSystemTools : : Error ( " Could not open file for read in copy operation " ,
2004-03-09 03:05:04 +03:00
sinfile . c_str ( ) ) ;
return 0 ;
}
// now copy input to output and expand variables in the
// input file at the same time
std : : string inLine ;
std : : string outLine ;
while ( cmSystemTools : : GetLineFromStream ( fin , inLine ) )
{
outLine = " " ;
this - > ConfigureString ( inLine , outLine , atOnly , escapeQuotes ) ;
fout < < outLine . c_str ( ) < < " \n " ;
}
// close the files before attempting to copy
fin . close ( ) ;
fout . close ( ) ;
2004-05-27 20:53:15 +04:00
if ( ! cmSystemTools : : CopyFileIfDifferent ( tempOutputFile . c_str ( ) ,
soutfile . c_str ( ) ) )
{
res = 0 ;
}
else
{
cmSystemTools : : SetPermissions ( soutfile . c_str ( ) , perm ) ;
}
2004-03-09 03:05:04 +03:00
cmSystemTools : : RemoveFile ( tempOutputFile . c_str ( ) ) ;
}
2004-05-27 20:53:15 +04:00
return res ;
2004-03-09 03:05:04 +03:00
}
2004-04-18 22:41:46 +04:00
void cmMakefile : : AddWrittenFile ( const char * file )
{ this - > GetCMakeInstance ( ) - > AddWrittenFile ( file ) ; }
2004-03-09 03:05:04 +03:00
2004-04-18 22:41:46 +04:00
bool cmMakefile : : HasWrittenFile ( const char * file )
{ return this - > GetCMakeInstance ( ) - > HasWrittenFile ( file ) ; }
2004-03-09 03:05:04 +03:00
2004-04-18 22:41:46 +04:00
bool cmMakefile : : CheckInfiniteLoops ( )
{
std : : vector < std : : string > : : iterator it ;
for ( it = m_ListFiles . begin ( ) ;
it ! = m_ListFiles . end ( ) ;
+ + it )
{
if ( this - > HasWrittenFile ( it - > c_str ( ) ) )
{
cmOStringStream str ;
str < < " File " < < it - > c_str ( ) < < " is written by WRITE_FILE (or FILE WRITE) command and should not be used as input to CMake. Please use CONFIGURE_FILE to be safe. Refer to the note next to FILE WRITE command. " ;
cmSystemTools : : Error ( str . str ( ) . c_str ( ) ) ;
return false ;
}
}
return true ;
}
2004-05-21 00:56:34 +04:00
void cmMakefile : : SetProperty ( const char * prop , const char * value )
{
if ( ! prop )
{
return ;
}
if ( ! value )
{
value = " NOTFOUND " ;
}
m_Properties [ prop ] = value ;
}
const char * cmMakefile : : GetProperty ( const char * prop ) const
{
std : : map < cmStdString , cmStdString > : : const_iterator i =
m_Properties . find ( prop ) ;
if ( i ! = m_Properties . end ( ) )
{
return i - > second . c_str ( ) ;
}
return 0 ;
}
bool cmMakefile : : GetPropertyAsBool ( const char * prop ) const
{
std : : map < cmStdString , cmStdString > : : const_iterator i =
m_Properties . find ( prop ) ;
if ( i ! = m_Properties . end ( ) )
{
return cmSystemTools : : IsOn ( i - > second . c_str ( ) ) ;
}
return false ;
}