2002-08-31 00:01:48 +04:00
/*=========================================================================
2002-10-24 02:03:27 +04:00
Program : CMake - Cross - Platform Makefile Generator
2002-08-31 00:01:48 +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.
2002-08-31 00:01:48 +04: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 .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "cmGlobalGenerator.h"
# include "cmLocalUnixMakefileGenerator.h"
# include "cmMakefile.h"
# include "cmSystemTools.h"
# include "cmSourceFile.h"
# include "cmMakeDepend.h"
# include "cmCacheManager.h"
# include "cmGeneratedFileStream.h"
2005-03-14 19:29:15 +03:00
# include "cmSubDirectory.h"
2003-06-23 22:10:12 +04:00
# include <cmsys/RegularExpression.hxx>
2002-08-31 00:01:48 +04:00
cmLocalUnixMakefileGenerator : : cmLocalUnixMakefileGenerator ( )
{
2002-11-08 23:46:08 +03:00
m_WindowsShell = false ;
m_IncludeDirective = " include " ;
m_MakefileVariableSize = 0 ;
2003-08-01 21:13:43 +04:00
m_IgnoreLibPrefix = false ;
2003-10-28 19:06:06 +03:00
m_PassMakeflags = false ;
2004-03-31 19:01:52 +04:00
m_UseRelativePaths = false ;
2002-08-31 00:01:48 +04:00
}
cmLocalUnixMakefileGenerator : : ~ cmLocalUnixMakefileGenerator ( )
{
}
void cmLocalUnixMakefileGenerator : : Generate ( bool fromTheTop )
2004-11-05 23:03:45 +03:00
{
this - > ConfigureOutputPaths ( ) ;
if ( ! fromTheTop )
{
// Generate depends
cmMakeDepend md ;
md . SetMakefile ( m_Makefile ) ;
md . GenerateMakefileDependencies ( ) ;
this - > ProcessDepends ( md ) ;
}
// output the makefile fragment
std : : string dest = m_Makefile - > GetStartOutputDirectory ( ) ;
dest + = " /Makefile " ;
this - > OutputMakefile ( dest . c_str ( ) , ! fromTheTop ) ;
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator : : ConfigureOutputPaths ( )
2002-08-31 00:01:48 +04:00
{
2004-03-31 19:01:52 +04:00
m_UseRelativePaths = m_Makefile - > IsOn ( " CMAKE_USE_RELATIVE_PATHS " ) ;
2002-08-31 00:01:48 +04:00
// suppoirt override in output directories
if ( m_Makefile - > GetDefinition ( " LIBRARY_OUTPUT_PATH " ) )
{
m_LibraryOutputPath = m_Makefile - > GetDefinition ( " LIBRARY_OUTPUT_PATH " ) ;
if ( m_LibraryOutputPath . size ( ) )
{
2005-02-10 16:22:00 +03:00
m_LibraryOutputPath =
cmSystemTools : : CollapseFullPath ( m_LibraryOutputPath . c_str ( ) ,
m_Makefile - > GetStartOutputDirectory ( ) ) ;
2002-08-31 00:01:48 +04:00
if ( m_LibraryOutputPath [ m_LibraryOutputPath . size ( ) - 1 ] ! = ' / ' )
{
m_LibraryOutputPath + = " / " ;
}
if ( ! cmSystemTools : : MakeDirectory ( m_LibraryOutputPath . c_str ( ) ) )
{
cmSystemTools : : Error ( " Error failed create "
" LIBRARY_OUTPUT_PATH directory: " ,
m_LibraryOutputPath . c_str ( ) ) ;
}
m_Makefile - > AddLinkDirectory ( m_LibraryOutputPath . c_str ( ) ) ;
}
}
if ( m_Makefile - > GetDefinition ( " EXECUTABLE_OUTPUT_PATH " ) )
{
m_ExecutableOutputPath =
m_Makefile - > GetDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
if ( m_ExecutableOutputPath . size ( ) )
{
2005-02-10 16:22:00 +03:00
m_ExecutableOutputPath =
cmSystemTools : : CollapseFullPath ( m_ExecutableOutputPath . c_str ( ) ,
m_Makefile - > GetStartOutputDirectory ( ) ) ;
2002-08-31 00:01:48 +04:00
if ( m_ExecutableOutputPath [ m_ExecutableOutputPath . size ( ) - 1 ] ! = ' / ' )
{
m_ExecutableOutputPath + = " / " ;
}
if ( ! cmSystemTools : : MakeDirectory ( m_ExecutableOutputPath . c_str ( ) ) )
{
cmSystemTools : : Error ( " Error failed to create "
" EXECUTABLE_OUTPUT_PATH directory: " ,
m_ExecutableOutputPath . c_str ( ) ) ;
}
m_Makefile - > AddLinkDirectory ( m_ExecutableOutputPath . c_str ( ) ) ;
}
}
}
2002-12-10 17:28:05 +03:00
void
cmLocalUnixMakefileGenerator : : AddDependenciesToSourceFile ( cmDependInformation const * info ,
cmSourceFile * i ,
std : : set < cmDependInformation const * > * visited )
{
// add info to the visited set
visited - > insert ( info ) ;
// add this dependency and the recurse
2002-12-10 21:59:53 +03:00
// now recurse with info's dependencies
for ( cmDependInformation : : DependencySet : : const_iterator d =
info - > m_DependencySet . begin ( ) ;
d ! = info - > m_DependencySet . end ( ) ; + + d )
2002-12-10 17:28:05 +03:00
{
2002-12-10 21:59:53 +03:00
if ( visited - > find ( * d ) = = visited - > end ( ) )
{
if ( ( * d ) - > m_FullPath ! = " " )
2002-12-10 17:28:05 +03:00
{
2004-01-20 22:36:00 +03:00
i - > GetDepends ( ) . push_back ( ( * d ) - > m_FullPath . c_str ( ) ) ;
2002-12-10 17:28:05 +03:00
}
2002-12-10 21:59:53 +03:00
this - > AddDependenciesToSourceFile ( * d , i , visited ) ;
2002-12-10 17:28:05 +03:00
}
}
}
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : ProcessDepends ( const cmMakeDepend & md )
{
// Now create cmDependInformation objects for files in the directory
cmTargets & tgts = m_Makefile - > GetTargets ( ) ;
for ( cmTargets : : iterator l = tgts . begin ( ) ; l ! = tgts . end ( ) ; l + + )
{
std : : vector < cmSourceFile * > & classes = l - > second . GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : iterator i = classes . begin ( ) ;
i ! = classes . end ( ) ; + + i )
{
if ( ! ( * i ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) )
{
// get the depends
const cmDependInformation * info =
md . GetDependInformationForSourceFile ( * ( * i ) ) ;
// Delete any hints from the source file's dependencies.
( * i ) - > GetDepends ( ) . erase ( ( * i ) - > GetDepends ( ) . begin ( ) , ( * i ) - > GetDepends ( ) . end ( ) ) ;
2002-12-10 17:28:05 +03:00
2002-08-31 00:01:48 +04:00
// Now add the real dependencies for the file.
if ( info )
{
2002-12-10 17:28:05 +03:00
// create visited set
std : : set < cmDependInformation const * > visited ;
this - > AddDependenciesToSourceFile ( info , * i , & visited ) ;
2002-08-31 00:01:48 +04:00
}
}
}
}
}
// This is where CMakeTargets.make is generated
void cmLocalUnixMakefileGenerator : : OutputMakefile ( const char * file ,
bool withDepends )
{
// Create sub directories fro aux source directories
std : : vector < std : : string > & auxSourceDirs =
m_Makefile - > GetAuxSourceDirectories ( ) ;
if ( auxSourceDirs . size ( ) )
{
// For the case when this is running as a remote build
// on unix, make the directory
for ( std : : vector < std : : string > : : iterator i = auxSourceDirs . begin ( ) ;
i ! = auxSourceDirs . end ( ) ; + + i )
{
if ( i - > c_str ( ) [ 0 ] ! = ' / ' )
{
std : : string dir = m_Makefile - > GetCurrentOutputDirectory ( ) ;
if ( dir . size ( ) & & dir [ dir . size ( ) - 1 ] ! = ' / ' )
{
dir + = " / " ;
}
dir + = * i ;
cmSystemTools : : MakeDirectory ( dir . c_str ( ) ) ;
}
else
{
cmSystemTools : : MakeDirectory ( i - > c_str ( ) ) ;
}
}
}
// Create a stream that writes to a temporary file
// then does a copy at the end. This is to allow users
// to hit control-c during the make of the makefile
2004-11-03 15:51:51 +03:00
cmGeneratedFileStream fout ( file ) ;
2002-08-31 00:01:48 +04:00
if ( ! fout )
{
return ;
}
fout < < " # CMAKE generated Makefile, DO NOT EDIT! \n "
< < " # Generated by \" " < < m_GlobalGenerator - > GetName ( ) < < " \" "
< < " Generator, CMake Version "
< < cmMakefile : : GetMajorVersion ( ) < < " . "
< < cmMakefile : : GetMinorVersion ( ) < < " \n "
< < " # Generated from the following files: \n # "
< < m_Makefile - > GetHomeOutputDirectory ( ) < < " /CMakeCache.txt \n " ;
std : : vector < std : : string > lfiles = m_Makefile - > GetListFiles ( ) ;
// sort the array
std : : sort ( lfiles . begin ( ) , lfiles . end ( ) , std : : less < std : : string > ( ) ) ;
// remove duplicates
std : : vector < std : : string > : : iterator new_end =
std : : unique ( lfiles . begin ( ) , lfiles . end ( ) ) ;
lfiles . erase ( new_end , lfiles . end ( ) ) ;
for ( std : : vector < std : : string > : : const_iterator i = lfiles . begin ( ) ;
i ! = lfiles . end ( ) ; + + i )
{
fout < < " # " < < i - > c_str ( ) < < " \n " ;
}
fout < < " \n \n " ;
fout < < " # disable some common implicit rules to speed things up \n " ;
fout < < " .SUFFIXES: \n " ;
fout < < " .SUFFIXES:.hpuxmakemusthaverule \n " ;
// create a make variable with all of the sources for this Makefile
// for depend purposes.
fout < < " CMAKE_MAKEFILE_SOURCES = " ;
for ( std : : vector < std : : string > : : const_iterator i = lfiles . begin ( ) ;
i ! = lfiles . end ( ) ; + + i )
{
2003-12-22 23:16:46 +03:00
fout < < " " < < this - > ConvertToRelativeOutputPath ( i - > c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
// Add the cache to the list
std : : string cacheFile = m_Makefile - > GetHomeOutputDirectory ( ) ;
cacheFile + = " /CMakeCache.txt " ;
2003-12-22 23:16:46 +03:00
fout < < " " < < this - > ConvertToRelativeOutputPath ( cacheFile . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
fout < < " \n \n \n " ;
2003-12-22 20:24:26 +03:00
2002-12-05 22:56:31 +03:00
this - > OutputMakeVariables ( fout ) ;
2002-12-06 00:53:09 +03:00
std : : string checkCache = m_Makefile - > GetHomeOutputDirectory ( ) ;
checkCache + = " /cmake.check_cache " ;
2003-12-22 23:16:46 +03:00
checkCache = this - > ConvertToRelativeOutputPath ( checkCache . c_str ( ) ) ;
2003-10-28 19:06:06 +03:00
// most unix makes will pass the command line flags to make down
// to sub invoked makes via an environment variable. However, some
// makes do not support that, so you have to pass the flags explicitly
const char * allRule = " $(MAKE) $(MAKESILENT) all " ;
if ( m_PassMakeflags )
{
allRule = " $(MAKE) $(MAKESILENT) -$(MAKEFLAGS) all " ;
}
2002-08-31 00:01:48 +04:00
// Set up the default target as the VERY first target, so that make with no arguments will run it
this - >
OutputMakeRule ( fout ,
" Default target executed when no arguments are given to make, first make sure cmake.depends exists, cmake.check_depends is up-to-date, check the sources, then build the all target " ,
" default_target " ,
2002-12-06 00:53:09 +03:00
checkCache . c_str ( ) ,
2002-08-31 00:01:48 +04:00
" $(MAKE) $(MAKESILENT) cmake.depends " ,
" $(MAKE) $(MAKESILENT) cmake.check_depends " ,
" $(MAKE) $(MAKESILENT) -f cmake.check_depends " ,
2003-10-28 19:06:06 +03:00
allRule ) ;
2003-08-27 01:13:43 +04:00
// Generation of SILENT target must be after default_target.
if ( ! m_Makefile - > IsOn ( " CMAKE_VERBOSE_MAKEFILE " ) )
{
fout < < " # Suppresses display of executed commands \n " ;
fout < < " $(VERBOSE).SILENT: \n \n " ;
}
2002-08-31 00:01:48 +04:00
this - > OutputTargetRules ( fout ) ;
this - > OutputDependLibs ( fout ) ;
this - > OutputTargets ( fout ) ;
this - > OutputSubDirectoryRules ( fout ) ;
std : : string dependName = m_Makefile - > GetStartOutputDirectory ( ) ;
dependName + = " /cmake.depends " ;
if ( withDepends )
{
std : : ofstream dependout ( dependName . c_str ( ) ) ;
if ( ! dependout )
{
cmSystemTools : : Error ( " Error can not open for write: " , dependName . c_str ( ) ) ;
return ;
}
dependout < < " # .o dependencies in this directory. " < < std : : endl ;
std : : string checkDepend = m_Makefile - > GetStartOutputDirectory ( ) ;
checkDepend + = " /cmake.check_depends " ;
std : : ofstream checkdependout ( checkDepend . c_str ( ) ) ;
if ( ! checkdependout )
{
cmSystemTools : : Error ( " Error can not open for write: " , checkDepend . c_str ( ) ) ;
return ;
}
checkdependout < < " # This file is used as a tag file, that all sources depend on. If a source changes, then the rule to rebuild this file will cause cmake.depends to be rebuilt. " < < std : : endl ;
// if there were any depends output, then output the check depends
// information inot checkdependout
if ( this - > OutputObjectDepends ( dependout ) )
{
this - > OutputCheckDepends ( checkdependout ) ;
}
else
{
checkdependout < < " all: \n \t @echo cmake.depends is up-to-date \n " ;
}
}
this - > OutputCustomRules ( fout ) ;
this - > OutputMakeRules ( fout ) ;
// only add the depend include if the depend file exists
if ( cmSystemTools : : FileExists ( dependName . c_str ( ) ) )
{
2002-11-08 23:46:08 +03:00
fout < < m_IncludeDirective < < " cmake.depends \n " ;
2002-08-31 00:01:48 +04:00
}
}
2003-11-27 01:38:37 +03:00
std : : string cmLocalUnixMakefileGenerator : : GetBaseTargetName ( const char * n ,
2003-01-18 02:01:05 +03:00
const cmTarget & t )
{
2004-08-24 19:30:33 +04:00
std : : string pathPrefix = " " ;
# ifdef __APPLE__
if ( t . GetPropertyAsBool ( " MACOSX_BUNDLE " ) )
{
pathPrefix = n ;
pathPrefix + = " .app/Contents/MacOS/ " ;
}
# endif
2003-01-18 02:01:05 +03:00
const char * targetPrefix = t . GetProperty ( " PREFIX " ) ;
2004-10-21 22:34:02 +04:00
const char * prefixVar = t . GetPrefixVariable ( ) ;
2003-01-18 02:01:05 +03:00
// if there is no prefix on the target use the cmake definition
if ( ! targetPrefix & & prefixVar )
2004-09-27 19:36:29 +04:00
{
// first check for a language specific suffix var
const char * ll = t . GetLinkerLanguage ( this - > GetGlobalGenerator ( ) ) ;
if ( ll )
{
std : : string langPrefix = prefixVar + std : : string ( " _ " ) + ll ;
targetPrefix = m_Makefile - > GetDefinition ( langPrefix . c_str ( ) ) ;
}
// if there not a language specific suffix then use the general one
if ( ! targetPrefix )
{
targetPrefix = m_Makefile - > GetSafeDefinition ( prefixVar ) ;
}
2003-01-18 02:01:05 +03:00
}
2004-08-24 19:30:33 +04:00
std : : string name = pathPrefix + ( targetPrefix ? targetPrefix : " " ) ;
2003-11-27 01:38:37 +03:00
name + = n ;
return name ;
}
2002-08-31 00:01:48 +04:00
2003-08-05 16:49:23 +04:00
// Output the rules for any targets
void cmLocalUnixMakefileGenerator : : OutputEcho ( std : : ostream & fout ,
const char * msg )
{
std : : string echostring = msg ;
// for unix we want to quote the output of echo
// for nmake and borland, the echo should not be quoted
if ( strcmp ( m_GlobalGenerator - > GetName ( ) , " Unix Makefiles " ) = = 0 )
{
cmSystemTools : : ReplaceString ( echostring , " \\ \n " , " " ) ;
cmSystemTools : : ReplaceString ( echostring , " \t " , " " ) ;
cmSystemTools : : ReplaceString ( echostring , " \n \t " , " \" \n \t @echo \" " ) ;
fout < < " \t @echo \" " < < echostring . c_str ( ) < < " \" \n " ;
}
else
{
cmSystemTools : : ReplaceString ( echostring , " \n \t " , " \n \t @echo " ) ;
fout < < " \t @echo " < < echostring . c_str ( ) < < " \n " ;
}
}
2002-08-31 00:01:48 +04:00
// Output the rules for any targets
void cmLocalUnixMakefileGenerator : : OutputTargetRules ( std : : ostream & fout )
{
2003-08-04 23:35:02 +04:00
const cmTargets & tgts = m_Makefile - > GetTargets ( ) ;
2003-08-05 16:49:23 +04:00
2003-08-04 23:35:02 +04:00
// add the help target
fout < < " help: \n " ;
2003-08-05 16:49:23 +04:00
this - > OutputEcho ( fout , " The following are some of the valid targets for this Makefile: " ) ;
2003-08-05 17:07:31 +04:00
this - > OutputEcho ( fout , " ... all (the default if no target is provided) " ) ;
this - > OutputEcho ( fout , " ... clean " ) ;
this - > OutputEcho ( fout , " ... depend " ) ;
2004-04-15 20:07:58 +04:00
this - > OutputEcho ( fout , " ... install " ) ;
2003-08-05 17:07:31 +04:00
this - > OutputEcho ( fout , " ... rebuild_cache " ) ;
2003-08-04 23:35:02 +04:00
// libraries
2003-08-05 16:49:23 +04:00
std : : string path ;
2003-08-04 23:35:02 +04:00
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
if ( ( l - > second . GetType ( ) = = cmTarget : : STATIC_LIBRARY ) | |
( l - > second . GetType ( ) = = cmTarget : : SHARED_LIBRARY ) | |
( l - > second . GetType ( ) = = cmTarget : : MODULE_LIBRARY ) )
{
2003-08-05 16:49:23 +04:00
std : : string path2 = m_LibraryOutputPath ;
path2 + = this - > GetFullTargetName ( l - > first . c_str ( ) , l - > second ) ;
path = " ... " ;
2003-12-22 23:16:46 +03:00
path + = this - > ConvertToRelativeOutputPath ( path2 . c_str ( ) ) ;
2003-08-05 16:49:23 +04:00
this - > OutputEcho ( fout , path . c_str ( ) ) ;
2003-08-04 23:35:02 +04:00
}
}
// executables
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
2004-02-29 02:59:19 +03:00
if ( l - > second . GetType ( ) = = cmTarget : : EXECUTABLE )
2003-08-04 23:35:02 +04:00
{
2003-08-05 16:49:23 +04:00
path = " ... " ;
path + = l - > first + cmSystemTools : : GetExecutableExtension ( ) ;
this - > OutputEcho ( fout , path . c_str ( ) ) ;
2003-08-04 23:35:02 +04:00
}
}
// list utilities last
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
2003-08-05 16:49:23 +04:00
if ( l - > second . GetType ( ) = = cmTarget : : UTILITY )
2003-08-04 23:35:02 +04:00
{
2003-08-05 16:49:23 +04:00
path = " ... " ;
path + = l - > first ;
this - > OutputEcho ( fout , path . c_str ( ) ) ;
2003-08-04 23:35:02 +04:00
}
}
fout < < " \n \n " ;
2002-08-31 00:01:48 +04:00
// for each target add to the list of targets
fout < < " TARGETS = " ;
// list libraries first
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
if ( l - > second . IsInAll ( ) )
{
2003-01-18 02:01:05 +03:00
if ( ( l - > second . GetType ( ) = = cmTarget : : STATIC_LIBRARY ) | |
( l - > second . GetType ( ) = = cmTarget : : SHARED_LIBRARY ) | |
( l - > second . GetType ( ) = = cmTarget : : MODULE_LIBRARY ) )
2002-08-31 00:01:48 +04:00
{
2003-08-08 17:17:01 +04:00
path = m_LibraryOutputPath ;
2003-01-18 02:01:05 +03:00
path + = this - > GetFullTargetName ( l - > first . c_str ( ) , l - > second ) ;
2002-08-31 00:01:48 +04:00
fout < < " \\ \n "
2004-01-23 21:01:28 +03:00
< < this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( path . c_str ( ) ) . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
}
}
// executables
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
2004-02-29 02:59:19 +03:00
if ( l - > second . GetType ( ) = = cmTarget : : EXECUTABLE & &
2002-08-31 00:01:48 +04:00
l - > second . IsInAll ( ) )
{
2003-08-08 17:17:01 +04:00
path = m_ExecutableOutputPath ;
2003-01-18 02:01:05 +03:00
path + = this - > GetFullTargetName ( l - > first . c_str ( ) , l - > second ) ;
2004-01-23 21:01:28 +03:00
fout < < " \\ \n " < < this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( path . c_str ( ) ) . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
}
// list utilities last
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
if ( l - > second . GetType ( ) = = cmTarget : : UTILITY & &
2002-10-10 18:43:59 +04:00
l - > second . IsInAll ( ) )
2002-08-31 00:01:48 +04:00
{
fout < < " \\ \n " < < l - > first . c_str ( ) ;
}
}
fout < < " \n \n " ;
2004-12-06 20:38:04 +03:00
std : : string outputName ;
2002-08-31 00:01:48 +04:00
// get the classes from the source lists then add them to the groups
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
std : : vector < cmSourceFile * > classes = l - > second . GetSourceFiles ( ) ;
if ( classes . begin ( ) ! = classes . end ( ) )
{
fout < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _SRC_OBJS " ) < < " = " ;
for ( std : : vector < cmSourceFile * > : : iterator i = classes . begin ( ) ;
i ! = classes . end ( ) ; i + + )
{
2003-06-03 18:30:23 +04:00
if ( ! ( * i ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) & &
! ( * i ) - > GetCustomCommand ( ) )
2004-09-22 22:42:05 +04:00
{
std : : string outExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
( * i ) - > GetSourceExtension ( ) . c_str ( ) ) ;
2004-04-18 21:16:34 +04:00
if ( outExt . size ( ) & & ! ( * i ) - > GetPropertyAsBool ( " EXTERNAL_OBJECT " ) )
2002-08-31 00:01:48 +04:00
{
2004-04-18 21:16:34 +04:00
fout < < " \\ \n " ;
2004-04-28 18:15:40 +04:00
std : : string ofname = ( * i ) - > GetSourceName ( ) + outExt ;
ofname = this - > CreateSafeUniqueObjectFileName ( ofname . c_str ( ) ) ;
fout < < this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( ofname . c_str ( ) ) . c_str ( ) ) ;
2004-04-18 21:16:34 +04:00
}
}
}
fout < < " \n \n " ;
fout < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _EXTERNAL_OBJS " ) < < " = " ;
for ( std : : vector < cmSourceFile * > : : iterator i = classes . begin ( ) ;
i ! = classes . end ( ) ; i + + )
{
if ( ! ( * i ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) & &
! ( * i ) - > GetCustomCommand ( ) )
{
2004-09-22 22:42:05 +04:00
std : : string outExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
( * i ) - > GetSourceExtension ( ) . c_str ( ) ) ;
2004-04-18 21:16:34 +04:00
if ( outExt . size ( ) & & ( * i ) - > GetPropertyAsBool ( " EXTERNAL_OBJECT " ) )
{
fout < < " \\ \n " ;
fout < < this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( ( * i ) - > GetFullPath ( ) . c_str ( ) ) . c_str ( ) ) < < " " ;
2002-08-31 00:01:48 +04:00
}
}
}
fout < < " \n \n " ;
fout < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _SRC_OBJS_QUOTED " ) < < " = " ;
for ( std : : vector < cmSourceFile * > : : iterator i = classes . begin ( ) ;
i ! = classes . end ( ) ; i + + )
{
2003-06-03 18:30:23 +04:00
if ( ! ( * i ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) & &
! ( * i ) - > GetCustomCommand ( ) )
2002-08-31 00:01:48 +04:00
{
2004-09-22 22:42:05 +04:00
std : : string outExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
( * i ) - > GetSourceExtension ( ) . c_str ( ) ) ;
2004-04-18 21:16:34 +04:00
if ( outExt . size ( ) & & ! ( * i ) - > GetPropertyAsBool ( " EXTERNAL_OBJECT " ) )
2002-08-31 00:01:48 +04:00
{
2004-04-28 18:15:40 +04:00
std : : string ofname = ( * i ) - > GetSourceName ( ) + outExt ;
ofname = this - > CreateSafeUniqueObjectFileName ( ofname . c_str ( ) ) ;
2004-12-06 20:38:04 +03:00
outputName = this - > ConvertToMakeTarget ( ConvertToRelativeOutputPath ( ofname . c_str ( ) ) . c_str ( ) ) ;
fout < < " \\ \n " ;
// if it already is double quoted because of spaces don't do it again.
if ( outputName . size ( ) & & outputName [ 0 ] ! = ' \" ' )
{
fout < < " \" " < < outputName < < " \" " ;
}
else
{
fout < < outputName < < " " ;
}
2002-08-31 00:01:48 +04:00
}
}
}
fout < < " \n \n " ;
2004-04-18 21:16:34 +04:00
fout < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _EXTERNAL_OBJS_QUOTED " ) < < " = " ;
for ( std : : vector < cmSourceFile * > : : iterator i = classes . begin ( ) ;
i ! = classes . end ( ) ; i + + )
{
if ( ! ( * i ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) & &
! ( * i ) - > GetCustomCommand ( ) )
{
2004-09-22 22:42:05 +04:00
std : : string outExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
( * i ) - > GetSourceExtension ( ) . c_str ( ) ) ;
2004-04-18 21:16:34 +04:00
if ( outExt . size ( ) & & ( * i ) - > GetPropertyAsBool ( " EXTERNAL_OBJECT " ) )
{
2004-12-06 20:38:04 +03:00
outputName =
this - > ConvertToMakeTarget ( ConvertToRelativeOutputPath ( ( * i ) - > GetFullPath ( ) . c_str ( ) ) . c_str ( ) ) ;
fout < < " \\ \n " ;
// if it already is double quoted because of spaces don't do it again.
if ( outputName . size ( ) & & outputName [ 0 ] ! = ' \" ' )
{
fout < < " \" " < < outputName < < " \" " ;
}
else
{
fout < < outputName < < " " ;
}
2004-04-18 21:16:34 +04:00
}
}
}
fout < < " \n \n " ;
2002-08-31 00:01:48 +04:00
}
}
2003-11-27 01:38:37 +03:00
// This list contains extra files created for a target. It includes
// the extra names associated with a versioned shared library.
fout < < " TARGET_EXTRAS = " ;
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
if ( l - > second . IsInAll ( ) )
{
if ( l - > second . GetType ( ) = = cmTarget : : SHARED_LIBRARY | |
l - > second . GetType ( ) = = cmTarget : : MODULE_LIBRARY )
{
std : : string targetName ;
std : : string targetNameSO ;
std : : string targetNameReal ;
std : : string targetNameBase ;
this - > GetLibraryNames ( l - > first . c_str ( ) , l - > second ,
targetName , targetNameSO ,
targetNameReal , targetNameBase ) ;
if ( targetNameSO ! = targetName )
{
path = m_LibraryOutputPath ;
path + = targetNameSO ;
fout < < " \\ \n "
2003-12-22 23:16:46 +03:00
< < this - > ConvertToRelativeOutputPath ( path . c_str ( ) ) ;
2003-11-27 01:38:37 +03:00
}
if ( targetNameReal ! = targetName & &
targetNameReal ! = targetNameSO )
{
path = m_LibraryOutputPath ;
path + = targetNameReal ;
fout < < " \\ \n "
2003-12-22 23:16:46 +03:00
< < this - > ConvertToRelativeOutputPath ( path . c_str ( ) ) ;
2003-11-27 01:38:37 +03:00
}
}
}
}
fout < < " \n \n " ;
2002-08-31 00:01:48 +04:00
fout < < " CLEAN_OBJECT_FILES = " ;
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
std : : vector < cmSourceFile * > classes = l - > second . GetSourceFiles ( ) ;
if ( classes . begin ( ) ! = classes . end ( ) )
{
fout < < " $( " < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _SRC_OBJS " )
< < " ) " ;
}
}
fout < < " \n \n " ;
2004-05-17 23:56:34 +04:00
const char * additional_clean_files =
2004-05-21 00:56:34 +04:00
m_Makefile - > GetProperty ( " ADDITIONAL_MAKE_CLEAN_FILES " ) ;
2004-03-29 01:36:38 +04:00
if ( additional_clean_files & & strlen ( additional_clean_files ) > 0 )
{
2004-05-17 23:56:34 +04:00
std : : string arg = additional_clean_files ;
std : : vector < std : : string > args ;
cmSystemTools : : ExpandListArgument ( arg , args ) ;
2004-03-29 01:36:38 +04:00
fout < < " ADDITIONAL_MAKE_CLEAN_FILES = " ;
2004-05-17 23:56:34 +04:00
for ( std : : vector < std : : string > : : iterator i = args . begin ( ) ; i ! = args . end ( ) ; + + i )
{
fout < < this - > ConvertToRelativeOutputPath ( i - > c_str ( ) ) < < " " ;
}
2004-03-29 01:36:38 +04:00
fout < < " \n \n " ;
}
2004-05-21 00:56:34 +04:00
2002-09-12 00:43:35 +04:00
const char * qt_files = m_Makefile - > GetDefinition ( " GENERATED_QT_FILES " ) ;
2002-09-13 16:18:13 +04:00
if ( qt_files ! = NULL & &
2002-09-12 00:43:35 +04:00
strlen ( m_Makefile - > GetDefinition ( " GENERATED_QT_FILES " ) ) > 0 )
{
fout < < " GENERATED_QT_FILES = " ;
2002-09-13 16:18:13 +04:00
fout < < qt_files ;
2002-09-12 00:43:35 +04:00
fout < < " \n \n " ;
}
2002-08-31 00:01:48 +04:00
}
2003-06-03 18:30:23 +04:00
std : : string cmLocalUnixMakefileGenerator : : CreatePreBuildRules (
2003-06-03 22:55:20 +04:00
const cmTarget & target , const char * /* targetName */ )
2003-06-03 18:30:23 +04:00
{
std : : string customRuleCode = " " ;
bool initNext = false ;
for ( std : : vector < cmCustomCommand > : : const_iterator cr =
target . GetPreBuildCommands ( ) . begin ( ) ;
cr ! = target . GetPreBuildCommands ( ) . end ( ) ; + + cr )
{
if ( initNext )
{
customRuleCode + = " \n \t " ;
}
else
{
initNext = true ;
}
2005-02-22 18:32:44 +03:00
customRuleCode + = this - > ConstructScript ( cr - > GetCommandLines ( ) , " \n \t " ) ;
2003-06-03 18:30:23 +04:00
}
return customRuleCode ;
}
2002-08-31 00:01:48 +04:00
2003-06-03 18:30:23 +04:00
std : : string cmLocalUnixMakefileGenerator : : CreatePreLinkRules (
2003-06-03 22:55:20 +04:00
const cmTarget & target , const char * /* targetName */ )
2002-08-31 00:01:48 +04:00
{
std : : string customRuleCode = " " ;
bool initNext = false ;
for ( std : : vector < cmCustomCommand > : : const_iterator cr =
2003-06-03 18:30:23 +04:00
target . GetPreLinkCommands ( ) . begin ( ) ;
cr ! = target . GetPreLinkCommands ( ) . end ( ) ; + + cr )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
if ( initNext )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
customRuleCode + = " \n \t " ;
}
else
{
initNext = true ;
2002-08-31 00:01:48 +04:00
}
2005-02-22 18:32:44 +03:00
customRuleCode + = this - > ConstructScript ( cr - > GetCommandLines ( ) , " \n \t " ) ;
2003-06-03 18:30:23 +04:00
}
return customRuleCode ;
}
std : : string cmLocalUnixMakefileGenerator : : CreatePostBuildRules (
2003-06-03 22:55:20 +04:00
const cmTarget & target , const char * /* targetName */ )
2003-06-03 18:30:23 +04:00
{
std : : string customRuleCode = " " ;
bool initNext = false ;
for ( std : : vector < cmCustomCommand > : : const_iterator cr =
target . GetPostBuildCommands ( ) . begin ( ) ;
cr ! = target . GetPostBuildCommands ( ) . end ( ) ; + + cr )
{
if ( initNext )
{
customRuleCode + = " \n \t " ;
}
else
{
initNext = true ;
}
2005-02-22 18:32:44 +03:00
customRuleCode + = this - > ConstructScript ( cr - > GetCommandLines ( ) , " \n \t " ) ;
2002-08-31 00:01:48 +04:00
}
return customRuleCode ;
}
2002-11-08 23:46:08 +03:00
void cmLocalUnixMakefileGenerator : : OutputLibraryRule ( std : : ostream & fout ,
const char * name ,
const cmTarget & t ,
const char * createVariable ,
2002-11-12 02:10:30 +03:00
const char * comment ,
const char * linkFlags
2002-11-08 23:46:08 +03:00
)
{
2003-11-27 01:38:37 +03:00
std : : string targetName ;
std : : string targetNameSO ;
std : : string targetNameReal ;
std : : string targetNameBase ;
this - > GetLibraryNames ( name , t ,
targetName , targetNameSO ,
targetNameReal , targetNameBase ) ;
2003-12-24 21:17:17 +03:00
std : : string outpath ;
2004-04-01 17:59:32 +04:00
std : : string outdir ;
if ( m_UseRelativePaths )
{
outdir = this - > ConvertToRelativeOutputPath ( m_LibraryOutputPath . c_str ( ) ) ;
}
else
{
outdir = m_LibraryOutputPath ;
}
2004-03-31 19:01:52 +04:00
if ( ! m_WindowsShell & & m_UseRelativePaths & & outdir . size ( ) )
2003-12-24 21:17:17 +03:00
{
outpath = " \" `cd " ;
}
outpath + = outdir ;
2004-03-31 19:01:52 +04:00
if ( ! m_WindowsShell & & m_UseRelativePaths & & outdir . size ( ) )
2003-12-24 21:17:17 +03:00
{
outpath + = " ;pwd` \" / " ;
}
2004-03-31 19:01:52 +04:00
if ( outdir . size ( ) = = 0 & & m_UseRelativePaths & & ! m_WindowsShell )
2003-12-24 21:17:17 +03:00
{
outpath = " \" `pwd` \" / " ;
}
2003-11-27 01:38:37 +03:00
// The full path versions of the names.
2003-12-24 21:17:17 +03:00
std : : string targetFullPath = outpath + targetName ;
std : : string targetFullPathSO = outpath + targetNameSO ;
std : : string targetFullPathReal = outpath + targetNameReal ;
std : : string targetFullPathBase = outpath + targetNameBase ;
2004-04-01 17:59:32 +04:00
// If not using relative paths then the output path needs to be
// converted here
if ( ! m_UseRelativePaths )
{
targetFullPath = this - > ConvertToRelativeOutputPath ( targetFullPath . c_str ( ) ) ;
targetFullPathSO = this - > ConvertToRelativeOutputPath ( targetFullPathSO . c_str ( ) ) ;
targetFullPathReal = this - > ConvertToRelativeOutputPath ( targetFullPathReal . c_str ( ) ) ;
targetFullPathBase = this - > ConvertToRelativeOutputPath ( targetFullPathBase . c_str ( ) ) ;
}
2002-11-08 23:46:08 +03:00
// get the objects that are used to link this library
2004-09-22 22:42:05 +04:00
std : : string objs = " $( " + this - > CreateMakeVariable ( name , " _SRC_OBJS " )
+ " ) $( " + this - > CreateMakeVariable ( name , " _EXTERNAL_OBJS " ) + " ) " ;
std : : string objsQuoted = " $( " + this - > CreateMakeVariable ( name , " _SRC_OBJS_QUOTED " )
+ " ) $( " + this - > CreateMakeVariable ( name , " _EXTERNAL_OBJS_QUOTED " ) + " ) " ;
2002-11-08 23:46:08 +03:00
// create a variable with the objects that this library depends on
2003-11-27 01:38:37 +03:00
std : : string depend =
objs + " $( " + this - > CreateMakeVariable ( name , " _DEPEND_LIBS " ) + " ) " ;
2002-11-08 23:46:08 +03:00
std : : vector < std : : string > commands ;
2003-11-27 01:38:37 +03:00
std : : string cmakecommand = this - > ConvertToOutputForExisting (
2004-08-06 22:51:41 +04:00
m_Makefile - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ) ;
2003-11-27 01:38:37 +03:00
// Remove any existing files for this library.
std : : string remove = cmakecommand ;
remove + = " -E remove -f " ;
remove + = targetFullPathReal ;
if ( targetFullPathSO ! = targetFullPathReal )
{
remove + = " " ;
remove + = targetFullPathSO ;
}
if ( targetFullPath ! = targetFullPathSO & &
targetFullPath ! = targetFullPathReal )
{
remove + = " " ;
remove + = targetFullPath ;
}
commands . push_back ( remove ) ;
2003-06-03 18:30:23 +04:00
// collect custom commands for this target and add them to the list
std : : string customCommands = this - > CreatePreBuildRules ( t , name ) ;
if ( customCommands . size ( ) > 0 )
{
commands . push_back ( customCommands ) ;
}
// collect custom commands for this target and add them to the list
customCommands = this - > CreatePreLinkRules ( t , name ) ;
if ( customCommands . size ( ) > 0 )
{
commands . push_back ( customCommands ) ;
}
2003-11-27 01:38:37 +03:00
// collect up the build rules
std : : vector < std : : string > rules ;
2004-08-06 22:51:41 +04:00
rules . push_back ( m_Makefile - > GetRequiredDefinition ( createVariable ) ) ;
2003-11-27 01:38:37 +03:00
// expand multi-command semi-colon separated lists
// of commands into separate commands
2002-12-12 02:13:33 +03:00
cmSystemTools : : ExpandList ( rules , commands ) ;
2003-11-27 01:38:37 +03:00
// Create necessary symlinks for library.
if ( targetFullPath ! = targetFullPathReal )
{
std : : string symlink = cmakecommand ;
symlink + = " -E cmake_symlink_library " ;
symlink + = targetFullPathReal ;
symlink + = " " ;
symlink + = targetFullPathSO ;
symlink + = " " ;
symlink + = targetFullPath ;
commands . push_back ( symlink ) ;
}
2002-11-08 23:46:08 +03:00
// collect custom commands for this target and add them to the list
2003-06-03 18:30:23 +04:00
customCommands = this - > CreatePostBuildRules ( t , name ) ;
2002-08-31 00:01:48 +04:00
if ( customCommands . size ( ) > 0 )
{
2002-11-08 23:46:08 +03:00
commands . push_back ( customCommands ) ;
2002-08-31 00:01:48 +04:00
}
2003-11-27 01:38:37 +03:00
2002-11-08 23:46:08 +03:00
// collect up the link libraries
cmOStringStream linklibs ;
this - > OutputLinkLibraries ( linklibs , name , t ) ;
for ( std : : vector < std : : string > : : iterator i = commands . begin ( ) ;
i ! = commands . end ( ) ; + + i )
{
this - > ExpandRuleVariables ( * i ,
2004-09-23 19:44:17 +04:00
t . GetLinkerLanguage ( m_GlobalGenerator ) ,
2002-11-08 23:46:08 +03:00
objs . c_str ( ) ,
2003-11-27 01:38:37 +03:00
targetFullPathReal . c_str ( ) ,
2002-11-08 23:46:08 +03:00
linklibs . str ( ) . c_str ( ) ,
0 , 0 , 0 , objsQuoted . c_str ( ) ,
2003-11-27 01:38:37 +03:00
targetFullPathBase . c_str ( ) ,
targetNameSO . c_str ( ) ,
2002-11-12 02:10:30 +03:00
linkFlags ) ;
2002-11-08 23:46:08 +03:00
}
2003-12-24 21:17:17 +03:00
targetFullPath = m_LibraryOutputPath + targetName ;
2002-11-08 23:46:08 +03:00
this - > OutputMakeRule ( fout , comment ,
targetFullPath . c_str ( ) ,
2002-08-31 00:01:48 +04:00
depend . c_str ( ) ,
2002-11-08 23:46:08 +03:00
commands ) ;
2004-01-09 20:28:47 +03:00
depend = targetFullPath ;
2004-01-23 17:54:50 +03:00
std : : string tgt = this - > ConvertToRelativeOutputPath ( targetFullPath . c_str ( ) ) ;
tgt = this - > ConvertToMakeTarget ( tgt . c_str ( ) ) ;
cmSystemTools : : ConvertToUnixSlashes ( tgt ) ;
if ( tgt . find ( ' / ' , 0 ) ! = tgt . npos )
2004-01-09 20:28:47 +03:00
{
// we need a local target
depend = this - > ConvertToRelativeOutputPath ( depend . c_str ( ) ) ;
std : : string target = targetName ;
commands . resize ( 0 ) ;
this - > OutputMakeRule ( fout ,
comment ,
target . c_str ( ) ,
depend . c_str ( ) ,
commands ) ;
}
2004-08-06 22:51:41 +04:00
// Add a target with the canonical name (no prefix, suffix or path).
2004-10-18 19:48:18 +04:00
this - > OutputMakeRule ( fout ,
comment ,
name ,
2005-02-25 03:32:50 +03:00
tgt . c_str ( ) ,
2004-10-18 19:48:18 +04:00
0 ) ;
2004-08-05 18:17:26 +04:00
2002-11-08 23:46:08 +03:00
}
void cmLocalUnixMakefileGenerator : : OutputSharedLibraryRule ( std : : ostream & fout ,
const char * name ,
const cmTarget & t )
{
2004-09-22 22:42:05 +04:00
const char * linkLanguage = t . GetLinkerLanguage ( this - > GetGlobalGenerator ( ) ) ;
2004-10-27 18:53:01 +04:00
if ( ! linkLanguage )
{
cmSystemTools : : Error ( " CMake can not determine linker language target: " ,
t . GetName ( ) ) ;
return ;
}
2004-09-22 22:42:05 +04:00
std : : string createRule = " CMAKE_ " ;
createRule + = linkLanguage ;
createRule + = " _CREATE_SHARED_LIBRARY " ;
2004-04-27 20:02:32 +04:00
std : : string buildType = m_Makefile - > GetSafeDefinition ( " CMAKE_BUILD_TYPE " ) ;
2002-11-12 02:10:30 +03:00
buildType = cmSystemTools : : UpperCase ( buildType ) ;
2004-04-27 20:02:32 +04:00
std : : string linkFlags = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_LINKER_FLAGS " ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
if ( buildType . size ( ) )
{
std : : string build = " CMAKE_SHARED_LINKER_FLAGS_ " ;
build + = buildType ;
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( build . c_str ( ) ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
}
2003-08-22 19:56:44 +04:00
if ( m_Makefile - > IsOn ( " WIN32 " ) & & ! ( m_Makefile - > IsOn ( " CYGWIN " ) | | m_Makefile - > IsOn ( " MINGW " ) ) )
2002-11-12 23:24:31 +03:00
{
2003-08-22 19:56:44 +04:00
const std : : vector < cmSourceFile * > & sources = t . GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator i = sources . begin ( ) ;
i ! = sources . end ( ) ; + + i )
2002-11-12 23:24:31 +03:00
{
2003-08-22 19:56:44 +04:00
if ( ( * i ) - > GetSourceExtension ( ) = = " def " )
{
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( " CMAKE_LINK_DEF_FILE_FLAG " ) ;
2003-12-22 23:16:46 +03:00
linkFlags + = this - > ConvertToRelativeOutputPath ( ( * i ) - > GetFullPath ( ) . c_str ( ) ) ;
2003-08-22 19:56:44 +04:00
linkFlags + = " " ;
}
2002-11-12 23:24:31 +03:00
}
}
2003-11-27 01:38:37 +03:00
2002-12-21 01:15:45 +03:00
const char * targetLinkFlags = t . GetProperty ( " LINK_FLAGS " ) ;
if ( targetLinkFlags )
{
linkFlags + = targetLinkFlags ;
linkFlags + = " " ;
}
2002-11-08 23:46:08 +03:00
this - > OutputLibraryRule ( fout , name , t ,
2004-09-22 22:42:05 +04:00
createRule . c_str ( ) ,
2002-11-12 02:10:30 +03:00
" shared library " ,
linkFlags . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputModuleLibraryRule ( std : : ostream & fout ,
const char * name ,
const cmTarget & t )
{
2004-09-22 22:42:05 +04:00
const char * linkLanguage = t . GetLinkerLanguage ( this - > GetGlobalGenerator ( ) ) ;
2004-10-27 18:53:01 +04:00
if ( ! linkLanguage )
{
cmSystemTools : : Error ( " CMake can not determine linker language for target: " ,
t . GetName ( ) ) ;
return ;
}
2004-09-22 22:42:05 +04:00
std : : string createRule = " CMAKE_ " ;
createRule + = linkLanguage ;
createRule + = " _CREATE_SHARED_MODULE " ;
2004-04-27 20:02:32 +04:00
std : : string buildType = m_Makefile - > GetSafeDefinition ( " CMAKE_BUILD_TYPE " ) ;
2002-11-12 02:10:30 +03:00
buildType = cmSystemTools : : UpperCase ( buildType ) ;
2004-04-27 20:02:32 +04:00
std : : string linkFlags = m_Makefile - > GetSafeDefinition ( " CMAKE_MODULE_LINKER_FLAGS " ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
if ( buildType . size ( ) )
{
std : : string build = " CMAKE_MODULE_LINKER_FLAGS_ " ;
build + = buildType ;
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( build . c_str ( ) ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
}
2002-12-21 01:15:45 +03:00
const char * targetLinkFlags = t . GetProperty ( " LINK_FLAGS " ) ;
if ( targetLinkFlags )
{
linkFlags + = targetLinkFlags ;
linkFlags + = " " ;
}
2002-11-08 23:46:08 +03:00
this - > OutputLibraryRule ( fout , name , t ,
2004-09-22 22:42:05 +04:00
createRule . c_str ( ) ,
2002-11-12 02:10:30 +03:00
" shared module " ,
linkFlags . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputStaticLibraryRule ( std : : ostream & fout ,
const char * name ,
const cmTarget & t )
{
2004-09-22 22:42:05 +04:00
const char * linkLanguage = t . GetLinkerLanguage ( this - > GetGlobalGenerator ( ) ) ;
2004-10-27 18:53:01 +04:00
if ( ! linkLanguage )
{
cmSystemTools : : Error ( " CMake can not determine linker language for target: " ,
t . GetName ( ) ) ;
return ;
}
2004-09-22 22:42:05 +04:00
std : : string createRule = " CMAKE_ " ;
createRule + = linkLanguage ;
createRule + = " _CREATE_STATIC_LIBRARY " ;
2002-12-31 20:59:02 +03:00
std : : string linkFlags ;
2004-04-23 00:58:04 +04:00
const char * targetLinkFlags = t . GetProperty ( " STATIC_LIBRARY_FLAGS " ) ;
2002-12-31 20:59:02 +03:00
if ( targetLinkFlags )
{
linkFlags + = targetLinkFlags ;
linkFlags + = " " ;
}
2002-11-08 23:46:08 +03:00
this - > OutputLibraryRule ( fout , name , t ,
2004-09-22 22:42:05 +04:00
createRule . c_str ( ) ,
2002-12-31 20:41:12 +03:00
" static library " ,
2002-12-31 20:59:02 +03:00
linkFlags . c_str ( ) ) ;
2002-11-08 23:46:08 +03:00
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputExecutableRule ( std : : ostream & fout ,
2002-11-12 02:10:30 +03:00
const char * name ,
const cmTarget & t )
2002-08-31 00:01:48 +04:00
{
2002-11-12 02:10:30 +03:00
std : : string linkFlags ;
2004-04-27 20:02:32 +04:00
std : : string buildType = m_Makefile - > GetSafeDefinition ( " CMAKE_BUILD_TYPE " ) ;
2002-11-12 02:10:30 +03:00
buildType = cmSystemTools : : UpperCase ( buildType ) ;
2002-11-08 23:46:08 +03:00
std : : string flags ;
2003-06-11 17:44:31 +04:00
// Construct the full path to the executable that will be generated.
std : : string target = m_ExecutableOutputPath ;
if ( target . length ( ) = = 0 )
{
target = m_Makefile - > GetCurrentOutputDirectory ( ) ;
if ( target . size ( ) & & target [ target . size ( ) - 1 ] ! = ' / ' )
{
target + = " / " ;
}
}
2004-02-29 02:59:19 +03:00
# ifdef __APPLE__
2004-02-29 17:53:05 +03:00
if ( t . GetPropertyAsBool ( " MACOSX_BUNDLE " ) )
2004-02-29 02:59:19 +03:00
{
// Make bundle directories
target + = name ;
target + = " .app/Contents/MacOS/ " ;
}
# endif
2003-06-11 17:44:31 +04:00
target + = name ;
2003-12-22 20:24:26 +03:00
target + = cmSystemTools : : GetExecutableExtension ( ) ;
bool needsLocalTarget = false ;
2004-04-01 18:59:46 +04:00
if ( m_UseRelativePaths )
{
2005-02-25 03:32:50 +03:00
std : : string tgt =
this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( target . c_str ( ) ) . c_str ( ) ) ;
2004-04-01 18:59:46 +04:00
if ( tgt . find ( ' / ' , 0 ) ! = tgt . npos )
{
needsLocalTarget = true ;
}
}
else
2003-12-22 20:24:26 +03:00
{
needsLocalTarget = true ;
}
2004-08-06 22:51:41 +04:00
std : : string objs = " $( " + this - > CreateMakeVariable ( name , " _SRC_OBJS " ) +
" ) $( " + this - > CreateMakeVariable ( name , " _EXTERNAL_OBJS " ) + " ) " ;
2002-08-31 00:01:48 +04:00
std : : string depend = " $( " ;
depend + = this - > CreateMakeVariable ( name , " _SRC_OBJS " )
2004-04-18 21:16:34 +04:00
+ " ) $( " + this - > CreateMakeVariable ( name , " _EXTERNAL_OBJS " )
2002-08-31 00:01:48 +04:00
+ " ) $( " + this - > CreateMakeVariable ( name , " _DEPEND_LIBS " ) + " ) " ;
2002-11-08 23:46:08 +03:00
std : : vector < std : : string > rules ;
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( " CMAKE_EXE_LINKER_FLAGS " ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
if ( buildType . size ( ) )
{
std : : string build = " CMAKE_EXE_LINKER_FLAGS_ " ;
build + = buildType ;
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( build . c_str ( ) ) ;
2002-11-12 02:10:30 +03:00
linkFlags + = " " ;
}
2004-09-22 22:42:05 +04:00
const char * linkLanguage = t . GetLinkerLanguage ( this - > GetGlobalGenerator ( ) ) ;
2004-10-27 18:53:01 +04:00
if ( ! linkLanguage )
{
cmSystemTools : : Error ( " CMake can not determine linker language for target: " ,
t . GetName ( ) ) ;
return ;
}
2004-09-22 22:42:05 +04:00
std : : string langVar = " CMAKE_ " ;
langVar + = linkLanguage ;
std : : string ruleVar = langVar + " _LINK_EXECUTABLE " ;
std : : string flagsVar = langVar + " _FLAGS " ;
std : : string sharedFlagsVar = " CMAKE_SHARED_LIBRARY_ " ;
sharedFlagsVar + = langVar ;
sharedFlagsVar + = " _FLAGS " ;
rules . push_back ( m_Makefile - > GetRequiredDefinition ( ruleVar . c_str ( ) ) ) ;
flags + = m_Makefile - > GetSafeDefinition ( flagsVar . c_str ( ) ) ;
flags + = " " ;
flags + = m_Makefile - > GetSafeDefinition ( sharedFlagsVar . c_str ( ) ) ;
flags + = " " ;
2002-11-14 04:14:05 +03:00
2002-10-10 18:43:59 +04:00
cmOStringStream linklibs ;
2002-08-31 00:01:48 +04:00
this - > OutputLinkLibraries ( linklibs , 0 , t ) ;
2002-11-08 23:46:08 +03:00
std : : string comment = " executable " ;
2002-08-31 00:01:48 +04:00
2002-11-08 23:46:08 +03:00
std : : vector < std : : string > commands ;
2004-02-29 02:59:19 +03:00
2003-06-03 18:30:23 +04:00
std : : string customCommands = this - > CreatePreBuildRules ( t , name ) ;
if ( customCommands . size ( ) > 0 )
{
commands . push_back ( customCommands . c_str ( ) ) ;
}
customCommands = this - > CreatePreLinkRules ( t , name ) ;
if ( customCommands . size ( ) > 0 )
{
commands . push_back ( customCommands . c_str ( ) ) ;
}
2002-12-12 02:13:33 +03:00
cmSystemTools : : ExpandList ( rules , commands ) ;
2003-06-03 18:30:23 +04:00
customCommands = this - > CreatePostBuildRules ( t , name ) ;
2002-08-31 00:01:48 +04:00
if ( customCommands . size ( ) > 0 )
{
2002-11-08 23:46:08 +03:00
commands . push_back ( customCommands . c_str ( ) ) ;
}
2002-11-14 04:14:05 +03:00
if ( cmSystemTools : : IsOn ( m_Makefile - > GetDefinition ( " BUILD_SHARED_LIBS " ) ) )
{
2004-09-22 22:42:05 +04:00
std : : string sFlagVar = std : : string ( " CMAKE_SHARED_BUILD_ " ) + linkLanguage
+ std : : string ( " _FLAGS " ) ;
linkFlags + = m_Makefile - > GetSafeDefinition ( sFlagVar . c_str ( ) ) ;
2002-11-14 04:14:05 +03:00
linkFlags + = " " ;
}
2004-02-29 17:53:05 +03:00
if ( t . GetPropertyAsBool ( " WIN32_EXECUTABLE " ) )
2002-11-08 23:46:08 +03:00
{
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( " CMAKE_CREATE_WIN32_EXE " ) ;
2002-11-08 23:46:08 +03:00
linkFlags + = " " ;
}
else
{
2004-04-27 20:02:32 +04:00
linkFlags + = m_Makefile - > GetSafeDefinition ( " CMAKE_CREATE_CONSOLE_EXE " ) ;
2002-11-08 23:46:08 +03:00
linkFlags + = " " ;
}
2002-12-21 01:15:45 +03:00
const char * targetLinkFlags = t . GetProperty ( " LINK_FLAGS " ) ;
if ( targetLinkFlags )
{
linkFlags + = targetLinkFlags ;
linkFlags + = " " ;
}
2002-11-08 23:46:08 +03:00
for ( std : : vector < std : : string > : : iterator i = commands . begin ( ) ;
i ! = commands . end ( ) ; + + i )
{
this - > ExpandRuleVariables ( * i ,
2004-09-23 19:44:17 +04:00
linkLanguage ,
2002-11-08 23:46:08 +03:00
objs . c_str ( ) ,
2005-02-25 03:32:50 +03:00
this - > ConvertToRelativeOutputPath ( target . c_str ( ) ) . c_str ( ) ,
2002-11-08 23:46:08 +03:00
linklibs . str ( ) . c_str ( ) ,
2002-11-12 02:10:30 +03:00
0 ,
0 ,
flags . c_str ( ) ,
0 ,
0 ,
2003-11-27 01:38:37 +03:00
0 ,
2002-11-12 02:10:30 +03:00
linkFlags . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
this - > OutputMakeRule ( fout ,
comment . c_str ( ) ,
target . c_str ( ) ,
depend . c_str ( ) ,
2002-11-08 23:46:08 +03:00
commands ) ;
2003-06-11 17:44:31 +04:00
// If there is no executable output path, add a rule with the
// relative path to the executable. This is necessary for
// try-compile to work in this case.
2003-12-22 20:24:26 +03:00
if ( needsLocalTarget )
{
2005-02-25 03:32:50 +03:00
depend = this - > ConvertToRelativeOutputPath ( target . c_str ( ) ) ;
2003-12-22 20:24:26 +03:00
target = name ;
target + = cmSystemTools : : GetExecutableExtension ( ) ;
commands . resize ( 0 ) ;
this - > OutputMakeRule ( fout ,
comment . c_str ( ) ,
target . c_str ( ) ,
depend . c_str ( ) ,
commands ) ;
}
2004-08-06 22:51:41 +04:00
// Add a target with the canonical name (no prefix, suffix or path).
// Note that on some platforms the "local target" added above will
// actually be the canonical name and will have set "target"
// correctly. Do not duplicate this target.
if ( target ! = name )
{
2005-02-25 03:32:50 +03:00
this - > OutputMakeRule ( fout , comment . c_str ( ) , name ,
this - > ConvertToRelativeOutputPath ( target . c_str ( ) ) . c_str ( ) , 0 ) ;
2004-08-06 22:51:41 +04:00
}
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputUtilityRule ( std : : ostream & fout ,
const char * name ,
const cmTarget & t )
{
const char * cc = 0 ;
2003-06-03 18:30:23 +04:00
std : : string customCommands = this - > CreatePreBuildRules ( t , name ) ;
std : : string customCommands2 = this - > CreatePreLinkRules ( t , name ) ;
if ( customCommands2 . size ( ) > 0 )
{
customCommands + = customCommands2 ;
}
customCommands2 = this - > CreatePostBuildRules ( t , name ) ;
if ( customCommands2 . size ( ) > 0 )
{
customCommands + = customCommands2 ;
}
2002-08-31 00:01:48 +04:00
if ( customCommands . size ( ) > 0 )
{
cc = customCommands . c_str ( ) ;
}
2002-11-08 23:46:08 +03:00
std : : string comment = " Utility " ;
2002-08-31 00:01:48 +04:00
std : : string depends ;
2003-07-24 19:37:43 +04:00
depends = " $( " + this - > CreateMakeVariable ( name , " _DEPEND_LIBS " ) + " ) " ;
2002-09-06 16:33:21 +04:00
std : : string replaceVars ;
2003-06-03 18:30:23 +04:00
const std : : vector < cmCustomCommand > & ccs = t . GetPostBuildCommands ( ) ;
2002-08-31 00:01:48 +04:00
for ( std : : vector < cmCustomCommand > : : const_iterator i = ccs . begin ( ) ;
i ! = ccs . end ( ) ; + + i )
{
2002-09-06 16:33:21 +04:00
const std : : vector < std : : string > & dep = i - > GetDepends ( ) ;
for ( std : : vector < std : : string > : : const_iterator d = dep . begin ( ) ;
d ! = dep . end ( ) ; + + d )
{
depends + = " \\ \n " ;
replaceVars = * d ;
m_Makefile - > ExpandVariablesInString ( replaceVars ) ;
2004-01-23 21:01:28 +03:00
depends + = this - > ConvertToMakeTarget ( this - > ConvertToRelativeOutputPath ( replaceVars . c_str ( ) ) . c_str ( ) ) ;
2002-09-06 16:33:21 +04:00
}
2002-08-31 00:01:48 +04:00
}
2002-09-06 16:33:21 +04:00
this - > OutputMakeRule ( fout , comment . c_str ( ) , name ,
depends . c_str ( ) , cc ) ;
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputTargets ( std : : ostream & fout )
{
// for each target
const cmTargets & tgts = m_Makefile - > GetTargets ( ) ;
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
switch ( l - > second . GetType ( ) )
{
case cmTarget : : STATIC_LIBRARY :
this - > OutputStaticLibraryRule ( fout , l - > first . c_str ( ) , l - > second ) ;
break ;
case cmTarget : : SHARED_LIBRARY :
this - > OutputSharedLibraryRule ( fout , l - > first . c_str ( ) , l - > second ) ;
break ;
case cmTarget : : MODULE_LIBRARY :
this - > OutputModuleLibraryRule ( fout , l - > first . c_str ( ) , l - > second ) ;
break ;
case cmTarget : : EXECUTABLE :
this - > OutputExecutableRule ( fout , l - > first . c_str ( ) , l - > second ) ;
break ;
case cmTarget : : UTILITY :
this - > OutputUtilityRule ( fout , l - > first . c_str ( ) , l - > second ) ;
break ;
// This is handled by the OutputCustomRules method
case cmTarget : : INSTALL_FILES :
// This is handled by the OutputInstallRules method
case cmTarget : : INSTALL_PROGRAMS :
// This is handled by the OutputInstallRules method
2002-10-10 18:43:59 +04:00
break ;
2002-08-31 00:01:48 +04:00
}
}
}
// For each target that is an executable or shared library, generate
// the "<name>_DEPEND_LIBS" variable listing its library dependencies.
void cmLocalUnixMakefileGenerator : : OutputDependLibs ( std : : ostream & fout )
{
// Build a set of libraries that will be linked into any target in
// this directory.
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > used ;
2002-08-31 00:01:48 +04:00
// for each target
const cmTargets & tgts = m_Makefile - > GetTargets ( ) ;
2002-12-06 23:35:22 +03:00
2002-08-31 00:01:48 +04:00
for ( cmTargets : : const_iterator l = tgts . begin ( ) ;
l ! = tgts . end ( ) ; l + + )
{
// Each dependency should only be emitted once per target.
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > emitted ;
2002-08-31 00:01:48 +04:00
if ( ( l - > second . GetType ( ) = = cmTarget : : SHARED_LIBRARY )
| | ( l - > second . GetType ( ) = = cmTarget : : MODULE_LIBRARY )
2002-12-06 23:35:22 +03:00
| | ( l - > second . GetType ( ) = = cmTarget : : STATIC_LIBRARY )
2002-08-31 00:01:48 +04:00
| | ( l - > second . GetType ( ) = = cmTarget : : EXECUTABLE )
2004-02-29 02:59:19 +03:00
| | ( l - > second . GetType ( ) = = cmTarget : : UTILITY ) )
2002-08-31 00:01:48 +04:00
{
fout < < this - > CreateMakeVariable ( l - > first . c_str ( ) , " _DEPEND_LIBS " ) < < " = " ;
// A library should not depend on itself!
emitted . insert ( l - > first ) ;
2002-12-06 23:35:22 +03:00
// for static libraries do not depend on other libraries
if ( l - > second . GetType ( ) ! = cmTarget : : STATIC_LIBRARY )
2002-08-31 00:01:48 +04:00
{
2002-12-06 23:35:22 +03:00
// Now, look at all link libraries specific to this target.
const cmTarget : : LinkLibraries & tlibs = l - > second . GetLinkLibraries ( ) ;
for ( cmTarget : : LinkLibraries : : const_iterator lib = tlibs . begin ( ) ;
lib ! = tlibs . end ( ) ; + + lib )
2002-08-31 00:01:48 +04:00
{
2002-12-06 23:35:22 +03:00
// Record that this library was used.
used . insert ( lib - > first ) ;
// Don't emit the same library twice for this target.
if ( emitted . insert ( lib - > first ) . second )
{
// Output this dependency.
this - > OutputLibDepend ( fout , lib - > first . c_str ( ) ) ;
}
2002-08-31 00:01:48 +04:00
}
}
2002-12-06 23:35:22 +03:00
// for all targets depend on utilities
2002-08-31 00:01:48 +04:00
// Now, look at all utilities specific to this target.
const std : : set < cmStdString > & tutils = l - > second . GetUtilities ( ) ;
for ( std : : set < cmStdString > : : const_iterator util = tutils . begin ( ) ;
util ! = tutils . end ( ) ; + + util )
2002-12-06 23:35:22 +03:00
{
2002-08-31 00:01:48 +04:00
// Record that this utility was used.
used . insert ( * util ) ;
// Don't emit the same utility twice for this target.
if ( emitted . insert ( * util ) . second )
{
// Output this dependency.
2004-02-03 17:26:36 +03:00
std : : string utilType = * util + " _LIBRARY_TYPE " ;
const char * libType = m_Makefile - > GetDefinition ( utilType . c_str ( ) ) ;
if ( libType )
{
this - > OutputLibDepend ( fout , util - > c_str ( ) ) ;
}
else
{
this - > OutputExeDepend ( fout , util - > c_str ( ) ) ;
}
2002-08-31 00:01:48 +04:00
}
}
fout < < " \n " ;
}
}
fout < < " \n " ;
// Loop over the libraries used and make sure there is a rule to
// build them in this makefile. If the library is in another
// directory, add a rule to jump to that directory and make sure it
// exists.
2004-09-30 00:07:07 +04:00
for ( std : : set < cmStdString > : : const_iterator lib = used . begin ( ) ;
2002-08-31 00:01:48 +04:00
lib ! = used . end ( ) ; + + lib )
{
// loop over the list of directories that the libraries might
// be in, looking for an ADD_LIBRARY(lib...) line. This would
// be stored in the cache
std : : string libPath = * lib + " _CMAKE_PATH " ;
const char * cacheValue = m_Makefile - > GetDefinition ( libPath . c_str ( ) ) ;
2002-12-06 23:35:22 +03:00
2002-08-31 00:01:48 +04:00
// if cache and not the current directory add a rule, to
// jump into the directory and build for the first time
2003-12-18 21:04:28 +03:00
if ( cacheValue & & * cacheValue & &
2002-08-31 00:01:48 +04:00
( ! this - > SamePath ( m_Makefile - > GetCurrentOutputDirectory ( ) , cacheValue ) ) )
{
// add the correct extension
std : : string ltname = * lib + " _LIBRARY_TYPE " ;
const char * libType
= m_Makefile - > GetDefinition ( ltname . c_str ( ) ) ;
// if it was a library..
if ( libType )
{
2002-11-08 23:46:08 +03:00
std : : string library ;
2002-08-31 00:01:48 +04:00
std : : string libpath = cacheValue ;
if ( libType & & std : : string ( libType ) = = " SHARED " )
{
2004-04-27 20:02:32 +04:00
library = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_LIBRARY_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
library + = * lib ;
2004-04-27 20:02:32 +04:00
library + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_LIBRARY_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
else if ( libType & & std : : string ( libType ) = = " MODULE " )
{
2004-04-27 20:02:32 +04:00
library = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_MODULE_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
library + = * lib ;
2004-04-27 20:02:32 +04:00
library + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_MODULE_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
else if ( libType & & std : : string ( libType ) = = " STATIC " )
{
2004-04-27 20:02:32 +04:00
library = m_Makefile - > GetSafeDefinition ( " CMAKE_STATIC_LIBRARY_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
library + = * lib ;
2004-04-27 20:02:32 +04:00
library + = m_Makefile - > GetSafeDefinition ( " CMAKE_STATIC_LIBRARY_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
else
{
cmSystemTools : : Error ( " Unknown library type! " ) ;
return ;
}
if ( m_LibraryOutputPath . size ( ) )
{
libpath = m_LibraryOutputPath ;
}
else
{
libpath + = " / " ;
}
libpath + = library ;
// put out a rule to build the library if it does not exist
this - > OutputBuildTargetInDir ( fout ,
cacheValue ,
library . c_str ( ) ,
2004-01-22 18:54:15 +03:00
libpath . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
// something other than a library...
else
{
std : : string exepath = cacheValue ;
if ( m_ExecutableOutputPath . size ( ) )
{
exepath = m_ExecutableOutputPath ;
}
else
{
exepath + = " / " ;
}
2002-12-06 23:35:22 +03:00
std : : string fullName = lib - > c_str ( ) ;
fullName + = cmSystemTools : : GetExecutableExtension ( ) ;
exepath + = fullName ;
2002-08-31 00:01:48 +04:00
this - > OutputBuildTargetInDir ( fout ,
2002-12-06 23:35:22 +03:00
cacheValue ,
fullName . c_str ( ) ,
2004-01-22 18:54:15 +03:00
exepath . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
}
}
}
2002-11-14 02:27:29 +03:00
void cmLocalUnixMakefileGenerator : : OutputBuildTargetInDirWindows ( std : : ostream & fout ,
const char * path ,
const char * library ,
2004-01-22 18:54:15 +03:00
const char * fullpath )
2002-11-14 02:27:29 +03:00
{
2004-04-23 20:52:48 +04:00
std : : string jumpBack ;
if ( m_UseRelativePaths )
{
jumpBack = cmSystemTools : : RelativePath ( cmSystemTools : : GetProgramPath ( path ) . c_str ( ) ,
m_Makefile - > GetCurrentOutputDirectory ( ) ) ;
}
else
{
jumpBack = m_Makefile - > GetCurrentOutputDirectory ( ) ;
}
2003-12-22 20:24:26 +03:00
jumpBack = this - > ConvertToOutputForExisting ( jumpBack . c_str ( ) ) ;
2002-12-22 19:50:24 +03:00
std : : string wpath = this - > ConvertToOutputForExisting ( path ) ;
2004-05-03 20:34:25 +04:00
std : : string wfullpath = this - > ConvertToRelativeOutputPath ( fullpath ) ;
2002-11-14 02:27:29 +03:00
fout < < wfullpath
< < " : \n \t cd " < < wpath < < " \n "
< < " \t $(MAKE) -$(MAKEFLAGS) $(MAKESILENT) cmake.depends \n "
< < " \t $(MAKE) -$(MAKEFLAGS) $(MAKESILENT) cmake.check_depends \n "
< < " \t $(MAKE) -$(MAKEFLAGS) $(MAKESILENT) -f cmake.check_depends \n "
2004-01-22 18:54:15 +03:00
< < " \t $(MAKE) $(MAKESILENT) " < < library
2003-12-22 20:24:26 +03:00
< < " \n \t cd " < < jumpBack < < " \n " ;
2002-11-14 02:27:29 +03:00
}
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : OutputBuildTargetInDir ( std : : ostream & fout ,
const char * path ,
const char * library ,
2004-01-22 18:54:15 +03:00
const char * fullpath )
2002-08-31 00:01:48 +04:00
{
2002-11-14 02:27:29 +03:00
if ( m_WindowsShell )
{
2004-01-22 18:54:15 +03:00
this - > OutputBuildTargetInDirWindows ( fout , path , library , fullpath ) ;
2002-11-14 02:27:29 +03:00
return ;
}
2002-12-22 19:50:24 +03:00
fout < < this - > ConvertToOutputForExisting ( fullpath )
< < " : \n \t cd " < < this - > ConvertToOutputForExisting ( path )
2002-08-31 00:01:48 +04:00
< < " ; $(MAKE) $(MAKESILENT) cmake.depends "
< < " ; $(MAKE) $(MAKESILENT) cmake.check_depends "
< < " ; $(MAKE) $(MAKESILENT) -f cmake.check_depends "
< < " ; $(MAKE) $(MAKESILENT) "
2004-01-22 18:54:15 +03:00
< < library < < " \n \n " ;
2002-08-31 00:01:48 +04:00
}
bool cmLocalUnixMakefileGenerator : : SamePath ( const char * path1 , const char * path2 )
{
2002-11-08 23:46:08 +03:00
if ( strcmp ( path1 , path2 ) = = 0 )
{
return true ;
}
# if defined(_WIN32) || defined(__APPLE__)
return
cmSystemTools : : LowerCase ( this - > ConvertToOutputForExisting ( path1 ) ) = =
cmSystemTools : : LowerCase ( this - > ConvertToOutputForExisting ( path2 ) ) ;
# else
return false ;
# endif
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputLibDepend ( std : : ostream & fout ,
const char * name )
{
std : : string libPath = name ;
libPath + = " _CMAKE_PATH " ;
const char * cacheValue = m_Makefile - > GetDefinition ( libPath . c_str ( ) ) ;
2003-12-18 21:04:28 +03:00
if ( cacheValue & & * cacheValue )
2002-08-31 00:01:48 +04:00
{
// if there is a cache value, then this is a library that cmake
// knows how to build, so we can depend on it
std : : string libpath ;
if ( ! this - > SamePath ( m_Makefile - > GetCurrentOutputDirectory ( ) , cacheValue ) )
{
// if the library is not in the current directory, then get the full
// path to it
if ( m_LibraryOutputPath . size ( ) )
{
libpath = m_LibraryOutputPath ;
}
else
{
libpath = cacheValue ;
libpath + = " / " ;
}
}
else
{
// library is in current Makefile so use lib as a prefix
libpath = m_LibraryOutputPath ;
}
// add the correct extension
std : : string ltname = name ;
ltname + = " _LIBRARY_TYPE " ;
const char * libType = m_Makefile - > GetDefinition ( ltname . c_str ( ) ) ;
if ( libType & & std : : string ( libType ) = = " SHARED " )
{
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_LIBRARY_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
libpath + = name ;
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_LIBRARY_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
else if ( libType & & std : : string ( libType ) = = " MODULE " )
{
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_MODULE_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
libpath + = name ;
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_SHARED_MODULE_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
else if ( libType & & std : : string ( libType ) = = " STATIC " )
{
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_STATIC_LIBRARY_PREFIX " ) ;
2002-11-08 23:46:08 +03:00
libpath + = name ;
2004-04-27 20:02:32 +04:00
libpath + = m_Makefile - > GetSafeDefinition ( " CMAKE_STATIC_LIBRARY_SUFFIX " ) ;
2002-08-31 00:01:48 +04:00
}
2003-12-22 23:16:46 +03:00
fout < < this - > ConvertToRelativeOutputPath ( libpath . c_str ( ) ) < < " " ;
2002-08-31 00:01:48 +04:00
}
2004-04-09 16:37:45 +04:00
else
{
if ( cmSystemTools : : FileExists ( name ) )
{
std : : string nameStr = name ;
// if it starts with / or \ or ?:/ or ?:\ then it must be a full path
if ( ( nameStr . size ( ) & & ( nameStr [ 0 ] = = ' / ' | | nameStr [ 0 ] = = ' \\ ' ) ) | |
( ( nameStr . size ( ) > 3 ) & & ( nameStr [ 1 ] = = ' : ' ) & & ( nameStr [ 2 ] = = ' / ' | | nameStr [ 2 ] = = ' \\ ' ) ) )
{
fout < < this - > ConvertToRelativeOutputPath ( name ) < < " " ;
}
}
}
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputExeDepend ( std : : ostream & fout ,
const char * name )
{
std : : string exePath = name ;
exePath + = " _CMAKE_PATH " ;
const char * cacheValue = m_Makefile - > GetDefinition ( exePath . c_str ( ) ) ;
2003-12-18 21:04:28 +03:00
if ( cacheValue & & * cacheValue )
2002-08-31 00:01:48 +04:00
{
// if there is a cache value, then this is a executable/utility that cmake
// knows how to build, so we can depend on it
std : : string exepath ;
if ( ! this - > SamePath ( m_Makefile - > GetCurrentOutputDirectory ( ) , cacheValue ) )
{
// if the exe/utility is not in the current directory, then get the full
// path to it
if ( m_ExecutableOutputPath . size ( ) )
{
exepath = m_ExecutableOutputPath ;
}
else
{
exepath = cacheValue ;
exepath + = " / " ;
}
}
else
{
// library is in current Makefile
exepath = m_ExecutableOutputPath ;
}
// add the library name
exepath + = name ;
// add the correct extension
2002-11-08 23:46:08 +03:00
exepath + = cmSystemTools : : GetExecutableExtension ( ) ;
2003-12-22 23:16:46 +03:00
fout < < this - > ConvertToRelativeOutputPath ( exepath . c_str ( ) ) < < " " ;
2002-08-31 00:01:48 +04:00
}
2003-06-03 18:30:23 +04:00
// if it isn't in the cache, it might still be a utility target
// so check for that
else
{
std : : map < cmStdString , cmTarget > & targets = m_Makefile - > GetTargets ( ) ;
if ( targets . find ( name ) ! = targets . end ( ) )
{
fout < < name < < " " ;
}
}
2002-08-31 00:01:48 +04:00
}
// fix up names of directories so they can be used
// as targets in makefiles.
inline std : : string FixDirectoryName ( const char * dir )
{
std : : string s = dir ;
// replace ../ with 3 under bars
size_t pos = s . find ( " ../ " ) ;
if ( pos ! = std : : string : : npos )
{
s . replace ( pos , 3 , " ___ " ) ;
}
// replace / directory separators with a single under bar
pos = s . find ( " / " ) ;
while ( pos ! = std : : string : : npos )
{
s . replace ( pos , 1 , " _ " ) ;
pos = s . find ( " / " ) ;
}
return s ;
}
2003-08-05 16:49:23 +04:00
void cmLocalUnixMakefileGenerator : :
BuildInSubDirectoryWindows ( std : : ostream & fout ,
const char * directory ,
const char * target1 ,
const char * target2 ,
bool silent )
2002-11-08 23:46:08 +03:00
{
2003-12-22 20:24:26 +03:00
std : : string dir ;
2002-11-08 23:46:08 +03:00
if ( target1 )
{
2003-12-22 20:24:26 +03:00
dir = this - > ConvertToOutputForExisting ( directory ) ;
2002-11-23 00:59:21 +03:00
if ( dir [ 0 ] = = ' \" ' )
{
dir = dir . substr ( 1 , dir . size ( ) - 2 ) ;
}
2002-11-08 23:46:08 +03:00
fout < < " \t if not exist \" " < < dir < < " \\ $(NULL) \" "
< < " "
< < " $(MAKE) $(MAKESILENT) rebuild_cache \n " ;
if ( ! silent )
{
2003-08-01 20:49:12 +04:00
fout < < " \t @echo " < < directory < < " : building " < < target1 < < " \n " ;
2002-11-08 23:46:08 +03:00
}
fout < < " \t cd " < < dir < < " \n "
< < " \t $(MAKE) -$(MAKEFLAGS) $(MAKESILENT) " < < target1 < < " \n " ;
}
if ( target2 )
{
if ( ! silent )
{
2003-08-01 20:49:12 +04:00
fout < < " \t @echo " < < directory < < " : building " < < target2 < < " \n " ;
2002-11-08 23:46:08 +03:00
}
fout < < " \t $(MAKE) -$(MAKEFLAGS) $(MAKESILENT) " < < target2 < < " \n " ;
2003-12-22 20:24:26 +03:00
}
2004-04-23 20:52:48 +04:00
std : : string currentDir ;
if ( m_UseRelativePaths )
2003-12-22 20:24:26 +03:00
{
2004-04-23 20:52:48 +04:00
currentDir = dir ;
cmSystemTools : : ConvertToUnixSlashes ( currentDir ) ;
std : : string cdback = " .. " ;
unsigned int i = 0 ;
if ( currentDir . size ( ) > 2 & & currentDir [ 0 ] = = ' . ' & & currentDir [ 1 ] = = ' / ' )
2003-12-22 20:24:26 +03:00
{
2004-04-23 20:52:48 +04:00
// start past ./ if it starts with ./
i = 2 ;
2003-12-22 20:24:26 +03:00
}
2004-04-23 20:52:48 +04:00
for ( ; i < currentDir . size ( ) ; + + i )
{
if ( currentDir [ i ] = = ' / ' )
{
cdback + = " /.. " ;
}
}
fout < < " \t cd " < < this - > ConvertToOutputForExisting ( cdback . c_str ( ) ) < < " \n \n " ;
}
else
{
currentDir = m_Makefile - > GetCurrentOutputDirectory ( ) ;
fout < < " \t cd " < < this - > ConvertToOutputForExisting ( currentDir . c_str ( ) ) < < " \n \n " ;
2002-11-08 23:46:08 +03:00
}
}
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : BuildInSubDirectory ( std : : ostream & fout ,
const char * dir ,
const char * target1 ,
const char * target2 ,
bool silent )
{
2002-11-08 23:46:08 +03:00
if ( m_WindowsShell )
{
this - > BuildInSubDirectoryWindows ( fout , dir , target1 , target2 , silent ) ;
return ;
}
2003-12-22 23:16:46 +03:00
std : : string directory = this - > ConvertToRelativeOutputPath ( dir ) ;
2002-08-31 00:01:48 +04:00
if ( target1 )
{
fout < < " \t @if test ! -d " < < directory
< < " ; then $(MAKE) rebuild_cache; fi \n " ;
if ( ! silent )
{
2003-08-01 20:49:12 +04:00
fout < < " \t @echo " < < directory < < " : building " < < target1 < < " \n " ;
2002-08-31 00:01:48 +04:00
}
fout < < " \t @cd " < < directory
< < " ; $(MAKE) " < < target1 < < " \n " ;
}
if ( target2 )
{
if ( ! silent )
{
2003-08-01 20:49:12 +04:00
fout < < " \t @echo " < < directory < < " : building " < < target2 < < " \n " ;
2002-08-31 00:01:48 +04:00
}
fout < < " \t @cd " < < directory
< < " ; $(MAKE) " < < target2 < < " \n " ;
}
fout < < " \n " ;
}
void
2005-03-14 19:29:15 +03:00
cmLocalUnixMakefileGenerator
: : OutputSubDirectoryVars ( std : : ostream & fout ,
const char * var ,
const char * target ,
const char * target1 ,
const char * target2 ,
const char * depend ,
const std : : vector < cmSubDirectory > & SubDirectories ,
bool silent , int order )
2002-08-31 00:01:48 +04:00
{
if ( ! depend )
{
depend = " " ;
}
if ( SubDirectories . size ( ) = = 0 )
{
return ;
}
fout < < " # Variable for making " < < target < < " in subdirectories. \n " ;
2004-03-10 00:28:44 +03:00
fout < < var < < " = " ;
2002-10-17 18:51:23 +04:00
unsigned int ii ;
2004-04-23 20:52:48 +04:00
// make sure all the pre-order subdirectories are fist
// other than that keep the same order that the user specified
2005-03-14 19:29:15 +03:00
std : : vector < cmStdString > orderedDirs ;
2004-04-23 20:52:48 +04:00
// collect pre-order first
for ( ii = 0 ; ii < SubDirectories . size ( ) ; ii + + )
{
if ( m_Makefile - > IsDirectoryPreOrder ( SubDirectories [ ii ] . first . c_str ( ) ) )
{
orderedDirs . push_back ( SubDirectories [ ii ] ) ;
}
}
// now collect post order dirs
2002-10-17 18:51:23 +04:00
for ( ii = 0 ; ii < SubDirectories . size ( ) ; ii + + )
2004-04-23 20:52:48 +04:00
{
if ( ! m_Makefile - > IsDirectoryPreOrder ( SubDirectories [ ii ] . first . c_str ( ) ) )
{
orderedDirs . push_back ( SubDirectories [ ii ] ) ;
}
}
for ( ii = 0 ; ii < orderedDirs . size ( ) ; ii + + )
2002-08-31 00:01:48 +04:00
{
2004-04-23 20:52:48 +04:00
if ( ! orderedDirs [ ii ] . second )
{
continue ;
}
if ( order = = 1 & & m_Makefile - > IsDirectoryPreOrder ( orderedDirs [ ii ] . first . c_str ( ) ) )
{
continue ;
}
if ( order = = 2 & & ! m_Makefile - > IsDirectoryPreOrder ( orderedDirs [ ii ] . first . c_str ( ) ) )
2002-08-31 00:01:48 +04:00
{
2004-03-10 00:28:44 +03:00
continue ;
2002-08-31 00:01:48 +04:00
}
2004-04-23 20:52:48 +04:00
2004-03-10 00:28:44 +03:00
fout < < " \\ \n " ;
2004-04-23 20:52:48 +04:00
std : : string subdir = FixDirectoryName ( orderedDirs [ ii ] . first . c_str ( ) ) ;
2004-03-10 00:28:44 +03:00
fout < < target < < " _ " < < subdir . c_str ( ) ;
2002-08-31 00:01:48 +04:00
}
2004-03-10 00:28:44 +03:00
fout < < " \n \n " ;
2002-08-31 00:01:48 +04:00
fout < < " # Targets for making " < < target < < " in subdirectories. \n " ;
std : : string last = " " ;
2004-04-23 20:52:48 +04:00
for ( unsigned int cc = 0 ; cc < orderedDirs . size ( ) ; cc + + )
2002-08-31 00:01:48 +04:00
{
2004-04-23 20:52:48 +04:00
if ( ! orderedDirs [ cc ] . second )
2004-03-10 00:28:44 +03:00
{
continue ;
2004-04-23 20:52:48 +04:00
}
std : : string subdir = FixDirectoryName ( orderedDirs [ cc ] . first . c_str ( ) ) ;
if ( order = = 1 & & m_Makefile - > IsDirectoryPreOrder ( orderedDirs [ cc ] . first . c_str ( ) ) )
{
last = subdir ;
continue ;
}
if ( order = = 2 & & ! m_Makefile - > IsDirectoryPreOrder ( orderedDirs [ cc ] . first . c_str ( ) ) )
{
last = subdir ;
continue ;
2004-03-10 00:28:44 +03:00
}
2004-04-23 20:52:48 +04:00
2002-08-31 00:01:48 +04:00
fout < < target < < " _ " < < subdir . c_str ( ) < < " : " < < depend ;
// Make each subdirectory depend on previous one. This forces
// parallel builds (make -j 2) to build in same order as a single
// threaded build to avoid dependency problems.
2002-10-17 18:51:23 +04:00
if ( cc > 0 )
2002-08-31 00:01:48 +04:00
{
fout < < " " < < target < < " _ " < < last . c_str ( ) ;
}
fout < < " \n " ;
last = subdir ;
std : : string dir = m_Makefile - > GetCurrentOutputDirectory ( ) ;
dir + = " / " ;
2004-04-23 20:52:48 +04:00
dir + = orderedDirs [ cc ] . first ;
2002-08-31 00:01:48 +04:00
this - > BuildInSubDirectory ( fout , dir . c_str ( ) ,
target1 , target2 , silent ) ;
}
fout < < " \n \n " ;
}
// output rules for decending into sub directories
void cmLocalUnixMakefileGenerator : : OutputSubDirectoryRules ( std : : ostream & fout )
{
// Output Sub directory build rules
2005-03-14 19:29:15 +03:00
const std : : map < std : : string , cmSubDirectory > & SubDirectories
2002-08-31 00:01:48 +04:00
= m_Makefile - > GetSubDirectories ( ) ;
if ( SubDirectories . size ( ) = = 0 )
{
return ;
}
2002-12-05 22:56:31 +03:00
2002-08-31 00:01:48 +04:00
this - > OutputSubDirectoryVars ( fout ,
" SUBDIR_BUILD " ,
" default_target " ,
" default_target " ,
0 , " $(TARGETS) " ,
SubDirectories ,
2004-04-23 20:52:48 +04:00
false , 1 ) ;
this - > OutputSubDirectoryVars ( fout ,
" SUBDIR_PREORDER_BUILD " ,
" default_target " ,
" default_target " ,
2004-06-01 17:58:00 +04:00
0 , 0 ,
2004-04-23 20:52:48 +04:00
SubDirectories ,
false , 2 ) ;
2002-08-31 00:01:48 +04:00
this - > OutputSubDirectoryVars ( fout , " SUBDIR_CLEAN " , " clean " ,
" clean " ,
0 , 0 ,
SubDirectories ) ;
this - > OutputSubDirectoryVars ( fout , " SUBDIR_DEPEND " , " depend " ,
" depend " ,
0 , 0 ,
SubDirectories ) ;
}
// Output the depend information for all the classes
// in the makefile. These would have been generated
// by the class cmMakeDepend GenerateMakefile
bool cmLocalUnixMakefileGenerator : : OutputObjectDepends ( std : : ostream & fout )
{
bool ret = false ;
// Iterate over every target.
std : : map < cmStdString , cmTarget > & targets = m_Makefile - > GetTargets ( ) ;
for ( std : : map < cmStdString , cmTarget > : : const_iterator target = targets . begin ( ) ;
target ! = targets . end ( ) ; + + target )
{
// Iterate over every source for this target.
const std : : vector < cmSourceFile * > & sources = target - > second . GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator source = sources . begin ( ) ;
source ! = sources . end ( ) ; + + source )
{
if ( ! ( * source ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) )
{
if ( ! ( * source ) - > GetDepends ( ) . empty ( ) )
{
// Iterate through all the dependencies for this source.
for ( std : : vector < std : : string > : : const_iterator dep =
( * source ) - > GetDepends ( ) . begin ( ) ;
dep ! = ( * source ) - > GetDepends ( ) . end ( ) ; + + dep )
{
2003-02-20 16:52:43 +03:00
std : : string s = ( * source ) - > GetSourceName ( ) ;
2004-09-22 22:42:05 +04:00
std : : string outExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
( * source ) - > GetSourceExtension ( ) . c_str ( ) ) ;
s + = outExt ;
2004-11-10 23:39:10 +03:00
s = this - > CreateSafeUniqueObjectFileName ( s . c_str ( ) ) ;
2003-12-22 23:16:46 +03:00
fout < < this - > ConvertToRelativeOutputPath ( s . c_str ( ) ) < < " : "
< < this - > ConvertToRelativeOutputPath ( dep - > c_str ( ) ) < < " \n " ;
2002-08-31 00:01:48 +04:00
ret = true ;
}
fout < < " \n \n " ;
}
}
}
}
return ret ;
}
// Output the depend information for all the classes
// in the makefile. These would have been generated
// by the class cmMakeDepend GenerateMakefile
void cmLocalUnixMakefileGenerator : : OutputCheckDepends ( std : : ostream & fout )
{
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > emittedLowerPath ;
std : : set < cmStdString > emitted ;
2002-08-31 00:01:48 +04:00
// Iterate over every target.
std : : map < cmStdString , cmTarget > & targets = m_Makefile - > GetTargets ( ) ;
fout < < " # Suppresses display of executed commands \n " ;
fout < < " .SILENT: \n " ;
fout < < " # disable some common implicit rules to speed things up \n " ;
fout < < " .SUFFIXES: \n " ;
fout < < " .SUFFIXES:.hpuxmakemusthaverule \n " ;
this - > OutputMakeVariables ( fout ) ;
fout < < " default: \n " ;
fout < < " \t $(MAKE) $(MAKESILENT) -f cmake.check_depends all \n "
< < " \t $(MAKE) $(MAKESILENT) -f cmake.check_depends cmake.depends \n \n " ;
for ( std : : map < cmStdString , cmTarget > : : const_iterator target = targets . begin ( ) ;
target ! = targets . end ( ) ; + + target )
{
// Iterate over every source for this target.
const std : : vector < cmSourceFile * > & sources = target - > second . GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator source = sources . begin ( ) ;
source ! = sources . end ( ) ; + + source )
{
if ( ! ( * source ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) )
{
if ( ! ( * source ) - > GetDepends ( ) . empty ( ) )
{
for ( std : : vector < std : : string > : : const_iterator dep =
( * source ) - > GetDepends ( ) . begin ( ) ;
dep ! = ( * source ) - > GetDepends ( ) . end ( ) ; + + dep )
{
2003-07-29 02:12:23 +04:00
// do not call CollapseFullPath on dep here, because it already
// has been done because m_FullPath on cmDependInformation
// always is it called. If it is called here, network builds are
// very slow because of the number of stats
2003-12-22 23:16:46 +03:00
std : : string dependfile = this - > ConvertToRelativeOutputPath ( dep - > c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
// use the lower path function to create uniqe names
std : : string lowerpath = this - > LowerCasePath ( dependfile . c_str ( ) ) ;
if ( emittedLowerPath . insert ( lowerpath ) . second )
{
emitted . insert ( dependfile ) ;
2003-11-01 01:22:57 +03:00
fout < < " all: " < < dependfile < < " \n " ;
2002-08-31 00:01:48 +04:00
}
}
}
}
}
}
fout < < " \n \n # if any of these files changes run make dependlocal \n " ;
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > : : iterator i ;
2002-08-31 00:01:48 +04:00
for ( i = emitted . begin ( ) ; i ! = emitted . end ( ) ; + + i )
{
2003-11-01 01:22:57 +03:00
fout < < " cmake.depends: " < < * i < < " \n " ;
2002-08-31 00:01:48 +04:00
}
2003-11-01 01:22:57 +03:00
fout < < " cmake.depends: \n "
< < " \t $(MAKE) $(MAKESILENT) dependlocal \n \n " ;
2002-08-31 00:01:48 +04:00
fout < < " \n \n " ;
fout < < " # if a .h file is removed then run make dependlocal \n \n " ;
2004-09-30 00:07:07 +04:00
for ( std : : set < cmStdString > : : iterator it = emitted . begin ( ) ;
2002-10-17 18:51:23 +04:00
it ! = emitted . end ( ) ; + + it )
2002-08-31 00:01:48 +04:00
{
2002-10-17 18:51:23 +04:00
fout < < * it < < " : \n "
2002-08-31 00:01:48 +04:00
< < " \t $(MAKE) $(MAKESILENT) dependlocal \n \n " ;
}
}
// Output each custom rule in the following format:
// output: source depends...
// (tab) command...
void cmLocalUnixMakefileGenerator : : OutputCustomRules ( std : : ostream & fout )
{
2003-06-03 18:30:23 +04:00
// we cannot provide multiple rules for a single output
// so we will keep track of outputs to make sure we don't write
// two rules. First found wins
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > processedOutputs ;
2002-08-31 00:01:48 +04:00
2003-06-03 18:30:23 +04:00
// first output all custom rules
const std : : vector < cmSourceFile * > & sources = m_Makefile - > GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator i = sources . begin ( ) ;
i ! = sources . end ( ) ; + + i )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
if ( ( * i ) - > GetCustomCommand ( ) )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
cmCustomCommand * c = ( * i ) - > GetCustomCommand ( ) ;
// escape spaces and convert to native slashes path for
// the command
2003-06-11 19:00:59 +04:00
std : : string comment = c - > GetComment ( ) ;
2005-02-22 18:32:44 +03:00
std : : vector < std : : string > commands ;
// Add each command line to the set of commands.
for ( cmCustomCommandLines : : const_iterator cl = c - > GetCommandLines ( ) . begin ( ) ;
cl ! = c - > GetCommandLines ( ) . end ( ) ; + + cl )
{
// Build the command line in a single string.
const cmCustomCommandLine & commandLine = * cl ;
std : : string cmd = commandLine [ 0 ] ;
cmSystemTools : : ReplaceString ( cmd , " /./ " , " / " ) ;
cmd = this - > ConvertToRelativeOutputPath ( cmd . c_str ( ) ) ;
for ( unsigned int j = 1 ; j < commandLine . size ( ) ; + + j )
{
cmd + = " " ;
cmd + = cmSystemTools : : EscapeSpaces ( commandLine [ j ] . c_str ( ) ) ;
}
commands . push_back ( cmd ) ;
}
2004-01-23 17:54:50 +03:00
std : : vector < std : : string > depends ;
2003-06-03 18:30:23 +04:00
// Collect out all the dependencies for this rule.
for ( std : : vector < std : : string > : : const_iterator d =
c - > GetDepends ( ) . begin ( ) ;
d ! = c - > GetDepends ( ) . end ( ) ; + + d )
2002-10-10 18:43:59 +04:00
{
2003-06-03 18:30:23 +04:00
std : : string dep = * d ;
m_Makefile - > ExpandVariablesInString ( dep ) ;
2002-08-31 00:01:48 +04:00
2003-06-03 18:30:23 +04:00
// watch for target dependencies,
std : : string libPath = dep + " _CMAKE_PATH " ;
const char * cacheValue = m_Makefile - > GetDefinition ( libPath . c_str ( ) ) ;
2003-12-18 21:04:28 +03:00
if ( cacheValue & & * cacheValue )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
libPath = cacheValue ;
if ( m_Makefile - > GetDefinition ( " EXECUTABLE_OUTPUT_PATH " ) & &
m_Makefile - > GetDefinition ( " EXECUTABLE_OUTPUT_PATH " ) [ 0 ] ! = ' \0 ' )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
libPath = m_Makefile - > GetDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
}
libPath + = " / " ;
libPath + = dep ;
libPath + = cmSystemTools : : GetExecutableExtension ( ) ;
dep = libPath ;
2002-08-31 00:01:48 +04:00
}
2003-06-03 18:30:23 +04:00
cmSystemTools : : ReplaceString ( dep , " /./ " , " / " ) ;
cmSystemTools : : ReplaceString ( dep , " /$(IntDir)/ " , " / " ) ;
2003-12-22 23:16:46 +03:00
dep = this - > ConvertToRelativeOutputPath ( dep . c_str ( ) ) ;
2004-01-23 17:54:50 +03:00
depends . push_back ( dep . c_str ( ) ) ;
}
2003-06-03 18:30:23 +04:00
// output rule
if ( processedOutputs . find ( c - > GetOutput ( ) ) = = processedOutputs . end ( ) )
{
this - > OutputMakeRule ( fout ,
2003-06-11 19:00:59 +04:00
( comment . size ( ) ? comment . c_str ( ) : " Custom command " ) ,
2005-02-22 18:32:44 +03:00
c - > GetOutput ( ) ,
2004-01-23 17:54:50 +03:00
depends ,
2005-02-22 18:32:44 +03:00
commands ) ;
2003-06-03 18:30:23 +04:00
processedOutputs . insert ( c - > GetOutput ( ) ) ;
}
else
{
cmSystemTools : : Error ( " An output was found with multiple rules on how to build it for output: " ,
2005-02-22 18:32:44 +03:00
c - > GetOutput ( ) ) ;
2002-08-31 00:01:48 +04:00
}
}
2003-06-03 18:30:23 +04:00
}
2002-08-31 00:01:48 +04:00
}
2002-11-08 23:46:08 +03:00
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : OutputMakeVariables ( std : : ostream & fout )
{
const char * variables =
" # the standard shell for make \n "
" SHELL = /bin/sh \n "
" \n " ;
2002-11-08 23:46:08 +03:00
if ( ! m_WindowsShell )
{
fout < < variables ;
}
else
{
fout < <
" !IF \" $(OS) \" == \" Windows_NT \" \n "
" NULL= \n "
" !ELSE \n "
" NULL=nul \n "
" !ENDIF \n " ;
}
if ( m_MakeSilentFlag . size ( ) )
{
fout < < " MAKESILENT = " < < m_MakeSilentFlag < < " \n " ;
}
std : : string cmakecommand = this - > ConvertToOutputForExisting (
2004-08-06 22:51:41 +04:00
m_Makefile - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ) ;
2002-08-31 00:01:48 +04:00
fout < < " CMAKE_COMMAND = "
2002-11-08 23:46:08 +03:00
< < cmakecommand
2002-08-31 00:01:48 +04:00
< < " \n " ;
2002-11-08 23:46:08 +03:00
fout < < " RM = " < < cmakecommand . c_str ( ) < < " -E remove -f \n " ;
2002-08-31 00:01:48 +04:00
if ( m_Makefile - > GetDefinition ( " CMAKE_EDIT_COMMAND " ) )
{
fout < < " CMAKE_EDIT_COMMAND = "
2002-11-08 23:46:08 +03:00
< < this - > ConvertToOutputForExisting ( m_Makefile - > GetDefinition ( " CMAKE_EDIT_COMMAND " ) )
2002-08-31 00:01:48 +04:00
< < " \n " ;
}
fout < < " CMAKE_CURRENT_SOURCE = " < <
2003-12-22 23:16:46 +03:00
this - > ConvertToRelativeOutputPath ( m_Makefile - > GetStartDirectory ( ) )
2002-11-08 23:46:08 +03:00
< < " \n " ;
2002-08-31 00:01:48 +04:00
fout < < " CMAKE_CURRENT_BINARY = " < <
2003-12-22 23:16:46 +03:00
this - > ConvertToRelativeOutputPath ( m_Makefile - > GetStartOutputDirectory ( ) )
2002-11-08 23:46:08 +03:00
< < " \n " ;
2002-08-31 00:01:48 +04:00
fout < < " CMAKE_SOURCE_DIR = " < <
2003-12-22 23:16:46 +03:00
this - > ConvertToRelativeOutputPath ( m_Makefile - > GetHomeDirectory ( ) )
2002-11-08 23:46:08 +03:00
< < " \n " ;
2002-08-31 00:01:48 +04:00
fout < < " CMAKE_BINARY_DIR = " < <
2003-12-22 23:16:46 +03:00
this - > ConvertToRelativeOutputPath ( m_Makefile - > GetHomeOutputDirectory ( ) )
2002-11-08 23:46:08 +03:00
< < " \n " ;
2004-09-22 22:42:05 +04:00
fout < < " \n \n " ;
}
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : OutputMakeRules ( std : : ostream & fout )
{
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" default build rule " ,
2002-08-31 00:01:48 +04:00
" all " ,
2004-04-23 20:52:48 +04:00
" cmake.depends $(SUBDIR_PREORDER_BUILD) $(TARGETS) $(SUBDIR_BUILD) " ,
2002-08-31 00:01:48 +04:00
0 ) ;
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" clean generated files " ,
2002-08-31 00:01:48 +04:00
" clean " ,
" $(SUBDIR_CLEAN) " ,
" -@ $(RM) $(CLEAN_OBJECT_FILES) "
2004-03-29 01:36:38 +04:00
" $(TARGETS) $(TARGET_EXTRAS) $(GENERATED_QT_FILES) $(GENERATED_FLTK_FILES) $(ADDITIONAL_MAKE_CLEAN_FILES) " ) ;
2002-08-31 00:01:48 +04:00
// collect up all the sources
2003-08-01 23:33:59 +04:00
std : : vector < std : : string > allsources ;
2002-08-31 00:01:48 +04:00
std : : map < cmStdString , cmTarget > & targets = m_Makefile - > GetTargets ( ) ;
2003-06-03 18:30:23 +04:00
for ( std : : map < cmStdString , cmTarget > : : const_iterator target = targets . begin ( ) ;
2002-08-31 00:01:48 +04:00
target ! = targets . end ( ) ; + + target )
{
// Iterate over every source for this target.
const std : : vector < cmSourceFile * > & sources = target - > second . GetSourceFiles ( ) ;
for ( std : : vector < cmSourceFile * > : : const_iterator source = sources . begin ( ) ;
source ! = sources . end ( ) ; + + source )
{
if ( ! ( * source ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) )
{
2003-12-22 23:16:46 +03:00
allsources . push_back ( this - > ConvertToRelativeOutputPath ( ( * source ) - > GetFullPath ( ) . c_str ( ) ) ) ;
2002-08-31 00:01:48 +04:00
}
}
}
2003-08-07 19:42:02 +04:00
std : : string checkCache = m_Makefile - > GetHomeOutputDirectory ( ) ;
checkCache + = " /cmake.check_cache " ;
std : : vector < std : : string > cmake_depends ;
cmake_depends . push_back ( " $(CMAKE_MAKEFILE_SOURCES) " ) ;
2002-08-31 00:01:48 +04:00
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" dependencies. " ,
2002-08-31 00:01:48 +04:00
" cmake.depends " ,
2003-08-07 19:42:02 +04:00
cmake_depends ,
2002-08-31 00:01:48 +04:00
" $(CMAKE_COMMAND) "
" -S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
2003-08-07 19:42:02 +04:00
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
2002-08-31 00:01:48 +04:00
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" dependencies " ,
2002-08-31 00:01:48 +04:00
" cmake.check_depends " ,
2003-08-01 23:33:59 +04:00
allsources ,
2003-08-07 19:42:02 +04:00
" $(CMAKE_COMMAND) "
" -S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
2002-08-31 00:01:48 +04:00
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" dependencies " ,
2002-08-31 00:01:48 +04:00
" depend " ,
" $(SUBDIR_DEPEND) " ,
" $(CMAKE_COMMAND) "
" -S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" dependencies " ,
2002-08-31 00:01:48 +04:00
" dependlocal " ,
0 ,
" $(CMAKE_COMMAND) "
" -S$(CMAKE_CURRENT_SOURCE) -O$(CMAKE_CURRENT_BINARY) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
2003-08-07 19:42:02 +04:00
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" CMakeCache.txt " ,
2002-08-31 00:01:48 +04:00
" rebuild_cache " ,
2004-01-29 17:01:39 +03:00
0 ,
2002-08-31 00:01:48 +04:00
" $(CMAKE_COMMAND) "
2002-12-06 00:53:09 +03:00
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
2003-08-07 19:42:02 +04:00
std : : vector < std : : string > check_cache_depends ;
2002-12-06 00:53:09 +03:00
std : : string CMakeCache = m_Makefile - > GetHomeOutputDirectory ( ) ;
CMakeCache + = " /CMakeCache.txt " ;
2003-12-22 23:16:46 +03:00
CMakeCache = this - > ConvertToRelativeOutputPath ( CMakeCache . c_str ( ) ) ;
2003-08-07 19:42:02 +04:00
check_cache_depends . push_back ( " $(CMAKE_MAKEFILE_SOURCES) " ) ;
2002-12-06 00:53:09 +03:00
2002-12-05 22:56:31 +03:00
this - > OutputMakeRule ( fout ,
" CMakeCache.txt because out-of-date: " ,
2002-12-06 00:53:09 +03:00
checkCache . c_str ( ) ,
2003-08-07 19:42:02 +04:00
check_cache_depends ,
2002-12-05 22:56:31 +03:00
" $(CMAKE_COMMAND) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
2002-08-31 00:01:48 +04:00
// if CMAKE_EDIT_COMMAND is defined then add a rule to run it
// called edit_cache
if ( m_Makefile - > GetDefinition ( " CMAKE_EDIT_COMMAND " ) )
{
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" edit CMakeCache.txt " ,
2002-08-31 00:01:48 +04:00
" edit_cache " ,
0 ,
" $(CMAKE_EDIT_COMMAND) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
}
2003-08-07 01:58:47 +04:00
else
{
this - > OutputMakeRule ( fout ,
" edit CMakeCache.txt " ,
" edit_cache " ,
0 ,
" $(CMAKE_COMMAND) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -i " ) ;
}
2004-04-30 19:36:54 +04:00
std : : string cacheFile = m_Makefile - > GetHomeOutputDirectory ( ) ;
cacheFile + = " /CMakeCache.txt " ;
2002-08-31 00:01:48 +04:00
this - > OutputMakeRule ( fout ,
2002-11-08 23:46:08 +03:00
" CMakeCache.txt " ,
2004-04-30 19:36:54 +04:00
cacheFile . c_str ( ) ,
2002-08-31 00:01:48 +04:00
0 ,
" $(CMAKE_COMMAND) "
" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) " ) ;
this - > OutputMakeRule ( fout ,
" Rule to keep make from removing Makefiles "
" if control-C is hit during a run of cmake. " ,
" .PRECIOUS " ,
" Makefile cmake.depends " ,
0 ) ;
this - > OutputSourceObjectBuildRules ( fout ) ;
// find ctest
2004-08-06 22:51:41 +04:00
std : : string ctest = m_Makefile - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
2002-08-31 00:01:48 +04:00
ctest = cmSystemTools : : GetFilenamePath ( ctest . c_str ( ) ) ;
ctest + = " / " ;
ctest + = " ctest " ;
ctest + = cmSystemTools : : GetExecutableExtension ( ) ;
if ( ! cmSystemTools : : FileExists ( ctest . c_str ( ) ) )
{
2004-08-06 22:51:41 +04:00
ctest = m_Makefile - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
2002-08-31 00:01:48 +04:00
ctest = cmSystemTools : : GetFilenamePath ( ctest . c_str ( ) ) ;
ctest + = " /Debug/ " ;
ctest + = " ctest " ;
ctest + = cmSystemTools : : GetExecutableExtension ( ) ;
}
if ( ! cmSystemTools : : FileExists ( ctest . c_str ( ) ) )
{
2004-08-06 22:51:41 +04:00
ctest = m_Makefile - > GetRequiredDefinition ( " CMAKE_COMMAND " ) ;
2002-08-31 00:01:48 +04:00
ctest = cmSystemTools : : GetFilenamePath ( ctest . c_str ( ) ) ;
ctest + = " /Release/ " ;
ctest + = " ctest " ;
ctest + = cmSystemTools : : GetExecutableExtension ( ) ;
}
2003-05-05 16:42:11 +04:00
if ( ! cmSystemTools : : FileExists ( ctest . c_str ( ) ) )
2002-08-31 00:01:48 +04:00
{
2003-05-05 16:42:11 +04:00
if ( ! m_Makefile - > GetDefinition ( " PROJECT_NAME " ) | |
strcmp ( m_Makefile - > GetDefinition ( " PROJECT_NAME " ) , " CMake " ) )
{
return ;
}
2004-08-06 22:51:41 +04:00
ctest = m_Makefile - > GetRequiredDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
2003-05-05 16:42:11 +04:00
ctest + = " /ctest " ;
2002-08-31 00:01:48 +04:00
}
2003-12-30 00:27:40 +03:00
if ( m_Makefile - > IsOn ( " CMAKE_TESTING_ENABLED " ) )
{
fout < < " ARGS= \n " ;
std : : string cmd = this - > ConvertToOutputForExisting ( ctest . c_str ( ) ) ;
cmd + = " $(ARGS) " ;
this - > OutputMakeRule ( fout ,
" tests " ,
" test " ,
" " ,
cmd . c_str ( ) ) ;
}
2004-06-10 02:56:00 +04:00
if ( m_Makefile - > GetDefinition ( " CMake_BINARY_DIR " ) )
{
// We are building CMake itself. We cannot use the original
// executable to install over itself.
2004-08-06 22:51:41 +04:00
std : : string rule = m_Makefile - > GetRequiredDefinition ( " EXECUTABLE_OUTPUT_PATH " ) ;
2004-06-10 02:56:00 +04:00
rule + = " /cmake " ;
rule = cmSystemTools : : ConvertToOutputPath ( rule . c_str ( ) ) ;
rule + = " -P cmake_install.cmake " ;
this - > OutputMakeRule ( fout , " installation " , " install " , " " , rule . c_str ( ) ) ;
}
else
{
this - > OutputMakeRule ( fout , " installation " , " install " , " " ,
" $(CMAKE_COMMAND) -P cmake_install.cmake " ) ;
}
2004-04-15 20:07:58 +04:00
2002-08-31 00:01:48 +04:00
}
void
cmLocalUnixMakefileGenerator : :
OutputBuildObjectFromSource ( std : : ostream & fout ,
const char * shortName ,
const cmSourceFile & source ,
const char * extraCompileFlags ,
bool shared )
{
// Header files shouldn't have build rules.
2004-09-24 16:39:02 +04:00
if ( source . GetPropertyAsBool ( " HEADER_FILE_ONLY " ) | |
m_GlobalGenerator - > IgnoreFile ( source . GetSourceExtension ( ) . c_str ( ) ) )
2002-08-31 00:01:48 +04:00
{
return ;
}
2004-09-24 16:39:02 +04:00
2004-09-22 22:42:05 +04:00
std : : string outputExt =
m_GlobalGenerator - > GetLanguageOutputExtensionFromExtension (
source . GetSourceExtension ( ) . c_str ( ) ) ;
std : : string objectFile = std : : string ( shortName ) + outputExt ;
2004-04-28 18:15:40 +04:00
objectFile = this - > CreateSafeUniqueObjectFileName ( objectFile . c_str ( ) ) ;
2003-12-22 23:16:46 +03:00
objectFile = this - > ConvertToRelativeOutputPath ( objectFile . c_str ( ) ) ;
2002-11-08 23:46:08 +03:00
std : : vector < std : : string > rules ;
std : : string flags ;
if ( extraCompileFlags )
2002-08-31 00:01:48 +04:00
{
2002-11-08 23:46:08 +03:00
flags + = extraCompileFlags ;
2002-08-31 00:01:48 +04:00
}
2002-11-08 23:46:08 +03:00
std : : string sourceFile =
2003-12-22 23:16:46 +03:00
this - > ConvertToRelativeOutputPath ( source . GetFullPath ( ) . c_str ( ) ) ;
2004-04-27 20:02:32 +04:00
std : : string buildType = m_Makefile - > GetSafeDefinition ( " CMAKE_BUILD_TYPE " ) ;
2002-11-08 23:46:08 +03:00
buildType = cmSystemTools : : UpperCase ( buildType ) ;
2004-09-03 20:03:41 +04:00
// find out what language the source file is
const char * lang =
m_GlobalGenerator - > GetLanguageFromExtension ( source . GetSourceExtension ( ) . c_str ( ) ) ;
// for now if the lang is defined add the rules and flags for it
2004-09-22 22:42:05 +04:00
std : : string comment = outputExt ;
comment + = " file " ;
if ( lang )
{
comment + = " from " ;
comment + = lang ;
comment + = " : " ;
if ( comment . size ( ) < 18 )
{
comment . resize ( 18 , ' ' ) ;
}
}
2004-09-03 20:03:41 +04:00
if ( lang )
{
std : : string varString = " CMAKE_ " ;
varString + = lang ;
varString + = " _COMPILE_OBJECT " ;
rules . push_back ( m_Makefile - > GetRequiredDefinition ( varString . c_str ( ) ) ) ;
varString = " CMAKE_ " ;
varString + = lang ;
varString + = " _FLAGS " ;
flags + = m_Makefile - > GetSafeDefinition ( varString . c_str ( ) ) ;
flags + = " " ;
if ( buildType . size ( ) )
2002-08-31 00:01:48 +04:00
{
2004-09-03 20:03:41 +04:00
varString + = " _ " ;
varString + = buildType ;
flags + = m_Makefile - > GetSafeDefinition ( varString . c_str ( ) ) ;
2002-11-08 23:46:08 +03:00
flags + = " " ;
2002-08-31 00:01:48 +04:00
}
2004-09-03 20:03:41 +04:00
if ( shared )
2002-11-08 23:46:08 +03:00
{
2004-09-03 20:03:41 +04:00
varString = " CMAKE_SHARED_LIBRARY_ " ;
varString + = lang ;
varString + = " _FLAGS " ;
flags + = m_Makefile - > GetSafeDefinition ( varString . c_str ( ) ) ;
flags + = " " ;
2002-11-08 23:46:08 +03:00
}
2004-09-03 20:03:41 +04:00
if ( cmSystemTools : : IsOn ( m_Makefile - > GetDefinition ( " BUILD_SHARED_LIBS " ) ) )
{
varString = " CMAKE_SHARED_BUILD_ " ;
varString + = lang ;
varString + = " _FLAGS " ;
flags + = m_Makefile - > GetSafeDefinition ( varString . c_str ( ) ) ;
flags + = " " ;
}
}
else
2004-09-22 22:42:05 +04:00
{
// if the language is not defined and should not be ignored,
// then produce an error
2004-09-24 16:39:02 +04:00
cmSystemTools : : Error ( " Unexpected file type " ,
sourceFile . c_str ( ) ) ;
2004-09-03 20:03:41 +04:00
}
2004-09-22 22:42:05 +04:00
flags + = this - > GetIncludeFlags ( lang ) ;
2002-11-08 23:46:08 +03:00
// expand multi-command semi-colon separated lists
// of commands into separate commands
std : : vector < std : : string > commands ;
2002-12-12 02:13:33 +03:00
cmSystemTools : : ExpandList ( rules , commands ) ;
2002-11-08 23:46:08 +03:00
for ( std : : vector < std : : string > : : iterator i = commands . begin ( ) ;
i ! = commands . end ( ) ; + + i )
{
this - > ExpandRuleVariables ( * i ,
2004-09-23 19:44:17 +04:00
lang ,
2002-11-08 23:46:08 +03:00
0 , // no objects
0 , // no target
0 , // no link libs
sourceFile . c_str ( ) ,
objectFile . c_str ( ) ,
2002-11-12 02:10:30 +03:00
flags . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
2002-12-14 00:16:48 +03:00
std : : vector < std : : string > sourceAndDeps ;
sourceAndDeps . push_back ( sourceFile ) ;
// Check for extra object-file dependencies.
2002-12-14 01:34:34 +03:00
std : : vector < std : : string > depends ;
2002-12-14 00:16:48 +03:00
const char * additionalDeps = source . GetProperty ( " OBJECT_DEPENDS " ) ;
if ( additionalDeps )
{
cmSystemTools : : ExpandListArgument ( additionalDeps , depends ) ;
for ( std : : vector < std : : string > : : iterator i = depends . begin ( ) ;
i ! = depends . end ( ) ; + + i )
{
2003-12-22 23:16:46 +03:00
sourceAndDeps . push_back ( this - > ConvertToRelativeOutputPath ( i - > c_str ( ) ) ) ;
2002-12-14 00:16:48 +03:00
}
}
2002-08-31 00:01:48 +04:00
this - > OutputMakeRule ( fout ,
comment . c_str ( ) ,
objectFile . c_str ( ) ,
2002-12-14 01:34:34 +03:00
sourceAndDeps ,
2002-11-08 23:46:08 +03:00
commands ) ;
2002-08-31 00:01:48 +04:00
}
void cmLocalUnixMakefileGenerator : : OutputSourceObjectBuildRules ( std : : ostream & fout )
{
2004-09-22 22:42:05 +04:00
fout < < " # Rules to build source files : \n \n " ;
2002-08-31 00:01:48 +04:00
2004-09-30 00:07:07 +04:00
std : : set < cmStdString > rules ;
2002-08-31 00:01:48 +04:00
// Iterate over every target.
std : : map < cmStdString , cmTarget > & targets = m_Makefile - > GetTargets ( ) ;
for ( std : : map < cmStdString , cmTarget > : : const_iterator target = targets . begin ( ) ;
target ! = targets . end ( ) ; + + target )
{
bool shared = ( ( target - > second . GetType ( ) = = cmTarget : : SHARED_LIBRARY ) | |
2002-10-10 18:43:59 +04:00
( target - > second . GetType ( ) = = cmTarget : : MODULE_LIBRARY ) ) ;
2002-08-31 00:01:48 +04:00
std : : string exportsDef = " " ;
if ( shared )
{
2003-02-07 22:04:16 +03:00
std : : string export_symbol ;
if ( const char * custom_export_name = target - > second . GetProperty ( " DEFINE_SYMBOL " ) )
{
export_symbol = custom_export_name ;
}
else
{
std : : string in = target - > first + " _EXPORTS " ;
export_symbol = cmSystemTools : : MakeCindentifier ( in . c_str ( ) ) ;
}
exportsDef = " -D " + export_symbol ;
2002-08-31 00:01:48 +04:00
}
// Iterate over every source for this target.
2003-06-03 18:30:23 +04:00
const std : : vector < cmSourceFile * > & sources =
target - > second . GetSourceFiles ( ) ;
2002-08-31 00:01:48 +04:00
for ( std : : vector < cmSourceFile * > : : const_iterator source = sources . begin ( ) ;
source ! = sources . end ( ) ; + + source )
{
2003-06-03 18:30:23 +04:00
if ( ! ( * source ) - > GetPropertyAsBool ( " HEADER_FILE_ONLY " ) & &
! ( * source ) - > GetCustomCommand ( ) )
2002-08-31 00:01:48 +04:00
{
std : : string shortName ;
std : : string sourceName ;
// If the full path to the source file includes this
// directory, we want to use the relative path for the
// filename of the object file. Otherwise, we will use just
// the filename portion.
2003-06-03 18:30:23 +04:00
if ( ( cmSystemTools : : GetFilenamePath (
( * source ) - > GetFullPath ( ) ) . find (
m_Makefile - > GetCurrentDirectory ( ) ) = = 0 )
| | ( cmSystemTools : : GetFilenamePath (
( * source ) - > GetFullPath ( ) ) . find (
m_Makefile - > GetCurrentOutputDirectory ( ) ) = = 0 ) )
2002-08-31 00:01:48 +04:00
{
2003-06-03 18:30:23 +04:00
sourceName = ( * source ) - > GetSourceName ( ) + " . " +
( * source ) - > GetSourceExtension ( ) ;
2002-08-31 00:01:48 +04:00
shortName = ( * source ) - > GetSourceName ( ) ;
// The path may be relative. See if a directory needs to be
// created for the output file. This is a ugly, and perhaps
// should be moved elsewhere.
std : : string relPath =
cmSystemTools : : GetFilenamePath ( ( * source ) - > GetSourceName ( ) ) ;
if ( relPath ! = " " )
{
std : : string outPath = m_Makefile - > GetCurrentOutputDirectory ( ) ;
outPath + = " / " + relPath ;
cmSystemTools : : MakeDirectory ( outPath . c_str ( ) ) ;
}
}
else
{
sourceName = ( * source ) - > GetFullPath ( ) ;
shortName = cmSystemTools : : GetFilenameName ( ( * source ) - > GetSourceName ( ) ) ;
}
std : : string shortNameWithExt = shortName +
( * source ) - > GetSourceExtension ( ) ;
// Only output a rule for each .o once.
2002-12-02 18:33:35 +03:00
std : : string compileFlags = exportsDef ;
compileFlags + = " " ;
2002-08-31 00:01:48 +04:00
if ( rules . find ( shortNameWithExt ) = = rules . end ( ) )
{
2002-12-02 18:33:35 +03:00
2002-08-31 00:01:48 +04:00
if ( ( * source ) - > GetProperty ( " COMPILE_FLAGS " ) )
{
2002-12-02 18:33:35 +03:00
compileFlags + = ( * source ) - > GetProperty ( " COMPILE_FLAGS " ) ;
2002-12-02 21:18:38 +03:00
compileFlags + = " " ;
2002-08-31 00:01:48 +04:00
}
this - > OutputBuildObjectFromSource ( fout ,
shortName . c_str ( ) ,
* ( * source ) ,
2002-12-02 18:33:35 +03:00
compileFlags . c_str ( ) ,
2002-08-31 00:01:48 +04:00
shared ) ;
rules . insert ( shortNameWithExt ) ;
}
}
}
}
}
2002-11-08 23:46:08 +03:00
2002-08-31 00:01:48 +04:00
void cmLocalUnixMakefileGenerator : : OutputMakeRule ( std : : ostream & fout ,
2002-11-08 23:46:08 +03:00
const char * comment ,
const char * target ,
const char * depends ,
const char * command ,
const char * command2 ,
const char * command3 ,
const char * command4 )
{
std : : vector < std : : string > commands ;
if ( command )
{
commands . push_back ( command ) ;
}
if ( command2 )
{
commands . push_back ( command2 ) ;
}
if ( command3 )
{
commands . push_back ( command3 ) ;
}
if ( command4 )
{
commands . push_back ( command4 ) ;
}
this - > OutputMakeRule ( fout , comment , target , depends , commands ) ;
}
void cmLocalUnixMakefileGenerator : : OutputMakeRule ( std : : ostream & fout ,
const char * comment ,
const char * target ,
const char * depends ,
const std : : vector < std : : string > & commands )
2002-12-14 00:16:48 +03:00
{
std : : vector < std : : string > depend ;
if ( depends )
{
depend . push_back ( depends ) ;
}
this - > OutputMakeRule ( fout , comment , target , depend , commands ) ;
}
2003-08-07 19:42:02 +04:00
void cmLocalUnixMakefileGenerator : : OutputMakeRule ( std : : ostream & fout ,
const char * comment ,
const char * target ,
const std : : vector < std : : string > & depends ,
const char * command )
{
std : : vector < std : : string > commands ;
if ( command )
{
commands . push_back ( command ) ;
}
this - > OutputMakeRule ( fout , comment , target , depends , commands ) ;
}
2002-12-14 00:16:48 +03:00
void cmLocalUnixMakefileGenerator : : OutputMakeRule ( std : : ostream & fout ,
const char * comment ,
const char * target ,
const std : : vector < std : : string > & depends ,
const std : : vector < std : : string > & commands )
2002-08-31 00:01:48 +04:00
{
if ( ! target )
{
cmSystemTools : : Error ( " no target for OutputMakeRule " ) ;
return ;
}
std : : string replace ;
if ( comment )
{
replace = comment ;
m_Makefile - > ExpandVariablesInString ( replace ) ;
fout < < " #--------------------------------------------------------- \n " ;
fout < < " # " < < replace ;
fout < < " \n # \n " ;
}
fout < < " \n " ;
replace = target ;
m_Makefile - > ExpandVariablesInString ( replace ) ;
2003-08-01 23:33:59 +04:00
2003-12-22 23:16:46 +03:00
std : : string tgt = this - > ConvertToRelativeOutputPath ( replace . c_str ( ) ) ;
2004-01-23 17:54:50 +03:00
tgt = this - > ConvertToMakeTarget ( tgt . c_str ( ) ) ;
2004-10-27 16:49:41 +04:00
const char * space = " " ;
if ( tgt . size ( ) = = 1 )
{
// Add a space before the ":" to avoid drive letter confusion on
// Windows.
space = " " ;
}
2003-08-06 01:39:50 +04:00
if ( depends . empty ( ) )
2003-08-01 23:33:59 +04:00
{
2004-10-27 16:49:41 +04:00
fout < < tgt . c_str ( ) < < space < < " : \n " ;
2003-08-01 23:33:59 +04:00
}
else
2002-08-31 00:01:48 +04:00
{
2003-08-06 01:39:50 +04:00
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists.
2003-08-01 23:33:59 +04:00
for ( std : : vector < std : : string > : : const_iterator dep = depends . begin ( ) ;
dep ! = depends . end ( ) ; + + dep )
{
replace = * dep ;
m_Makefile - > ExpandVariablesInString ( replace ) ;
2004-01-23 17:54:50 +03:00
replace = this - > ConvertToMakeTarget ( replace . c_str ( ) ) ;
2004-10-27 16:49:41 +04:00
fout < < tgt . c_str ( ) < < space < < " : " < < replace . c_str ( ) < < " \n " ;
2003-08-01 23:33:59 +04:00
}
2002-08-31 00:01:48 +04:00
}
2003-08-06 01:39:50 +04:00
2002-11-08 23:46:08 +03:00
int count = 0 ;
for ( std : : vector < std : : string > : : const_iterator i = commands . begin ( ) ;
i ! = commands . end ( ) ; + + i )
2002-08-31 00:01:48 +04:00
{
2002-11-08 23:46:08 +03:00
replace = * i ;
m_Makefile - > ExpandVariablesInString ( replace ) ;
2002-12-11 00:47:37 +03:00
if ( count = = 0 & & replace . find_first_not_of ( " \t \n \r " ) ! = std : : string : : npos & &
replace [ 0 ] ! = ' - ' & & replace . find ( " echo " ) ! = 0
2002-11-08 23:46:08 +03:00
& & replace . find ( " $(MAKE) " ) ! = 0 )
2002-08-31 00:01:48 +04:00
{
2002-11-08 23:46:08 +03:00
std : : string echostring = " Building " ;
echostring + = comment ;
echostring + = " " ;
echostring + = target ;
echostring + = " ... " ;
2003-08-05 16:49:23 +04:00
this - > OutputEcho ( fout , echostring . c_str ( ) ) ;
2002-08-31 00:01:48 +04:00
}
2002-11-08 23:46:08 +03:00
fout < < " \t " < < replace . c_str ( ) < < " \n " ;
count + + ;
2002-08-31 00:01:48 +04:00
}
fout < < " \n " ;
}
2002-11-08 23:46:08 +03:00
std : : string cmLocalUnixMakefileGenerator : : LowerCasePath ( const char * path )
{
# ifdef _WIN32
return cmSystemTools : : LowerCase ( path ) ;
# else
return std : : string ( path ) ;
# endif
}
2004-04-28 18:15:40 +04:00
std : : string &
cmLocalUnixMakefileGenerator : : CreateSafeUniqueObjectFileName ( const char * sin )
{
2004-05-04 19:24:32 +04:00
if ( m_Makefile - > IsOn ( " CMAKE_MANGLE_OBJECT_FILE_NAMES " ) )
{
std : : map < cmStdString , cmStdString > : : iterator it = m_UniqueObjectNamesMap . find ( sin ) ;
if ( it = = m_UniqueObjectNamesMap . end ( ) )
{
std : : string ssin = sin ;
bool done ;
int cc = 0 ;
char rpstr [ 100 ] ;
sprintf ( rpstr , " _p_ " ) ;
cmSystemTools : : ReplaceString ( ssin , " + " , rpstr ) ;
std : : string sssin = sin ;
do
2004-04-28 18:15:40 +04:00
{
2004-05-04 19:24:32 +04:00
done = true ;
for ( it = m_UniqueObjectNamesMap . begin ( ) ;
it ! = m_UniqueObjectNamesMap . end ( ) ;
+ + it )
2004-04-28 18:15:40 +04:00
{
2004-05-04 19:24:32 +04:00
if ( it - > second = = ssin )
{
done = false ;
}
2004-04-28 18:15:40 +04:00
}
2004-05-04 19:24:32 +04:00
if ( done )
{
break ;
}
sssin = ssin ;
cmSystemTools : : ReplaceString ( ssin , " _p_ " , rpstr ) ;
sprintf ( rpstr , " _p%d_ " , cc + + ) ;
2004-04-28 18:15:40 +04:00
}
2004-05-04 19:24:32 +04:00
while ( ! done ) ;
m_UniqueObjectNamesMap [ sin ] = ssin ;
2004-04-28 18:15:40 +04:00
}
2004-05-04 19:24:32 +04:00
}
else
{
m_UniqueObjectNamesMap [ sin ] = sin ;
2004-04-28 18:15:40 +04:00
}
return m_UniqueObjectNamesMap [ sin ] ;
}
2002-11-08 23:46:08 +03:00
std : : string
2003-08-01 22:34:51 +04:00
cmLocalUnixMakefileGenerator : : CreateMakeVariable ( const char * sin , const char * s2in )
2002-11-08 23:46:08 +03:00
{
2003-08-01 22:34:51 +04:00
std : : string s = sin ;
std : : string s2 = s2in ;
2002-11-08 23:46:08 +03:00
std : : string unmodified = s ;
unmodified + = s2 ;
2003-08-01 22:34:51 +04:00
// if there is no restriction on the length of make variables
// and there are no "." charactors in the string, then return the
// unmodified combination.
if ( ! m_MakefileVariableSize & & unmodified . find ( ' . ' ) = = s . npos )
{
return unmodified ;
}
// see if the variable has been defined before and return
// the modified version of the variable
2002-11-08 23:46:08 +03:00
std : : map < cmStdString , cmStdString > : : iterator i = m_MakeVariableMap . find ( unmodified ) ;
if ( i ! = m_MakeVariableMap . end ( ) )
{
return i - > second ;
}
2003-08-01 22:34:51 +04:00
// start with the unmodified variable
2002-11-08 23:46:08 +03:00
std : : string ret = unmodified ;
2003-08-01 22:34:51 +04:00
// if this there is no value for m_MakefileVariableSize then
// the string must have bad characters in it
if ( ! m_MakefileVariableSize )
{
cmSystemTools : : ReplaceString ( ret , " . " , " _ " ) ;
int ni = 0 ;
char buffer [ 5 ] ;
// make sure the _ version is not already used, if
// it is used then add number to the end of the variable
while ( m_ShortMakeVariableMap . count ( ret ) & & ni < 1000 )
{
+ + ni ;
sprintf ( buffer , " %04d " , ni ) ;
ret = unmodified + buffer ;
}
m_ShortMakeVariableMap [ ret ] = " 1 " ;
m_MakeVariableMap [ unmodified ] = ret ;
return ret ;
}
2002-11-08 23:46:08 +03:00
// if the string is greater the 32 chars it is an invalid vairable name
// for borland make
2002-11-18 01:31:12 +03:00
if ( static_cast < int > ( ret . size ( ) ) > m_MakefileVariableSize )
2002-11-08 23:46:08 +03:00
{
int keep = m_MakefileVariableSize - 8 ;
int size = keep + 3 ;
std : : string str1 = s ;
std : : string str2 = s2 ;
// we must shorten the combined string by 4 charactors
// keep no more than 24 charactors from the second string
2002-11-18 01:31:12 +03:00
if ( static_cast < int > ( str2 . size ( ) ) > keep )
2002-11-08 23:46:08 +03:00
{
str2 = str2 . substr ( 0 , keep ) ;
}
2002-11-18 01:31:12 +03:00
if ( static_cast < int > ( str1 . size ( ) ) + static_cast < int > ( str2 . size ( ) ) > size )
2002-11-08 23:46:08 +03:00
{
str1 = str1 . substr ( 0 , size - str2 . size ( ) ) ;
}
char buffer [ 5 ] ;
2002-12-09 06:34:17 +03:00
int ni = 0 ;
sprintf ( buffer , " %04d " , ni ) ;
2002-11-08 23:46:08 +03:00
ret = str1 + str2 + buffer ;
2002-12-09 06:34:17 +03:00
while ( m_ShortMakeVariableMap . count ( ret ) & & ni < 1000 )
2002-11-08 23:46:08 +03:00
{
2002-12-09 06:34:17 +03:00
+ + ni ;
sprintf ( buffer , " %04d " , ni ) ;
2002-11-08 23:46:08 +03:00
ret = str1 + str2 + buffer ;
}
2002-12-09 06:34:17 +03:00
if ( ni = = 1000 )
2002-11-08 23:46:08 +03:00
{
2003-02-14 17:54:15 +03:00
cmSystemTools : : Error ( " Borland makefile variable length too long " ) ;
2002-11-08 23:46:08 +03:00
return unmodified ;
}
// once an unused variable is found
m_ShortMakeVariableMap [ ret ] = " 1 " ;
}
2003-02-14 17:54:15 +03:00
// always make an entry into the unmodified to variable map
2002-11-08 23:46:08 +03:00
m_MakeVariableMap [ unmodified ] = ret ;
return ret ;
}
2003-11-27 01:38:37 +03:00
void cmLocalUnixMakefileGenerator : : GetLibraryNames ( const char * n ,
const cmTarget & t ,
std : : string & name ,
std : : string & soName ,
std : : string & realName ,
std : : string & baseName )
{
// Check for library version properties.
const char * version = t . GetProperty ( " VERSION " ) ;
const char * soversion = t . GetProperty ( " SOVERSION " ) ;
if ( ( t . GetType ( ) ! = cmTarget : : SHARED_LIBRARY & &
t . GetType ( ) ! = cmTarget : : MODULE_LIBRARY ) | |
2003-12-12 22:35:18 +03:00
! m_Makefile - > GetDefinition ( " CMAKE_SHARED_LIBRARY_SONAME_C_FLAG " ) )
2003-11-27 01:38:37 +03:00
{
// Versioning is supported only for shared libraries and modules,
// and then only when the platform supports an soname flag.
version = 0 ;
soversion = 0 ;
}
if ( version & & ! soversion )
{
// The soversion must be set if the library version is set. Use
// the library version as the soversion.
soversion = version ;
}
// The library name.
name = this - > GetFullTargetName ( n , t ) ;
// The library's soname.
soName = name ;
if ( soversion )
{
soName + = " . " ;
soName + = soversion ;
}
// The library's real name on disk.
realName = name ;
if ( version )
{
realName + = " . " ;
realName + = version ;
}
else if ( soversion )
{
realName + = " . " ;
realName + = soversion ;
}
// The library name without extension.
baseName = this - > GetBaseTargetName ( n , t ) ;
}
2003-12-22 20:24:26 +03:00
2004-01-23 17:54:50 +03:00
std : : string cmLocalUnixMakefileGenerator : : ConvertToMakeTarget ( const char * tgt )
{
// Make targets should not have a leading './' for a file in the
// directory containing the makefile.
std : : string ret = tgt ;
if ( ret . size ( ) > 2 & &
( ret [ 0 ] = = ' . ' ) & &
( ( ret [ 1 ] = = ' / ' ) | | ret [ 1 ] = = ' \\ ' ) )
{
std : : string upath = ret ;
cmSystemTools : : ConvertToUnixSlashes ( upath ) ;
if ( upath . find ( 2 , ' / ' ) = = upath . npos )
{
ret = ret . substr ( 2 , ret . size ( ) - 2 ) ;
}
}
return ret ;
}