% Copyright 1996-2000 Critical Mass, Inc. All rights reserved.
% See file COPYRIGHT-CMASS for details.
% 
% Standard configuration file for a 386 box running Windows NT or Windows 95.
%

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

readonly TARGET       = "NT386"    % code generation target
readonly BUILD_DIR    = TARGET     % directory for results
readonly OS_TYPE      = "WIN32"    % { "WIN32" or "POSIX" }
readonly WORD_SIZE    = "32BITS"   % { "32BITS" or "64BITS" }
readonly GNU_PLATFORM = "i486--nt" % "cpu-vendor-os" string for GNU
readonly INSTALL_KEY  = "4JJ2-D7A2-2KE2"
% readonly INSTALL_KEY  = "4TD2-87A2-2KW2"
% readonly INSTALL_KEY  = "4HC2-J7A2-2K92"

readonly NAMING_CONVENTIONS = "2"
%                                        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 or Windows 95      =>  .obj .io    .mo       XX.lib
%

%-------------------------------------------------- default compile options ---
% "set_config_options" is called before starting the compilation.  It should
% be used to provide system-wide default options.

proc set_config_options () is
  m3_option ("-why")   %-- produce a listing that explains what's happening and why
  m3_debug (TRUE)      %-- produce object code with debugging symbols
  M3_OPTIONS += "-w1"  %-- produce "level 1" warnings
end

%--------------------------------------------------------- Reactor defaults ---
% The first time a user runs Reactor, it will configure itself to use
% the executables defined below.

INITIAL_REACTOR_BROWSER = "C:\\PROGRA~1\\PLUS!\\MICROS~1\\EXPLORE.EXE"
%-or- INIITAL_REACTOR_BROWSER = "C:\\Netscape\\Navigator\\Program\Netscape.exe"
% A World-Wide Web browser.  Reactor passes it an initial URL
% its first command-line argument.

INITIAL_REACTOR_EDITOR = "C:\\GNU\\emacs.bat"
% A text editor.  Reactor passes it "<file> +<line>" on the
% command-line when it wants to edit <file> initially positioned
% at <line>.

%------------------------------------------------------------- export paths ---
% During the installation, destination directories that do not exists 
% 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 = "c:\\cm3\\"
%-- handy for installations that keep all M3 stuff together

BIN_INSTALL   = INSTALL_ROOT & "bin"          % executables
LIB_INSTALL   = INSTALL_ROOT & "lib"          % libraries
PKG_INSTALL   = INSTALL_ROOT & "pkg"          % packages
DOC_INSTALL   = INSTALL_ROOT & "doc"          % documents
EMACS_INSTALL = INSTALL_ROOT & "elisp"        % emacs lisp code
MAN_INSTALL   = INSTALL_ROOT & "man"          % man pages
HTML_INSTALL  = INSTALL_ROOT & "www"          % public hypertext

% 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.
%
USE_ROOT  = INSTALL_ROOT
BIN_USE   = BIN_INSTALL   % executables
LIB_USE   = LIB_INSTALL   % libraries
PKG_USE   = PKG_INSTALL   % packages

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

%------------------------------------------------ C development environment ---
% These are handy definitions for access the local C development environment.
% They are only used within this configuration file for convenience.

readonly DEV_LIB = "G:\\MSDEV\\LIB\\"  % libraries
readonly DEV_BIN = "G:\\MSDEV\\BIN\\"  % executables

%------------------------------------------------ external system libraries ---
% SYSTEM_LIBS provides a mapping from Modula-3 names for the common
% external libraries to site-dependent information about how they
% are accessed.  If SYSTEM_LIBS{x} is defined it should be a list
% of linker arguments that are used when linking against that library.
% If SYSTEM_LIBS{x} is not defined, the Modula-3 system will assume
% that the library is not available.

SYSTEM_LIBS = {
  "LIBC"       : [ DEV_LIB & "msvcrt.lib",
                   DEV_LIB & "winspool.lib",
                   DEV_LIB & "\\comctl32.lib",
                   LIB_USE & "\\wsock32.lib",
                   LIB_USE & "\\comdlg32.lib",
                   LIB_USE & "\\netapi32.lib",
                   LIB_USE & "\\gdi32.lib",
                   LIB_USE & "\\user32.lib",
                   LIB_USE & "\\advapi32.lib",
                   LIB_USE & "\\kernel32.lib" ],
% "LEX-YACC"   : [ DEV_LIB & "lex.lib" ], %-- not on most Win32 platforms
% "FLEX-BISON" : [ DEV_LIB & "flex.lib" ], %-- not on most Win32 platforms
  "ODBC"       : [ LIB_USE & "\\odbc32.lib",
                   LIB_USE & "\\odbccp32.lib" ],
  "OPENGL"     : [ LIB_USE & "\\opengl32.lib",
                   LIB_USE & "\\glu32.lib" ],
  "TCP"        : [  ]
}

