#!/usr/bin/env python """ This script is meant to be imported by aanet's make.py build scripts. It defines the compiler and linker flags. When run as stand-alone command, it prints all the settings. """ import os, sys from util import aafabricate from util.aafabricate import shell, ExecutionError, run, after, subjob, subjobs_report d1 = dir() def env( key ) : try : return os.environ[key] except : return None aadir = env('AADIR') if not aadir : print("Please run 'source setenv.sh' first, to set the AAnet environment.") raise SystemExit build_dir = aadir+"/build/" lib_dir = aadir+"/lib/" aa3dwww = os.environ['HOME']+"/www/aa3d/" root_config = os.environ['ROOTSYS'] + '/bin/root-config' incroot = shell(root_config,'--cflags') libroot = shell(root_config,'--libs') +' -lEG ' rootcintopt = "-I"+shell(root_config,'--incdir') rootversion = shell( root_config , "--version").split("/") gccversion = shell("gcc","--version").splitlines()[0].split()[-1] #gccversion = int( ( gccversion.decode("utf-8") ).split(".")[0] ) # major version only gccversion = int( ( gccversion ).split(".")[0] ) cc = "g++" gccopt = "-fPIC -Wall -g -O3 " # support ancient compiler in lyon print( gccversion, rootversion[0]) if gccversion < 5 : gccopt += "-std=c++11" if float(rootversion[0])<6.26 : aafabricate.stdcxx = "-std=c++11" fortran_comp= 'gfortran -fPIC -fno-second-underscore ' libfortran = " -lgfortran " dirjpp = env('JPP_DIR') or aadir+'/jpp' #libjpp = "-L"+dirjpp + "/out/Linux/lib/ -Wl,--unresolved-symbols=ignore-all -ltriggerROOT -llang -levtROOT -L/pbs/home/h/heijboer/sps/aanet_df/lib " libjpp = "-L"+dirjpp + "/out/Linux/lib/ -lacousticsROOT -lcompassROOT -ltriggerROOT -llang -luuid -levtROOT -L/pbs/home/h/heijboer/sps/aanet_df/lib " incjpp = "-I" + dirjpp + "/software/ -I"+dirjpp+"/externals/antares-daq/include/" haveantcc = os.path.exists( dirjpp+"/externals/antares-daq/include/antcc") incaa = "-I" + aadir + "/evt -I"+aadir+"/astro -I" + aadir +" -I"+aadir+"/externals -I"+aadir+"/externals/km3net-dataformat/offline " +"-I"+aadir+"/externals/km3net-dataformat/online -I"+aadir+"/externals/flux" libdatafmt = "-L"+aadir+"/externals/km3net-dataformat/lib/ -lKM3NeTROOT -luuid" libflux = "-L"+aadir+"/externals/flux/ -lKM3NeTflux" libaa = "-L"+aadir+"/lib -laaevt -laastro " + libfortran # --------------------------------- # Check jpp and antcc # --------------------------------- if os.path.exists( dirjpp ) : gccopt += " -D HAVEJPP " rootcintopt += " -DHAVEJPP " if not dirjpp in env("LD_LIBRARY_PATH"): print ("note: JPP lib dir not in LD_LIBRARY_PATH -> using full-path linking") w = " -Wl,-rpath,"+dirjpp+"/out/Linux/lib " libjpp = w + libjpp else : print ("NOTE: will build without JPP") libjpp = incjpp = dirjpp = "" if haveantcc : gccopt += " -D HAVEANTCC " rootcintopt += "-DHAVEANTCC " libjpp += dirjpp + "/externals/antares-daq/out/Linux/lib/libantccROOT.so " # ------------------------------------------------- # Some strange hack for apple(?) # ------------------------------------------------- if sys.platform == 'darwin': incroot = incroot.replace('-stdlib=libc++', '') libroot = libroot.replace('-stdlib=libc++', '') # ================================================= # default functions to compile, build, etc # ================================================= def base( s ): return s.rsplit('.',1)[0].rsplit("/")[-1] def write_dictionary( source_file ) : "call rootcint on a source file. If the source file is a .cc, the dictonary uses the .hh" dict_cc_file = build_dir+"/"+base(source_file)+'.dict.cc' linkdef = base(source_file)+'.linkdef.h' source_file = source_file.replace(".cc",".hh") run('rootcling -f {dict_cc_file} {rootcintopt} {incaa} {incjpp} {source_file} {linkdef}') return dict_cc_file def compile( source_file , extra_args = "" ) : obj = build_dir+"/"+base(source_file)+'.o' # tell gcc we really want to build an obj file, even if it's a .hh xopt = "-x c++" if source_file.endswith("h") else "" run('{cc} {gccopt} -c -o {obj} {extra_args} -I. {incaa} {incroot} {incjpp} {xopt} {source_file} ') return obj def compile_fortran( source_file ): obj = source_file.replace(".f",".o") run('{fortran_comp} -c -o {obj} {source_file} ') return obj def make_library( object_files, target , extra_link_args = "" ): objs = " ".join( object_files ) res = run('{cc} {gccopt} -shared {objs} {libroot} {libdatafmt} {libflux} {libjpp} {extra_link_args} -o {target} ') return res def make_executable( source_file, target = 'auto', extra_args = '' ): if target == 'auto' : target = source_file.replace(".cc","") res = run('{cc} -Wl,--no-as-needed {gccopt} {incaa} {incroot} {incjpp} {libroot} {libdatafmt} {libflux} {libjpp} {libaa} {extra_args} -o {target} {source_file} ') def default_build_shared_library( sources, target, extra_link_args = "", extra_compile_args = "" ): with subjob("generating root dictionaries") : dict_files = [ write_dictionary( s ) for s in sources ] with subjob("compiling c++ files"): obj_files = [ compile( s , extra_args = extra_compile_args ) for s in sources + dict_files ] with subjob("linking and copying pcm files"): make_library( obj_files , target , extra_link_args ) pcm_files = " ".join( s.replace('.cc' , '_rdict.pcm' ) for s in dict_files ) run("cp {pcm_files} {lib_dir}") subjobs_report() # ------------------------------------------------- # Parameters that control the build process # ------------------------------------------------- dependency_dirs = [ '.', aadir ] parallel_jobs = 4 build_debug = True # ------------------------------------------------- # Nice output # ------------------------------------------------- D = locals() setup_s = "\n".join( [ "%15s : %s " % (k, D[k]) for k in dir() if k not in d1 and k != 'd1' \ and not k.startswith("__") ] ) def print_setup(): print ("========================================================================") print (setup_s) print ("========================================================================") if __name__ == "__main__" : print_setup()