# Specifying sources

The most primitive declarations in an `m3makefile` are those that identify source files. They can be Modula-3, C or assembler files. A source file has three attributes: a package, the subdirectory within the package where the declaration occurs, and a visibility. The visibility has two values, visible and hidden. When a package A imports a package B, only the visible sources in B are available to compilations that occur in A. By default all sources are visible. However, it is possible to explicitly control the visibility of Modula-3 interfaces.

Source files are named relative to the `m3makefile` that mentions them.

The following calls define source files:

interface(X) declares that the file `X.i3` contains an interface.

implementation(X) declares that the file `X.m3` contains a module.

module(X) declares both the interface `X.i3` and the module `X.m3`.

generic_interface(X) declares that the file `X.ig` contains a generic interface.

generic_implementation(X) declares that the file `X.mg` contains a generic module.

generic_module(X) declares both a generic interface and module.

h_source(X) declares that the file `X.h` contains a C include file.

c_source(X) declares that the file `X.c` contains a C module.

s_source(X) declares that the file `X.s` contains an assembly module.

pgm_source(X) declares that the file `X` contains compilable source (e.g. `.ic`, `.mc`, `.is` or `.ms` files).

With the exception of `h_source`, each of the procedures above defines a hidden source file. There are capitalized variants Interface, Module, Generic_interface, Generic_implementation, and Generic_module that identify their sources as visible. Remember, only those interfaces that are marked as visible will be available to importers of your library or package.

With the exception of generic_interface, generic_implementation, and h_source, all other calls add their argument to the set `PGM_SOURCES`. This set is compiled by this invocation of `m3build`, either by the Modula-3 compiler or the C compiler, as appropriate.

template(X) declares that the file `X.tmpl` contains quake code that is to be included in this build, and in all builds that import this package.

The template call is used to extend the set of available procedures. For example, the table package includes a template that defines the table procedure which instantiates the generic table module. See also the predefined general-purpose procedures for instantiating generics that you can use to define procedures in your own templates for instantiating your own generic modules.