Compiling under VS2005/Older SDK

=== Introduction ===
This is an archive of the changes need to be made so old versions of source would compile under VS 2005. This is for old codebases only SDK code newer than November 2006 does not need any of the following fixes, instead the article to read is Compiling under VS2005.
=== Requirements (other SDKs and Setup of those) ===
Necessary steps needed to enable compiling with the Visual Studio C++ 2005 Express Edition:
Files required
*MS DirectX SDK
*MS Platform SDK
Setup
Go to Tools - Options: Projects and Solutions - VC++ Directories
* In the upper right drop down box, select "Executable files" and add "...\Microsoft Platform SDK\Bin" (replace with the correct path)
* Then select "Include files" and add "...\Microsoft Platform SDK\Include" and "...\Microsoft DirectX SDK (December 2005)\Include"
* Then select "Library files" and add "...\Microsoft Platform SDK\Lib" and "...\Microsoft DirectX SDK (December 2005)\Lib\x86"
* Finally, go to the project properties for hl and client and add user32.lib to Linker->Input->Additional Dependencies (with spaces between entries)
== Project Configuration ==
=== Disabling Deprecated Declaration Warnings ===
This fix will disable the deprecated declaration warnings, which indeed is only a warning.
It warns that the used functions are old ones and there are new, more secure versions but this can be ignored.
..\public\tier0\dbg.h
add
 #pragma warning(disable : 4996)
after #pragma once (new line) to disable old, insecure functions warning.
=== Disabling /COMMENT Warning ===
This fix will remove comments from debug obj. since the comment doesn't work in VS2005 it wont be put in anyway.
Find:
 #ifdef _WIN32
 	#ifdef _DEBUG
 		#pragma comment(compiler)
 		#pragma comment(exestr,"*** DEBUG file detected, Last Compile: " __DATE__ ", " __TIME__ " ***")
 	#endif
 #endif
Replace With:
 #ifdef _WIN32
 	#ifdef _DEBUG
 		//#pragma comment(compiler)
 		//#pragma comment(exestr,"*** DEBUG file detected, Last Compile: " __DATE__ ", " __TIME__ " ***")
 	#endif
 #endif
=== wchar_t Linker errors ===
Linker errors with wchar_t as values:
 Client->;Properties->C/C++->Language
 and set Treat wchar_t as Built in Type to No.
This is because the Valve library vgui_control.lib is compiled with the option - Treat wchar_t as Built in Type - set to No so they need to be the same.
An alternative fix is to recompile vgui_control.lib with the option set to Yes - its found in src\vgui2\controls. Backing up vgui_control.lib is recommended - found in src\lib\public and recompile it with the option set to yes and then copy that to where the original lib was backed up.
== Code Changes ==
=== General ===
==== error C2065: 'i' : undeclared identifier ====
For the error C2065: 'i' : undeclared identifier, there are two ways to fix this.
For one after the other, rightclick client and hl,
go to C/C++ -> Language and set
 Force Conformance in For Loop to No.
Alternatively fix would be adding the "int"-declaration into code.
=== Release-Compile configuration ===
==== Shared fixes ====
..\public\vstdlib\strtools.h(90):
 inline char*	Q_strrchr (const char *s, char c)					{ return strrchr( (char *)s, c ); }
..\public\vstdlib\strtools.h(93) zu
 inline char*	Q_strstr( const char *s1, const char *search )		{ return strstr( (char *)s1, search ); }
..\cl_dll\hud_bitmapnumericdisplay.cpp(159)
 if( bStart || digit > 0 || pos <= pow((float)10,numSigDigits-1) )
..\game_shared\baseentity_shared.cpp(251)
 char *s = strchr( (char *)szKeyName, '#' );
..\tier1\KeyValues.cpp(800)
 char *subStr = strchr((char *)keyName, '/');
=== Memoverride Linking Errors & Fixes: ===
memoverride.obj : error LNK2019: unresolved external symbol __aligned_malloc_base referenced in function __aligned_malloc
memoverride.obj : error LNK2019: unresolved external symbol __aligned_free_base referenced in function __aligned_free
Lines 405 - 430 in memoverride.cpp:
Before:
 #if defined(_DEBUG) && _MSC_VER >= 1300
 void __cdecl _aligned_free_base(
 void *
 );
 void * __cdecl _aligned_malloc_base(
 size_t,
 size_t
 );
 void * __cdecl _aligned_malloc(
 size_t size,
 size_t align
 )
 {
 return _aligned_malloc_base(size, align);
 }
 void __cdecl _aligned_free(
 void *memblock
 )
 {
 _aligned_free_base(memblock);
 }
 #endif
