Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/system/README
ViewVC logotype

Annotation of /sml/trunk/src/system/README

Parent Directory Parent Directory | Revision Log Revision Log


Revision 498 - (view) (download)
Original Path: sml/branches/SMLNJ/src/system/README

1 : monnier 416 !!! ATTENTION !!!
2 :     As an SML/NJ compiler developer, please read this document carefully.
3 :     The new CM has a lot of good things to offer, but you must be aware
4 :     of the many changes that it incurs to the process of compiling the
5 :     SML/NJ compiler.
6 :     Matthias Blume (July 1999)
7 :     -------------------------------------------------------------------------
8 :    
9 :     * Libraries
10 :     -----------
11 :    
12 :     The new way of building the compiler is heavily library-oriented.
13 :     Aside from a tiny portion of code that is responsible for defining the
14 :     pervasive environment, _everything_ lives in libraries. Building the
15 :     compiler means compiling and stabilizing these libraries first. Some
16 :     of the libraries exist just for reasons of organizing the code, the
17 :     other ones are potentially useful in their own right. Therefore, as a
18 :     beneficial side-effect of compiling the compiler, you will end up with
19 :     stable versions of these libraries.
20 :    
21 :     At the moment, the following libraries are constructed when compiling
22 :     the compiler ("*" means that I consider the library potentially useful
23 :     in its own right):
24 :    
25 :     * basis.cm - The SML'97 basis library
26 :     - cm-hook.cm - an internal library for organizational purposes
27 :     - cm-lib.cm - the library that implements CM's functionality
28 :     * comp-lib.cm - a helper library for the compiler, MLRISC, and CM
29 : monnier 498 * full-cm.cm - the library that exports the public interface to
30 : monnier 416 the compilation manager (i.e., structure CM)
31 : monnier 498 * minimal-cm.cm - exports a reduced version of structure CM;
32 :     this one is pre-registered at the top level
33 : monnier 416 * host-cmb.cm - the library that exports the public interface to
34 :     the bootstrap compiler (i.e., structure CMB)
35 :     - host-compiler-0.cm
36 :     - an internal library for organizational purposes
37 :     * host-compiler.cm
38 :     - the library that exports the public interface to
39 :     the visible compiler (i.e., structure Compiler)
40 :     - intsys.cm - an internal library for organizational purposes
41 :     (In fact, its the "root" of the main hierarchy.)
42 :     * ml-yacc-lib.cm - needs no further comment
43 :     * smlnj-lib.cm - needs no further comment
44 : monnier 498 * <arch>-compiler.cm - exports the Compiler structure for the
45 :     given architecture (<Arch>Compiler).
46 :     * <arch>-<os>.cm - exports <Arch><OS>CMB for the given architecture-
47 :     OS combination.
48 : monnier 416 * target-compilers.cm
49 :     - library exporting target-specific versions of
50 : monnier 498 structure Compiler and of structure CMB.
51 :     This is a summary of all the <arch>-compiler.cm
52 :     and <arch>-<os>.cm libraries above.
53 :     (The existence of these libraries is the moral
54 : monnier 416 equivalent of "CMB.retarget" in the old CM.)
55 : monnier 498 * viscomp-core.cm - library that implements the machine-independent
56 :     core of the compiler.
57 :     * viscomp-<arch>.cm - library that implements the visible compiler
58 :     for a given architecture.
59 : monnier 416
60 :     * Before you can use the bootstrap compiler (CMB)...
61 :     ----------------------------------------------------
62 :    
63 :     To be able to use CMB at all, you must first say
64 :    
65 :     CM.autoload "host-cmb.cm";
66 :    
67 :     after you start sml.
68 :    
69 :     * Compiling the compiler -- a two-step procedure
70 :     ------------------------------------------------
71 :    
72 :     Until now (with the old CM), once we managed to run CMB.make() to
73 :     completion we had a directory full of binfiles that were ready to be
74 :     used by the boot procedure. This is no longer the case.
75 :    
76 :     The boot procedure now wants to use stable libraries (except for the
77 :     part that makes up the pervasive environment). Having stable
78 :     libraries around during development of these very libraries would be a
79 :     bit annoying because if CM sees a stable library it will no longer
80 :     bother to check the corresponding source files -- even if they have
81 :     changed. Therefore, libraries are not stabilized until you think you
82 :     are ready for that. Thus, you should run:
83 :    
84 :     CMB.make ();
85 :    
86 :     until you no longer get compile errors. CMB.make will return true in
87 :     this case. Then you say:
88 :    
89 :     CMB.deliver ();
90 :    
91 :     This command creates a second directory parallel to the "bin"
92 :     directory -- the "boot" directory. It will hold everything necessary
93 :     to bootstrap a new heap image. You will probably find that
94 :     CMB.deliver() compiles a number of additional files even though
95 :     CMB.make completed successfully. This is because CMB.make compiles
96 :     just those modules that will actually go into the heap image, but
97 :     CMB.deliver must also build the remaining files -- files that are part
98 :     of libraries to be stabilized but which are not used by the compiler.
99 :    
100 : monnier 498 You can reduce the number of extra files compiled and stabilized
101 :     during CMB.deliver at the expense of not building any cross-compilers.
102 :     For that, say
103 :     #set (CMB.symval "LIGHT") (SOME 1);
104 :     before running CMB.deliver.
105 :    
106 : monnier 416 After you have made the boot directory, if you want to continue
107 :     developing the compiler (i.e., make changes to some sources,
108 :     recompile, etc.), you must first get rid of that boot directory.
109 :     Running the "makeml" script (see below) will automatically remove the
110 :     boot directory.
111 :    
112 :     The names of "bin" and "boot" directories are
113 :    
114 :     <prefix>.bin.<arch>-<os>
115 :    
116 :     and
117 :    
118 :     <prefix>.boot.<arch>-<os>
119 :    
120 : monnier 498 respectively, with "sml" being the default for <prefix>. To change
121 : monnier 416 the prefix, use CMB.make' and CMB.deliver' with the new prefix
122 :     provided as the optional string argument to these functions.
123 :    
124 :     * Making the heap image
125 :     -----------------------
126 :    
127 :     The heap image is made by running the "makeml" script that you find
128 :     here in this directory. By default it will try to refer to the
129 : monnier 498 sml.boot.<arch>-<os> directory. You can change this using the -boot
130 : monnier 416 argument (which takes the full name of the boot directory to be used).
131 :    
132 :     The "feel" of using makeml should be mostly as it used to. However,
133 :     internally, there are some changes that you should be aware of:
134 :    
135 :     1. The script will make a heap image and also move its associated
136 :     libraries into a separate directory.
137 :    
138 :     2. There is no "-full" option anymore. This functionality should
139 :     eventually be provided by a library with a sufficiently rich export
140 :     interface.
141 :    
142 :     3. No image will be generated if you use the -rebuild option.
143 :     Instead, the script quits after making new bin and new boot
144 :     directories. You must re-invoke makeml with a suitable "-boot"
145 :     option to actually make the image. The argument to "-rebuild"
146 :     is the <prefix> for the new bin and boot directories (see above).
147 :    
148 :     4. Unless you use "-rebuild", makeml will delete the boot directory
149 :     (thus readying you for further "CMB.make();" runs).
150 :    
151 :     * Testing a newly generated heap image
152 :     --------------------------------------
153 :    
154 :     If you use a new heap image by saying "sml @SMLload=..." then things
155 :     will not go as you may expect because along with the new heap image
156 :     should go those new stable libraries, but unless you do something
157 :     about it, the new CM will look for its stable libraries in places
158 :     where you stored your _old_ stable libraries.
159 :    
160 :     After you have made the new heap image, the new libraries are in a
161 :     separate directory whose name is derived from the name of the heap
162 : monnier 429 image. The "testml" script that you also find here will run the heap
163 : monnier 416 image and instruct it to look for its libraries in that new library
164 :     directory.
165 :    
166 : monnier 498 "testml" takes the <prefix> of the heap image as its first
167 :     argument. All other arguments are passed verbatim to the ML process.
168 :    
169 :     The <prefix> is the same as the one used when you did "makeml". If
170 :     you run "testml" without arguments, <prefix> defaults to "sml".
171 :     Thus, if you just said "makeml" without argument you can also say
172 :     "testml" without argument. (Note that you _must_ supply the <prefix>
173 :     argument if you intend to pass any additional arguments.)
174 :    
175 : monnier 416 * Installing a heap image for more permanent use
176 :     ------------------------------------------------
177 :    
178 : monnier 498 You can "install" a newly generated heap image by replacing the old
179 :     image with the new one _AND AT THE SAME TIME_ replacing the old stable
180 :     libaries with the new ones. To do this, run the "installml" script.
181 : monnier 416
182 : monnier 498 Like "testml", "installml" also expects the <prefix> as its first
183 :     argument. <prefix> defaults to "sml" if no argument is specified.
184 :    
185 :     "installml" patches the ../../lib/pathconfig file to reflect any
186 :     changes or additions to the path name mapping.
187 :    
188 :     Thus, after a successful CMB.deliver, you should say
189 :    
190 :     ./makeml
191 :    
192 :     to make the new heap image + libraries, then
193 :    
194 :     ./testml
195 :    
196 :     to make sure everything works, and finally
197 :    
198 :     ./installml
199 :    
200 :     to replace your existing compiler with the one you just built and tested.
201 :    
202 : monnier 416 * Cross-compiling
203 :     -----------------
204 :    
205 :     All cross-compilers live in the "target-compilers.cm" library. You
206 :     must first say
207 :    
208 :     CM.autoload "target-compilers.cm";
209 :    
210 :     before you can access them. (This step corresponds to the old
211 :     CMB.retarget call.) After that, _all_ cross-compilers are available
212 :     at the same time. However, the ones that you are not using don't take
213 :     up any undue space because they only get loaded once you actually
214 :     mention them at the top-level. The names of the structures currently
215 :     exported by target-compilers.cm are:
216 :    
217 :     structure Alpha32UnixCMB
218 :     structure HppaUnixCMB
219 :     structure PPCMacOSCMB
220 :     structure PPCUnixCMB
221 :     structure SparcUnixCMB
222 :     structure X86UnixCMB
223 :     structure X86Win32CMB
224 :    
225 :     structure Alpha32Compiler
226 :     structure HppaCompiler
227 :     structure PPCCompiler
228 :     structure SparcCompiler
229 :     structure X86Compiler
230 :    
231 :     (PPCMacOSCMB is not very useful at the moment because there is no
232 :     implementation of the basis library for the MacOS.)
233 :    
234 : monnier 498 Alternatively, you can select just the one single structure that you
235 :     are interested in by auto-loading <arch>-compiler.cm or <arch>-<os>.cm.
236 :     <arch> currently ranges over "alpha32", "hppa", "ppc", "sparc", and "x86.
237 :     <os> can be either "unix" or "macos" or "win32".
238 :     (Obviously, not all combinations are valid.)
239 :    
240 : monnier 416 * Path configuration
241 :     --------------------
242 :    
243 :     + Basics:
244 :    
245 :     One of the new features of CM is its handling of path names. In the
246 :     old CM, one particular point of trouble was the autoloader. It
247 :     analyzes a group or library and remembers the locations of associated
248 :     files. Later, when the necessity arises, those files will be read.
249 :     Therefore, one was asking for trouble if the current working directory
250 :     was changed between analysis- and load-time, or, worse, if files
251 :     actually moved about (as is often the case if build- and
252 :     installation-directories are different, or, to put it more generally,
253 :     if CM's state is frozen into a heap image and used in a different
254 :     environment).
255 :    
256 :     Maybe it would have been possible to work around most of these
257 :     problems by fixing the path-lookup mechanism in the old CM and using
258 :     it extensively. But path-lookup (as in the Unix-shell's "PATH") is
259 :     inherently dangerous because one can never be too sure what it will be
260 :     that is found on the path. A new file in one of the directories early
261 :     in the path can upset the program that hopes to find something under
262 :     the same name later on the path. Even when ignoring security-issues
263 :     like trojan horses and such, this definitely opens the door for
264 : monnier 498 various unpleasant surprises. (Who has never named a test version
265 : monnier 416 of a program "test" an found that it acts strangely only to discover
266 :     later that /bin/test was run instead?)
267 :    
268 :     Thus, the new scheme used by CM is a fixed mapping of what I call
269 :     "configuration anchors" to corresponding directories. The mapping can
270 :     be changed, but one must do so explicitly. In effect, it does not
271 :     depend on the contents of the file system. Here is how it works:
272 :    
273 :     If I specify a relative pathname in one of CM's description files
274 :     where the first component (the first arc) of that pathname is known to
275 :     CM as a configuration anchor, then the corresponding directory
276 :     (according to CM's mapping) is prepended to the path. Suppose the
277 :     path name is "a/foo.sml" and "a" is a known anchor that maps to
278 :     "/usr/lib/smlnj", then the resulting complete pathname is
279 :     "/usr/lib/smlnj/a/foo.sml". The pathname can be a single arc (but
280 :     does not have to be). For example, the anchor "basis.cm" is typically
281 :     mapped to the directory where the basis library is stored.
282 :    
283 :     Now, the important point is that one can change the mapping of the
284 :     anchor, and the path name will also change accordingly -- even very
285 :     late in the game. CM avoids "elaborating" path names until it really
286 :     needs them when it is time to open files. CM is also willing to
287 :     re-elaborate the same names if there is reason to do so. Thus, the
288 :     "basis.cm" library that was analyzed "here" but then moved "there"
289 :     will also be found "there" if the anchor has been re-set accordingly.
290 :    
291 :     + Different configurations at different times:
292 :    
293 :     During compilation of the compiler, CMB uses a path configuration that
294 :     is read from the file "pathconfig" located here in this directory.
295 :    
296 :     At bootstrap time, the same anchors are mapped to the corresponding
297 :     sub-directory of the "boot" directory: basis.cm is mapped to
298 : monnier 498 sml.boot.<arch>-<os>/basis.cm -- which means that CM will look for a
299 :     library named sml.boot.<arch>-<os>/basis.cm/basis.cm -- and so forth.
300 : monnier 416
301 :     By the way, you will perhaps notice that there is no file
302 : monnier 498 sml.boot.<arch>-<os>/basis.cm/basis.cm
303 : monnier 416 but there _is_ the corresponding stable archive
304 : monnier 498 sml.boot.<arch>-<os>/basis.cm/CM/<arch>-<os>/basis.cm
305 : monnier 416 CM always looks for stable archives first.
306 :    
307 :     This mapping (from anchors to names in the boot directory) is the one
308 :     that will get frozen into the generated heap image at boot time.
309 :     Thus, unless it is changed, CM will look for its libraries in the boot
310 : monnier 429 directory. The aforementioned "testml" script will make sure that
311 : monnier 416 the mapping is changed to the one specified in a new "pathconfig" file
312 :     which was created by makeml and placed into the test library
313 :     directory. It points all anchors to the corresponding entry in the
314 : monnier 429 test library directory. Thus, "testml" will let a new heap image run
315 : monnier 416 with its corresponding new libraries.
316 :    
317 :     Normally, however, CM consults other pathconfig files at startup --
318 :     files that live in standard locations. These files are used to modify
319 :     the path configuration to let anchors point to their "usual" places.
320 :     The names of the files that are read (if present) are configurable via
321 :     environment variables. At the moment they default to
322 :     /usr/lib/smlnj-pathconfig
323 :     and
324 :     $HOME/.smlnj-pathconfig
325 :     The first one is configurable via CM_PATHCONFIG (and the default is
326 :     configurable at boot time via CM_PATHCONFIG_DEFAULT); the last is
327 :     configurable via CM_LOCAL_PATHCONFIG and CM_LOCAL_PATHCONFIG_DEFAULT.
328 :     In fact, the makeml script sets the CM_PATHCONFIG_DEFAULT variable
329 :     before making the heap image. Therefore, heap images generated by
330 :     makeml will look for their global pathconfig file in
331 :    
332 : monnier 429 `pwd`/../../lib/pathconfig
333 : monnier 416
334 : monnier 429 For example, I always keep my "good" libraries in `pwd`/../../lib --
335 :     where both the main "install" script and the "installml" script (see
336 : monnier 498 above) also put them -- so I don't have to do anything special about
337 : monnier 429 my pathconfig file.
338 : monnier 416
339 :     Once I have new heap image and libraries working, I replace the old
340 :     "good" image with the new one:
341 :    
342 :     mv <image>.<arch>-<osvariant> ../../bin/.heap/sml.<arch>-<osvariant>
343 :    
344 :     and then:
345 :    
346 : monnier 429 rm -r ../../lib/*.cm
347 :     mv <image>.libs/*.cm ../../lib
348 : monnier 416
349 : monnier 429 For convenience, there is a script called "installml" that automates
350 :     this task. Using the script has the added advantage that it will not
351 :     clobber libraries that belong to other than the current architecture.
352 :     (The rather heavy-handed "rm/mv" approach above will delete all stable
353 : monnier 498 libraries for all architectures.) "installml" also patches the
354 :     ../../lib/pathconfig file as necessary.
355 : monnier 429
356 : monnier 416 Of course, you can organize things differently for yourself -- the
357 :     path configuration mechanism should be sufficiently flexible.
358 :    
359 :     * Libraries vs. Groups
360 :     ----------------------
361 :    
362 :     With the old CM, "group" was the primary concept while "library" and
363 :     "stabilization" could be considered afterthoughts. This has changed.
364 :     Now "library" is the primary concept, "stabilization" is semantically
365 :     significant, and "groups" are a secondary mechanism.
366 :    
367 :     Libraries are used to "structure the world"; groups are used to give
368 :     structure to libraries. Each group can be used either in precisely
369 :     one library (in which case it cannot be used at the interactive
370 :     toplevel) or at the toplevel (in which case it cannot be used in any
371 :     library). In other words, if you count the toplevel as a library,
372 :     then each group has a unique "owner" library. Of course, there still
373 :     is no limit on how many times a group can be mentioned as a member of
374 :     other groups -- as long as all these other groups belong to the same
375 :     owner library.
376 :    
377 :     If you want to take a collection of files whose purpose fits that of a
378 :     library, then, please, make them into a library (i.e., not a group!).
379 :     The purpose of groups is to deal with name-space issues _within_
380 :     libraries.
381 :    
382 :     Aside from the fact that I find this design quite natural, there is
383 :     actually a technical reason for it: when you stabilize a library
384 :     (groups cannot be stabilized), then all its sub-groups (not
385 :     sub-libraries!) get "sucked into" the stable archive of the library.
386 :     In other words, even if you have n+1 CM description files (1 for the
387 :     library, n for n sub-groups), there will be just one file representing
388 :     the one stable archive (per architecture/os) for the whole thing. For
389 :     example, I structured the standard basis into one library with two
390 :     sub-groups, but once you compile it (CMB.deliver) there is only one
391 :     stable file that represents the whole basis library. If groups were
392 :     allowed to appear in more than one library, then stabilization would
393 :     duplicate the group (its code, its environment data structures, and
394 :     even its dynamic state).
395 :    
396 :     There is a small change to the syntax of group description files: they
397 :     must explicitly state which library they belong to. CM will verify
398 :     that. The owner library is specified in parentheses after the "group"
399 :     keyword. If the specification is missing (that's the "old" syntax),
400 :     then the the owner will be taken to be the interactive toplevel.
401 :    
402 :     * Pervasive environment, core environment, other "primitive" environments
403 :     -------------------------------------------------------------------------
404 :    
405 :     Just a handful of files is compiled at the beginning in order to
406 :     establish a number of "primitive" environments -- including the
407 :     "pervasive" environment and the "core" environment. The pervasive
408 :     environment no longer includes the entire basis library but only
409 :     non-modular bindings (top-level bindings of variables and types).
410 :    
411 :     CM cannot automatically determine dependencies for these initial
412 :     source files, but it still does use its regular cutoff recompilation
413 :     mechanism. Therefore, dependencies must be given explicitly. This is
414 :     done by a special description file which currently lives in
415 :     Init/init.cmi. See the long comment at the beginning of that file for
416 :     more details.
417 :    
418 :     * Autoloader
419 :     ------------
420 :    
421 :     The new system heavily relies on the autoloader. As a result, almost
422 :     no static environments need to get unpickled at bootstap time. The
423 :     construction of such environments is deferred until they become
424 :     necessary. Because of this, I was able to reduce the size of the heap
425 :     image by more than one megabyte (depending on the architecture). The
426 :     downside (although not really terribly bad) is that there is a short
427 :     wait when you first touch an identifier that hasn't been touched
428 :     before. (I acknowledge that the notion of "short" may depend on your
429 :     sense of urgency. :-)
430 :    
431 :     The reliance on the autoloader (and therefore CM's library mechanism)
432 :     means that in order to be able to use the system, your paths must be
433 :     properly configured.
434 :    
435 :     Two libraries get pre-registered at bootstap time: the basis library
436 : monnier 498 ("basis.cm") and CM itself ("minimal-cm.cm"). The latter is crucial:
437 : monnier 416 without it one wouldn't be able to register any other libraries
438 :     via CM.autoload. The registration of basis.cm is a mere convenience.
439 :    
440 :     Here are some other useful libraries that are not pre-registered but
441 :     which can easily be made accessible via CM.autoload (or, non-lazily,
442 :     via CM.make):
443 :    
444 : monnier 498 full-cm.cm - provides the actual ("full") structure CM
445 :     as described in the CM manual
446 : monnier 416 host-compiler.cm - provides "structure Compiler"
447 :     host-cmb.cm - provides "structure CMB"
448 :     target-compilers.cm - provides "structure <Arch>Compiler" and
449 :     "structure <Arch><OS>CMB" for various
450 :     values of <Arch> and <OS>
451 :     smlnj-lib.cm - the SML/NJ library
452 :    
453 :     * Internal sharing
454 :     ------------------
455 :    
456 :     Dynamic values of loaded modules are shared. This is true even for
457 :     those modules that are used by the interactive compiler itself. If
458 :     you load a module from a library that is also used by the interactive
459 :     compiler, then "loading" means "loading the static environmnent" -- it
460 :     does not mean "loading the code and linking it". Instead, you get to
461 :     share the compiler's dynamic values (and therefore the executable
462 :     code as well).
463 :    
464 :     Of course, if you load a module that hasn't been loaded before and
465 :     also isn't used by the interactive system, then CM will get the code
466 :     and link (execute) it.
467 :    
468 :     * Access control
469 :     ----------------
470 :    
471 :     In some places, you will find that the "group" and "library" keywords
472 :     in description files are preceeded by certain strings, sometimes in
473 :     parentheses. These strings are the names of "privileges". Don't
474 :     worry about them too much at the moment. For the time being, access
475 :     control is not enforced, but the infrastructure is in place.
476 :    
477 :     * Preprocessor
478 :     --------------
479 :    
480 :     The syntax of expressions in #if and #elif clauses is now more ML-ish
481 :     instead of C-ish. (Hey, this is ML after all!) In particular, you
482 :     must use "andalso", "orelse", and "not" instead of "&&", "||" and "!".
483 :     Unary minus is "~".
484 :    
485 :     A more interesting change is that you can now query the exports of
486 :     sources/subgroups/sublibraries:
487 :    
488 :     - Within the "members" section of the description (i.e., after "is"):
489 :     The expression
490 :     defined(<namespace> <name>)
491 :     is true if any of the included members preceeding this clause exports
492 :     a symbol "<namespace> <name>".
493 :     - Within the "exports" section of the description (i.e., before "is):
494 :     The same expression is true if _any_ of the members exports the
495 :     named symbol.
496 :     (It would be more logical if the exports section would follow the
497 :     members section, but for esthetic reasons I prefer the exports
498 :     section to come first.)
499 :    
500 :     Example:
501 :    
502 :     +--------------------------+
503 :     |Library |
504 :     | structure Foo |
505 :     |#if defined(structure Bar)|
506 :     | structure Bar |
507 :     |#endif |
508 :     |is |
509 :     |#if SMLNJ_VERSION > 110 |
510 :     | new-foo.sml |
511 :     |#else |
512 :     | old-foo.sml |
513 :     |#endif |
514 :     |#if defined(structure Bar)|
515 :     | bar-client.sml |
516 :     |#else |
517 :     | no-bar-so-far.sml |
518 :     |#endif |
519 :     +--------------------------+
520 :    
521 :     Here, the file "bar-client.sml" gets included if SMLNJ_VERSION is
522 :     greater than 110 and new-foo.sml exports a structure Bar _or_ if
523 :     SMLNJ_VERSION <= 110 and old-foo.sml exports structure Bar. Otherwise
524 :     "no-bar-so-far.sml" gets included instead. In addition, the export of
525 :     structure Bar is guarded by its own existence. (Structure Bar could
526 :     also be defined by "no-bar-so-far.sml" in which case it would get
527 :     exported regardless of the outcome of the other "defined" test.)
528 :    
529 :     Some things to note:
530 :    
531 :     - For the purpose of the pre-processor, order among members is
532 :     significant. (For the purpose of dependency analysis, order continues
533 :     to be not significant).
534 :     - As a consequence, in some cases pre-processor dependencies and
535 :     compilation-dependencies may end up to be opposites of each other.
536 :     (This is not a problem; it may very well be a feature.)
537 :    
538 :     * The Basis Library is no longer built-in
539 :     -----------------------------------------
540 :    
541 :     The SML'97 basis is no longer built-in. If you want to use it, you
542 :     must specify "basis.cm" as a member of your group/library.
543 :    
544 :     * No more aliases
545 :     -----------------
546 :    
547 :     The "alias" feature is no longer with us. At first I thought I could
548 :     keep it, but it turns out that it causes some fairly fundamental
549 :     problems with the autoloader. However, I don't think that this is a
550 :     big loss because path anchors make up for most of it. Moreover,
551 :     stable libraries can now easily be moved to convenient locations
552 :     without having to move large source trees at the same time. (See my
553 :     new build/install.sh script for examples of that.)
554 :    
555 :     * Don't use relative or absolute pathnames to refer to libraries
556 :     ----------------------------------------------------------------
557 :    
558 :     Don't use relative or absolute pathnames to refer to libraries. If
559 :     you do it anyway, you'll get an appropriate warning at the time when
560 :     you do CMB.deliver(). If you use relative or absolute pathnames to
561 :     refer to library B from library A, you will be committed to keeping B
562 :     in the same relative (to A) or absolute location. This, clearly,
563 :     would be undesirable.

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0