% Copyright (C) 1989, 1992 Digital Equipment Corporation 
% All rights reserved.
% See the file COPYRIGHT for a full description.
% 
% Last Modified On Thu Jun  2 11:20:08 PDT 1994 By kalsow  
%      Modified On Thu Apr  8 13:45:49 PDT 1993 by muller
% 
% Standard configuration file for LINUX
%

%-------------------------------------------------- compilation environment ---

readonly TARGET = "LINUX"
readonly DEFAULT_BUILD_DIR = TARGET

include ("PLATFORMS")  % get the target-dependent mappings
include (OS_TYPE)      % get the OS-dependent functions

readonly NAMING_CONVENTIONS = "0"
%                                        object files       libraries
%  0=Unix                          =>  .o   .io    .mo       libXX.a
%  1=Unix with a grumpy C compiler =>  .o   _i.o   _m.o      libXX.a
%  2=Windows/NT                    =>  .obj _i.obj _m.obj    XX.lib
%

%------------------------------------------------------------- export paths ---
% During the installation, destination directories that do not exist
% will be created.  You need the necessary permissions to do so; otherwise,
% the installation will fail, but can be restarted after you have 
% fixed the permissions.

INSTALL_ROOT = "/usr/local/soft/modula3-3.4/"
BIN_INSTALL   = INSTALL_ROOT & "bin"                % executables
LIB_INSTALL   = INSTALL_ROOT & "lib/m3/" & TARGET   % libraries
DOC_INSTALL   = INSTALL_ROOT & "lib/m3/doc"         % documents
PKG_INSTALL   = INSTALL_ROOT & "lib/m3/pkg"         % packages
EMACS_INSTALL = INSTALL_ROOT & "lib/elisp"          % emacs lisp code
MAN_INSTALL   = INSTALL_ROOT & "man"                % man pages
HTML_INSTALL  = INSTALL_ROOT & "lib/m3/www"         % public hypertext

% The manual pages normally go in subdirectories man{1,...8} of
% the MAN_INSTALL directory.  If you prefer to have them all in
% a single section, define MAN_SECTION to be that section's name.
% MAN_SECTION = "l"

% On some systems (e.g. AFS) you must install public files in a different
% place from where you use them.  If that is the case for your system,
% specify the "use" location here, otherwise leave them alone.
BIN_USE   = BIN_INSTALL
LIB_USE   = LIB_INSTALL
PKG_USE   = PKG_INSTALL

readonly INSTALL_IMPLS = "TRUE"
% "TRUE"
%    => save all source files during the install
%    => makes debugging easier and browsing more fruitful
% "" (i.e. FALSE)
%    => save only the exported interfaces and templates 
%    => makes the installed system slightly smaller.

readonly NEED_OBJECTS = ""
% "TRUE"
%    => accumulate a list of derived objects in COMPILE_OBJECTS
%    => for building shared libraries in the library_hooks function below
% ""
%    => don't bother

%---------------------------------------------------------------------- X11 ---
% If you have X11R4 installed and would like the X11R4 binding interfaces
% to be built, define the procedure "import_X11R4" to import the libraries
% that are needed.  Otherwise, define "import_X11R4" to be an empty procedure.
%
% If you use the MIT server with DECnet support, you need X11 and dnet,
% otherwise X11 should be enough.
% 
% Since X11R5 is an extension of X11R4, you can use the X11R5 libraries
% instead of X11R4.  However, the Modula-3 binding interfaces have not
% yet been upgraded to X11R5.
%

readonly proc import_X11R4() is
  import_lib("Xaw", "/usr/local/lib")
  import_lib("Xmu", "/usr/local/lib")
  import_lib("Xext", "/usr/local/lib")
  import_lib("Xt", "/usr/local/lib")
  import_lib("X11", "/usr/local/lib")
end

%---------------------------------------------------------------------- TeX ---
% If you have TeX, define "DVIPS" to convert DVI files to PostScript (or
% whatever your printer accepts).  Otherwise, define "DVIPS" to be an
% empty procedure
%
% If you have TeX, the implementation notes can be recompiled at your
% site with whatever local modifications you make.
%