After:
 #if defined(_DEBUG) && _MSC_VER >= 1300
 void __cdecl _aligned_free(
 void *
 );
 void * __cdecl _aligned_malloc(
 size_t,
 size_t
 );
 void * __cdecl _aligned_malloc_base(
 size_t size,
 size_t align
 )
 {
 return _aligned_malloc(size, align);
 }
 void __cdecl _aligned_free_base(
 void *memblock
 )
 {
 _aligned_free(memblock);
 }
 #endif
==== Client fixes (client.dll) ====
Linking Errors & Fixes:
Added msvcrt.lib and user32.lib to Linker->Input->Additional Dependencies (separated each with a space(" "))
Added LIBC to Linker->Input->Ignore specific library
Added /FORCE:MULTIPLE to Linker->Command Line->Additional Options
==== HL fixes (server.dll) ====
..\dlls\vguiscreen.cpp(69)
 char *s = strchr( (char *)szKeyName, '#' );
..\dlls\TemplateEntities.cpp(298)
 int iMax = pow((double)10, (int)(strlen(ENTITYIO_FIXUP_STRING)-1)); // -1 for the &
===== Changing function-run to function-link (error C3867) =====
..\dlls\hl2_dll\weapon_rpg.cpp
 * (150) SetTouch( &CMissile::MissileTouch );
 * (153) SetThink( &CMissile::IgniteThink );
 * (256) SetThink( &CMissile::SeekThink );
 * (311) SetThink( &CMissile::AugerThink );
 * (435) SetThink( &CMissile::SeekThink );
 * (881) SetTouch( &CAPCMissile::APCMissileTouch );
 * (916) SetThink( &CAPCMissile::BeginSeekThink );
 * (925) SetThink( &CAPCMissile::AugerStartThink );
 * (938) SetThink( &CMissile::AugerThink );
 * (945) SetThink( &CAPCMissile::ExplodeThink );
 * (955) SetThink( &CMissile::SeekThink );
 * (2058) pLaserDot->SetContextThink( &CLaserDot::LaserThink, gpGlobals->curtime + 0.1f, g_pLaserDotThink );
..\dlls\hl2_dll\weapon_physcannon.cpp
 * (2480) SetContextThink( &CWeaponPhysCannon::WaitForUpgradeThink, gpGlobals->curtime + 6.0f, s_pWaitForUpgradeContext );
 * (2502) SetContextThink( &CWeaponPhysCannon::WaitForUpgradeThink, gpGlobals->curtime + 0.1f, s_pWaitForUpgradeContext );
..\dlls\hl2_dll\weapon_crossbow.cpp(324)
 SetThink( &CBaseEntity::SUB_Remove );
..\dlls\hl2_dll\npc_BaseZombie.cpp(160)
 static int s_iAngryZombies = 0;
..\dlls\baseentity.cpp(57)
You should insert this at the end of the #includes
 #include <ctype.h>
