View Single Post
Old 06-17-2007, 10:03 PM   #3
ensiform
The Stig
 
ensiform's Avatar
 
Join Date: Nov 2004
Location: Sawtooth Cauldron
Posts: 1,241
Current Game: Borderlands 2
In case you are interested...

I haven't finished with getting the mac stuff since I don't actually build for MAC myself and I haven't toyed with the pk3 part yet either...

SConstruct:

Code:
# -*- mode: python -*-

# Jedi Academy build script

# TTimo <ttimo@idsoftware.com>
# Ensiform <ensiform[at]gmail[dot]com>

# http://scons.sourceforge.net



import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string, tempfile

import SCons



import scons_utils



conf_filename='site.conf'

# choose configuration variables which should be saved between runs

# ( we handle all those as strings )

serialized=[ 'CC', 'CXX', 'JOBS', 'BUILD', 'BUILD_ROOT', 'TARGET_GAME', 'TARGET_CGAME', 'TARGET_UI' ]



# help -------------------------------------------



Help("""

Usage: scons [OPTIONS] [TARGET] [CONFIG]



[OPTIONS] and [TARGET] are covered in command line options, use scons -H



[CONFIG]: KEY="VALUE" [...]

a number of configuration options saved between runs in the """ + conf_filename + """ file

erase """ + conf_filename + """ to start with default settings again



CC (default gcc)

CXX (default g++)

	Specify C and C++ compilers (defaults gcc and g++)

	ex: CC="gcc-3.3"

	You can use ccache and distcc, for instance:

	CC="ccache distcc gcc" CXX="ccache distcc g++"



JOBS (default 1)

	Parallel build



BUILD (default debug)

	Use debug-all/debug/release to select build settings

	ex: BUILD="release"

	debug-all: no optimisations, debugging symbols

	debug: -O -g

	release: all optimisations, including CPU target etc.

	

DEDICATED (default 2)

	Control regular / dedicated type of build:

	0 - client

	1 - dedicated server

	2 - both



TARGET_GAME (default 1)

	Build game module



BUILD_ROOT (default 'build')

	change the build root directory

	

NOCONF (default 0, not saved)

	ignore site configuration and use defaults + command line only



COPYBINS (default 0, not saved)

	copy the binaries in a ready-to-release format



BUILDMPBIN (default 0, not saved)

	build mp_bin.pk3 using bin/ directories and game binaries for all platforms



BUILDBUNDLE (default 0, not saved)

	create mac bundle files

"""

)



# end help ---------------------------------------



# sanity -----------------------------------------



EnsureSConsVersion( 0, 96 )



# end sanity -------------------------------------



# system detection -------------------------------



# CPU type

cpu = commands.getoutput('uname -m')

dll_cpu = '???' # grmbl, alternative naming for .so

exp = re.compile('.*i?86.*')

if exp.match(cpu):

	cpu = 'x86'

	dll_cpu = 'i386'

else:

	cpu = commands.getoutput('uname -p')

	if ( cpu == 'powerpc' ):

		cpu = 'ppc'

		dll_cpu = cpu

	else:

		cpu = 'cpu'

		dll_cpu = cpu

OS = commands.getoutput( 'uname -s' )



print 'cpu: ' + cpu



# end system detection ---------------------------



# default settings -------------------------------



CC = 'gcc'

CXX = 'g++'

JOBS = '1'

BUILD = 'debug'

DEDICATED = '2'

TARGET_GAME = '1'

TARGET_CGAME = '1'

TARGET_UI = '0'

BUILD_ROOT = 'build'

NOCONF = '0'

COPYBINS = '0'

BUILDMPBIN = '0'

BUILDBUNDLE = '0'



# end default settings ---------------------------



# arch detection ---------------------------------



def gcc_major():

	major = os.popen( CC + ' -dumpversion' ).read().strip()

	print 'dumpversion: %s' % major

	major = re.sub('^([^.]+)\\..*$', '\\1', major)

	print 'gcc major: %s' % major

	return major



gcc3 = (gcc_major() != '2')



def gcc_is_mingw():

	mingw = os.popen( CC + ' -dumpmachine' ).read()

	return re.search('mingw', mingw) != None



if gcc_is_mingw():

	g_os = 'win32'

elif cpu == 'ppc':

	g_os = 'Darwin'

else:

	g_os = 'Linux'

print 'os: %s' % g_os



# end arch detection -----------------------------



# site settings ----------------------------------



if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):

	site_dict = {}

	if (os.path.exists(conf_filename)):

		site_file = open(conf_filename, 'r')

		p = pickle.Unpickler(site_file)

		site_dict = p.load()

		print 'Loading build configuration from ' + conf_filename + ':'

		for k, v in site_dict.items():

			exec_cmd = k + '=\'' + v + '\''

			print '  ' + exec_cmd

			exec(exec_cmd)