readonly proc DVIPS(f) is
  % exec("dvi2ps", f & ".dvi >", f & ".ps")
end

%-------------------------------------------------------------------- emacs ---
% If you have emacs and want to compile ".el" files to ".elc" files,
% fill in the function below.  Otherwise, define it to be a no-op.

readonly proc emacs_compile (el) is
  exec ("emacs -batch -f batch-byte-compile", el)
end

%-------------------------------------------------------- Modula-3 compiler ---
% The syntax for the values passed to most of the M3_CONFIG options is
% "@pgm@arg1@...@argn@" where "@" is an arbitrary character.  The
% separator character must begin and end the value.

% Where is the driver?
M3 = LIB_USE & "/m3"

% What are the standard flags?
M3OPTIONS = [ "-w1", "-why", "-g" ]

M3_CONFIG_PROG = [
   "-Y1@gcc@",
   % --- the C compiler, with options to compile Modula-3 code

   "-Y2@gcc@",
   % --- the C compiler, with options to link Modula-3 code

   "-Y3@/usr/bin/ar@crus@",
   % --- program to build library archives

   "-Y4@touch@",
   % --- program to create the table of contents in archives

   "-Y6@" & LIB_USE & "/m3cgc1@-quiet@",
   % --- the Modula-3 IL to assembly language pass

   "-Y7@/usr/bin/as@",
   % --- the assembler

   "-z2@-lm@",  % --- libraries systematically linked with all programs

   "-z3" & LIB_USE & SL & "report_coverage.o",
   % --- library linked in programs compiled with "-Z" coverage option

   "-z5" & NAMING_CONVENTIONS,
   % Set the local naming conventions.

   "-z60",
   % Set the value of "-z6" to "0" if you want the m3 driver to split
   % library names and pass -L/-l arguments to the linker; otherwise ("-z61"),
   % the m3 driver will pass libraries with full path names.

   "-zA0",
   % The "-zA" option specifies the maximum size (in megabytes) that Pass0
   % is allowed to reach as a persistent server before the driver kills it.
   % Setting it to zero disables server mode.
   % NOTE: the current compiler is buggy, leave "-zA" alone!

   "-zB@-O@",  % --- pass 1 options implied by "-O"
   "-zC@-O@",  % --- pass 6 options implied by "-O"
   "-zD@@",    % --- pass 7 options implied by "-O"

   "-zE@-g@",  % --- pass 1 options implied by "-g"
   "-zF@-g@",  % --- pass 6 options implied by "-g"
   "-zG@@",     % --- pass 7 options implied by "-g"

   "-zH" & NAMING_CONVENTIONS,
   % --- the target's naming conventions

   "-zI" & TARGET,
   % --- the target architecture

   % "-zJ10",
   % The option "-zJx1" specifies that pass "x" is "noisy", "-zJx0"
   % specifices that it's not.  The default is to assume that passes
   % are not noisy.  The driver collects the standard output of noisy
   % passes in a file and then deletes the file, unless "-keep" or
   % "-verbose" is specified.

   "-zK0",
   % --- Set the value of "-zK" to "1" if you want the m3 driver to
   %     supply -Bdynamic/-Bstatic options to the linker, "0" otherwise.

   "-Bdynamic",
   % --- libraries are shared by default.  If you give -zK1 you should
   %     also provide an initial -Bdynamic or -Bstatic.

   "-zL0"
   % --- Set the value of "-zL" to "1" if you want .M3LINK files produced
   %     for a dynamic loader
]

