CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Path: gap4r8 / cnf / gac.in
Views: 418346
#!/bin/sh
#############################################################################
##
#W  gac.sh                      GAP compiler                 Martin Schoenert
##
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
##
##  gac [-d] [-c|-C] [-o <output>] {-f<option>} <input>...
##
##  'gac'  compiles the input files.   Input files  must be  GAP  source code
##  (suffix '.g' or '.gap'),  C source code (suffix '.c'),  or compiled  code
##  files (suffix '.o').
##
##  If '-d' is given then the code is compiled for dynamic loading
##  
##  If  neither '-c' nor '-C'  is given,  then 'gac'  compiles the code completely,
##  producing a  new kernel for static compilation or a dynamically loadable '.so'
##  file for dynamic compilation.
##
##  If '-c' is given,  then 'gac' only compiles the input files to 
##  '.o' object files, which must be further linked to make a static kernel or
##  dynamically loadable module
##
##  If '-C is given, then 'gac' only compiles the input files to C code, which 
##  will require compilation and linking to be usable.
##
##  If '-r' is given, then statically compiled files will be assumed to be given
##  by pathnames relative to the GAP root, and will be compiled for automatic loading
##  when files are sought relative to the GAP root.
##
##  The option '-o <output>' tells 'gac' to name the output file <output>.
##
##  The option  '-ffast-int-arith' tells  'gac' to emit  code for  arithmetic
##  operations, which works faster if both  operands are  small integers  and
##  slower otherwise.
##
##  The option '-ffast-plain-lists' tells 'gac' to emit code for list access,
##  which works faster if the list is a plain list and slower otherwise.
##
##  The option '-ffast-list-funcs' tells 'gac' to inline  the functions 'Add'
##  and 'Length' the code, which makes it a bit faster.
##
##  The option '-fno-check-types' tells 'gac' to  emit  no  error checks  for
##  list access, which makes it faster but may dump core if an error happens.
#
##  The option '-p <option>' tells 'gac' to pass the option  <option> to  the
##  C compiler.
##
##  The option '-P <option>' tells 'gac' to pass the option  <option> to  the
##  C linker.
##
##  The option '-L <option>' tells 'gac' to pass the option  <option>
##  to the C linker when linking dynamic modules. Contrary to -P the
##  option is appended at the end of the link command after the .o
##  files to link.
##
gap_bin=@gapbin@

if [ "X${gap_bin}" = "X$0" ];  then
    gap_dir="../../";
    gap_compiler="./gap";
    gap_binary="./";
else
    gap_dir="${gap_bin}/../..";
    gap_compiler="${gap_bin}/gap";
    gap_binary="${gap_bin}";
fi
gap_options=""
gap_include="${gap_dir}/src"
stat_identifier="USER";

# These three should be filled in by the standard autoconf procedures 
c_compiler="@CC@"
c_options="@CPPFLAGS@ @CFLAGS@ @GMP_CFLAGS@"
c_linker="@CC@"
c_link_options="@LDFLAGS@"
c_libs="@LIBS@ @GMP_LIBS@"

# These will need special care
c_dyn_options="@CPPFLAGS@ @CDYNOPTIONS@ @GMP_CFLAGS@"
c_dyn_linker="@CDYNLINKER@"
c_dyn_linking="@CDYNLINKING@"
c_dynlibs="@C_DYNLIBS@"
c_addlibs=""

# hardwire this for now. There is probably a nicer way 
# note: compstat.o is omitted on purpose from this list

