User:Winston/sandbox

From Valve Developer Community
Jump to: navigation, search

This is a blantant ripoff of [Wunderboy's sandbox page] - I'm using it to log the many things I had to fix to get the orange box sdk to compile under linux. I'm certainly not an expert, so this isn't a tutorial, but instead its a monologue - if you're having trouble doing the same thing, maybe this can be of help. If I come up with anything else thats worth putting in here, I'll do so.

Building the Orange Box server dll in Linux

I dual-booted Ubuntu onto my older XP machine. I had no particular reason to choose Ubuntu over anything else, but I liked the sound of it.

I followed every guide I could find online, installing xerces-c 2.6 and eventually finding a compiled version of G++-4.1 (the orange box makefile says it prefers 4.1, although all the tutorials I could find online, which AFAIK assume Ep1 SDK, say you need 3.4). I was good to go. Navigate to the linux_sdk folder in a terminal window, and type make.

Trouble getting started

The first error was that all the makefiles had windows line endings (\r\n) rather than linux ones (\n). Unfortunately, this wasn't at all obvious in gedit (the default text editor), so I spent a fortnight trying to work out why the whole thing just wouldn't work. In the end I installed nedit, and opened each makefile with that, as it showed up the \r character (carriage return) on the end of each line as a nice obvious <CR>. I removed these manually (apparently this could have been done by running dos2linux on each file in turn, but this only took 5 minutes)

Trouble with VCPM

This was great, it actually started building several files before failing. Given what I'd been through with the newline issue, this was practically bliss. It had actually started. I had some error messages that i think were the compiler trying to find some xerces-c v2.8 files, so I installed xerces-c 2.8 alongside the 2.6 I had already.

It then seemed to happily build VCPM, but trying to run it, I kept getting an 'unable to find shared library: libxerces-c.so.28' no matter what I tried. Eventually, online I found that first typing this command:

export LD_LIBRARY_PATH=/usr/lib/xercesc

worked wonders, and it actually started to try to build my mod. Woot! Note that this would need to be done every session before the mod would build.

Trouble with makefiles, filenames, etc

It quickly failed when it couldn't find Makefile.ServerSDK_ReleaseWin32 ... this was evidently because the wrong build configuration was set by the MOD_CONFIG parameter. I looked at the files that had been created in the linux_sdk folder, and one of them was Makefile.Server(HL2MP)_ReleaseWin32 ... so I changed the macro in my makefile to

MOD_CONFIG=Server(HL2MP)_ReleaseWin32

Now it started trying to build the server, but fails because of a syntax error: 'Syntax error: "(" unexpected' I guessed that this was down to the brackets in the filename. Hoping this wouldn't screw anything, I renamed the file and the MOD_CONFIG param, just removing the brackets, and tried again. Looks like this was right on, it goes a little further.

G++ complains of no input files, then there's a lot of directories not found... then its ultimately stopped by an error thats something to do with ai_activity.o.

I remembered seeing something like this somewhere on the wiki, turns out it was the [script at the bottom of Wunderboy's sandbox page].

While this no doubt fixed other problems, unfortunately after I ran the script, I was still getting the ai_activity.o error. Looking at it again, its probably just cos its the first file alphabetically in the server project.

I tried manually editing the generated server makefile, replacing ../../ with ../ in all the paths that looked like the ones that were "not found" - but this produced permission denied errors instead. Looking at the command that produces all the error message, I can make the No Input error stop if I remove all parameters except for the .o filename and the source filename, but clearly this causes lots of undefined errors. I had to try running this command manually, to see what parameter was messing it up.

The problem appeared to be the include directories. Specifically, in the INCLUDES define of Makefile.ServerHL2MP_ReleaseWin32, there were some seperated like this: -Iinclude1 -Iinclude2 -Iinclude3, etc, and some seperated like -Iinclude1;include2;include3 - if I changed this second type to match the first, then it definately noticed the .cpp source file. However, there were loads of errors with ai_activity.cpp, so it still fails on the first file.

The list of errors is actually longer than the terminal will show, but i saw several "no such file or directory" errors fly past, and some .h filenames, then I end up with what appears to be a list of every ACT_ activity definition not being defined. By commenting out all of the ADD_ACTIVITY_TO_SR lines (which make up virtually all the file), I was able to see the earlier errors: lots of undefined (mostly member) variables in baseflex.h, basecombatcharacter.h, player.h, ai_basenpc.h, etc. Something's seriously screwed.

If it wasn't finding a whole bunch of included headers, I figured the include directories had to be messed up. So I changed the INCLUDES define I mentioned just above, replacing a bunch of ../../ with just ../ - giving me this:

INCLUDES=-I../common -I../public -I../public/tier0 -I../public/tier1 -I./ -I../game/shared -I../game/server -I../utils/common -I../game/shared/hl2 -I../game/server/hl2 -I../game/server/hl2mp -I../game/shared/hl2mp -I../game/server/episodic -I../game/shared/episodic -DNDEBUG -D_USRDLL -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DGAME_DLL -DVECTOR -DPROTECTED_THINGS_ENABLE -Dsprintf=use_Q_snprintf_instead_of_sprintf -Dstrncpy=use_Q_strncpy_instead -D_snprintf=use_Q_snprintf_instead -DHL2MP -DHL2_DLL -DVERSION_SAFE_STEAM_API_INTERFACES

and - WOAH - its building! This is a very slow process, even compared to a windows build.

Code errors

There are some things that the microsoft compiler let you get away with that linux doesn't. Firstly, I get errors in the achievement management code. Specifically, these are in achievements_hlx.cpp, and I don't use achievements ... so I just commented out every DECLARE_ACHIEVEMENT line from that file, as those were what was causing the problem.

I got some file not found errors because I'd included files using \ instead of / to seperate the directories (windows doesn't mind, but linux does).

I also got some undefined min & max function errors - evidently, wherever VS pulls its macros from, G++ doesn't. So I added them myself, in a nice little "ignore this if you're windows" section:

#ifndef _WIN32
	#define max(a,b) (a) > (b) ? (a) : (b)
	#define min(a,b) (a) < (b) ? (a) : (b)
#endif

In npc_hunter.cpp, around line 1023, was

class CAI_HunterEscortBehavior : public CAI_FollowBehavior
{
	typedef CAI_FollowBehavior BaseClass;

	DECLARE_CLASS( CAI_HunterEscortBehavior, CAI_FollowBehavior );

It seems that the typedef conflicts with a typedef that the DECLARE_CLASS macro does, so I commented out the typedef line here

Next, an error in item_itemcrate.cpp:

const char *pszItemCrateModelName[] =
{
	{"models/items/item_item_crate.mdl"},
	("models/items/item_beacon_crate.mdl"),
};

Its complaining about the bracers {}, and I have to agree, it doesn't seem to make much sense to me. I changed it to this, and all was well:

const char *pszItemCrateModelName[] =
{
	"models/items/item_item_crate.mdl",
	"models/items/item_beacon_crate.mdl",
};

Now there's an error in npc_attackchopper.cpp, something's failing trying to assign SKIN_DUD (an enum value) to a skin member variable. I don't see why, but I just replaced this:

enum
{
	SKIN_REGULAR,
	SKIN_DUD,
};

with this

#define SKIN_REGULAR 0
#define SKIN_DUD 1

and that file compiled

Now I'm getting an error in npc_citizen17.cpp (I don't think valve compiled the NPC code in linux!) It can't find a way of casting this call to EmitSound line to any of the definitions in baseentity.h:

EmitSound( CPASAttenuationFilter( pTarget, "HealthKit.Touch" ), pTarget->entindex(), "HealthKit.Touch" );

I'm not sure whether its a problem casting the CPASAttentuationFilter or a problem with the string, but I just replaced it with the simpler version of EmitSound used elsewhere in the file:

EmitSound( "HealthKit.Touch" );

And now, voila, it's compiled a .so! Woot.