SAS/C Compilation and Linking

Vol 1 Ch.8 covers the sc compiler in detail — what each option does, what files it produces, how it integrates with slink. Vol 1 Ch.9 covers running the resulting program from the Workbench (icons, ToolTypes, project setup). Source: Vol 1 Ch.8–9, pp. 83–152.

The compilation pipeline

myprog.c ──sc──► myprog.o ─┐
utils.c ──sc──► utils.o ─┤
                          ├──slink──► myprog (executable)
   c.o (startup) ─────────┤
   lib:sc.lib ─────────────┤
   lib:amiga.lib ──────────┘

sc is the compiler (and the assembler; see SAS/C Assembly Language). slink is the linker. lib:sc.lib provides the SAS/C runtime; lib:amiga.lib provides NDK stub code for the system libraries.

sc — the compiler

sc [options] source... [-o output]

Essential options

Option Effect
link Compile + link in one step
o=name Set output file name
optimize=N Optimization level 0–4
debug=line Emit line-number tables for CodeProbe
debug=symbol Emit full symbol table (default)
debug=local Emit local variable info
define=SYM Define preprocessor symbol (e.g., define=DEBUG)
undef=SYM Undefine a symbol
includedir=dir Add an include path
libdir=dir Add a library search path
error=N Treat message N as error
warn=N Treat message N as warning
ignore=N Suppress message N
msg=N sev Set severity of message N (warn / error / ignore)
structureequivalence Allow struct assignment (default)
nostructureequivalence Disallow struct assignment (strict ANSI)
stackcheck Enable runtime stack overflow check (default)
nostackcheck Disable stack check
stkneed=N Set default stack size in bytes (default 4000)
code=small Small code model (faster calls, smaller executable)
code=far Far code model (default for large programs)
data=small Small data model (base-relative, faster)
data=far Far data model (absolute addressing)
math=standard Standard math library (default)
math=ffp FFP fast math
math=ieee IEEE math (use with fpsp on bare 68000)
cpu=68000 Target 68000 (no 020+ instructions)
cpu=68020 Target 68020+ (default; allows bitfield instructions etc.)
cpu=68030 / cpu=68040 / cpu=68060 Target specific CPU

The two most common invocations:

# Debug build
sc link optimize=0 debug=line debug=local myprog.c

# Release build
sc link optimize=4 structureequivalence myprog.c

Combining options

Multiple options are comma-separated, no spaces:

sc myprog.c optimize=2,debug=line,structureequivalence

Whitespace between the option and its argument is allowed: optimize = 2.

Preprocessor

sc's preprocessor is C89-compatible with extensions. The relevant options:

Option Effect
define=NAME Define NAME (as 1)
define=NAME=value Define NAME to value
undef=NAME Undefine a previously defined name
includedir=path Add include path (prepends to list)
preinclude=file Include file before main source
E Run preprocessor only, print to stdout

#include searches these paths in order:

  1. The directory of the current source file
  2. INCLUDE: (the SAS/C system include directory)
  3. Paths given by includedir
  4. Paths in SASC_INCLUDE environment variable

Compiler messages

sc issues numbered messages (1–299 are C compiler messages, 300+ are linker / runtime). The full list is in the manual and via sc -? or the help system.

To get verbose output, use verbose. To log a full session:

sc myprog.c 2>build.log

slink is invoked as:

slink [options] FROM obj1.o obj2.o ... lib1.lib lib2.lib TO output [options]

or with the short form:

slink [FROM obj... lib...] [TO output] [options]

The FROM and TO keywords are case-insensitive. sLink (capital L) is the actual command name; slink is a 4-letter abbreviation.

The order of objects and libraries matters. slink resolves undefined symbols by searching libraries in order, including only the modules needed. A typical order:

slink from c.o myprog.o utils.o lib:sc.lib lib:amiga.lib to myprog

The startup module c.o must come first. sc.lib provides the SAS/C runtime. amiga.lib provides the NDK stubs for the system libraries.

Option Effect
ND Strip debug info (release)
ADDSYM Add symbol table
MAP Emit a map file
VERBOSE Verbose link output
NOICONS Don't bind icons to the output
STRIPDEBUG Strip debug info (alias for ND)

Map files

A map file lists every symbol in the linked program with its address — useful for resolving "undefined symbol" errors and for understanding the link layout.

slink from c.o prog.o lib:sc.lib to prog map

The map file is written to prog.map (or the name with .map appended).

Running from Workbench

Vol 1 Ch.9. To run a program from Workbench by double-clicking its icon, the program must accept Workbench startup arguments:

  • argc == 0 (no argv[0])
  • argv may contain WBench (Workbench startup) and other tool types
  • The startup file handles (pr_CIS, pr_COS, pr_CES) point to NIL: or a console if launched from a console process

A Workbench-launched program should:

  1. Check argc > 0 to distinguish Shell vs Workbench launch.
  2. If from Workbench, open your own window via Intuition or read the icon's ToolTypes.
  3. If from Shell, proceed with the normal argc/argv parsing.

Example: Workbench-aware main

int main(int argc, char **argv)
{
    if (argc == 0) {
        /* Workbench launch — read ToolTypes, open window */
        struct WBArg *args = ArgArrayInit();
        if (args) {
            /* process args[0] (your program) and args[1] (its icon) */
            ArgArrayDone();
        }
        open_my_window();
    } else {
        /* Shell launch */
        parse_args(argc, argv);
    }
    return 0;
}

ToolTypes

The icon's ToolTypes are accessed via the DiskObject API:

struct DiskObject *dob = GetDiskObject(argv[0]);
if (dob) {
    char *buf = NULL;
    if (FindToolType(dob->do_ToolTypes, "PUBSCREEN"))
        buf = FindToolType(dob->do_ToolTypes, "PUBSCREEN");
    /* use buf */
    FreeDiskObject(dob);
}

Project structure

A typical SAS/C project:

myproject/
├── smakefile
├── source/
│   ├── main.c
│   ├── utils.c
│   └── utils.h
├── icons/
│   └── myproject.info
├── lib/
│   └── (linker output: myproject, myproject.map)
└── docs/
    └── readme

smakefile template:

CC = sc
LD = slink
CFLAGS = optimize=2 structureequivalence debug=line
LDFLAGS = lib:sc.lib lib:amiga.lib

OBJS = main.o utils.o

myproject: $(OBJS)
    $(LD) from c.o $(OBJS) $(LDFLAGS) to myproject

%.o: %.c
    $(CC) $(CFLAGS) $<

clean:
    delete myproject $(OBJS)

.PHONY: clean

See Also


Sources: SAS Institute Inc., "SAS/C Development System User's Guide, Volume 1" Ch.8–9, Version 6.50 (1993), pp. 83–152. Raw: raw/sasc/sasc-compilation-and-linking-extract.md Updated: 2026-10-02