#
#     Copyright (c) 2017-2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

# Compiler Configurations for native Linux/x86 targets
#
include rcfiles/lincommonrc;

#
# Environment variables/variables which are needed for the "module" command
#
variable NVINCDIRENV is environment(NV_OPTL_INCLUDE_DIRS);
variable NVLIBSDIRENV is environment(NV_OPTL_LIB_DIRS);
variable NVLIBSENV is environment(NV_OPTL_LIBS);
set NVOPTLLIBSDIR=$replace($NVLIBSDIRENV,":", );
set NVOPTLLIBS=$replace($NVLIBSENV," ", );
set NVOPTLINCDIR=$replace($NVINCDIRENV,":", );

# directories
set DEFASDIR=$PATH;
#ORIGset DEFSTDINC=$foreach(dd,$COMPINCDIR,$COMPBASE/$COMPSYS/$COMPVER/$(COMPINCPREFIX)$dd ) /usr/local/include $GCCINC $GCCDIR/include /usr/include;
set DEFSTDINC=$foreach(dd,$COMPINCDIR,$COMPBASE/$COMPSYS/$COMPVER/$(COMPINCPREFIX)$dd )  $GCCINC  $NVOPTLINCDIR;
#need a saved version of the above
set OLDSTDINC=$foreach(dd,$COMPINCDIR,$COMPBASE/$COMPSYS/$COMPVER/$(COMPINCPREFIX)$dd ) $GCCINCDIR;
variable DEFCPPINCSUFF is hide default(CC);
set DEFCPPINC=$NVOPTLINCDIR $OLDSTDINC $if($IS_CPLUS,$GPPDIR);
set DEFLDDIR=$PATH;
set DEFMVDIR=$PATH;

# arguments
set DEFASARGS=;
set DEFCOMMON=-x 119 0xa10000 $NOLLALIGN -x 122 0x40 -x 123 0x1000 -x 127 4 -x 127 17 $ILPALIGN
    -x 19 0x400000 -x 28 0x40000 -x 120 0x10000000
    $TARGETCOMMON $LINUXCOMMON
    $MVECT
    $if($X86_64TARGET,-x 59 4)
    $if($CG2,-x 59 4)
    $if(-Kieee,-x 6 0x100) $TPVAL $if($DODWARF,-x 120 0x1000);
set DEFCARGS=$DEFCOMMON $MALIGN;
set DEFCPPARGS=$DEFCOMMON $MALIGN;
set DEFCEXTARGS=$DEFCOMMON $MALIGN;
set DEFFARGS=$DEFCOMMON -x 51 0x20 -x 124 0x1401;
set DEFFEXTARGS=$DEFCOMMON -x 51 0x20 -x 124 0x1401;
variable GCCVERSION is default(0);
set DEFGNU=$if($expr($GCCVERSION>20000),--gnu_version=$GCCVERSION -D__pgnu_vsn=$GCCVERSION);
set DEFGNU2=$if($expr($GCCVERSION>20000),-gnuvsn $GCCVERSION);
set DEFGNUC=$if($expr($GCCVERSION>20000),-def __pgnu_vsn=$GCCVERSION);
set DEFF90COMMON=
    $NOLLALIGN
    -x 19 0x400000
    $if($equal($TARGETARCH,64),-quad)
    $if($X86_64TARGET,-x 59 4)
    $if($CG2,-x 59 4)
    -x 15 2 -x 49 0x400004 -x 51 0x20 -x 57 0x4c -x 58 0x10000 -x 124 0x1000;
set DEFF902COMMON=-x 51 0x20
    $DEFCOMMON -x 124 0x1400 -y 15 2;
set DEFF901ARGS= -nostatic $DEFF90COMMON $TPVAL -x 57 0xfb0000 -x 58 0x78031040 $MVECTSIMDWID $if($expr($OPTLEVELUSE>=2),-x 70 0x6c00 -x 47 0x400000) -x 47 0x08;
set DEFF902ARGS=$DEFF902COMMON -x 57 0x3b0000 -x 58 0x48000000;
set DEFF90EXTARGS=-x 124 0x1400 -x 51 0x20  -nostatic;
variable LDSO is default(/lib/ld-linux.so.2);

variable ADDEHFRAME is default($if($or($equal($TARGETARCH,64),$IS_CPLUS),1));
variable EHFRAME is default($if($or($ADDEHFRAME, $equal($TRACEBACKSW,ON)),$if($equal($TRACEBACKSW,ON),$ifn(-Bstatic,--export-dynamic)) --eh-frame-hdr));

