You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
8.3 KiB
276 lines
8.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "stdafx.h" |
|
#include "makefilecreator.h" |
|
#include "cmdlib.h" |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: constructor |
|
//----------------------------------------------------------------------------- |
|
CMakefileCreator::CMakefileCreator() { |
|
m_FileToBaseDirMapping.SetLessFunc( DefLessFunc( int ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: destructor |
|
//----------------------------------------------------------------------------- |
|
CMakefileCreator::~CMakefileCreator() |
|
{ |
|
} |
|
|
|
void CMakefileCreator::CreateMakefiles( CVCProjConvert & proj ) |
|
{ |
|
m_ProjName = proj.GetName(); |
|
m_BaseDir = proj.GetBaseDir(); |
|
for ( int i = 0; i < proj.GetNumConfigurations(); i++ ) |
|
{ |
|
m_FileToBaseDirMapping.RemoveAll(); |
|
m_BuildDirectories.RemoveAll(); |
|
m_BaseDirs.RemoveAll(); |
|
|
|
CreateMakefileName( proj.GetName().String(), proj.GetConfiguration(i) ); |
|
CreateBaseDirs( proj.GetConfiguration(i) ); |
|
FileHandle_t f = g_pFileSystem->Open( m_MakefileName.String(), "w+" ); |
|
if ( !f ) |
|
{ |
|
Warning( "failed to open %s for writing.\n", m_MakefileName.String() ); |
|
continue; |
|
} |
|
OutputDirs(f); |
|
OutputIncludes( proj.GetConfiguration(i), f ); |
|
OutputObjLists( proj.GetConfiguration(i), f ); |
|
OutputMainBuilder(f); |
|
OutputBuildTarget(f); |
|
g_pFileSystem->Close(f); |
|
} |
|
} |
|
|
|
|
|
void CMakefileCreator::CreateBaseDirs( CVCProjConvert::CConfiguration & config ) |
|
{ |
|
// m_BaseDirs.Insert( "" ); |
|
for ( int i = 0; i < config.GetNumFileNames(); i++ ) |
|
{ |
|
if ( config.GetFileType(i) == CVCProjConvert::CConfiguration::FILE_SOURCE ) |
|
{ |
|
char basedir[ MAX_PATH ]; |
|
char fulldir[ MAX_PATH ]; |
|
Q_snprintf( fulldir, sizeof(fulldir), "%s/%s", m_BaseDir.String(), config.GetFileName(i) ); |
|
if ( Q_ExtractFilePath( fulldir, basedir, sizeof(basedir) ) ) |
|
{ |
|
Q_FixSlashes( basedir ); |
|
Q_StripTrailingSlash( basedir ); |
|
int index = m_BaseDirs.Find( basedir ); |
|
if ( index == m_BaseDirs.InvalidIndex() ) |
|
{ |
|
index = m_BaseDirs.Insert( basedir ); |
|
} |
|
m_FileToBaseDirMapping.Insert(i, index ); |
|
} |
|
else |
|
{ |
|
m_FileToBaseDirMapping.Insert(i, 0 ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
void CMakefileCreator::CleanupFileName( char *name ) |
|
{ |
|
for ( int i = Q_strlen( name ) - 1; i >= 0; --i ) |
|
{ |
|
if ( name[i] == ' ' || name[i] == '|' || name[i] == '\\' || name[i] == '/' || ( name[i] == '.' && i>=1 && name[i-1] == '.' )) |
|
{ |
|
Q_memmove( &name[i], &name[i+1], Q_strlen( name ) - i - 1 ); |
|
name[ Q_strlen( name ) - 1 ] = 0; |
|
} |
|
} |
|
} |
|
|
|
void CMakefileCreator::CreateMakefileName( const char *projectName, CVCProjConvert::CConfiguration & config ) |
|
{ |
|
char makefileName[ MAX_PATH ]; |
|
Q_snprintf( makefileName, sizeof(makefileName), "Makefile.%s_%s", projectName, config.GetName().String() ); |
|
CleanupFileName( makefileName ); |
|
m_MakefileName = makefileName; |
|
} |
|
|
|
void CMakefileCreator::CreateDirectoryFriendlyName( const char *dirName, char *friendlyDirName, int friendlyDirNameSize ) |
|
{ |
|
Q_strncpy( friendlyDirName, dirName, friendlyDirNameSize ); |
|
|
|
int i; |
|
for ( i = Q_strlen( friendlyDirName ) - 1; i >= 0; --i ) |
|
{ |
|
if ( friendlyDirName[i] == '/' || friendlyDirName[i] == '\\' ) |
|
{ |
|
friendlyDirName[i] = '_'; |
|
} |
|
if ( isalpha( friendlyDirName[i] ) ) |
|
{ |
|
friendlyDirName[i] = toupper(friendlyDirName[i]); |
|
} |
|
if ( friendlyDirName[i] == '.' ) |
|
{ |
|
Q_memmove( &friendlyDirName[i], &friendlyDirName[i+1], Q_strlen( friendlyDirName ) - i - 1 ); |
|
friendlyDirName[ Q_strlen( friendlyDirName ) - 1 ] = 0; |
|
} |
|
} |
|
|
|
// strip any leading/trailing underscores |
|
while ( friendlyDirName[0] == '_' && Q_strlen(friendlyDirName)>0 ) |
|
{ |
|
Q_memmove( &friendlyDirName[0], &friendlyDirName[1], Q_strlen( friendlyDirName )- 1 ); |
|
friendlyDirName[ Q_strlen( friendlyDirName ) - 1 ] = 0; |
|
} |
|
while ( Q_strlen(friendlyDirName)>0 && friendlyDirName[Q_strlen(friendlyDirName)-1] == '_' ) |
|
{ |
|
friendlyDirName[ Q_strlen( friendlyDirName ) - 1 ] = 0; |
|
} |
|
|
|
CleanupFileName( friendlyDirName ); |
|
} |
|
|
|
void CMakefileCreator::CreateObjDirectoryFriendlyName ( char *name ) |
|
{ |
|
#ifdef _WIN32 |
|
char *updir = "..\\"; |
|
#else |
|
char *updir = "../"; |
|
#endif |
|
|
|
char *sep = Q_strstr( name, updir ); |
|
while ( sep ) |
|
{ |
|
Q_strcpy( sep, sep + strlen(updir) ); |
|
sep = Q_strstr( sep, updir ); |
|
} |
|
} |
|
|
|
void CMakefileCreator::FileWrite( FileHandle_t f, const char *fmt, ... ) |
|
{ |
|
va_list args; |
|
va_start(args, fmt); |
|
char stringBuf[ 4096 ]; |
|
Q_vsnprintf( stringBuf, sizeof(stringBuf), fmt, args ); |
|
va_end(args); |
|
g_pFileSystem->Write( stringBuf, Q_strlen(stringBuf), f ); |
|
} |
|
|
|
void CMakefileCreator::OutputIncludes( CVCProjConvert::CConfiguration & config, FileHandle_t f ) |
|
{ |
|
FileWrite( f, "INCLUDES=" ); |
|
for ( int i = 0; i < config.GetNumIncludes(); i++ ) |
|
{ |
|
FileWrite( f, "-I%s ", config.GetInclude(i) ); |
|
} |
|
|
|
for ( int i = 0; i < config.GetNumDefines(); i++ ) |
|
{ |
|
FileWrite( f, "-D%s ", config.GetDefine(i) ); |
|
} |
|
FileWrite( f, "\n\n" ); |
|
} |
|
|
|
void CMakefileCreator::OutputDirs( FileHandle_t f ) |
|
{ |
|
for ( int i = m_BaseDirs.First(); i != m_BaseDirs.InvalidIndex(); i = m_BaseDirs.Next(i) ) |
|
{ |
|
const char *dirName = m_BaseDirs.GetElementName(i); |
|
if ( !dirName || !Q_strlen(dirName) ) |
|
{ |
|
dirName = m_BaseDir.String(); |
|
} |
|
|
|
char friendlyDirName[ MAX_PATH ]; |
|
CreateDirectoryFriendlyName( dirName, friendlyDirName, sizeof(friendlyDirName) ); |
|
int dirLen = Q_strlen(friendlyDirName); |
|
Q_strncat( friendlyDirName, "_SRC_DIR", sizeof(friendlyDirName), COPY_ALL_CHARACTERS ); |
|
struct OutputDirMapping_t dirs; |
|
dirs.m_SrcDir = friendlyDirName; |
|
dirs.m_iBaseDirIndex = i; |
|
friendlyDirName[ dirLen ] = 0; |
|
Q_strncat( friendlyDirName, "_OBJ_DIR", sizeof(friendlyDirName), COPY_ALL_CHARACTERS ); |
|
dirs.m_ObjDir = friendlyDirName; |
|
friendlyDirName[ dirLen ] = 0; |
|
Q_strncat( friendlyDirName, "_OBJS", sizeof(friendlyDirName), COPY_ALL_CHARACTERS ); |
|
dirs.m_ObjName = friendlyDirName; |
|
|
|
char objDirName[ MAX_PATH ]; |
|
Q_snprintf( objDirName, sizeof(objDirName) , "obj%c$(NAME)_$(ARCH)%c", CORRECT_PATH_SEPARATOR, CORRECT_PATH_SEPARATOR ); |
|
Q_strncat( objDirName, dirName, sizeof(objDirName), COPY_ALL_CHARACTERS ); |
|
CreateObjDirectoryFriendlyName( objDirName ); |
|
dirs.m_ObjOutputDir = objDirName; |
|
|
|
m_BuildDirectories.AddToTail( dirs ); |
|
|
|
FileWrite( f, "%s=%s\n", dirs.m_SrcDir.String(), dirName ); |
|
FileWrite( f, "%s=%s\n", dirs.m_ObjDir.String(), objDirName ); |
|
} |
|
FileWrite( f, "\n\n" ); |
|
} |
|
|
|
void CMakefileCreator::OutputMainBuilder( FileHandle_t f ) |
|
{ |
|
int i; |
|
FileWrite( f, "\n\nall: dirs $(NAME)_$(ARCH).$(SHLIBEXT)\n\n" ); |
|
FileWrite( f, "dirs:\n" ); |
|
for ( i = 0; i < m_BuildDirectories.Count(); i++ ) |
|
{ |
|
FileWrite( f, "\t-mkdir -p $(%s)\n", m_BuildDirectories[i].m_ObjDir.String() ); |
|
} |
|
FileWrite( f, "\n\n" ); |
|
|
|
|
|
FileWrite( f, "\n\n$(NAME)_$(ARCH).$(SHLIBEXT): " ); |
|
for ( i = 0; i < m_BuildDirectories.Count(); i++ ) |
|
{ |
|
FileWrite( f, "$(%s) ", m_BuildDirectories[i].m_ObjName.String() ); |
|
} |
|
FileWrite( f, "\n\t$(CLINK) $(SHLIBLDFLAGS) $(DEBUG) -o $(BUILD_DIR)/$@ " ); |
|
for ( i = 0; i < m_BuildDirectories.Count(); i++ ) |
|
{ |
|
FileWrite( f, "$(%s) ", m_BuildDirectories[i].m_ObjName.String() ); |
|
} |
|
FileWrite( f, "$(LDFLAGS) $(CPP_LIB)\n\n" ); |
|
} |
|
|
|
void CMakefileCreator::OutputObjLists( CVCProjConvert::CConfiguration & config, FileHandle_t f ) |
|
{ |
|
for ( int buildDirIndex = 0; buildDirIndex < m_BuildDirectories.Count(); buildDirIndex++ ) |
|
{ |
|
struct OutputDirMapping_t & dirs = m_BuildDirectories[buildDirIndex]; |
|
FileWrite( f, "%s= \\\n", dirs.m_ObjName.String() ); |
|
|
|
for ( int j = m_FileToBaseDirMapping.FirstInorder(); j != m_FileToBaseDirMapping.InvalidIndex(); j = m_FileToBaseDirMapping.NextInorder(j) ) |
|
{ |
|
if ( dirs.m_iBaseDirIndex == m_FileToBaseDirMapping[j] ) |
|
{ |
|
char baseName[ MAX_PATH ]; |
|
const char *fileName = config.GetFileName(m_FileToBaseDirMapping.Key(j)); |
|
Q_FileBase( fileName, baseName, sizeof(baseName) ); |
|
Q_SetExtension( baseName, ".o", sizeof(baseName) ); |
|
|
|
FileWrite( f, "\t$(%s)/%s \\\n", dirs.m_ObjDir.String(), baseName ); |
|
} |
|
} |
|
FileWrite( f, "\n\n" ); |
|
} |
|
|
|
} |
|
|
|
void CMakefileCreator::OutputBuildTarget( FileHandle_t f ) |
|
{ |
|
for( int i = 0; i < m_BuildDirectories.Count(); i++ ) |
|
{ |
|
struct OutputDirMapping_t & dirs = m_BuildDirectories[i]; |
|
FileWrite( f, "$(%s)/%%.o: $(%s)/%%.cpp\n", dirs.m_ObjDir.String(), dirs.m_SrcDir.String() ); |
|
FileWrite( f, "\t$(DO_CC)\n\n"); |
|
} |
|
|
|
} |
|
|
|
|