# -*- mode: python -*-
# coding=utf-8

#*****************************************************************************
#                    The Dark Mod GPL Source Code
# 
# This file is part of the The Dark Mod Source Code, originally based 
# on the Doom 3 GPL Source Code as published in 2011.
# 
# The Dark Mod Source Code is free software: you can redistribute it 
# and/or modify it under the terms of the GNU General Public License as 
# published by the Free Software Foundation, either version 3 of the License, 
# or (at your option) any later version. For details, see LICENSE.TXT.
# 
# Project: The Dark Mod Updater & Packager (http://www.thedarkmod.com/)
# 
#*****************************************************************************

# The Dark Mod Updater & Packager build script for Linux
# Based on id's game sconscript
# Author: greebo

import sys, os, time, commands, re, pickle, StringIO, commands, pdb, string
import SCons
import scons_utils

# choose configuration variables which should be saved between runs
# ( we handle all those as strings )
serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'TARGET_ARCH']

# global build mode ------------------------------

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

help_string = """
Usage: scons [OPTIONS] [TARGET]

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

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.

TARGET_ARCH (default: "x86")
	Build for either x86 or x64 architecture.

"""

Help( help_string )

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

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

EnsureSConsVersion( 0, 98 )

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

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

# CPU type
cpu = commands.getoutput('uname -m')
exp = re.compile('.*i?86.*')
if exp.match(cpu):
	cpu = 'x86'
else:
	cpu = commands.getoutput('uname -p')
	if ( cpu == 'powerpc' ):
		cpu = 'ppc'
	elif ( cpu == 'amd64' ):
		# leave as is
		pass
	else:
		cpu = 'cpu'

if sys.platform == 'darwin':
	g_os = 'MacOSX'
elif sys.platform.startswith('freebsd'):
	g_os = 'FreeBSD'
else:
	g_os = 'Linux'

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

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

CC = 'gcc'
CXX = 'g++'
JOBS = '1'
BUILD = 'release'
BASEFLAGS = ''
TARGET_ARCH = 'x86'
if g_os == 'FreeBSD':
        # FreeBSD uses Clang instead of GCC
        CC = 'cc'
        CXX = 'c++'
        TARGET_ARCH = 'x64'

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

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

for k in ARGUMENTS.keys():
	exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
	print 'Command line: ' + exec_cmd
	exec( exec_cmd )

if TARGET_ARCH == 'x32':
	TARGET_ARCH = 'x86'

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

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

BUILD_ROOT = 'build'
g_build = BUILD_ROOT + '/scons_' + TARGET_ARCH + '/' + BUILD

SConsignFile( 'scons.signatures' )
Decider('MD5-timestamp')

SetOption('num_jobs', JOBS)

LINK = CXX

# common flags
BASECPPFLAGS = [ ]
CORECPPPATH = [ ]
CORELIBPATH = [ ]
CORECPPFLAGS = [ ]
BASELINKFLAGS = [ ]

# for release build, further optimisations that may not work on all files
OPTCPPFLAGS = [ ]

BASECPPFLAGS.append( BASEFLAGS )
BASECPPFLAGS.append( '-pipe' )
# warn all
BASECPPFLAGS.append( '-Wall' )
# Use C++11 features
BASECPPFLAGS.append( '-std=c++11' )
if ( g_os == 'Linux' ):
	# Use old ABI for std::string and std::list (which is not fully compliant with C++11)
	# This allows to link with C++ libraries, which were built in older versions of GCC
	BASECPPFLAGS.append( '-D_GLIBCXX_USE_CXX11_ABI=0' )

# Don't throw warnings for unknown pragmas (used by VC++)
BASECPPFLAGS.append('-Wno-unknown-pragmas')

# this define is necessary to make sure threading support is enabled in X
CORECPPFLAGS.append( '-DXTHREADS' )

# don't wrap gcc messages
BASECPPFLAGS.append( '-fmessage-length=0' )