M3_CONFIG_LIB = [
   "-Y1@gcc@-B" & LIB_USE & "/@",
   % --- the C compiler, with options to compile Modula-3 code

   "-Y2@gcc@",
   % --- the C compiler, with options to link Modula-3 code

   "-Y3@/usr/bin/ar@crus@",
   % --- program to build library archives

   "-Y4@touch@",
   % --- program to create the table of contents in archives

   "-Y6@" & LIB_USE & "/m3cgc1@-quiet@",
   % --- the Modula-3 IL to assembly language pass

   "-Y7@" & LIB_USE & "/as@",
   % --- the assembler

   "-z2@-lm@",  % --- libraries systematically linked with all programs

   "-z3" & LIB_USE & SL & "report_coverage.o",
   % --- library linked in programs compiled with "-Z" coverage option

   "-z5" & NAMING_CONVENTIONS,
   % Set the local naming conventions.

   "-z60",
   % Set the value of "-z6" to "0" if you want the m3 driver to split
   % library names and pass -L/-l arguments to the linker; otherwise ("-z61"),
   % the m3 driver will pass libraries with full path names.

   "-zA0",
   % The "-zA" option specifies the maximum size (in megabytes) that Pass0
   % is allowed to reach as a persistent server before the driver kills it.
   % Setting it to zero disables server mode.
   % NOTE: the current compiler is buggy, leave "-zA" alone!

   "-zB@-O@",  % --- pass 1 options implied by "-O"
   "-zC@-O@",  % --- pass 6 options implied by "-O"
   "-zD@@",    % --- pass 7 options implied by "-O"

   "-zE@-g@",  % --- pass 1 options implied by "-g"
   "-zF@-g@",  % --- pass 6 options implied by "-g"
   "-zG@@",     % --- pass 7 options implied by "-g"

   "-zH" & NAMING_CONVENTIONS,
   % --- the target's naming conventions

   "-zI" & TARGET,
   % --- the target architecture

   % "-zJ10",
   % The option "-zJx1" specifies that pass "x" is "noisy", "-zJx0"
   % specifices that it's not.  The default is to assume that passes
   % are not noisy.  The driver collects the standard output of noisy
   % passes in a file and then deletes the file, unless "-keep" or
   % "-verbose" is specified.

   "-zK0",
   % --- Set the value of "-zK" to "1" if you want the m3 driver to
   %     supply -Bdynamic/-Bstatic options to the linker, "0" otherwise.

   "-Bdynamic",
   % --- libraries are shared by default.  If you give -zK1 you should
   %     also provide an initial -Bdynamic or -Bstatic.

   "-zL0"
   % --- Set the value of "-zL" to "1" if you want .M3LINK files produced
   %     for a dynamic loader
]

M3_CONFIG = M3_CONFIG_PROG

proc build_standalone() is
   % --- reset the linker to avoid shared libraries.
   M3_CONFIG_PROG += "-Y2@gcc@-static@"
end

proc build_shared() is
   % --- reset the linker to use shared libraries.
   M3_CONFIG_PROG += "-Y2@gcc@-shared@"
end

%-------------------------------------------------------------------- hooks ---
% These are the "last chance" hooks that are called each time a library
% or program is built.  They might build shared libraries or strip
% executables...

proc library_hooks(x) is
end

proc program_hooks(x) is
end

%---------------------------------------------------------------- bootstrap ---
% These functions are used during the bootstrap process
%

if defined("_bootstrap")
  BOOT_CC   = "gcc"
  BOOT_ASM  = "/usr/bin/as"
  BOOT_AR   = "ar crus"
  BOOT_RAN  = "touch"
  BOOT_LINK = "gcc"
  include("COMMON.BOOT")
end

%------------------------------------------------------------- installation ---
% "install_file" is called during an "m3build install" for
% each file that neededs to be externally exported.

readonly proc install_file (src, dest, mode) is
  % exec ("install -c -m", mode, src, dest)
  exec ("cp -p -d -f", src, dest)
end

%---------------------------------------------- the rest of the environment ---

include ("COMMON")

%------------------- hooks to do some magic ----------------------------