set DEFLDSTARTUP = $LCRT1 $LCRTI $LTRACE $LCRTB $LEVENTI $if($ACCMULTI,$LINITACC) $if($CONCUR,$LINITMP) $if($PROFILE,$LPROFO) $FTNMAIN $EHFRAME;
set DEFMUNCHLDSTARTUP =$DEFLDSTARTUP;
set DEFLDENDUP = $LCRTE $LCRTN;
set DEFSTDDIRS = $if($isdir($FLANGLIBDIR),$FLANGLIBDIR) $CPPLIB $COMPLIBMP $LOCALBINDLIB $COMPLIBSO $COMPLIBLF $COMPLIB $COMPLIBSTATIC $LIBDIR $GCCDIR $G77LIBDIR $NVOPTLLIBSDIR;
variable NORPATH is default();	#  set by -Mnorpath
variable NOPGIRPATH is default();	# set by -static-nvidia
set DEFSTDPATHS = $ifn($NORPATH,$ifn($NOPGIRPATH,$SITERPATHS $LOCALBINDPATHS $USRRPATH $STDRPATHMP $foreach(ll,$replace($USER_LIBRARY_PATH,",", ), -rpath $ll)) $STDRPATHSO $ifn($NOPGIRPATH,$STDRPATHLF $STDRPATH) $CUDARPATH)  $ifn($NORPATH,$GCCRPATH);
variable PGISTATIC is default();
variable PGISTATICX is default($PGISTATIC);
variable PGIUNSTATIC is default();
variable PGIUNSTATICX is default($PGIUNSTATIC);
set DEFSTDLIBS = $PGISTATIC $ifn($NOSTDLIBS, $if($CONCUR,$LMP), $SSEMMLIBS) $ifn($NOSTDLIBS,$SSELIBS $STARTGROUP $MRTL $CRTL $STUBS $ENDGROUP) $PGIUNSTATIC $ifn($NOSTDLIBS,$LRTLIB $G77LIBLIB $STARTGROUP $LC $LM $ENDGROUP) $NVOPTLLIBS;
set LDLIB3=$LMPIPROFLIB $PGISTATIC $LMPILIB $PGIUNSTATIC $STARTGROUP $MATHCUDALIB $LCUDAFORLIB $FLANGCUDALIBS $ACCTOOLLIB $ACCLIB $OMPDEVLIB $CUDALIB $MANCUDALIB $LCUDALIB $ACCLIB2 $LCUDAFOR2LIB $ifn($NOSTDFTNLIBS, $PGISTATIC $FTNRTL $PGIUNSTATIC) $ENDGROUP;

# other settings
set DEFASTYPE=ELF;
set DEFCACHESIZE=$test(cachesize);

# names of, directories of, arguments to programs used as tools
variable COMPLIBLF is	# used with -Mlfs
	default($LOCALCOMPLIBLF $foreach(dd,$COMPLIBLFDIR,$COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)$dd ));
variable COMPLIBLFDIR is	# set by -Mlfs
	help(Compiler library subdirectory for large file support)
	default();
variable COMPGLIBDIR is default();
variable COMPGLIBLFDIR is default();	# used with -Mlfs
variable LOCALCOMPLIBLF is default();
variable COMPLIBSO is default();	# used with -KPIC
variable CPPLIB is default();
variable SITERPATHS is default($if($SITERPATH,$foreach(dd,$SITERPATH,-rpath $dd )));
variable LOCALBINDPATHS is default($if($LOCALBINDLIB,-rpath $LOCALBINDLIB));
variable SITERPATH is default();
variable USRRPATH is default();
variable EXTRACOMPLIBDIR is default();
variable STDRPATH is default($if($notequal($LOCALCOMPLIB,),-rpath $LOCALCOMPLIB) $if($isdir($FLANGLIBDIR),-rpath $FLANGLIBDIR) $foreach(dd,$COMPLIBDIR $EXTRACOMPLIBDIR,-rpath $COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)$dd ));
variable STDRPATHLF is default();
variable STDRPATHSO is default();

variable LM is default(-lm);
variable HUGELIB is default();
variable LNSPGC is default(-lns$(PFX)c);
variable CRTL is default($HUGELIB $LNSPGC -l$(PFX)c);
#
# ISANYAVX =  (ISTPHOST && (AVX512VL | AVX2 | AVX))) || ((tp == icelake) || (tp == skylake) || (tp == haswell) || (tp == sandybridge))
# if linking for any AVX*, ISANYAVX will be "-avx512", "-avx2", or "-avx"
variable AVXEXTENSION is default(
         $select($AVX512VL-$AVX2-$AVX,1-1-1,-avx512,0-1-1,-avx2,0-0-1,-avx,0-0-0,));
variable ISANYAVX is default(
         $if($ISTPHOST,
           $AVXEXTENSION,
           $select($CLTPVAL,"-tp icelake","-avx512","-tp skylake","-avx512","-tp haswell","-avx2","-tp zen","-avx2","-tp zen2","-avx2","-tp sandybridge","-avx")));
