6.7 KiB
Build Directives
A project can contain multiple files. The build system decides how each file is used based on directives in your source, and each file's extension selects the tool that compiles or assembles it.
Projects with multiple files
All files in a project must be referenced from the main project file with one of these reference types:
- Include file — a source file embedded in another using an
#includeor similar directive. - Linked file — a source file compiled/assembled and linked into the
project alongside the main file, using the
//#linkor;#linkdirective. A binary file can be included in an assembly project with theincbindirective. - Resource file — a file that must be included in the project but is
neither included nor linked from the main file (for example it is
included from a non-main file). Use the
//#resourceor;#resourcedirective.
Here's a C example:
//#link "lzg.c"
#include "lzg.h"
If a file cannot be found, check the syntax. Often double quotes are
required, e.g. #include "file.inc".
Only system files that are part of the compiler toolchain can be found
with the <foo.h> syntax.
Assembler files can include files using the .include or .incbin
directives:
.segment "CHARS"
.incbin "tileset.chr"
C preprocessor defines
The preprocessor macro __MAIN__ is defined when compiling the main C
file of a project. You can use this to run tests on your module files:
//#link "file_needed_for_test.c"
#ifdef __MAIN__
#include "file_needed_for_test.h"
void main() {
test_my_module();
}
#endif
The macro __8BITWORKSHOP__ is defined on all C files.
Build directives
Build directives are comment lines that tell the build system how to compile, assemble, or link a project. They can appear in any source file and are never seen by the toolchain:
- C, SDCC, and cmoc sources mark them with
//. - Assembly sources mark them with
;.
The keyword follows the comment marker and a #, and the line must
begin with the comment (leading whitespace is allowed).
//#symbol — define a symbol
Defines a preprocessor macro, an assembler symbol, or a linker symbol:
//#symbol [<phase>] NAME[=VALUE]
The optional phase is one of:
| Phase | Meaning |
|---|---|
c, cc, compiler |
C preprocessor define (default) |
as, asm, assembler |
assembler symbol |
ld, link, linker |
linker symbol |
A compiler define takes a text value (cc65 -D, sdcc -D). Assembler
and linker symbols take an integer expression:
//#symbol VERSION=3
//#symbol as START=$8000
//#symbol ld NES_MAPPER=4
A linker symbol defined by a source file replaces (rather than
duplicates) a symbol of the same name that the platform already defines,
so //#symbol ld NES_MAPPER=... can select a different mapper without
editing the platform defaults. Linker values must be integer
expressions; a text value is reported as a build error rather than
passed to the linker.
//#flag — pass a raw argument
Passes arguments straight to one tool phase, with no interpretation:
//#flag <phase> <arg> [<arg> ...]
//#flag c -Osir
//#flag as --cpu 65c02
//#flag ld -m map.txt
Arguments may be quoted with single or double quotes when they contain spaces. This is an escape hatch that the build system cannot validate.
//#tooldef — set a typed build parameter
Sets a named build parameter that the build system understands:
//#tooldef <phase> NAME=VALUE
For the linker phase, the supported parameters are:
| Name | Meaning |
|---|---|
cfgfile |
linker configuration file to use (e.g. for CC65's ld65) |
libargs |
comma-separated list of library/symbol arguments |
//#tooldef ld cfgfile=apple2-hgr2.cfg
//#tooldef ld libargs=,nes.lib
Commenting out a directive
To disable a directive, break the marker; for example, use ////# in C
or ;;# in assembly. A directive that is already commented out is
deliberately not recognized.
Legacy #define directives
For backwards compatibility the build system still understands the older
#define-based forms:
| Legacy form | Same as |
|---|---|
#define CFGFILE <file> |
//#tooldef ld cfgfile=<file> |
#define LIBARGS <a,b,...> |
//#tooldef ld libargs=<a,b,...> |
#define NES_MAPPER <n> |
//#symbol ld NES_MAPPER=<n> |
#define CC65_FLAGS <a,b,...> |
//#flag c <a> <b> ... |
These may be prefixed with ; or / as well (for example ;#define),
so they can appear in assembly sources. New code should prefer the
explicit //# directives above.
CC65 custom config files
CC65's linker is controlled with configuration files that define memory areas and the layout of the final binary or ROM.
Tell the linker to use a custom config file from your main C program:
//#tooldef ld cfgfile=apple2-hgr2.cfg
//#resource "apple2-hgr2.cfg"
The legacy form is also supported:
#define CFGFILE apple2-hgr2.cfg
//#resource "apple2-hgr2.cfg"
Note the lack of quotes around the file name.
CC65 #embed directive
You can include binary files directly in
CC65 .c files, a feature not available from the CC65 command line. For
example, given an uploaded file image-c64.multi.lz4:
const char image_c64_multi_lz4[] = {
#embed "image-c64.multi.lz4"
};
This creates a byte array named image_c64_multi_lz4 with the contents
of the binary file.
The #embed directive is also supported in Oscar64 and Wiz files.
SDCC #pragma
With SDCC, enable additional optimization by adding one of these lines to the top of the file:
#pragma opt_code_size // for smaller code
#pragma opt_code_speed // for faster code
Either pragma slows builds but produces faster and smaller code.
File extensions
The extension of your source file determines the tool used to assemble
or compile it. The current platform resolves extensions that several
tools share (.c, .s, .bas), so the mapping depends on both. Common
cases:
| Extension | File type | Tool (platform) |
|---|---|---|
.c |
C source file | cc65 (6502), sdcc (Z80), cmoc (6809), smlrc (x86), TCC (ARM) |
.s .ca65 |
Assembler file | ca65 (6502) |
.s |
Assembler file | sdasz80 (Z80), TCC (ARM) |
.dasm .a |
Assembler file | dasm |
.z |
Assembler file | zmac (Z80) |
.nesasm |
Assembler file | NESASM (nes) |
.lnk |
Assembler file | Merlin 32 (apple2) |
.bb .bas |
batariBASIC file | batariBASIC (vcs) |
.fb .bas |
FastBasic file | FastBasic (atari8) |
.cc2600 |
C source file | CC2600 (vcs) |
.cc7800 .c78 |
C source file | CC7800 (atari7800) |
.v |
Verilog file | Verilator |
See Toolchains & Platforms for the full platform × extension → tool table.