else:

	print 'Site settings ignored'



# end site settings ------------------------------



# command line settings --------------------------



for k in ARGUMENTS.keys():

	exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''

	print 'Command line: ' + exec_cmd

	exec( exec_cmd )



# end command line settings ----------------------



# save site configuration ----------------------



if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):

	for k in serialized:

		exec_cmd = 'site_dict[\'' + k + '\'] = ' + k

		exec(exec_cmd)



	site_file = open(conf_filename, 'w')

	p = pickle.Pickler(site_file)

	p.dump(site_dict)

	site_file.close()



# end save site configuration ------------------



# arch detection ---------------------------------



def gcc_major():

	major = os.popen( CC + ' -dumpversion' ).read().strip()

	major = re.sub('^([^.]+)\\..*$', '\\1', major)

	print 'gcc major: %s' % major

	return major



gcc3 = (gcc_major() != '2')



def gcc_is_mingw():

	mingw = os.popen( CC + ' -dumpmachine' ).read()

	return re.search('mingw', mingw) != None



win32_build = gcc_is_mingw()



# end arch detection -----------------------------



# general configuration, target selection --------



g_build = BUILD_ROOT + '/' + BUILD



SConsignFile( 'scons.signatures' )



SetOption('num_jobs', JOBS)



if ( OS == 'Linux' ):

	LINK = CC

else:

	LINK = CXX



# common flags

# BASE + GAME + OPT for game



BASECPPFLAGS = [ ]

CORECPPPATH = [ ]

CORELIBPATH = [ ]

CORECPPFLAGS = [ ]

GAMECPPFLAGS = [ ]

BASELINKFLAGS = [ ]

CORELINKFLAGS = [ ]



# for release build, further optimisations that may not work on all files

OPTCPPFLAGS = [ ]



if ( OS == 'Darwin' ):

	# taken from xcode's default project settings

	BASECPPFLAGS += [ '-D__MACOS__', '-Wno-long-double', '-arch', 'ppc', '-fasm-blocks', '-fpascal-strings', '-faltivec', '-mcpu=G4', '-mtune=G4', '-Wno-unknown-pragmas' ]



BASECPPFLAGS.append( '-pipe' )

# warn all

BASECPPFLAGS.append( '-Wall' )

# don't wrap gcc messages

BASECPPFLAGS.append( '-fmessage-length=0' )



if ( BUILD == 'debug-all' ):

	BASECPPFLAGS.append( '-g' )

	BASECPPFLAGS.append( '-D_DEBUG' )
	BASECPPFLAGS.append( '-fno-stack-protector' )

elif ( BUILD == 'debug' ):

	BASECPPFLAGS.append( '-g' )

	BASECPPFLAGS.append( '-O1' )

	BASECPPFLAGS.append( '-D_DEBUG' )
	BASECPPFLAGS.append( '-fno-stack-protector' )

elif ( BUILD == 'release' ):

	BASECPPFLAGS.append( '-DNDEBUG' )
	BASECPPFLAGS.append( '-DFINAL_BUILD' )
	BASECPPFLAGS.append( '-fno-stack-protector' )

	if ( OS == 'Linux' ):

		# -fomit-frame-pointer: gcc manual indicates -O sets this implicitely,

		# only if that doesn't affect debugging

		# on Linux, this affects backtrace capability, so I'm assuming this is needed

		# -finline-functions: implicit at -O3

		# -fschedule-insns2: implicit at -O3

		# -funroll-loops ?

		# -mfpmath=sse -msse ?
		OPTCPPFLAGS = [ '-march=i686', '-mmmx', '-fexpensive-optimizations', '-O3', '-static' ]

	elif ( OS == 'Darwin' ):

		OPTCPPFLAGS = [ '-O3', '-falign-functions=16', '-falign-loops=16', '-finline' ]

else:

	print 'Unknown build configuration ' + BUILD

	sys.exit(0)



# create the build environments

g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )

scons_utils.SetupUtils( g_base_env )



g_env = g_base_env.Copy()



g_env['CPPFLAGS'] += OPTCPPFLAGS

g_env['CPPFLAGS'] += CORECPPFLAGS

g_env['LINKFLAGS'] += CORELINKFLAGS



if ( OS == 'Linux' ):

	g_env.Append(LINKFLAGS = '-rdynamic')

	g_env.Append(LINKFLAGS = '-m32')

	g_env.Append(CPPFLAGS = '-m32')