variable MRTL is default(
         $if($notequal($PGISTATIC,),
           -lnvcpumath $if($andnot($notequal($ISANYAVX,),$FMA4), $COMPLIB/nvcpumath$ISANYAVX.ld --undefined=__nv_noextlib),
           "-lnvcpumath"$ifn($FMA4,$ISANYAVX)));
variable LFC is default();
variable G77LIBLIB is default();
variable GCCDIR is default();
variable GCCINC is default();
variable G77DIR is default();
variable G77LIBDIR is default();
variable LC is default(-lgcc -lc -lgcc);
variable LCRT1 is default ($if($equal($PROFFLAG,-pg),$STDOBJDIR/gcrt1.o,$STDOBJDIR/crt1.o));

variable LCRTI is default ($STDOBJDIR/crti.o);
variable LCRTB is default ($LCRTBDEF);	# set by -shared
variable LCRTBDEF is default ($GCCDIR/crtbegin.o);	# set by -Bstatic, can be over-ridden by -shared
variable LEVENTI is default ();
variable LINITACC is default ($lookup($COMPLIBOBJ,initacc.o));
variable LINITMP is default ($lookup($COMPLIBOBJ,initmp.o));
variable LTHREAD is default(-lpthread);
variable LMP is default (-lpgmp $if($CONCURSW,$PGIUNSTATICX $PGISTATICX) $PGIUNSTATIC $LTHREAD $PGISTATIC);
variable LCRTE is default ($GCCDIR/crtend.o);
variable LCRTN is default ($STDOBJDIR/crtn.o);
variable LPROFO is default ($lookup($COMPLIBOBJ,init_pgpf.o));
variable LTRACE is default ();
variable LMPILIB is default ();
variable LMPIPROFLIB is default ();
# If compiling a plain `.cu` file add `-lrt` when statically linking
variable LRTLIB is default ($if($land($ANYCU,$equal($PGISTATICX,-Bstatic)),$LRTLIBNAME));
variable LRTLIBNAME is default (-lrt $LTHREAD);

suffix lo is string(lo) help(Libtool object: link);
suffix la is string(la) help(Libtool archive: link);
set LINKNOBJSUFFIX=a lo la;
set LINKOBJSUFFIX=o;

tool makelocalrc is
  program(makelocalrc) directory($DRIVERDIR);

switch -Bdynamic is
	help(Passed to linker; specify dynamic binding)
	helpgroup(linker)
	set(PGISTATICX=)
	set(PGIUNSTATICX=)
	positional(linker);

switch -Bsymbolic is
	help(Passed to linker; specify symbolic binding)
	helpgroup(linker)
	positional(linker);

switch -gfortranlibs is
	help(Include gfortran library when linking)
	set(G77LIBLIB=$if($notequal($G77DIR,),$LFC))
	set(G77LIBDIR=$if($notequal($G77DIR,),$G77DIR,$warning(compiler installation did not find libg2c or libgfortran - -g77libs ignored)))
	helpgroup(linker);
switch -g77libs is hide
  shorthand(-gfortranlibs);

switch -R$ldarg is
	help(Passed to linker; just link symbols from object, or add directory to run time search path)
	helpgroup(linker)
	positional(linker);

switch -rpath dir is
	help(Passed to linker; add directory to runtime shared library search path)
	helpgroup(linker)
	replace(-rpath $dir)
	positional(linker);