% SYSTEM_LIBORDER defines the order in which SYSTEM_LIBS should be
% scanned by the linker.

SYSTEM_LIBORDER = [ "OPENGL", "DECPEX", "MOTIF", "X11", "TCP", "ODBC",
                    "FLEX-BISON", "LEX-YACC", "LIBC" ]

%--------------------------------------------------------- Modula-3 backend ---
% For platforms without an integrated backend, "m3_backend" is called to
% translate Modula-3 intermediate code to object code.

% proc m3_backend (source, object, optimize, debug) is
% end

M3_BACKEND_MODE = "0"
% -- defines how the frontend, backend, and assembler interact
%  "0"  -- don't call m3_backend, M3CG produces object code
%  "1"  -- don't call m3_backend, M3CG produces assembly code
%  "2"  -- call m3_backend, it produces object code
%  "3"  -- call m3_backend, it produces assembly code

%--------------------------------------------------------------- C compiler ---
% "compile_c" is called to compile C source files.  Note that this function
% is only called if your program or library explicitly includes C source
% code, the system distributed by Critical Mass does not.

proc compile_c (source, object, options, optimize, debug) is
  local args = [ "-D_MT", "-D_DLL", "-D_X86_", "-DWIN32", "-nologo", options ]
  if optimize  args += "-O2"            end
  if debug     args += [ "-Od", "-Zi" ] end
  local res = try_exec ("@" & DEV_BIN & "cl", arglist ("@", [ args,"-c", source ]))
  delete_file ("vc40.pdb")
  return res
end

%---------------------------------------------------------------- assembler ---
% "assemble" is called to assemble .s or .asm files.  Note that this function
% is only called if your program or library explicitly includes assembly source
% code, the system distributed by Critical Mass does not.

proc assemble (source, object) is
  local args = arglist ("@", [ "/Ml", "/t", "/z", source & "," & object & ";" ])
  return try_exec ("@" & DEV_BIN & "masm386", args)
end

%--------------------------------------------------------- library creation ---
% "make_lib" is called to combine a collection of object modules into
% a library.

%% NOTE: we should set the "base" load address of the various DLLs
%%  to avoid relocating them everytime they're loaded....

%% m3_lib_flags = [ "-debugtype:cv", "-machine:i386" ]
m3_lib_flags = [ "-ign:__real" ]

proc make_lib (lib, options, objects, imported_libs, shared) is
  local ret_code  = "0"
  local lib_file  = lib & ".lib"
  local lib0_file = lib & ".lib.sa"
  local def_file  = lib & ".def"
  local dll_file  = lib & ".dll"
  local listing   = lib & ".lst"
  local lib_args  = arglist ("@", [ m3_lib_flags, "-out:" & lib_file,
                                     options, objects ])
  local link_args = arglist ("@", [ m3_link_flags, "-def:" & def_file,
                                    "-dll", "-out:" & dll_file,
                                    "-implib:" & lib_file,
                                     options, objects, imported_libs ])

  ret_code = try_exec ("@" & BIN_USE & "\\mklib", lib_args, ">", listing)
  if not equal (ret_code, 0) return ret_code end
  if stale (lib_file, lib_file) 
    write("error: library creation failed" & EOL)
    return 1
  end

  if shared
    % build an import library & DLL
    delete_file (lib0_file)
    exec ("@ren", lib_file, lib0_file)
    ret_code = try_exec ("@" & DEV_BIN & "link", link_args, ">", listing)
    % make sure the extra stuff gets shipped
    BindExport (dll_file)
    install_derived (lib0_file)
    if stale (dll_file, dll_file) 
      write("error: dynamic link library creation failed" & EOL)
      return 1
    end

  else
    delete_file (lib0_file)
    delete_file (dll_file)
  end

  % make sure the junk gets cleaned up
  deriveds ("", [ listing, lib_file, lib0_file, def_file, dll_file ])

  return ret_code
end

% proc make_lib (lib, options, objects, imported_libs, shared) is
%   local lib_file = lib & ".lib"
%   local listing  = lib & ".lst"
%   local args = arglist ("@", [ m3_lib_flags, "-out:" & lib_file,
%                                options, objects ])
%   deriveds ("", [ listing ])
%   return try_exec ("@" & DEV_BIN & "lib", args, ">", listing)
% end