if ( OS == 'Darwin' ):

	# configure for dynamic bundle

	g_env['SHLINKFLAGS'] = '$LINKFLAGS -bundle -flat_namespace -undefined suppress'

	g_env['SHLIBSUFFIX'] = '.so'



# maintain this dangerous optimization off at all times

g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )



if ( int(JOBS) > 1 ):

	print 'Using buffered process output'

	scons_utils.SetupBufferedOutput( g_env )



# mark the globals



GLOBALS = 'g_env OS g_os BUILD gcc3 cpu'



# end general configuration ----------------------



# win32 cross compilation ----------------------



if g_os == 'win32' and os.name != 'nt':

	# mingw doesn't define the cpu type, but our only target is x86

	g_env.Append(CPPDEFINES = '_M_IX86=400')

	g_env.Append(LINKFLAGS = '-static-libgcc')

	g_env.Append(LIBS = 'ws2_32')

	# scons doesn't support cross-compiling, so set these up manually

	g_env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1

	g_env['WIN32DEFSUFFIX']	= '.def'

	g_env['PROGSUFFIX']	= '.exe'

	g_env['SHLIBSUFFIX']	= '.dll'

	g_env['SHCCFLAGS']	= '$CCFLAGS'



# end win32 cross compilation ------------------



# targets ----------------------------------------



toplevel_targets = []



if ( TARGET_GAME == '1' ):

	Export( 'GLOBALS ' + GLOBALS )

	BuildDir( g_build + '/game', '.', duplicate = 0 )

	game = SConscript( g_build + '/game/SConscript.game' )

	if ( g_os == 'win32' ):

		toplevel_targets.append( InstallAs( '#jampgamex86.dll', game ) )

	else:

		toplevel_targets.append( InstallAs( '#jampgamei386.so', game ) )



if ( TARGET_CGAME == '1' ):

	Export( 'GLOBALS ' + GLOBALS )

	BuildDir( g_build + '/cgame', '.', duplicate = 0 )

	cgame = SConscript( g_build + '/cgame/SConscript.cgame' )

	if ( g_os == 'win32' ):

		toplevel_targets.append( InstallAs( '#cgamex86.dll', cgame ) )

	else:

		toplevel_targets.append( InstallAs( '#cgame.i386.so', cgame ) )



if ( TARGET_UI == '1' ):

	Export( 'GLOBALS ' + GLOBALS )

	BuildDir( g_build + '/ui', '.', duplicate = 0 )

	ui = SConscript( g_build + '/ui/SConscript.ui' )

	if ( g_os == 'win32' ):

		toplevel_targets.append( InstallAs( '#ui_mp_x86.dll', ui ) )

	else:

		toplevel_targets.append( InstallAs( '#ui.i386.so', ui ) )



class CopyBins(scons_utils.idSetupBase):

	def copy_bins( self, target, source, env ):

		for i in source:

			j = os.path.normpath( os.path.join( os.path.dirname( i.abspath ), '../bin', os.path.basename( i.abspath ) ) )

			self.SimpleCommand( 'cp ' + i.abspath + ' ' + j )

			if ( OS == 'Linux' ):

				self.SimpleCommand( 'strip ' + j )

			else:

				# see strip and otool man pages on mac

				self.SimpleCommand( 'strip -ur ' + j )



copybins_target = []

if ( COPYBINS != '0' ):

	copy = CopyBins()

	copybins_target.append( Command( 'copybins', toplevel_targets, Action( copy.copy_bins ) ) )