OBJECTS="\
    ariths.o \
    blister.o \
    bool.o \
    c_filt1.o \
    c_meths1.o \
    c_oper1.o \
    c_random.o \
    c_type1.o \
    calls.o \
    code.o \
    compiler.o \
    costab.o \
    cyclotom.o \
    dt.o \
    dteval.o \
    exprs.o \
    finfield.o \
    funcs.o \
    gap.o \
    gasman.o \
    gmpints.o \
    gvars.o \
    integer.o \
    intfuncs.o \
    intrprtr.o \
    iostream.o \
    listfunc.o \
    listoper.o \
    lists.o \
    macfloat.o \
    objccoll.o \
    objcftl.o \
    objects.o \
    objfgelm.o \
    objpcgel.o \
    objscoll.o \
    opers.o \
    permutat.o \
    plist.o \
    pperm.o \
    precord.o \
    profile.o \
    range.o \
    rational.o \
    read.o \
    records.o \
    saveload.o \
    scanner.o \
    sctable.o \
    set.o \
    stats.o \
    streams.o \
    string.o \
    sysfiles.o \
    system.o \
    tietze.o \
    trans.o \
    vars.o \
    vec8bit.o \
    vecffe.o \
    vecgf2.o \
    vector.o \
    weakptr.o \
    @ITANIUMOBJ@
"

EXTOBJS=


#############################################################################
##
#F  gap_compile <output> <input> <module-name> <identifier>
##
gap_compile () {
    echo ${gap_compiler} ${gap_options} -C $1 $2 $3 $4
    ${gap_compiler} ${gap_options} -C "$1" "$2" "$3" "$4"
}


#############################################################################
##
#F  c_compile   <output> <input> <options>
##
c_compile () {
    echo ${c_compiler}  $3 -o $1 -I${gap_dir} \
         -I${gap_bin} -DCONFIG_H -c $2
    ${c_compiler} $3 -o $1 -I${gap_dir} \
         -I${gap_bin} -DCONFIG_H -c $2 || exit 1
}


#############################################################################
##
#F  c_link_dyn <output> <input>
##
c_link_dyn () {
    echo ${c_dyn_linker} ${c_dyn_linking} -o $1 $2 ${c_addlibs}
    ${c_dyn_linker} ${c_dyn_linking} -o $1 $2 ${c_addlibs} || exit 1
}


#############################################################################
##
#F  c_link <output> <inputs_o>
##
c_link () {
    echo ${c_linker} ${c_dynlibs}  -o $1 $2 ${c_link_options} -lm ${c_libs}
    ${c_linker} ${c_dynlibs} -o $1 $2 ${c_link_options} \
        -lm ${c_libs} || exit 1
}

#############################################################################
##
#F process_o_file <basename> <filename> 
##
## Compile according to comp_mode and comp_howfar
## 
## This does everything except the final link phase in the static case
## in that case it adds the basename and object file path of $names and $objects
##

process_o_file () {
  name=$1
  o_file=$2
  # just remember for the linking stage later
  names="${names} ${name}"
  objects="${objects} $o_file"
}

#############################################################################
##
#F process_c_file <basename> <filename> 
##
## Compile according to comp_mode and comp_howfar
## 
## This does everything except the final link phase in the static case
## in that case it adds the basename and object file path of $names and $objects
##

process_c_file () {
    name=$1
    c_file=$2
    extra_cflags=$3

    if [ $comp_howfar != "object" ]; then
       o_file=${gactmp}/$$_${name}.o
        temps_o="${temps_o} ${o_file}"
    elif [ "X$output" != "X" ]; then
       o_file=$output
    else 
       o_file=${name}.o
    fi
    if [ $comp_mode = "comp_static" ]; then
       c_compile_opts=$c_options
    else
       c_compile_opts=$c_dyn_options
    fi
    c_compile $o_file $c_file "$c_compile_opts $extra_cflags"
    if [ $comp_howfar = "link" ]; then
      process_o_file $name $o_file
    fi 
}

#############################################################################
##
#F process_gap_file <filename> <ext>
##
## Compile according to comp_mode and comp_howfar
## 
## This does everything except the final link phase in the static case
## in that case it adds the basename and object file path of $names and $objects
##

process_gap_file () {
  name=`basename $1 $2`

  if [ $comp_howfar != "c_code" ]; then
    c_file=${gactmp}/$$_${name}.c
    temps_c="${temps_c} $gap_compile_to"
  elif [ "X$output" = "X" ]; then
     c_file=${name}.c
  else
     c_file=$output
  fi
  gap_compile_in=$input
  gap_compile_name=$input  
  if [ $comp_mode = "comp_static" ]; then
    gap_compile_id=Init_${name}
    if [ $comp_static_root_relative = "yes" ]; then
        gap_compile_in=${gap_dir}/$input;
        gap_compile_name=GAPROOT/$input;
    fi
  else
    gap_compile_id=Init_Dynamic
  fi
  gap_compile $c_file ${gap_compile_in} $gap_compile_id ${gap_compile_name}
  if [ $comp_howfar != "c_code" ]; then
    process_c_file $name $c_file
    echo rm -f $c_file
    rm -f $c_file
  fi
}

