<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body class='hmmessage'>host vs. target naming<BR>
 <BR>
I think this stuff is mildly messed up.<BR>Currently slashes and foo.lib vs. libfoo.a "go together".<BR>
<BR>I contend that this is suspicous.<BR>
<BR>The "slash" character is pretty much always related to the host.<BR>If a cross build stops at some point and gets copied from one machine<BR>to another and resumed, and the slash character changes en route,<BR>that is interesting. However, in this case, I think the paths<BR>written to .m3ship etc. should probably be host and target-independent.<BR>Either use arrays of path elements, or declare that one or the other<BR>or both slash characters are the "abstract" representation, and convert<BR>as needed at runtime. Or, just always use a forward slash. They always work.<BR>But avoid presenting to them to the Win32 user.<BR>
<BR>The "naming" conventions:<BR> kernel32.lib vs. libkernel32.a <BR> foo.exe vs. foo <BR> foo.dll vs. foo.so <BR>
<BR>The last two are strictly a function of target.<BR>A Linux-hosted NT386-targeted config should write foo.exe and foo.dll.<BR> Never (by default) foo and foo.so.<BR>
A NT386-hosted Linux-targeted config should write foo and foo.so.<BR> Never (by default) foo.exe and foo.dll.<BR>
<BR>The first is a function of toolset, and tendencies go both ways I think.<BR>I think mainly they go with the host. That is..almost none of this stuff<BR>varies in any build, but in one example I have, NT386 targeting NT386GNU,<BR>the cm3 "host" is sort of "cross", but the backend is really "native",<BR>and the files are libkernel32.a, etc.<BR>
<BR>I suggest that in M3Path.m3, Prefix and Suffix always be indexed by "target" (i.e. FALSE).<BR>Directory and volume separator code unchanged.<BR>
<BR>Something like the following, which also switches NT386GNU to Unix naming conventions.<BR>
<BR>Probably Target.m3 should hardcode the target naming conventions, and<BR>the value be exposed perhaps to Quake (for the likes of my NT386.common). That is not done here.<BR>Using something other than numbers might be good too -- "Unix", "GrumpyUnix", "Win32".<BR>
<BR> <BR>Index: src/Builder.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/cm3/src/Builder.m3,v<BR>retrieving revision 1.18<BR>diff -c -r1.18 Builder.m3<BR>*** src/Builder.m3 24 Feb 2008 16:36:44 -0000 1.18<BR>--- src/Builder.m3 17 Mar 2008 08:11:01 -0000<BR>***************<BR>*** 12,17 ****<BR>--- 12,18 ----<BR>  IMPORT Msg, Arg, Utils, M3Path, M3Backend, M3Compiler;<BR>  IMPORT Quake, QMachine, QValue, QVal, QVSeq;<BR>  IMPORT M3Loc, M3Unit, M3Options, MxConfig AS M3Config;<BR>+ IMPORT QIdent;<BR>  FROM Target IMPORT M3BackendMode_t, BackendAssembly;<BR>  <BR>  TYPE<BR>***************<BR>*** 101,108 ****<BR>      main          : M3ID.T;             (* "Main" *)<BR>      m3env         : Env;                (* the compiler's environment closure *)<BR>      target        : TEXT;               (* target machine *)<BR>!     host_os       : M3Path.OSKind;      (* host system *)<BR>!     target_os     : M3Path.OSKind;      (* target os *)<BR>      m3backend_mode: M3BackendMode_t;    (* tells how to turn M3CG -> object *)<BR>      m3backend     : ConfigProc;         (* translate M3CG -> ASM or OBJ *)<BR>      c_compiler    : ConfigProc;         (* compile C code *)<BR>--- 102,108 ----<BR>      main          : M3ID.T;             (* "Main" *)<BR>      m3env         : Env;                (* the compiler's environment closure *)<BR>      target        : TEXT;               (* target machine *)<BR>!     target_os    := M3Path.OSKind.Unix; (* target os *)<BR>      m3backend_mode: M3BackendMode_t;    (* tells how to turn M3CG -> object *)<BR>      m3backend     : ConfigProc;         (* translate M3CG -> ASM or OBJ *)<BR>      c_compiler    : ConfigProc;         (* compile C code *)<BR>***************<BR>*** 139,153 ****<BR>    END;<BR>  <BR>  PROCEDURE SetupNamingConventionsInternal (VAR s : State; mach : Quake.Machine) =<BR>    BEGIN<BR>      s.machine       := mach;<BR>!     s.host_os := GetOSType (s, "NAMING_CONVENTIONS");<BR>!     IF (GetDefn (s, "TARGET_NAMING") = NIL)<BR>!       THEN s.target_os := s.host_os;<BR>!       ELSE s.target_os := GetOSType (s, "TARGET_NAMING");<BR>      END;<BR>!     M3Path.SetOS (s.host_os, host := TRUE);<BR>!     M3Path.SetOS (s.target_os, host := FALSE);<BR>    END SetupNamingConventionsInternal;<BR>  <BR>  PROCEDURE SetupNamingConventions (mach : Quake.Machine) =<BR>--- 139,166 ----<BR>    END;<BR>  <BR>  PROCEDURE SetupNamingConventionsInternal (VAR s : State; mach : Quake.Machine) =<BR>+   VAR<BR>+     value : QValue.Binding;<BR>    BEGIN<BR>      s.machine       := mach;<BR>! <BR>!     value := GetDefn (s, "NAMING_CONVENTIONS");<BR>!     IF value # NIL THEN<BR>!       WITH host_os = GetOSType (s, value) DO<BR>!         s.target_os := host_os;<BR>!         M3Path.SetOS (host_os, host := TRUE);<BR>!         M3Path.SetOS (host_os, host := FALSE);<BR>!       END;<BR>!     END;<BR>! <BR>!     value := GetDefn (s, "TARGET_NAMING");<BR>!     IF value # NIL THEN<BR>!       WITH target_os = GetOSType (s, value) DO<BR>!         s.target_os := target_os;<BR>!         M3Path.SetOS (target_os, host := FALSE);<BR>!       END;<BR>      END;<BR>! <BR>    END SetupNamingConventionsInternal;<BR>  <BR>  PROCEDURE SetupNamingConventions (mach : Quake.Machine) =<BR>***************<BR>*** 230,261 ****<BR>      RETURN s;<BR>    END CompileUnits;<BR>  <BR>! PROCEDURE GetOSType (s: State;  sym: TEXT): M3Path.OSKind =<BR>!   VAR val := GetConfigItem (s, sym);<BR>    BEGIN<BR>!     IF    Text.Equal (val, "0")   THEN RETURN M3Path.OSKind.Unix;<BR>!     ELSIF Text.Equal (val, "1")   THEN RETURN M3Path.OSKind.GrumpyUnix;<BR>!     ELSIF Text.Equal (val, "2")   THEN RETURN M3Path.OSKind.Win32;<BR>      END;<BR>!     ConfigErr (s, sym, "unrecognized naming convention: " & val);<BR>      RETURN M3Path.OSKind.Unix;<BR>    END GetOSType;<BR>  <BR>! PROCEDURE GetConfigItem (s: State;  symbol: TEXT; default: TEXT := NIL): TEXT =<BR>!   VAR bind := GetDefn (s, symbol);<BR>    BEGIN<BR>      IF bind = NIL THEN<BR>        IF default # NIL THEN<BR>          RETURN default;<BR>        END;<BR>      END;<BR>-     IF (bind = NIL) THEN ConfigErr (s, symbol, "not defined"); END;<BR>      TRY<BR>        RETURN QVal.ToText (s.machine, bind.value);<BR>      EXCEPT Quake.Error (msg) =><BR>!       ConfigErr (s, symbol, msg);<BR>      END;<BR>      RETURN NIL;<BR>    END GetConfigItem;<BR>  <BR>  PROCEDURE GetConfigProc (s: State;  symbol: TEXT;<BR>--- 243,282 ----<BR>      RETURN s;<BR>    END CompileUnits;<BR>  <BR>! PROCEDURE GetOSType (s: State; bind: QValue.Binding): M3Path.OSKind =<BR>!   VAR val := BindingToText (s, bind);<BR>    BEGIN<BR>!     IF Text.Length (val) = 1 THEN<BR>!       CASE (Text.GetChar (val, 0)) OF<BR>!         | '0' => RETURN M3Path.OSKind.Unix;<BR>!         | '1' => RETURN M3Path.OSKind.GrumpyUnix;<BR>!         | '2' => RETURN M3Path.OSKind.Win32;<BR>!         ELSE<BR>!       END;<BR>      END;<BR>!     ConfigErr (s, s.machine.map.id2txt(bind.name), "unrecognized naming convention: " & val);<BR>      RETURN M3Path.OSKind.Unix;<BR>    END GetOSType;<BR>  <BR>! PROCEDURE BindingToText (s: State; bind: QValue.Binding; default: TEXT := NIL): TEXT =<BR>    BEGIN<BR>      IF bind = NIL THEN<BR>        IF default # NIL THEN<BR>          RETURN default;<BR>        END;<BR>+       ConfigErr (s, s.machine.map.id2txt(bind.name), "not defined");<BR>      END;<BR>      TRY<BR>        RETURN QVal.ToText (s.machine, bind.value);<BR>      EXCEPT Quake.Error (msg) =><BR>!       ConfigErr (s, s.machine.map.id2txt(bind.name), msg);<BR>      END;<BR>      RETURN NIL;<BR>+   END BindingToText;<BR>+ <BR>+ PROCEDURE GetConfigItem (s: State;  symbol: TEXT; default: TEXT := NIL): TEXT =<BR>+   BEGIN<BR>+     RETURN BindingToText (s, GetDefn (s, symbol), default);<BR>    END GetConfigItem;<BR>  <BR>  PROCEDURE GetConfigProc (s: State;  symbol: TEXT;<BR>Index: src/M3Path.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/cm3/src/M3Path.i3,v<BR>retrieving revision 1.2<BR>diff -c -r1.2 M3Path.i3<BR>*** src/M3Path.i3 18 Feb 2008 03:53:19 -0000 1.2<BR>--- src/M3Path.i3 17 Mar 2008 08:11:02 -0000<BR>***************<BR>*** 14,20 ****<BR>    END;<BR>  <BR>  VAR (* possibly changed at initialization and then CONST *)<BR>-   SlashChar := '/';<BR>    SlashText := "/";<BR>  <BR>  TYPE<BR>--- 14,19 ----<BR>Index: src/M3Path.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-sys/cm3/src/M3Path.m3,v<BR>retrieving revision 1.28<BR>diff -c -r1.28 M3Path.m3<BR>*** src/M3Path.m3 25 Feb 2008 18:31:18 -0000 1.28<BR>--- src/M3Path.m3 17 Mar 2008 08:11:02 -0000<BR>***************<BR>*** 9,15 ****<BR>  <BR>  MODULE M3Path;<BR>  <BR>! IMPORT Pathname, Text, Env;<BR>  IMPORT RTIO, Process;<BR>  <BR>  CONST<BR>--- 9,15 ----<BR>  <BR>  MODULE M3Path;<BR>  <BR>! IMPORT Pathname, Text;<BR>  IMPORT RTIO, Process;<BR>  <BR>  CONST<BR>***************<BR>*** 114,124 ****<BR>  <BR>  PROCEDURE Join (dir, base: TEXT;  k: Kind;  host: BOOLEAN): TEXT =<BR>    VAR<BR>!     os       := os_map [host];<BR>!     pre      := Prefix [os][k];<BR>!     ext      := Suffix [os][k];<BR>!     d_sep    := DirSep [os];<BR>!     v_sep    := VolSep [os];<BR>      ch       : CHAR;<BR>      buf      : ARRAY [0..255] OF CHAR;<BR>      dir_len  := 0;<BR>--- 114,125 ----<BR>  <BR>  PROCEDURE Join (dir, base: TEXT;  k: Kind;  host: BOOLEAN): TEXT =<BR>    VAR<BR>!     host_os  := os_map [host];<BR>!     target_os := os_map [FALSE];<BR>!     pre      := Prefix [target_os][k];<BR>!     ext      := Suffix [target_os][k];<BR>!     d_sep    := DirSep [host_os];<BR>!     v_sep    := VolSep [host_os];<BR>      ch       : CHAR;<BR>      buf      : ARRAY [0..255] OF CHAR;<BR>      dir_len  := 0;<BR>***************<BR>*** 191,199 ****<BR>      d_index := -1;<BR>      v_index := -1;<BR>      start   := 0;<BR>!     os      := os_map [host];<BR>!     d_sep   := DirSep [os];<BR>!     v_sep   := VolSep [os];<BR>      ext     : TEXT;<BR>      ext_len : INTEGER;<BR>      pre     : TEXT;<BR>--- 192,201 ----<BR>      d_index := -1;<BR>      v_index := -1;<BR>      start   := 0;<BR>!     host_os := os_map [host];<BR>!     target_os := os_map [FALSE];<BR>!     d_sep   := DirSep [host_os];<BR>!     v_sep   := VolSep [host_os];<BR>      ext     : TEXT;<BR>      ext_len : INTEGER;<BR>      pre     : TEXT;<BR>***************<BR>*** 222,228 ****<BR>        t.dir := Text.FromChars (SUBARRAY (nm, 0, v_index+1));<BR>        start := v_index + 1;<BR>      ELSIF (d_index = 0) THEN<BR>!       t.dir := DirSepText [os];<BR>        start := 1;<BR>      ELSE<BR>        t.dir := Text.FromChars (SUBARRAY (nm, 0, d_index));<BR>--- 224,230 ----<BR>        t.dir := Text.FromChars (SUBARRAY (nm, 0, v_index+1));<BR>        start := v_index + 1;<BR>      ELSIF (d_index = 0) THEN<BR>!       t.dir := DirSepText [host_os];<BR>        start := 1;<BR>      ELSE<BR>        t.dir := Text.FromChars (SUBARRAY (nm, 0, d_index));<BR>***************<BR>*** 234,241 ****<BR>      t.kind := Kind.Unknown;<BR>      ext_len := 0;<BR>      FOR k := FIRST (Kind) TO LAST (Kind) DO<BR>!       ext := Suffix [os][k];<BR>!       IF ExtMatch (nm_txt, ext, os) THEN<BR>          ext_len := Text.Length (ext);<BR>          t.kind := k;<BR>          EXIT;<BR>--- 236,243 ----<BR>      t.kind := Kind.Unknown;<BR>      ext_len := 0;<BR>      FOR k := FIRST (Kind) TO LAST (Kind) DO<BR>!       ext := Suffix [target_os][k];<BR>!       IF ExtMatch (nm_txt, ext, host_os) THEN<BR>          ext_len := Text.Length (ext);<BR>          t.kind := k;<BR>          EXIT;<BR>***************<BR>*** 245,252 ****<BR>      (* extract the base component *)<BR>      t.base := Text.FromChars (SUBARRAY (nm, start, base_len - ext_len));<BR>  <BR>!     pre := Prefix[os][t.kind];<BR>!     IF (Text.Length (pre) > 0) AND PrefixMatch (t.base, pre, os) THEN<BR>        t.base := Text.Sub (t.base, Text.Length (pre));<BR>      END;<BR>  <BR>--- 247,254 ----<BR>      (* extract the base component *)<BR>      t.base := Text.FromChars (SUBARRAY (nm, start, base_len - ext_len));<BR>  <BR>!     pre := Prefix[target_os][t.kind];<BR>!     IF (Text.Length (pre) > 0) AND PrefixMatch (t.base, pre, host_os) THEN<BR>        t.base := Text.Sub (t.base, Text.Length (pre));<BR>      END;<BR>  <BR>***************<BR>*** 321,337 ****<BR>--- 323,343 ----<BR>  <BR>  PROCEDURE DefaultProgram (host: BOOLEAN): TEXT =<BR>    BEGIN<BR>+     host := FALSE;<BR>      RETURN Default_pgm [os_map [host]];<BR>    END DefaultProgram;<BR>  <BR>  PROCEDURE ProgramName (base: TEXT;  host: BOOLEAN): TEXT =<BR>    BEGIN<BR>+     host := FALSE;<BR>      RETURN base & Suffix[os_map [host]][Kind.PGM];<BR>    END ProgramName;<BR>  <BR>  PROCEDURE LibraryName (base: TEXT;  host: BOOLEAN): TEXT =<BR>    VAR os := os_map [host];<BR>    BEGIN<BR>+     host := FALSE;<BR>+     os := os_map [host];<BR>      RETURN Prefix[os][Kind.LIB] & base & Suffix[os][Kind.LIB];<BR>    END LibraryName;<BR>  <BR>***************<BR>*** 764,786 ****<BR>      lcase[i] := VAL (ORD (i) - ORD ('A') + ORD ('a'), CHAR);<BR>    END;<BR>  <BR>!  (* OSKind is determined from "naming conventions"<BR>!     which are mostly about foo.lib vs. libfoo.a, foo.dll vs. libfoo.so, foo vs. foo.exe.<BR>!     "Naming conventions" also determines the slash, however NT386GNU uses<BR>!     Win32 "naming conventions" (currently) but forward slashes. In reality,<BR>!     forward slashes work almost anywhere, but at this time we are not pushing<BR>!     through the change to use forward slashes more on regular NT386.<BR>!     What we do here is probe our runtime for its slash as was already being<BR>!     done to set the Quake SL variable, but applying the result to more code.<BR>! <BR>!     In general this run-time/compile-time determinations probably need better abstraction.<BR>!     At least in other places, where the way time works is used to determine if the runtime is Unix.<BR>!     In this case, the slash could be fed in at build time, or set in Quake, however<BR>!     how to get his data from Quake efficiently (and early enough?), is to be determined.<BR>    *)<BR>    IF Text.GetChar (Pathname.Join ("a", "b"), 1) = BackSlash THEN<BR>  <BR>-     SlashChar := BackSlash;<BR>      SlashText := "\\";<BR>      os_map [TRUE]  := OSKind.Win32;<BR>      os_map [FALSE] := OSKind.Win32;<BR>--- 770,780 ----<BR>      lcase[i] := VAL (ORD (i) - ORD ('A') + ORD ('a'), CHAR);<BR>    END;<BR>  <BR>!  (* Probe the host for what slash it uses, and default host and<BR>!     target "naming conventions" based on that.<BR>    *)<BR>    IF Text.GetChar (Pathname.Join ("a", "b"), 1) = BackSlash THEN<BR>  <BR>      SlashText := "\\";<BR>      os_map [TRUE]  := OSKind.Win32;<BR>      os_map [FALSE] := OSKind.Win32;<BR>***************<BR>*** 789,809 ****<BR>  <BR>      lcase [Slash] := BackSlash;<BR>  <BR>-   ELSE<BR>- <BR>-     WITH OS = Env.Get("OS") DO<BR>-       IF OS # NIL AND Text.Equal (OS, "Windows_NT") THEN<BR>- <BR>-         (* NT386GNU uses foo.lib instead of libfoo.a (at least for now), and forward slashes. *)<BR>- <BR>-         os_map [TRUE]  := OSKind.Win32;<BR>-         os_map [FALSE] := OSKind.Win32;<BR>-         DirSep [OSKind.Win32] := DirSep [OSKind.Unix]; (* Slash *)<BR>-         DirSepText [OSKind.Win32] := DirSepText [OSKind.Unix]; (* "//" *)<BR>-         VolSep [OSKind.Win32] := VolSep [OSKind.Unix]; (* Null *)<BR>- <BR>-      END;<BR>-     END;<BR>    END;<BR>  <BR>    (* Test (); *)<BR>--- 783,788 ----<BR>
<BR> - Jay<BR> <BR><br /><hr />Need to know the score, the latest news, or you need your HotmailŪ-get your "fix". <a href='http://www.msnmobilefix.com/Default.aspx' target='_new'>Check it out.</a></body>
</html>