==== Linking fixes ====
Added msvcrt.lib and user32.lib to Linker->Input->Additional Dependencies (separated each with a space(" "))
Added /FORCE:MULTIPLE to Linker->Command Line->Additional Options
=== Debug-Compile configuration ===
==== Linking Errors & Fixes ====
Added msvcrtd.lib and user32.lib Linker->Input->Additional Dependencies
Added /FORCE:MULTIPLE to Linker->Command Line->Additional Options
==== Client ====
...\public\tier0\memoverride.cpp line 405-430 (410-435 if you added functions above (release hl))
Remove "_base" from those functions and add it to return-var. Looks then like this:
*(406/411)
 void __cdecl _aligned_free(
*(410/415)
 void * __cdecl _aligned_malloc(
*(415/420)
 void * __cdecl _aligned_malloc_base(
*(420/425)
 return _aligned_malloc(size, align);
*(423/428)
 void __cdecl _aligned_free_base(
*(427/432)
 _aligned_free(memblock);
==== HL ====
...\dlls\ai_behavior_follow.cpp(2090)
 //ASSERT_INVARIANT( sizeof(FollowerListIter_t) == sizeof(AI_FollowManagerInfoHandle_t) );
Linking Errors & Fixes:
Added user32.lib to Linker->Input->Additional Dependencies
Added /FORCE:MULTIPLE to Linker->Command Line->Additional Options
Added LIBCMTD to hl->Properties->Configuration Properties->Linker->Input->Ignore Specific Library
== Other fixes ==
=== STRDUP ===
The problem with strdup doesn't happen in debug mode since Valve overrides strdup with their own strdup func. The heap error only shows itself when using the debugger in release mode. I believe it's because strdup() in the C library that comes with 2005 express uses new() instead of malloc(). So when Valve frees the memory using free() it gives the error. Here's the fix I hope...
..\tier1\stringpool.cpp(73)
CHANGE
 	pszNew = strdup( pszValue );
TO
 	#ifndef _debug
 		pszNew = (char*) malloc(sizeof(char) * (strlen(pszValue) + 1)); // Use Valve's malloc instead of strdup
 		strcpy(pszNew, pszValue);
 	#else
 		pszNew = strdup( pszValue ); // Use Valve's debug strdup
 	#endif
..\cl_dll\c_baseflex.cpp(921)
CHANGE
 	g_flexcontroller[g_numflexcontrollers++] = strdup( szName );
TO
 		#ifndef _debug
 			g_flexcontroller[g_numflexcontrollers] = (char*) malloc(sizeof(char) * (strlen(szName) + 1)); //Use V's malloc instead of strdup
 			strcpy(g_flexcontroller[g_numflexcontrollers++], szName);
 		#else
 			g_flexcontroller[g_numflexcontrollers++] = strdup( szName ); //Use V's debug strdup
 		#endif
=== BotPutInServer Linker Failures ===
(worked for me, didn't have to do this with SP)
Various BotPutInServer lines will fail to link in DEBUG mode. Commenting the BotPutInServer lines out works just fine. This may have some negative affect on bots. I quite frankly have not looked into that stuff at all, other than to see that it breaks the build.
Fix:
A better way would be
 	adding hl2mp_bot_temp.h and hl2mp_bot_temp.cpp 
 	to the HL project under the Source Files->HL2MP folder.
 	hl2mp_bot_temp.h and hl2mp_bot_temp.cpp can both be found in yourmod/src/dlls/hl2mp_dll folder.
=== Warnings ===
..\public\tier0\memoverride.cpp
*(107)
 __declspec(restrict) __declspec(noalias) void *malloc( size_t nSize ) 
*(111)
 __declspec(noalias) void free( void *pMem ) 
*(116)
 __declspec(restrict) __declspec(noalias) void *realloc( void *pMem, size_t nSize ) 
*(121)
 __declspec(restrict) __declspec(noalias) void *calloc( size_t nCount, size_t nElementSize )
*add this function to line 136 (i don't get what this is for???)
 void *_calloc_impl( size_t nCount, size_t nElementSize )
 {
 return calloc(nCount, nElementSize);
 } 
comment out _heap_init() and _heap_term(), means, (i don't get what this is for???)
 comment out everything from line 298 to line 303 (these lines are these lines if you added the function *_calloc_impl (which is 4 lines long) to line 136.
== Remaining error list ==
Here is a list of warnings not fixed yet. Though it's not defined whether they have to be or should be fixed or not.
=== SP Debug Client ===
 ..\public\tier0\commonmacros.h(29) : warning C4005: 'ARRAYSIZE': Makro-Neudefinition
 pathto\microsoft platform sdk\include\winnt.h(950): Siehe vorherige Definition von 'ARRAYSIZE'
..\public\tier0\memoverride.cpp(413)(418)(418) : warning C4565 (I should be able to fix that, will check that again later...)
LINK : warning LNK4075: ignoring /INCREMENTAL due to /FORCE specification.
LONG LIST of .obj files, all with warning:
 warning LNK4224: /COMMENT is no longer supported; ignored.
msvcrt.lib(MSVCR80.dll) : warning LNK4006: _free already defined in "memoverride.obj"; second definition ignored
.\cl_dll___Win32_HL2_Debug/client.dll : warning LNK4088: image being generated due to /FORCE option; image may not run.
=== SP Debug hl ===
 ..\public\tier0\memdbgon.h(83) : warning C4996: 'strcpy' (can stay like that...)
same for 'wcscpy' and 'strtok'
+some new double-definitions (LIBCMTD.lib, ...)
+the errors of SP Debug Client (LNK4224: /COMMENT, warning C4005: 'ARRAYSIZE')
== Related articles ==
*Microsoft Visual Studio 6.0 Usage
*Compiling under VS2002
*Compiling under VS2005
Category:Tutorials
Category:Programming