%
% The address block from 0x64800000 to 0x65ffffff was officially reserved
% for Modula-3 shared libraries under LINUX. This will leave room for some
% growth and a few extra libraries. The size of each library is included
% in the table to help compute the starting addresses.
%
% the following sizes give approximately in hexa:
%
%    50K =   d000
%    75K =  13000
%   125K =  20000
%   200K =  31000
%   300K =  4a000
%   450K =  6e000
%   750K =  b8000
%  1250K = 132000
%  2000K = 1e9000
%  3000K = 2dd000
%  4500K = 44b000

LINUX_SHLIBS = {}
LINUX_SHLIBS{"libm3"} = ["0x64800000","0x4000","0x2000","3","4","2692128"]
%LINUX_SHLIBS{"m3tk"} = ["0x64b00000","0x4000","0x2000","3","4","3356712"]
LINUX_SHLIBS{"ui"} = ["0x64f00000","0x4000","0x2000","3","4","1712982"]
LINUX_SHLIBS{"vbtkit"} = ["0x65100000","0x4000","0x2000","3","4","1647366"]
LINUX_SHLIBS{"tcp"} = ["0x65300000","0x4000","0x2000","3","4","54164"]
LINUX_SHLIBS{"X11R4"} = ["0x65313000","0x4000","0x2000","3","4","256282"]
LINUX_SHLIBS{"m3tools"} = ["0x65363000","0x4000","0x2000","3","4","58886"]
LINUX_SHLIBS{"jvideo"} = ["0x65377000","0x4000","0x2000","3","4","184814"]
LINUX_SHLIBS{"formsvbtpixmaps"} = ["0x653b7000","0x4000","0x2000","3","4","40172"]
LINUX_SHLIBS{"videovbt"} = ["0x653ca000","0x4000","0x2000","3","4","54700"]
LINUX_SHLIBS{"netobj"} = ["0x653df000","0x4000","0x2000","3","4","311444"]
LINUX_SHLIBS{"formsvbt"} = ["0x6544d000","0x4000","0x2000","3","4","580382"]
LINUX_SHLIBS{"codeview"} = ["0x6551d000","0x4000","0x2000","3","4","123766"]
LINUX_SHLIBS{"mg"} = ["0x6554d000","0x4000","0x2000","3","4","379412"]
LINUX_SHLIBS{"mgkit"} = ["0x655ed000","0x4000","0x2000","3","4","426502"]
LINUX_SHLIBS{"zeus"} = ["0x6568d000","0x4000","0x2000","3","4","340814"]
LINUX_SHLIBS{"synloc"} = ["0x656f6000","0x4000","0x2000","3","4","19646"]
LINUX_SHLIBS{"synex"} = ["0x65708000","0x4000","0x2000","3","4","108918"]
LINUX_SHLIBS{"metasyn"} = ["0x65738000","0x4000","0x2000","3","4","96994"]
LINUX_SHLIBS{"obliqrt"} = ["0x65768000","0x4000","0x2000","3","4","445314"]
LINUX_SHLIBS{"obliqlibui"} = ["0x65818000","0x4000","0x2000","3","4","41362"]
LINUX_SHLIBS{"obliqlibm3"} = ["0x6582b000","0x4000","0x2000","3","4","59264"]
LINUX_SHLIBS{"obliqparse"} = ["0x65843000","0x4000","0x2000","3","4","129680"]
LINUX_SHLIBS{"obliqprint"} = ["0x65879000","0x4000","0x2000","3","4","72174"]
LINUX_SHLIBS{"obliq"} = ["0x65899000","0x4000","0x2000","3","4","97216"]
LINUX_SHLIBS{"obliqlibanim"} = ["0x658c9000","0x4000","0x2000","3","4","77718"]
LINUX_SHLIBS{"m3core"} = ["0x658f9000","0x4000","0x2000","3","4","900000"]

SHLIB_CALLED = "FALSE"
SHLIB_INFO = []

proc shared_lib_info(x) is
  SHLIB_INFO = x
  SHLIB_CALLED = "TRUE"
end

% Quake is weak on integers but since it is turing complete, they can
% be emulated painfully

