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 569 - (view) (download)

1 : blume 537 Compiler Hacker's Guide to the new CM...
2 :     ========================================
3 : monnier 416
4 : blume 537 Last change: 2/2000
5 :    
6 : monnier 416 * Libraries
7 :     -----------
8 :    
9 :     The new way of building the compiler is heavily library-oriented.
10 :     Aside from a tiny portion of code that is responsible for defining the
11 :     pervasive environment, _everything_ lives in libraries. Building the
12 :     compiler means compiling and stabilizing these libraries first. Some
13 :     of the libraries exist just for reasons of organizing the code, the
14 :     other ones are potentially useful in their own right. Therefore, as a
15 :     beneficial side-effect of compiling the compiler, you will end up with
16 :     stable versions of these libraries.
17 :    
18 :     At the moment, the following libraries are constructed when compiling
19 :     the compiler ("*" means that I consider the library potentially useful
20 :     in its own right):
21 :    
22 :     * basis.cm - The SML'97 basis library
23 :     - cm-hook.cm - an internal library for organizational purposes
24 :     - cm-lib.cm - the library that implements CM's functionality
25 :     * comp-lib.cm - a helper library for the compiler, MLRISC, and CM
26 : monnier 498 * full-cm.cm - the library that exports the public interface to
27 : monnier 416 the compilation manager (i.e., structure CM)
28 : monnier 498 * minimal-cm.cm - exports a reduced version of structure CM;
29 :     this one is pre-registered at the top level
30 : monnier 416 * host-cmb.cm - the library that exports the public interface to
31 :     the bootstrap compiler (i.e., structure CMB)
32 :     - host-compiler-0.cm
33 :     - an internal library for organizational purposes
34 :     * host-compiler.cm
35 :     - the library that exports the public interface to
36 :     the visible compiler (i.e., structure Compiler)
37 :     - intsys.cm - an internal library for organizational purposes
38 :     (In fact, its the "root" of the main hierarchy.)
39 :     * ml-yacc-lib.cm - needs no further comment
40 :     * smlnj-lib.cm - needs no further comment
41 : monnier 498 * <arch>-compiler.cm - exports the Compiler structure for the
42 :     given architecture (<Arch>Compiler).
43 :     * <arch>-<os>.cm - exports <Arch><OS>CMB for the given architecture-
44 :     OS combination.
45 : monnier 416 * target-compilers.cm
46 :     - library exporting target-specific versions of
47 : monnier 498 structure Compiler and of structure CMB.
48 :     This is a summary of all the <arch>-compiler.cm
49 :     and <arch>-<os>.cm libraries above.
50 :     (The existence of these libraries is the moral
51 : monnier 416 equivalent of "CMB.retarget" in the old CM.)
52 : monnier 498 * viscomp-core.cm - library that implements the machine-independent
53 :     core of the compiler.
54 :     * viscomp-<arch>.cm - library that implements the visible compiler
55 :     for a given architecture.
56 : monnier 416
57 :     * Before you can use the bootstrap compiler (CMB)...
58 :     ----------------------------------------------------
59 :    
60 :     To be able to use CMB at all, you must first say
61 :    
62 :     CM.autoload "host-cmb.cm";
63 :    
64 : blume 569 after you start sml. Alternatively -- and perhaps more conveniently --
65 :     you can provide "host-cmb.cm" as a command-line argument to sml:
66 : monnier 416
67 : blume 569 $ sml host-cmb.cm
68 : monnier 416
69 : blume 569 * Compiling the compiler
70 :     ------------------------
71 : monnier 416
72 : blume 569 We are now back to the old scheme where a call to CMB.make() suffices to
73 :     build a bootable set of files (libraries in our case). CMB.make maintains
74 :     two parallel hierarchies of derived files:
75 : monnier 416
76 : blume 569 1. the binfile hierarchy ("binfiles"), containing compiled objects for
77 :     each individual ML source file; this hierarchy is rooted at
78 :     <prefix>.bin.<arch>-<opsys>
79 :     2. the stable library hierarchy ("boot files"), containing library files
80 :     for each library that participates in building SML/NJ; this hierarchy
81 :     is rooted at
82 :     <prefix>.boot.<arch>-<opsys>
83 : monnier 416
84 : blume 569 The default for <prefix> is "sml". It can be changed by using
85 :     CMB.make' with the new <prefix> as the optional string argument.
86 : monnier 416
87 : blume 569 CMB.make uses bootfiles after it has verified that they are consistent
88 :     with their corresponding binfiles. Bootfiles do not need to be
89 :     deleted in order for CMB.make to work correctly.
90 : monnier 416
91 : blume 569 To bootstrap a new system (using the runtime system boot loader), the
92 :     bootfiles _must_ be present, the binfiles need not be present (but
93 :     their presence does not hurt either).
94 : monnier 416
95 : monnier 498 You can reduce the number of extra files compiled and stabilized
96 : blume 569 during CMB.make at the expense of not building any cross-compilers.
97 : monnier 498 For that, say
98 :     #set (CMB.symval "LIGHT") (SOME 1);
99 : blume 569 before running CMB.make.
100 : monnier 498
101 : monnier 416 * Making the heap image
102 :     -----------------------
103 :    
104 :     The heap image is made by running the "makeml" script that you find
105 :     here in this directory. By default it will try to refer to the
106 : monnier 498 sml.boot.<arch>-<os> directory. You can change this using the -boot
107 : monnier 416 argument (which takes the full name of the boot directory to be used).
108 :    
109 :     The "feel" of using makeml should be mostly as it used to. However,
110 :     internally, there are some changes that you should be aware of:
111 :    
112 : blume 569 1. The script will make a heap image and build a separate library directory
113 :     that contains links to the library files in the bootfile directory.
114 : monnier 416
115 :     2. There is no "-full" option anymore. This functionality should
116 :     eventually be provided by a library with a sufficiently rich export
117 :     interface.
118 :    
119 :     3. No image will be generated if you use the -rebuild option.
120 :     Instead, the script quits after making new bin and new boot
121 :     directories. You must re-invoke makeml with a suitable "-boot"
122 :     option to actually make the image. The argument to "-rebuild"
123 :     is the <prefix> for the new bin and boot directories (see above).
124 :    
125 : blume 569 Makeml will not destroy the bootfile directory.
126 : monnier 416
127 :     * Testing a newly generated heap image
128 :     --------------------------------------
129 :    
130 :     If you use a new heap image by saying "sml @SMLload=..." then things
131 :     will not go as you may expect because along with the new heap image
132 :     should go those new stable libraries, but unless you do something
133 : blume 569 about it, the newly booted system will look for its stable libraries
134 :     in places where you stored your _old_ stable libraries.
135 : monnier 416
136 :     After you have made the new heap image, the new libraries are in a
137 :     separate directory whose name is derived from the name of the heap
138 : blume 569 image. (Actually, only the directory hierachy is separate, the
139 :     library files themselves are hard links.) The "testml" script that you
140 :     also find here will run the heap image and instruct it to look for its
141 :     libraries in that new library directory.
142 : monnier 416
143 : monnier 498 "testml" takes the <prefix> of the heap image as its first
144 :     argument. All other arguments are passed verbatim to the ML process.
145 :    
146 :     The <prefix> is the same as the one used when you did "makeml". If
147 :     you run "testml" without arguments, <prefix> defaults to "sml".
148 :     Thus, if you just said "makeml" without argument you can also say
149 :     "testml" without argument. (Note that you _must_ supply the <prefix>
150 :     argument if you intend to pass any additional arguments.)
151 :    
152 : monnier 416 * Installing a heap image for more permanent use
153 :     ------------------------------------------------
154 :    
155 : monnier 498 You can "install" a newly generated heap image by replacing the old
156 :     image with the new one _AND AT THE SAME TIME_ replacing the old stable
157 :     libaries with the new ones. To do this, run the "installml" script.
158 : monnier 416
159 : monnier 498 Like "testml", "installml" also expects the <prefix> as its first
160 :     argument. <prefix> defaults to "sml" if no argument is specified.
161 :    
162 :     "installml" patches the ../../lib/pathconfig file to reflect any
163 :     changes or additions to the path name mapping.
164 :    
165 : blume 569 Thus, after a successful CMB.make, you should say
166 : monnier 498
167 :     ./makeml
168 :    
169 :     to make the new heap image + libraries, then
170 :    
171 :     ./testml
172 :    
173 :     to make sure everything works, and finally
174 :    
175 :     ./installml
176 :    
177 :     to replace your existing compiler with the one you just built and tested.
178 :    
179 : monnier 416 * Cross-compiling
180 :     -----------------
181 :    
182 :     All cross-compilers live in the "target-compilers.cm" library. You
183 :     must first say
184 :    
185 :     CM.autoload "target-compilers.cm";
186 :    
187 :     before you can access them. (This step corresponds to the old
188 :     CMB.retarget call.) After that, _all_ cross-compilers are available
189 :     at the same time. However, the ones that you are not using don't take
190 :     up any undue space because they only get loaded once you actually
191 :     mention them at the top-level. The names of the structures currently
192 :     exported by target-compilers.cm are:
193 :    
194 :     structure Alpha32UnixCMB
195 :     structure HppaUnixCMB
196 :     structure PPCMacOSCMB
197 :     structure PPCUnixCMB
198 :     structure SparcUnixCMB
199 :     structure X86UnixCMB
200 :     structure X86Win32CMB
201 :    
202 :     structure Alpha32Compiler
203 :     structure HppaCompiler
204 :     structure PPCCompiler
205 :     structure SparcCompiler
206 :     structure X86Compiler
207 :    
208 :     (PPCMacOSCMB is not very useful at the moment because there is no
209 :     implementation of the basis library for the MacOS.)
210 :    
211 : monnier 498 Alternatively, you can select just the one single structure that you
212 :     are interested in by auto-loading <arch>-compiler.cm or <arch>-<os>.cm.
213 :     <arch> currently ranges over "alpha32", "hppa", "ppc", "sparc", and "x86.
214 :     <os> can be either "unix" or "macos" or "win32".
215 :     (Obviously, not all combinations are valid.)
216 :    
217 : blume 569 Again, as with host-cmb.cm, you can specify the .cm file as an
218 :     argument to the sml command:
219 :    
220 :     $ sml target-compilers.cm
221 :    
222 :     or
223 :    
224 :     $ sml alpha32-unix.cm
225 :    
226 : monnier 416 * Path configuration
227 :     --------------------
228 :    
229 :     + Basics:
230 :    
231 :     One of the new features of CM is its handling of path names. In the
232 :     old CM, one particular point of trouble was the autoloader. It
233 :     analyzes a group or library and remembers the locations of associated
234 :     files. Later, when the necessity arises, those files will be read.
235 :     Therefore, one was asking for trouble if the current working directory
236 :     was changed between analysis- and load-time, or, worse, if files
237 :     actually moved about (as is often the case if build- and
238 :     installation-directories are different, or, to put it more generally,
239 :     if CM's state is frozen into a heap image and used in a different
240 :     environment).
241 :    
242 :     Maybe it would have been possible to work around most of these
243 :     problems by fixing the path-lookup mechanism in the old CM and using
244 :     it extensively. But path-lookup (as in the Unix-shell's "PATH") is
245 :     inherently dangerous because one can never be too sure what it will be
246 :     that is found on the path. A new file in one of the directories early
247 :     in the path can upset the program that hopes to find something under
248 :     the same name later on the path. Even when ignoring security-issues
249 :     like trojan horses and such, this definitely opens the door for
250 : monnier 498 various unpleasant surprises. (Who has never named a test version
251 : monnier 416 of a program "test" an found that it acts strangely only to discover
252 :     later that /bin/test was run instead?)
253 :    
254 :     Thus, the new scheme used by CM is a fixed mapping of what I call
255 :     "configuration anchors" to corresponding directories. The mapping can
256 :     be changed, but one must do so explicitly. In effect, it does not
257 :     depend on the contents of the file system. Here is how it works:
258 :    
259 :     If I specify a relative pathname in one of CM's description files
260 :     where the first component (the first arc) of that pathname is known to
261 :     CM as a configuration anchor, then the corresponding directory
262 :     (according to CM's mapping) is prepended to the path. Suppose the
263 :     path name is "a/foo.sml" and "a" is a known anchor that maps to
264 :     "/usr/lib/smlnj", then the resulting complete pathname is
265 :     "/usr/lib/smlnj/a/foo.sml". The pathname can be a single arc (but
266 :     does not have to be). For example, the anchor "basis.cm" is typically
267 :     mapped to the directory where the basis library is stored.
268 :    
269 :     Now, the important point is that one can change the mapping of the
270 :     anchor, and the path name will also change accordingly -- even very
271 :     late in the game. CM avoids "elaborating" path names until it really
272 :     needs them when it is time to open files. CM is also willing to
273 :     re-elaborate the same names if there is reason to do so. Thus, the
274 :     "basis.cm" library that was analyzed "here" but then moved "there"
275 :     will also be found "there" if the anchor has been re-set accordingly.
276 :    
277 :     + Different configurations at different times:
278 :    
279 :     During compilation of the compiler, CMB uses a path configuration that
280 :     is read from the file "pathconfig" located here in this directory.
281 :    
282 :     At bootstrap time, the same anchors are mapped to the corresponding
283 :     sub-directory of the "boot" directory: basis.cm is mapped to
284 : monnier 498 sml.boot.<arch>-<os>/basis.cm -- which means that CM will look for a
285 :     library named sml.boot.<arch>-<os>/basis.cm/basis.cm -- and so forth.
286 : monnier 416
287 :     By the way, you will perhaps notice that there is no file
288 : monnier 498 sml.boot.<arch>-<os>/basis.cm/basis.cm
289 : monnier 416 but there _is_ the corresponding stable archive
290 : monnier 498 sml.boot.<arch>-<os>/basis.cm/CM/<arch>-<os>/basis.cm
291 : monnier 416 CM always looks for stable archives first.
292 :    
293 :     This mapping (from anchors to names in the boot directory) is the one
294 :     that will get frozen into the generated heap image at boot time.
295 :     Thus, unless it is changed, CM will look for its libraries in the boot
296 : monnier 429 directory. The aforementioned "testml" script will make sure that
297 : monnier 416 the mapping is changed to the one specified in a new "pathconfig" file
298 :     which was created by makeml and placed into the test library
299 :     directory. It points all anchors to the corresponding entry in the
300 : monnier 429 test library directory. Thus, "testml" will let a new heap image run
301 : monnier 416 with its corresponding new libraries.
302 :    
303 :     Normally, however, CM consults other pathconfig files at startup --
304 :     files that live in standard locations. These files are used to modify
305 :     the path configuration to let anchors point to their "usual" places.
306 :     The names of the files that are read (if present) are configurable via
307 :     environment variables. At the moment they default to
308 :     /usr/lib/smlnj-pathconfig
309 :     and
310 :     $HOME/.smlnj-pathconfig
311 :     The first one is configurable via CM_PATHCONFIG (and the default is
312 :     configurable at boot time via CM_PATHCONFIG_DEFAULT); the last is
313 :     configurable via CM_LOCAL_PATHCONFIG and CM_LOCAL_PATHCONFIG_DEFAULT.
314 :     In fact, the makeml script sets the CM_PATHCONFIG_DEFAULT variable
315 :     before making the heap image. Therefore, heap images generated by
316 :     makeml will look for their global pathconfig file in
317 :    
318 : monnier 429 `pwd`/../../lib/pathconfig
319 : monnier 416
320 : monnier 429 For example, I always keep my "good" libraries in `pwd`/../../lib --
321 :     where both the main "install" script and the "installml" script (see
322 : monnier 498 above) also put them -- so I don't have to do anything special about
323 : monnier 429 my pathconfig file.
324 : monnier 416
325 :     Once I have new heap image and libraries working, I replace the old
326 :     "good" image with the new one:
327 :    
328 :     mv <image>.<arch>-<osvariant> ../../bin/.heap/sml.<arch>-<osvariant>
329 :    
330 :     and then:
331 :    
332 : monnier 429 rm -r ../../lib/*.cm
333 :     mv <image>.libs/*.cm ../../lib
334 : monnier 416
335 : monnier 429 For convenience, there is a script called "installml" that automates
336 :     this task. Using the script has the added advantage that it will not
337 :     clobber libraries that belong to other than the current architecture.
338 :     (The rather heavy-handed "rm/mv" approach above will delete all stable
339 : monnier 498 libraries for all architectures.) "installml" also patches the
340 :     ../../lib/pathconfig file as necessary.
341 : monnier 429
342 : monnier 416 Of course, you can organize things differently for yourself -- the
343 :     path configuration mechanism should be sufficiently flexible.
344 :    
345 :     * Libraries vs. Groups
346 :     ----------------------
347 :    
348 :     With the old CM, "group" was the primary concept while "library" and
349 :     "stabilization" could be considered afterthoughts. This has changed.
350 :     Now "library" is the primary concept, "stabilization" is semantically
351 :     significant, and "groups" are a secondary mechanism.
352 :    
353 :     Libraries are used to "structure the world"; groups are used to give
354 :     structure to libraries. Each group can be used either in precisely
355 :     one library (in which case it cannot be used at the interactive
356 :     toplevel) or at the toplevel (in which case it cannot be used in any
357 :     library). In other words, if you count the toplevel as a library,
358 :     then each group has a unique "owner" library. Of course, there still
359 :     is no limit on how many times a group can be mentioned as a member of
360 :     other groups -- as long as all these other groups belong to the same
361 :     owner library.
362 :    
363 :     If you want to take a collection of files whose purpose fits that of a
364 :     library, then, please, make them into a library (i.e., not a group!).
365 :     The purpose of groups is to deal with name-space issues _within_
366 :     libraries.
367 :    
368 :     Aside from the fact that I find this design quite natural, there is
369 :     actually a technical reason for it: when you stabilize a library
370 :     (groups cannot be stabilized), then all its sub-groups (not
371 :     sub-libraries!) get "sucked into" the stable archive of the library.
372 :     In other words, even if you have n+1 CM description files (1 for the
373 :     library, n for n sub-groups), there will be just one file representing
374 :     the one stable archive (per architecture/os) for the whole thing. For
375 :     example, I structured the standard basis into one library with two
376 : blume 569 sub-groups, but once you compile it (CMB.make) there is only one
377 : monnier 416 stable file that represents the whole basis library. If groups were
378 :     allowed to appear in more than one library, then stabilization would
379 :     duplicate the group (its code, its environment data structures, and
380 :     even its dynamic state).
381 :    
382 :     There is a small change to the syntax of group description files: they
383 :     must explicitly state which library they belong to. CM will verify
384 :     that. The owner library is specified in parentheses after the "group"
385 :     keyword. If the specification is missing (that's the "old" syntax),
386 :     then the the owner will be taken to be the interactive toplevel.
387 :    
388 : blume 537 * Pervasive environment, core environment, the init group "init.cmi"
389 : monnier 416 -------------------------------------------------------------------------
390 :    
391 : blume 569 CMB.make starts out by building and compiling the
392 : blume 537 "init group". This group cannot be described in the "usual" way
393 :     because it uses "magic" in three ways:
394 :     - it is used to later tie in the runtime system
395 : blume 569 - it exports the "core" environment
396 :     - it exports the "pervasive" environment
397 : monnier 416
398 : blume 537 The pervasive environment no longer includes the entire basis library
399 :     but only non-modular bindings (top-level bindings of variables and
400 :     types).
401 :    
402 : blume 569 CM cannot automatically determine dependencies (or exports) for the
403 :     init group source files, but it still does use its regular cutoff
404 :     recompilation mechanism. Therefore, dependencies must be given
405 :     explicitly. This is done by a special description file which
406 :     currently lives in Init/init.cmi. See the long comment at the
407 :     beginning of that file for more details.
408 : monnier 416
409 : blume 537 After it is built, init.cmi can be used as an "ordinary" library by
410 :     other libraries. (This is done, for example, by the implementation of
411 :     the Basis library.) Access to "init.cmi" is protected by the
412 : blume 569 privilege named "primitive". Also, note that the .cmi-file is not
413 :     automatically recognized as as CM description file. Therefore, it
414 :     must be given an explicit member class:
415 : blume 537
416 : blume 569 init.cmi : cm
417 :    
418 : monnier 416 * Autoloader
419 :     ------------
420 :    
421 :     The new system heavily relies on the autoloader. As a result, almost
422 : blume 569 no static environments need to get unpickled at bootstrap time. The
423 : monnier 416 construction of such environments is deferred until they become
424 : blume 569 necessary. Thanks of this, it was possible to reduce the size of the
425 :     heap image by more than one megabyte (depending on the architecture).
426 :     The downside (although not really terribly bad) is that there is a
427 :     short wait when you first touch an identifier that hasn't been touched
428 : monnier 416 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 : blume 569 you do CMB.make(). If you use relative or absolute pathnames to
561 : monnier 416 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