SML# Document Version 4.0.0
28 The smlsharp command

28.8 Typical examples

28.8.1 Start an interactive session

A typical way to start an interactive session is to execute smlsharp command with no argument.

    $ smlsharp

When you use a C library in the interactive session, specify -l option with the name of the library. For example, if you want to use zlib library, do

    $ smlsharp -lz

The libraries SML# uses, such as the standard C library and POSIX thread library, are available by default. You can use them without -l option.

28.8.2 Compile a program

If your program consists of only one .sml file (and its corresponding .smi file), just give the .sml file to smlsharp command and you will obtain its executable file.

    $ smlsharp foo.sml

If you don’t like the default name a.out, change it by -o option.

    $ smlsharp -o foo foo.sml

28.8.3 Compile separately and link a program

A typical way to compile and link a program consisting of multiple files is the following:

    $ smlsharp -c -O2 foo.sml
    $ smlsharp -c -O2 bar.sml
    $ smlsharp -c -O2 baz.sml
    $ smlsharp foo.smi

First, compile each .sml file in the project separately in random order by the smlsharp command with -c. If the compilation of foo.sml is done successfully, its object file foo.o is generated. After compiling all .sml files, link their object files into an executable file by giving the smlsharp command the .smi file whose top-level code is the entry of the program (in this example, foo.smi). At this time, the smlsharp command traces all .smi files reachable from foo.smi through _require relationship recursively and obtains the list of object files to be linked by replacing their .smi suffix with .o.

If you change this default correspondence from .smi files to .o files, create a map file and give it by -filemap option like the following:

    $ smlsharp -c -O2 -o obj/foo.o foo.sml
    $ smlsharp -c -O2 -o obj/bar.o bar.sml
    $ smlsharp -c -O2 -o obj/baz.o baz.sml
    $ smlsharp -filemap=objmap foo.smi

The contents of objmap file is given below:

    = foo.o obj/foo.o
    = bar.o obj/bar.o
    = baz.o obj/baz.o

SML# programs may be linked with arbitrary C/C++ programs and libraries. To link your program with C/C++ libraries, give them to the smlsharp command with a .smi file. For example, to link foo.sml with a C program util.c and C libraries libgl and libglu, do

    $ smlsharp -c -O2 foo.sml
    $ cc -c -O2 util.c
    $ smlsharp foo.smi util.o -lgl -lglu

28.8.4 Generate a Makefile

it is useful to combine SML# with “make” command so that your program is separately compiled and linked automatically. To use make command, you need to create a Makefile that includes dependencies between source files. By smlsharp -Mm command, you can automatically obtain a complete Makefile for building a SML# program automatically.

For example, suppose a project consisting of three .smi files foo.smi, bar.smi, and baz.smi (and their corresponding .sml files). The _require relationship between them is as follows:

  • foo.smi _requires bar.smi.

  • bar.smi _requires baz.smi.

In this case,

    $ smlsharp -Mm foo.smi -o Makefile

generates the following Makefile:

SMLSHARP = smlsharp
SMLFLAGS = -O2
LIBS =
all: foo
foo: foo.o bar.o baz.o foo.smi
        $(SMLSHARP) $(LDFLAGS) -o $@ foo.smi $(LIBS)
foo.o: foo.sml foo.smi bar.smi baz.smi
        $(SMLSHARP) $(SMLFLAGS) -o $@ -c u.sml
bar.o: bar.sml bar.smi baz.smi
        $(SMLSHARP) $(SMLFLAGS) -o $@ -c u.sml
baz.o: baz.sml baz.smi
        $(SMLSHARP) $(SMLFLAGS) -o $@ -c u.sml

Then, just do make and build your program.

  % make
  smlsharp  -o foo.o -c foo.sml
  smlsharp  -o bar.o -c bar.sml
  smlsharp  -o baz.o -c baz.sml
  smlsharp  -o foo foo.smi

Every time you modify the program and its _require relationship is changed, you need to do smlsharp -MMm to update the Makefile.

If your project contains source files of ml-lex and ml-yacc, smlsharp -Mm is not enough. You need additional rules that invokes those tools to generate .sml files. For example, if your project has a parser parser.grm, create Makefile by smlsharp -Mm and then add the following rule to the Makefile by hand:

parser.grm.sml parser.grm.sig: parser.grm
        ml-yacc parser.grm
parser.grm.sig: parser.grm.sml

It should be useful if you separate two Makefiles, one of which is automatically generated by smlsharp -Mm and another of which includes the additional rules. A simple way to manage two Makefiles is to organize Makefile with additional rules and include of the automatically generated one. For example, create a Makefile like the following:

# The default target is "all".
all:

# File dependency is automatically generated and included.
depend.mk:
        smlsharp -Mm foo.smi -o depend.mk
include depend.mk

# Additional rules.
parser.grm.sml parser.grm.sig: parser.grm
        ml-yacc parser.grm
parser.grm.sig: parser.grm.sml

Of course, you can exploit your favorite Makefile techniques.