#############################################################################
##
#F  clean_up
##
clean_up () {
    echo rm -f ${temps_c} ${temps_o}
    rm -f ${temps_c} ${temps_o}
}
trap "clean_up" 2 3


#############################################################################
##
##  parse the arguments
##
if [ $# = 0 ]; then
    echo "usage: $0 [-d|-r] [-c|-C] [-o <output>] [-l <gap_binary>] <input>..."
    exit 1
fi

comp_mode="comp_static"
comp_howfar="link"
comp_static_root_relative="no"
output=""
inputs=""

while [ $# -gt 0 ]; do
    case $1 in

    -c|--compile)         comp_howfar="object";;

    -d|--dynamic)         comp_mode="comp_dyna";;

    -C|--create-c)        comp_howfar="c_code";;

    -o|--output)          shift; output="$1";;
  
    -r)                   comp_static_root_relative="yes";;

    -ffast-int-arith)     if [ "X${gap_options}" = "X" ]; then
                              gap_options="-U FAST_INT_ARITH"
                          else
                              gap_options="${gap_options},FAST_INT_ARITH"
                          fi;;

    -ffast-plain-lists)   if [ "X${gap_options}" = "X" ]; then
                              gap_options="-U FAST_PLAIN_LISTS"
                          else
                              gap_options="${gap_options},FAST_PLAIN_LISTS"
                          fi;;

    -ffast-list-funcs)   # echo "$0: option $1 is not currently allowed, ignoring it";;
                          if [ "X${gap_options}" = "X" ]; then
                              gap_options="-U FAST_LIST_FUNCS"
                          else
                              gap_options="${gap_options},FAST_LIST_FUNCS"
                          fi;;

    -fno-check-types)     if [ "X${gap_options}" = "X" ]; then
                              gap_options="-U NO_CHECK_TYPES"
                          else
                              gap_options="${gap_options},NO_CHECK_TYPES"
                          fi;;

    -fno-check-list-elms) if [ "X${gap_options}" = "X" ]; then
                              gap_options="-U NO_CHECK_LIST_ELMS"
                          else
                              gap_options="${gap_options},NO_CHECK_LIST_ELMS"
                          fi;;

    -f*)                  echo "$0: no such option '$1'"
                          exit 1;;

    -k|--gap-compiler)    shift; gap_compiler="$1";;

    -i|--gap-include)     shift; gap_include="$1";;

    -l|--gap-binary)      shift; gap_binary="$1";;

    -p)                   shift; c_options="${c_options} $1" c_dyn_options="${c_dyn_options} $1";;

    -P)                   shift; c_link_options="${c_link_options} $1" c_dyn_linking="${c_dyn_linking} $1";;

    -L|--addlibs)         shift; c_addlibs="${c_addlibs} $1";;

    *.g|*.gap|*.gd|*.gi|*.c|*.cc|*.cpp|*.o)
                          inputs="${inputs} $1";;

    *)                    echo "$0: cannot handle this argument '$1'"
                          exit 1;;

    esac
    shift
done

if [ "X${inputs}" = "X" ]; then
    echo "$0: no input files given"
    exit 1
fi




#############################################################################
##
#F  make_compstat 
##