class MpBin(scons_utils.idSetupBase):

	def mp_bin( self, target, source, env ):

		temp_dir = tempfile.mkdtemp( prefix = 'mp_bin' )

		self.SimpleCommand( 'cp ../bin/ui* ' + temp_dir )

		self.SimpleCommand( 'cp ../bin/cgame* ' + temp_dir )

		# zip the mac bundles

		mac_bundle_dir = tempfile.mkdtemp( prefix = 'mp_mac' )

		self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/ui_mac.bundle" ' + mac_bundle_dir )

		self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/cgame_mac.bundle" ' + mac_bundle_dir )

		self.SimpleCommand( 'find %s -name \.svn | xargs rm -rf' % mac_bundle_dir )

		self.SimpleCommand( 'cd %s ; zip -r -D %s/ui_mac.zip ui_mac.bundle ; mv %s/ui_mac.zip %s/ui_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )

		self.SimpleCommand( 'cd %s ; zip -r -D %s/cgame_mac.zip cgame_mac.bundle ; mv %s/cgame_mac.zip %s/cgame_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )

		mp_bin_path = os.path.abspath( os.path.join ( os.getcwd(), '../etmain/mp_bin.pk3' ) )

		self.SimpleCommand( 'cd %s ; zip -r -D %s *' % ( temp_dir, mp_bin_path ) )



if ( BUILDMPBIN != '0' ):

	mp_bin = MpBin()

	mpbin_target = Command( 'mp_bin', toplevel_targets + copybins_target, Action( mp_bin.mp_bin ) )



class BuildBundle(scons_utils.idSetupBase):

	def make_bundle( self, target, source, env ):

		for i in source:

			self.SimpleCommand( './makebundle.sh %s' % i )



if ( BUILDBUNDLE != '0' ):

	build_bundle = BuildBundle()

	bundle_target = Command( 'build_bundle', toplevel_targets, Action( build_bundle.make_bundle ) )



# end targets ------------------------------------
SConscript.game:

Code:
# -*- mode: python -*-

# Jedi Academy build script

# TTimo <ttimo@idsoftware.com>
# Ensiform <ensiform[at]gmail[dot]com>

# http://scons.sourceforge.net



import sys, os

import scons_utils



Import( 'GLOBALS' )

Import( GLOBALS )



botai_string = """

ai_main.c

ai_tab.c

ai_util.c

ai_wpnav.c

"""



botai_list = scons_utils.BuildList( 'game', botai_string )



jampgame_string = """

AnimalNPC.c

bg_g2_utils.c

bg_killtracker.c

bg_langscript.c

bg_misc.c
bg_panimate.c

bg_pmove.c
bg_saber.c
bg_saberLoad.c
bg_saga.c

bg_slidemove.c
bg_vehicleLoad.c
bg_weapons.c
FighterNPC.c

g_active.c
g_admin.c
g_antiwarp.c
g_bot.c
g_censor.c
g_client.c

g_cmds.c

g_combat.c
g_crash.c
g_exphysics.c
g_fakebrush.c
g_holocron.c
g_ICARUScb.c

g_items.c
g_log.c

g_main.c

g_mem.c

g_misc.c

g_missile.c

g_mover.c
g_nav.c
g_navnew.c
g_object.c
g_saga.c

g_session.c
g_settings.c
g_shrubbot.c

g_spawn.c
g_strap.c

g_svcmds.c

g_syscalls.c

g_target.c

g_team.c
g_timer.c

g_trigger.c
g_turret.c
g_turret_G2.c
g_unlagged.c

g_utils.c
g_vehicles.c
g_vehicleTurret.c

g_vote.c
g_weapcfg.c

g_weapon.c
NPC.c
NPC_AI_Atst.c
NPC_AI_Default.c
NPC_AI_Droid.c
NPC_AI_GalakMech.c
NPC_AI_Grenadier.c
NPC_AI_Howler.c
NPC_AI_ImperialProbe.c
NPC_AI_Interrogator.c
NPC_AI_Jedi.c
NPC_AI_Mark1.c
NPC_AI_Mark2.c
NPC_AI_MineMonster.c
NPC_AI_Rancor.c
NPC_AI_Remote.c
NPC_AI_Seeker.c
NPC_AI_Sentry.c
NPC_AI_Sniper.c
NPC_AI_Stormtrooper.c
NPC_AI_Utils.c
NPC_AI_Wampa.c
NPC_behavior.c
NPC_combat.c
NPC_goal.c
NPC_misc.c
NPC_move.c
NPC_reactions.c
NPC_senses.c
NPC_sounds.c
NPC_spawn.c
NPC_stats.c
NPC_utils.c
q_math.c
q_shared.c
SpeederNPC.c
tri_coll_test.c
w_force.c
w_saber.c
WalkerNPC.c

"""



jampgame_list = scons_utils.BuildList( 'game', jampgame_string )



local_env = g_env.Copy()

local_env.Append( CPPDEFINES = [ 'SCONS_BUILD' ] ) # Tell the code that we are building from SCONS

local_env.Append( CPPDEFINES = [ 'NO_OMNIBOT_HEADER' ] ) # Don't include the Omni-Bot headers for Linux just yet.



local_env.Append( CPPDEFINES = [ 'QAGAME' ] ) # Server



local_env.Append( CPPDEFINES = [ '_JK2' ] ) # Raven Define for "MP"

local_env.Append( CPPDEFINES = [ '__linux__' ] ) # enforce the linux define because I'm not sure that gcc does this already, and our code relies on this preprocessor define



local_env['LINK'] = local_env['CXX']



source_list = botai_list

source_list += jampgame_list



#ret = local_env.Program( target = 'et', source = source_list )

ret = local_env.SharedLibrary( target = 'jampgame', source = source_list)

Return( 'ret' )


iojamp project lead / coder
ensiform is offline   you may: quote & reply,