#vim: set filetype=python
import os
import glob



#Add build option, use icc or gcc
AddOption('--useicc',
			dest='useicc',
			type='string',
			nargs=1,
			action='store',metavar='',help='use icc instead of gcc');

#export the environment
env = Environment(ENV=os.environ)
envVar = env['ENV']
bUseICC = True #default use ICC
sz = GetOption('useicc')
if sz == '0':
	bUseICC = False
	print "!!Use g++ to build"
else:
	print "!!Use Intel CC to build!!"


#define the subdir first
bin = './bin'
src = './src'

#include directory
home= envVar['HOME']
sephome = envVar['SEP']

cwd = os.getcwd()
print "current directory : ", cwd
print env

#code frame directory
cd = os.getcwd()
frame  =  cd+'/codelib'
srcframe = frame+'/src'

libpath = [sephome+'/lib']
libs = ['sep3d','sep','sepfilter','superset','stdc++']
inc = [sephome+'/include', srcframe, src]
inc.append(sephome+'/../seplib/seplib_base/lib/corelibs/include');
if (not bUseICC):
	obj = './obj'
	libs.append('gomp')
else:
	obj = './objicc'

#print "inc = ", inc
#need to specify the ./ directory as -I as well
sepArch = envVar['SEP_ARCH']

env['CPPPATH'] = inc
env['LIBPATH'] = libpath
env['LIBS'] = libs 
        
env['CPPDEFINES'] = sepArch

if (not bUseICC):
	env['CCFLAGS'] = ' -O2 -fopenmp -Wall -g '
else:
	#icc flags, related
	env['CCFLAGS'] = ' -O2 -g '   
	env['CC'] = 'icc'
	env['CXX'] = 'icc'
	env['LINKERFORPROGRAMS'] = 'icc'

env['LINKFLAGS'] = '-rdynamic'

#export the env
Export('env','envVar')

#Call the script in the src folder for .o files
comObjList = SConscript([srcframe+'/Sconscript'], variant_dir=obj,duplicate=0)

#Then build the local src directory
env['CPPPATH'] = inc
print 'env_CPPPATH', env['CPPPATH']

#build the obj files in the current src folder
#VariantDir(obj,src,duplicate=0)

cpplist = glob.glob(src+'/*.cpp')

objs = [] 
gpuCppObjs = []

#substitute the path with obj path
for f in cpplist:
    pt,fn = os.path.split(f)
    #sepearte the extensions
    fn1,ext = os.path.splitext(fn)
	 #decide which clist it belongs to
    ind = fn.find('gpu.cpp')
    if ind == -1: # regular cpu cpp files
        objs.append(env.Object(obj+os.sep+fn1+'.o',f))
    else:   # cpp that has connection with CUDA functions
        gpuCppObjs.append(env.Object(obj+os.sep+fn1+'.o',f))


#Build the cuda .cu.o objects
#directory
cudaDir = '/opt/nvidia/cuda'
cudaInc = cudaDir+'/include'
cudaLib = cudaDir+'/lib64'
#SDK CUDA
cudaSDKdir = '/opt/nvidia/cuda-2.3_sdk/C'
cudaSDKinc = cudaSDKdir + '/common/inc'
cudaSDKlib = cudaSDKdir + '/lib'
cudaLibs = ['cuda', 'cutil', 'cublas', 'cufft']

nvccBin = cudaDir + '/bin/nvcc'

cudaEnv = Environment();
cudaEnv.Tool('cuda2', toolpath=[frame+'/script'])

cudaEnv['CUDA_TOOLKIT_PATH'] = cudaDir
cudaEnv['CUDA_SDK_PATH'] = cudaSDKdir
cudaEnv['NVCC'] = nvccBin

##Already have
#cudaEnv.Append(CPPPATH=[cudaInc, cudaSDKinc])
cudaEnv.Append(CPPPATH=srcframe)
cudaEnv.Replace(NVCCFLAGS='-O2 -g ')

# includes.
cudaEnv.Append(NVCCINC=' '+ ''.join(['-I',srcframe]) + ' ')
cudaEnv.Append(NVCCINC=' '+ ''.join(['-I',srcframe]) + ' ')
cudaEnv.Append(NVCCINC=' '+ ''.join(['-I',cudaSDKinc]) + ' ')
cudaEnv.Append(NVCCINC=' '+ ''.join(['-I',cudaInc]) + ' ')
cudaEnv.Append(NVCCINC=' '+ ''.join(['-I',sephome+'/include']) + ' ')

cudaEnv.Replace(OBJSUFFIX= '.cu.o')
#cudaEnv.Replace(CPPSUFFIXES= '.cu')
"""
dict = cudaEnv.Dictionary()
keys = dict.keys()
keys.sort()
for key in keys:
    print "env variables = '%s', value='%s'" % (key,dict[key])
"""

#build the "cu.o" files
cuList = glob.glob(src+'/*.cu');
cudaObjs = []
for f in cuList:
	pt,fn = os.path.split(f)
	rf,ext= os.path.splitext(fn)
	cudaObjs.append(cudaEnv.Object(obj+os.sep+rf+'.o',f))

#for main.cpps
srcProgDir = src+'/prog'
#!!!Scons does not allow redirect dir twice
#VariantDir(obj,srcProgDir,duplicate=0)
progCppNameList=[]
progBinNameList=[]
progObjNameList=[]
progObjs = []
progCppNameList = glob.glob(srcProgDir+'/*.cpp')

l = len(progCppNameList)
#substitute the path with obj path
#for f in cpplist:
for i in range(0,l):
    pt,fn = os.path.split(progCppNameList[i])
    rf,ext = os.path.splitext(fn)
    #change the fn file extension to .x
    progObjNameList.append(obj+os.sep+rf+'.o')
    progBinNameList.append(bin+os.sep+rf+'.x')
    progObjs.append(env.Object(progObjNameList[i],progCppNameList[i]))

#need to build prgrams one by one
for i in range(0,l):
    target = progBinNameList[i]
    print target,"<-target",progObjs[i]
    #Can only concatenate lists, therefore the last brackets are critical
    env.Program(target,comObjList+objs+[progObjs[i]])

#Build program that needs CUDA support
srcCudaProgDir = src+'/cudaProg'
progCppNameList=[]
progBinNameList=[]
progObjNameList=[]
progObjs = []
cudaBuildEnv = env.Clone();
cudaBuildEnv.Append(LIBPATH=[cudaLib, cudaSDKlib])
cudaBuildEnv.Append(LIBS=cudaLibs)

progCppNameList = glob.glob(srcCudaProgDir+'/*.cpp')
print progCppNameList
l = len(progCppNameList)
#substitute the path with obj path
#for f in cpplist:
for i in range(0,l):
    pt,fn = os.path.split(progCppNameList[i])
    rf,ext = os.path.splitext(fn)
    progObjNameList.append(obj+os.sep+rf+'.o')
    #change the fn file extension to gpux
    progBinNameList.append(bin+os.sep+rf+'.gpux')
    progObjs.append(env.Object(progObjNameList[i],progCppNameList[i]))


#need to build prgrams one by one
for i in range(0,l):
    target = progBinNameList[i]
    print target,"<-Cuda target",progObjs[i]
    #Can only concatenate lists, therefore the last brackets are critical
    cudaBuildEnv.Program(target,comObjList+objs+gpuCppObjs+cudaObjs+[progObjs[i]])
#Just move the .gpux file to bin folder


### LATEX PART ######
from rsftex import *
End(resdir='fig',use='color,amsmath,amssymb,amsfonts,rplabels')