INC_NEXT = ["1","2","3","4","5","6","7","8","9","0"]
DEC_NEXT = ["9","0","1","2","3","4","5","6","7","8"]
INT_POS = ["5","4","3","2","1","0"]

proc init_int() is
  return ["0","0","0","0","0","0"]
end

proc inc_int(x) is
  local carry = " "

  foreach i in INT_POS
    if carry
      x[i] = INC_NEXT[x[i]]
      if equal(x[i],"0")
        carry = " "
      else
        carry = ""
      end
    end
  end
end

proc dec_int(x) is
  local carry = " "

  foreach i in INT_POS
    if carry
      x[i] = DEC_NEXT[x[i]]
      if equal(x[i],"9")
        carry = " "
      else
        carry = ""
      end
    end
  end
end

proc int_to_string(x) is
  return x[0] & x[1] & x[2] & x[3] & x[4] & x[5]
end

proc array_length(x) is
  local l = init_int()

  foreach i in x
    inc_int(l)
  end
  return l
end

proc reverse_array(x) is
  local l = array_length(x)
  local new = []

  foreach i in x
    dec_int(l)
    new += x[int_to_string(l)]
  end
  return new
end
  
% The linker requires the libraries to be in the right order,
% which is the exact opposite of what IMPORT_LIBS contains

%
% The order of -l and -L is reversed in prevision of reversing the array
%

proc _import_m3lib(x, pkg, subdir) is
  % IMPORT_LIBS += format ("%s%s%s%s%s%s%s", Pkg(pkg), SL, subdir, SL, LIB_pre, x, LIB_ext)
  IMPORT_LIBS += format ("-l%s", x)
  IMPORT_LIBS += format ("-L%s%s%s", Pkg(pkg), SL, subdir)
  M3LIBS{x} = [Location(pkg, subdir), HIDDEN, IMPORTED]
end

proc before_do_m3_hooks() is
  IMPORT_LIBS = reverse_array(IMPORT_LIBS)
end

proc before_library_hooks(x) is

  if equal(SHLIB_CALLED,"FALSE")
    if LINUX_SHLIBS contains PACKAGE
      foreach i in LINUX_SHLIBS{PACKAGE}
        SHLIB_INFO += i
      end
      SHLIB_INFO += ""

      SHLIB_CALLED = "TRUE"
      SHLIB_INFO[5] = PKG_INSTALL & SL & BUILD_PACKAGE & SL & BUILD_DIR & SL
      SHLIB_INFO[6] = LIB_USE
    end
  end

  if equal(SHLIB_CALLED,"TRUE")
    M3_CONFIG = M3_CONFIG_LIB
    exec("mkdir -p jump; mkdir -p jumpas")
  end
end

proc after_library_hooks(x) is

  if equal(SHLIB_CALLED,"TRUE")

    local lib = format("lib%s",x)
    local lib_a  = format ("lib%s.a", x)
    local lib_so = format("%s.so.%s.%s",lib,SHLIB_INFO[3],SHLIB_INFO[4])
    local lib_so_m = format("%s.so.%s",lib,SHLIB_INFO[3])
    local lib_sa = format("%s.sa",lib)

    if defined("_all")
      if stale (lib_a, lib_a)
        write ("missing ", lib_a, ": not building ", lib_so, CR)
      else
        if stale (lib_so, lib_a)
          exec(LIB_USE & "/buildShared -n " & lib & " -a " & SHLIB_INFO[0] & " -j " & SHLIB_INFO[1] & " -g " & SHLIB_INFO[2] & " -x " & SHLIB_INFO[3] & " -y " & SHLIB_INFO[4] & " -l \"" & IMPORT_LIBS & " " & OTHER_LIBS_L & "\"")
        end

        link_file(SHLIB_INFO[5] & lib_so,lib_so_m)
        _install_file(lib_so_m,SHLIB_INFO[6],"0755","T")
        install_derived(lib_so)
        install_derived(lib_sa)
      end
    end

    deriveds(lib_so, no_extension)
    deriveds(lib_sa, no_extension)
  end
end