make_compstat () {
    # make 'compstat.c' and compile it
    temps_c="${temps_c} ${gactmp}/$$compstat.c"
    echo     "/* made by 'gac', can be thrown away */"   >  ${gactmp}/$$compstat.c
    echo     "#include \"src/compiled.h\" "                   >> ${gactmp}/$$compstat.c

    echo     "#ifndef AVOID_PRECOMPILED"                         >> ${gactmp}/$$compstat.c
    echo     "extern StructInitInfo * Init__methsel1 ( void );"  >> ${gactmp}/$$compstat.c
    echo     "extern StructInitInfo * Init__type1 ( void );"     >> ${gactmp}/$$compstat.c
    echo     "extern StructInitInfo * Init__filter1 ( void );"   >> ${gactmp}/$$compstat.c
    echo     "extern StructInitInfo * Init__oper1( void );"      >> ${gactmp}/$$compstat.c
    echo     "extern StructInitInfo * Init__random( void );"     >> ${gactmp}/$$compstat.c
    echo     "#endif"                                            >> ${gactmp}/$$compstat.c

    for name in ${names}; do
        echo "extern StructInitInfo * Init__${name} ( void );" \
                                                         >> ${gactmp}/$$compstat.c
    done

    echo     "InitInfoFunc CompInitFuncs [] = {"         >> ${gactmp}/$$compstat.c
    echo     "#ifndef AVOID_PRECOMPILED"                 >> ${gactmp}/$$compstat.c
    echo     "    Init__methsel1,"                       >> ${gactmp}/$$compstat.c
    echo     "    Init__type1,"                          >> ${gactmp}/$$compstat.c
    echo     "    Init__oper1,"                          >> ${gactmp}/$$compstat.c
    echo     "    Init__filter1,"                        >> ${gactmp}/$$compstat.c
    echo     "    Init__random,"                         >> ${gactmp}/$$compstat.c
    echo     "#endif"                                    >> ${gactmp}/$$compstat.c

    for name in ${names}; do
        echo "    Init__${name},"                        >> ${gactmp}/$$compstat.c
    done
    echo "    0"                                         >> ${gactmp}/$$compstat.c
    echo "};"                                            >> ${gactmp}/$$compstat.c
    temps_o="${gactmp}/$$compstat.o ${temps_o}"
    c_compile ${gactmp}/$$compstat.o ${gactmp}/$$compstat.c "${c_options}"
    echo rm -f ${gactmp}/$$compstat.c
    rm -f ${gactmp}/$$compstat.c
    objects="${gactmp}/$$compstat.o ${objects}"
}

make_tmpdir () {
    basetmp=${TMPDIR:-/tmp}; #honor the TMPDIR environment variable.
    gactmp="$basetmp/gac$$";
    mkdir "$gactmp" || exit 1;
}

#On systems with mktemp(1) this function is better:
#make_tmpdir ()
#{
#    gactmp=`mktemp -d -t "gacXXXXXXX"`;
#}

#############################################################################
##
##  main loop
##

#Make temporary directory
make_tmpdir;

# loop over the input files
for input in ${inputs}; do
  case $input in

        *.g) process_gap_file $input .g;;
        *.gap) process_gap_file $input .gap;;
        *.gd) process_gap_file $input .gd;;
        *.gi) process_gap_file $input .gi;;

        *.c) # compile '.c' source files
            name=`basename ${input} .c`
            process_c_file $name $input;;

        *.cc) # compile '.cc' source files (C++)
            name=`basename ${input} .cc`
            process_c_file $name $input "-x c++";;

        *.cpp) # compile '.cpp' source files (also C++)
            name=`basename ${input} .cpp`
            process_c_file $name $input "-x c++";;

        *.o) # look over '.o' source files
            name=`basename ${input} .o`
            process_o_file $name $input;;
        esac
    done


#  static link phase
if [ $comp_howfar = "link" ]; then
    if [ $comp_mode = "comp_static" ]; then
        make_compstat

        # link everything together
        if [ "X${output}" = "X" ]; then output="gacout"; fi

        for object in $OBJECTS;  do
            objects="${gap_binary}/${object} ${objects}"
        done
        for object in $EXTOBJS;  do
            objects="${gap_dir}/${object} ${objects}"
        done

        c_link ${output} "${objects}"

    else
        if [ "X${output}" = "X" ]; then output="${name}.so"; fi
        c_link_dyn ${output} "${objects}"
    fi
    
    echo rm -f ${temps_o}
    rm -f ${temps_o}
fi

#Remove temporary directory.
#We may assume it is empty at this stage.
rmdir "${gactmp}"