%-------------------------------------------------------------------
% "skip_lib" is called when the compiler decides it doesn't need to
% call "make_lib", but it wants to discover the names of the derived
% files that should be deleted or shipped.

proc skip_lib (lib, shared) is
  local lib_file  = lib & ".lib"
  local lib0_file = lib & ".lib.sa"
  local def_file  = lib & ".def"
  local dll_file  = lib & ".dll"
  local listing   = lib & ".lst"

  if shared
    % would have built an import library & DLL
    BindExport (dll_file)
    install_derived (lib0_file)
  else
    delete_file (lib0_file)
    delete_file (dll_file)
  end

  % make sure the junk gets cleaned up
  deriveds ("", [ listing, lib_file, lib0_file, def_file, dll_file ])

  return 0
end

%------------------------------------------------------------------- linker ---
% "m3_link" is called to produce a final executable.
%---  "-pdb:none" enables the use of windbg with the resulting executable.

m3_link_flags = [ "-debug:mapped,partial", "-debugtype:cv", "-pdb:none",
                  "-align:0x1000", "-ignore:505", "-machine:i386",
                  "-nodefaultlib:libc" ]

proc m3_link (prog, options, objects, imported_libs, shared) is
  local pgm_file = prog & ".exe"
  local map_file = prog & ".map"
  local listing  = prog & ".lst"
  local imports  = imported_libs

  local entry = [ "-subsystem:console", "-entry:mainCRTStartup" ]
  if defined ("M3_WINDOWS_GUI")
    if M3_WINDOWS_GUI
      entry = [ "-subsystem:windows", "-entry:WinMainCRTStartup" ]
    end
  end

  if not shared
    imports = []
    foreach f in imported_libs
      local ff = f & ".sa"
      if stale (f, ff)
        imports += f
      else
        imports += ff
      end
    end
  end

  local args = arglist ("@", [ "-out:" & pgm_file, "-map:" & map_file,
                        entry, m3_link_flags, options, objects, imports ])

  deriveds ("", [ listing, map_file ])
  return try_exec ("@" & DEV_BIN & "LINK", args, ">", listing)
end

%-------------------------------------------------------------------
% "skip_link" is called when the compiler decides it doesn't need to
% call "m3_link", but it wants to discover the names of the derived
% files that should be deleted or shipped.

proc skip_link (prog, shared) is
  local map_file = prog & ".map"
  local listing  = prog & ".lst"

  deriveds ("", [ listing, map_file ])
  return 0
end

%------------------------------------------------------------ misc. options ---
% Note, most of these options can be set from the command line.  Otherwise,
% they can be set "permanently" here in the config file or in as needed
% in user's m3makefiles.

M3_FRONT_FLAGS = [ "-unfold_nested_procs", "-check_procs" ]
% --- internal configuration options passed directly to the Modula-3 front-end

M3_OPTIONS = [ ]
% --- user options passed directly to the Modula-3 front-end

% M3_KEEP_FILES = TRUE
% --- keep intermediate and temporary files

% M3_WINDOWS_GUI = TRUE
% --- generate a Windows GUI subsystem program instead of a console one.

% M3_COVERAGE = TRUE
% --- compile & link with coverage options

M3_COVERAGE_LIB = LIB_USE & "\\report_coverage.obj"
% --- library linked in programs compiled with "-Z" coverage option

% M3_SPLIT_LIBNAMES = TRUE
% --- split library names and pass -L/-l arguments to the linker

% M3_SHARED_LIB_ARG = "-R"
% --- pass "-R" flags to the linker too...

% M3_BOOTSTRAP = TRUE
% --- generate bootstrap code (assembly) instead of finaly object code

% M3_COMPILE_ONCE = TRUE
% --- don't recompile code to improve opaque object references

% SYS_HAS_LOADER = TRUE
% --- generate a loader info file with objects, libraries and timestamps

% M3_SKIP_LINK = TRUE
% --- skip the final link for programs, presumably to use the loader instead

% M3_MAIN_IN_C = TRUE
% --- generate the Modula-3 main program as C code

X11_WITH_SHARED_MEM = FALSE
% --- X11 libraries include the shared memory extensions (XShm...)

% M3_NEED_STANDALONE_LINKS = TRUE
% --- linker is broken and we need to build a directory of symbolic
%     links pointing to the non-shared libraries.

%-------------------------------------------------------------------- emacs ---
% If you have emacs and want to compile ".el" files to ".elc" files,
% fill in the function below.  Otherwise, comment out or delete the
% entire function.  Note, the distributed code assumes gnuemacs version 19
% or later.

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