|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// valvelibaw.cpp : implementation file
//
#include "stdafx.h"
#include "valvelib.h"
#include "valvelibaw.h"
#include "chooser.h"
#include <assert.h>
#include<atlbase.h>
extern CComModule _Module; #include <atlcom.h>
#include <initguid.h>
#include<comdef.h>
#ifdef _PSEUDO_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#define STUPID_MS_BUG 1
enum Config_t { CONFIG_DEBUG = 0, CONFIG_RELEASE };
enum Project_t { PROJECT_LIB = 0, PROJECT_DLL, PROJECT_EXE };
struct ProjectInfo_t { DSProjectSystem::IConfigurationPtr m_pConfig; long m_ConfigIndex; Config_t m_Config; Project_t m_Project; CString m_RelativeTargetPath; CString m_RelativeImplibPath; CString m_RelativeRootPath; CString m_RelativeSrcPath; CString m_TargetPath; CString m_RootName; CString m_BuildName; CString m_Ext; bool m_Tool; bool m_Console; bool m_Public; bool m_PublishImportLib; };
// This is called immediately after the custom AppWizard is loaded. Initialize
// the state of the custom AppWizard here.
void CValvelibAppWiz::InitCustomAppWiz() { // Create a new dialog chooser; CDialogChooser's constructor initializes
// its internal array with pointers to the steps.
m_pChooser = new CDialogChooser;
// Set the maximum number of steps.
SetNumberOfSteps(LAST_DLG);
// TODO: Add any other custom AppWizard-wide initialization here.
}
// This is called just before the custom AppWizard is unloaded.
void CValvelibAppWiz::ExitCustomAppWiz() { // Deallocate memory used for the dialog chooser
ASSERT(m_pChooser != NULL); delete m_pChooser; m_pChooser = NULL;
// TODO: Add code here to deallocate resources used by the custom AppWizard
}
// This is called when the user clicks "Create..." on the New Project dialog
// or "Next" on one of the custom AppWizard's steps.
CAppWizStepDlg* CValvelibAppWiz::Next(CAppWizStepDlg* pDlg) { // Delegate to the dialog chooser
return m_pChooser->Next(pDlg); }
// This is called when the user clicks "Back" on one of the custom
// AppWizard's steps.
CAppWizStepDlg* CValvelibAppWiz::Back(CAppWizStepDlg* pDlg) { // Delegate to the dialog chooser
return m_pChooser->Back(pDlg); }
//-----------------------------------------------------------------------------
// Deals with compiler settings
//-----------------------------------------------------------------------------
static void SetupCompilerSettings(ProjectInfo_t& info) { _bstr_t varTool; _bstr_t varSwitch; _variant_t varj = info.m_ConfigIndex;
// We're going to modify settings associated with cl.exe
varTool = "cl.exe";
// Standard include directories
CString includePath; if (info.m_Public) { includePath.Format("/I%spublic", info.m_RelativeSrcPath, info.m_RelativeSrcPath );
info.m_pConfig->AddToolSettings(varTool, (char const*)includePath, varj); }
// Control which version of the debug libraries to use (static single thread
// for normal projects, multithread for tools)
if (info.m_Tool) { if (info.m_Config == CONFIG_DEBUG) varSwitch = "/MTd"; else varSwitch = "/MT"; } else { // Suppress use of non-filesystem stuff in new non-tool projects...
if (info.m_Config == CONFIG_DEBUG) varSwitch = "/D \"fopen=dont_use_fopen\" /MTd"; else varSwitch = "/D \"fopen=dont_use_fopen\" /MT"; } info.m_pConfig->AddToolSettings(varTool, varSwitch, varj);
// If it's a DLL, define a standard exports macro...
if (info.m_Project == PROJECT_DLL) { CString dllExport; dllExport.Format("/D \"%s_DLL_EXPORT\"", info.m_RootName ); dllExport.MakeUpper(); info.m_pConfig->AddToolSettings(varTool, (char const*)dllExport, varj); }
// /W4 - Warning level 4
// /FD - Generates file dependencies
// /G6 - optimize for pentium pro
// Add _WIN32, as that's what all our other code uses
varSwitch = "/W4 /FD /G6 /D \"_WIN32\""; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj);
// Remove Preprocessor def for MFC DLL specifier, _AFXDLL
// /GX - No exceptions,
// /YX - no precompiled headers
// Remove WIN32, it's put there by default
varSwitch = "/D \"_AFXDLL\" /GX /YX /D \"WIN32\""; info.m_pConfig->RemoveToolSettings(varTool, varSwitch, varj);
switch (info.m_Config) { case CONFIG_DEBUG: // Remove the following switches (avoid duplicates, in addition to other things)
varSwitch = "/D \"NDEBUG\" /Zi /ZI /GZ"; info.m_pConfig->RemoveToolSettings(varTool, varSwitch, varj);
// Add the following switches:
// /ZI - Includes debug information in a program database compatible with Edit and Continue.
// /Zi - Includes debug information in a program database (no Edit and Continue)
// /Od - Disable optimization
// /GZ - Catch release build problems (uninitialized variables, fp stack problems)
// /Op - Improves floating-point consistency
// /Gm - Minimal rebuild
// /FR - Generate Browse Info
varSwitch = "/D \"_DEBUG\" /Od /GZ /Op /Gm /FR\"Debug/\""; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj);
if (info.m_Project == PROJECT_LIB) { // Static libraries cannot use edit-and-continue, why compile it in?
varSwitch = "/Zi"; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj); } else { varSwitch = "/ZI"; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj); } break;
case CONFIG_RELEASE: // Remove the following switches:
// /Zi - Generates complete debugging information
// /ZI - Includes debug information in a program database compatible with Edit and Continue.
// /Gm - Minimal rebuild
// /GZ - Catch release build problems (uninitialized variables, fp stack problems)
varSwitch = "/D \"_DEBUG\" /Gm /Zi /ZI /GZ"; info.m_pConfig->RemoveToolSettings(varTool, varSwitch, varj);
// Add the following switches:
// /Ox - Uses maximum optimization (/Ob1gity /Gs)
// /Ow - Assumes aliasing across function calls
// /Op - Improves floating-point consistency
// /Gf - String pooling
// /Oi - Generates intrinsic functions
// /Ot - Favors fast code
// /Og - Uses global optimizations
// /Gy - Enable function level linking
varSwitch = "/D \"NDEBUG\" /Ox /Ow /Op /Oi /Ot /Og /Gf /Gy"; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj); break; } }
//-----------------------------------------------------------------------------
// Deals with resource compiler
//-----------------------------------------------------------------------------
static void SetupResourceCompilerSettings(ProjectInfo_t& info) { _bstr_t varTool; _bstr_t varSwitch; _variant_t varj = info.m_ConfigIndex;
// Remove Preprocessor def for MFC DLL specifier, _AFXDLL
varTool = "rc.exe"; varSwitch = "/d \"_AFXDLL\""; info.m_pConfig->RemoveToolSettings(varTool, varSwitch, varj); }
//-----------------------------------------------------------------------------
// Deals with linker settings
//-----------------------------------------------------------------------------
static void SetupLinkerSettings(ProjectInfo_t& info) { _bstr_t varTool; _bstr_t varSwitch; _variant_t varj = info.m_ConfigIndex;
// We're going to modify settings associated with cl.exe
varTool = "link.exe";
// Remove windows libraries by default... hopefully we don't have windows dependencies
varSwitch = "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib"; info.m_pConfig->RemoveToolSettings(varTool, varSwitch, varj);
// Add libraries we always want to use
varSwitch = "tier0.lib"; info.m_pConfig->AddToolSettings(varTool, varSwitch, varj); // Hook in the static library path
CString libPath;
// FIXME: Still haven't decided on build-specific publish dir
if (info.m_Public) { libPath.Format( "/libpath:\"%slib\\common\\\" /libpath:\"%slib\\public\\\"", info.m_RelativeSrcPath, info.m_RelativeSrcPath ); } else { libPath.Format( "/libpath:\"%slib\\common\\\"", info.m_RelativeSrcPath ); }
info.m_pConfig->AddToolSettings(varTool, (char const*)libPath, varj); }
//-----------------------------------------------------------------------------
// Deals with lib settings
//-----------------------------------------------------------------------------
static void SetupLibSettings(ProjectInfo_t& info) { }
//-----------------------------------------------------------------------------
// Deals with custom build steps
//-----------------------------------------------------------------------------
static void SetupCustomBuildSteps(ProjectInfo_t& info) { // Create the custom build steps
CString copySteps; CString targets;
if (info.m_Project == PROJECT_LIB) { CString targetPath;
targetPath.Format( "%s%s.%s", info.m_RelativeTargetPath, info.m_RootName, info.m_Ext );
// NOTE: The second attrib is commented out because I'm fairly certain it causes
// a bug in VSS to make it overwrite the target on a get
copySteps.Format( "if exist %s attrib -r %s\n" "copy $(TargetPath) %s\n" "if exist $(TargetDir)\\%s.map copy $(TargetDir)\\%s.map %s%s.map", targetPath, targetPath, targetPath, info.m_RootName, info.m_RootName, info.m_RelativeTargetPath, info.m_RootName );
targets.Format( "%s\n", targetPath ); } else { CString targetPath; targetPath.Format( "%s%s.%s", info.m_RelativeTargetPath, info.m_RootName, info.m_Ext );
// NOTE: The second attrib is commented out because I'm fairly certain it causes
// a bug in VSS to make it overwrite the target on a get
copySteps.Format( "if exist %s attrib -r %s\n" "copy $(TargetPath) %s\n" "if exist $(TargetDir)\\%s.map copy $(TargetDir)\\%s.map %s%s.map", targetPath, targetPath, targetPath, info.m_RootName, info.m_RootName, info.m_RelativeTargetPath, info.m_RootName );
targets.Format( "%s", targetPath );
if ((info.m_Project == PROJECT_DLL) && info.m_PublishImportLib) { CString targetPath;
targetPath.Format( "%s%s.lib", info.m_RelativeImplibPath, info.m_RootName );
CString impLibCopy; impLibCopy.Format( "\nif exist %s attrib -r %s\n" "if exist $(TargetDir)\\%s.lib copy $(TargetDir)\\%s.lib %s\n", targetPath, targetPath, info.m_RootName, info.m_RootName, targetPath ); copySteps += impLibCopy;
CString implibTarget; implibTarget.Format( "\n%s", targetPath ); targets += implibTarget; } }
CString publishDir; publishDir.Format( "Publishing to target directory (%s)...", info.m_RelativeTargetPath ); info.m_pConfig->AddCustomBuildStep( (char const*)copySteps, (char const*)targets, (char const*)publishDir ); }
//-----------------------------------------------------------------------------
// Deals with MIDL build steps
//-----------------------------------------------------------------------------
static void SetupMIDLSettings(ProjectInfo_t& info) { }
//-----------------------------------------------------------------------------
// Deals with browse build steps
//-----------------------------------------------------------------------------
static void SetupBrowseSettings(ProjectInfo_t& info) { }
void CValvelibAppWiz::CustomizeProject(IBuildProject* pProject) { // This is called immediately after the default Debug and Release
// configurations have been created for each platform. You may customize
// existing configurations on this project by using the methods
// of IBuildProject and IConfiguration such as AddToolSettings,
// RemoveToolSettings, and AddCustomBuildStep. These are documented in
// the Developer Studio object model documentation.
// WARNING!! IBuildProject and all interfaces you can get from it are OLE
// COM interfaces. You must be careful to release all new interfaces
// you acquire. In accordance with the standard rules of COM, you must
// NOT release pProject, unless you explicitly AddRef it, since pProject
// is passed as an "in" parameter to this function. See the documentation
// on CCustomAppWiz::CustomizeProject for more information.
using namespace DSProjectSystem;
long lNumConfigs; IConfigurationsPtr pConfigs; IBuildProjectPtr pProj;
// Needed to convert IBuildProject to the DSProjectSystem namespace
pProj.Attach((DSProjectSystem::IBuildProject*)pProject, true);
// Add a release with symbols configuration
pProj->get_Configurations(&pConfigs); pConfigs->get_Count(&lNumConfigs);
// Needed for OLE2T below
USES_CONVERSION; CComBSTR configName;
ProjectInfo_t info; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_RELATIVE_PATH", info.m_RelativeTargetPath)) return; if (!Valvelibaw.m_Dictionary.Lookup("root", info.m_RootName)) return; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_TARGET_TYPE", info.m_Ext)) return; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_ROOT_RELATIVE_PATH", info.m_RelativeRootPath)) return; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_SRC_RELATIVE_PATH", info.m_RelativeSrcPath)) return; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_TARGET_PATH", info.m_TargetPath)) return;
CString tmp; info.m_Tool = (Valvelibaw.m_Dictionary.Lookup("VALVE_TOOL", tmp) != 0); info.m_Console = (Valvelibaw.m_Dictionary.Lookup("PROJTYPE_CON", tmp) != 0); info.m_Public = (Valvelibaw.m_Dictionary.Lookup("VALVE_PUBLIC_PROJECT", tmp) != 0); info.m_PublishImportLib = (Valvelibaw.m_Dictionary.Lookup("VALVE_PUBLISH_IMPORT_LIB", tmp) != 0); info.m_Project = PROJECT_LIB; if ( strstr( info.m_Ext, "dll" ) != 0 ) { info.m_Project = PROJECT_DLL; if (!Valvelibaw.m_Dictionary.Lookup("VALVE_IMPLIB_RELATIVE_PATH", info.m_RelativeImplibPath)) return; } else if ( strstr( info.m_Ext, "exe" ) != 0 ) { info.m_Project = PROJECT_EXE; }
//Get each individual configuration
for (long j = 1 ; j <= lNumConfigs ; j++) { _bstr_t varTool; _bstr_t varSwitch; _variant_t varj = j; info.m_ConfigIndex = j;
info.m_pConfig = pConfigs->Item(varj); // Figure if we're debug or release
info.m_pConfig->get_Name( &configName ); info.m_Config = CONFIG_RELEASE; info.m_BuildName = "Release"; if ( strstr( OLE2T(configName), "Debug" ) != 0 ) { info.m_Config = CONFIG_DEBUG; info.m_BuildName = "Debug"; }
// Not using MFC...
info.m_pConfig->AddToolSettings("mfc", "0", varj);
SetupCompilerSettings(info); SetupResourceCompilerSettings(info); if (info.m_Project != PROJECT_LIB) { SetupLinkerSettings(info);
if (!info.m_Console) SetupMIDLSettings(info); } else { SetupLibSettings(info); } SetupCustomBuildSteps(info); SetupBrowseSettings(info);
info.m_pConfig->MakeCurrentSettingsDefault(); } }
// Here we define one instance of the CValvelibAppWiz class. You can access
// m_Dictionary and any other public members of this class through the
// global Valvelibaw.
CValvelibAppWiz Valvelibaw;
|