switch -Mnorpath is
	help(Don't add -rpath paths to link line)
	helpgroup(linker)
	set(NORPATH=YES);

switch -Mrpath is hide
	help(Do add -rpath paths to link line)
	helpgroup(linker)
	set(NORPATH=);

switch -Mscalapack is
	help(Add Scalapack libraries)
	helpgroup(linker)
	append(LDLIB1=$if($equal($INTEGER64BIT,YES),
		-lscalapack_ilp64 -llapack_ilp64 -lblas_ilp64,
		-lscalapack_lp64 -llapack_lp64 -lblas_lp64))
	;

variable MKL_LOCATION is default() environment(MKLROOT);

# nvflang uses the same ABI as gfortran, hence use the gfortran
# compatible of MKL library. For nvfortran, keep using the intel
# version.
variable MKL_VERSION is default($if($ISNVNG,gf,intel));

switch -Mmkl is
	helpgroup(linker)
    help(Add Intel's Math Kernel libraries to the link line. Requires that the environment variable MKLROOT be set to the path to the local MKL installation--the part of the path that precedes 'lib/<arch>'.)
    fatal($if($equal($MKL_LOCATION,),MKLROOT not found. Please set the environment variable MKLROOT to the location of Intel's Math Kernel Libraries (the part of the path to the *.so files that precedes 'lib/<arch>'.),))
	append(USRINC=$MKL_LOCATION/include)
    append(LDLIB1=-L$MKL_LOCATION/lib/intel64)
    append(USRRPATH=-rpath $MKL_LOCATION/lib/intel64)
    append(LDLIB1=$if($equal($INTEGER64BIT,YES),
		      -lmkl_$(MKL_VERSION)_ilp64,
		      -lmkl_$(MKL_VERSION)_lp64
		     )
	  )
    append(LDLIB1=$if($equal($CONCURCOMPILE,YES),
		      $if($equal($LLVMVERSION,),
			  -lmkl_pgi_thread,
			  -lmkl_intel_thread
			 ),
		      -lmkl_sequential
		      )
	  )
    append(LDLIB1=-lmkl_core)
	;

switch -Mstabs is hide
	help(Disabled; for compatibility only)
	helpgroup(debug); # disabled for linux may 2006

switch -m is
	help(Passed to linker; display link map)
	helpgroup(linker)
	append(LDSWITCHES=-M);

switch --whole-archive is
	helpgroup(linker)
	help(Passed to linker; includes all objects in subsequent archives)
	helpname(--[no-]whole-archive)
	positional(linker);

switch --no-whole-archive is hide
	helpgroup(linker)
	help(Passed to linker; turns off --whole-archive)
	positional(linker);

switch --as-needed is
	helpgroup(linker)
	help(Passed to linker; only set DT_NEEDED for the following shared libraries if they are used)
	helpname(--[no-]as-needed)
	positional(linker);

switch --no-as-needed is hide
	helpgroup(linker)
	help(Passed to linker; restores default behavior after --as-needed)
	positional(linker);

variable HUGEN is default();
switch -Msmartalloc is
	helpgroup(opt)
	helpname(-M[no]smartalloc)
	help(Add call in main routine to enable optimized malloc routines)
	append(CGARGS=-x 129 0x20000000)
	nokeyword()
	keyword(
	    huge(
		helpname([no]huge)
		help(Link in the huge page runtime library)
		set(HUGEN=0)
		append(CGARGS=-x 129 0x10000000)
		set(HUGELIB=$if($NOPGIRPATH,$PGISTATIC)
			-lhugetlbfs_nvhpc
			$if($NOPGIRPATH,-u __pgi_setup_morecore))
	    )
	    huge:n(
		help(Link the huge page runtime library and allocate n huge pages)
		set(HUGEN=$n)
		append(CGARGS=-x 129 0x10000000 -x 156 $HUGEN)
		set(HUGELIB=$if($NOPGIRPATH,$PGISTATIC)
			-lhugetlbfs_nvhpc
			$if($NOPGIRPATH,-u __pgi_setup_morecore))
	    )
	    nohuge( # disable previous -Msmartalloc=huge
		hide
		set(HUGEN=0)
		append(CGARGS=-y 129 0x14000000)
		set(HUGELIB=)
	    )
	    hugebss(	if($equal($TARGET,linux86-64))
		help(Put the BSS section in huge pages)
		append(CGARGS=-x 129 0x4000000)
		set(HUGELIB=$if($NOPGIRPATH,$PGISTATIC)
			-lhugetlbfs_nvhpc
			$if($NOPGIRPATH,-u __pgi_setup_elflink))
		set(COMPLIBOBJ=$COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)$COMPLIBSUBDIR)
		set(STDRPATHSO=-rpath $COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)$COMPLIBSUBDIR)
		append(DEFLDARGS=-T $COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)$quote($COMPLIBPREFIX)lib/hugebss.ld)
	    )
	);

switch -Mnosmartalloc is hide
	helpgroup(opt)
	help(Don't add call in main routine to enable optimized malloc routines)
	append(CGARGS=-y 129 0x34000000)
	set(HUGEN=0)
	set(HUGELIB=);


switch -soname soname is
	helpgroup(linker)
	replace(-soname=$soname)
	positional(linker)
	help(Passed to linker; sets DT_SONAME field to the specified name);

switch -Mhugetlb is hide
	help(Link with huge TLB page libraries)
	helpgroup(linker)
	set(HUGEN=0)
	append(CGARGS=-x 129 0x10000000)
	set(HUGELIB=$if($NOPGIRPATH,$PGISTATIC)
		-lhugetlbfs_nvhpc
		$if($NOPGIRPATH,-u __pgi_setup_morecore));
#	append(DEFLDARGS=--hugetlbfs-link=BDT);

switch -Meh_frame is
	helpname(-M[no]eh_frame)
	help(Add link flags to preserve exception-handling frame information)
	helpgroup(linker)
	set(ADDEHFRAME=1);

switch -Mnoeh_frame is hide
	help(Don't add link flags to preserve exception-handling frame information)
	helpgroup(target)
	set(ADDEHFRAME=0);