if ( TARGET_ARCH == 'x86' ):
	BASECPPFLAGS.append( '-m32' )
	BASELINKFLAGS.append( '-m32' )
if ( TARGET_ARCH == 'x64' ):
	BASECPPFLAGS.append( '-m64' )
	BASELINKFLAGS.append( '-m64' )

if g_os == 'Linux':
	BASELINKFLAGS.append( '-pthread' )
	BASELINKFLAGS.append( '-lrt' )
	# Add the __linux__ define
	BASECPPFLAGS.append('-D__linux__')
elif g_os == 'FreeBSD':
	# FreeBSD
	BASELINKFLAGS.append( '-L/usr/local/lib' )
	BASELINKFLAGS.append( '-pthread' )
	BASELINKFLAGS.append( '-lrt' )
	BASELINKFLAGS.append( '-lz' )
	BASELINKFLAGS.append( '-lnghttp2' )
 	# Add the __freebsd__ define
	BASECPPFLAGS.append('-D__freebsd__')
elif g_os == 'MacOSX':
	# Mac OS X
	BASECPPFLAGS.append('-DMACOS_X')
	if TARGET_ARCH == 'x86':
		# Perform an Intel build
		BASECPPFLAGS.append(['-arch', 'i386', '-D__i386__'])
		BASELINKFLAGS.append(['-arch', 'i386'])
	elif TARGET_ARCH == 'ppc':
		# Perform a PowerPC build
		BASECPPFLAGS.append(['-arch', 'ppc', '-D__ppc__'])
		BASELINKFLAGS.append(['-arch', 'ppc'])

if ( BUILD == 'debug' ):
	OPTCPPFLAGS = [ '-g', '-O1', '-D_DEBUG' ]
elif ( BUILD == 'release' ):
	OPTCPPFLAGS = [ '-O2' ]
else:
	print 'Unknown build configuration ' + BUILD
	sys.exit(0)

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

g_base_env.Append(CPPPATH = '#/')
path_template = '#/../ThirdParty/artefacts/{0}/include'
g_base_env.Append(CPPPATH = path_template.format('zlib'))
g_base_env.Append(CPPPATH = path_template.format('libcurl'))
g_base_env.Append(CPPPATH = path_template.format('tinyformat'))
g_base_env.Append(CPPPATH = '#/libtdm_update')

# use includes from fbsd userland
# note: used only on TDM server
if g_os == 'FreeBSD':
	g_base_env.Append(CPPPATH = '/usr/local/include')

g_env = g_base_env.Clone()

g_env['CPPFLAGS'] += OPTCPPFLAGS
g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
g_env['CPPFLAGS'] += CORECPPFLAGS

# mark the globals
GLOBALS = 'g_env g_os TARGET_ARCH libtdm_update_list'

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

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

libtdm_update_list = None
Export( 'GLOBALS ' + GLOBALS )

# map this whole directory into build dir
VariantDir( g_build, '.', duplicate = 0 )
# map 'ThirdParty' dir from parent directory into 'ThirdParty' subdir
VariantDir( g_build + '/ThirdParty', '../ThirdParty', duplicate = 0 )
Export( 'GLOBALS ' + GLOBALS )

# build libraries
libtdm_update_list = SConscript( g_build + '/SConscript.libtdm_update' )
Export( 'GLOBALS ' + GLOBALS )

# Build the updater except on the TDM server
if g_os != 'FreeBSD':
    tdm_update = SConscript(g_build + '/SConscript.tdm_update')
    InstallAs( '#' + scons_utils.ExecutableName('bin/tdm_update', g_os, TARGET_ARCH), tdm_update )
# Build the packager
tdm_package = SConscript(g_build + '/SConscript.tdm_package')
InstallAs( '#' + scons_utils.ExecutableName('bin/tdm_package', g_os, TARGET_ARCH), tdm_package )

# end targets ------------------------------------

