<ulclass="crumbs"><li><ahref="../overview.html">Home</a></li><li><ahref="../inbuildn.html">Inbuild Modules</a></li><li><ahref="index.html">supervisor</a></li><li><ahref="index.html#P">Preliminaries</a></li><li><b>What This Module Does</b></li></ul></div>
<pclass="commentary firstcommentary"><aid="SP1"class="paragraph-anchor"></a><b>§1. Prerequisites. </b>The supervisor module is a part of the Inform compiler toolset. It is
full details, but essentially: it's C without predeclarations or header files,
and where functions have names like <spanclass="extract"><spanclass="extract-syntax">Tags::add_by_name</span></span> rather than just <spanclass="extract"><spanclass="extract-syntax">add_by_name</span></span>.
<pclass="commentary firstcommentary"><aid="SP2"class="paragraph-anchor"></a><b>§2. The Supervisor and its Parent. </b>The <ahref="index.html"class="internal">supervisor</a> module is part of both <ahref="../inform7/index.html"class="internal">inform7</a> and <ahref="../inbuild/index.html"class="internal">inbuild</a>, and acts
But when included in <ahref="../inbuild/index.html"class="internal">inbuild</a>, it might be asked to perform quite a variety
of tasks, sometimes several at once, as specified by the user at the command line.
(See <ahref="../inbuild/1-mn.html"class="internal">Main (in inbuild)</a>.) In this discussion, "the parent" means the tool which
is using <ahref="index.html"class="internal">supervisor</a>, and might be either <ahref="../inform7/index.html"class="internal">inform7</a> or <ahref="../inbuild/index.html"class="internal">inbuild</a>.
<pclass="commentary firstcommentary"><aid="SP3"class="paragraph-anchor"></a><b>§3. </b><ahref="index.html"class="internal">supervisor</a> has a relationship with its parent tool which involves to and
fro: it's not as simple as single one-time call from the parent to <ahref="index.html"class="internal">supervisor</a>
saying "now build this".
</p>
<ulclass="items"><li>(1) <ahref="index.html"class="internal">supervisor</a> has to be started and stopped at each end of the parent's
run, by calling <ahref="1-sm.html#SP3"class="internal">SupervisorModule::start</a> and <ahref="1-sm.html#SP3"class="internal">SupervisorModule::end</a>.
The former calls <ahref="1-ic.html#SP3"class="internal">Supervisor::start</a> in turn, and that activates a number of
subsystems with further calls. But all modules do something like this.
</li><li>(2) More unusually, when the parent is creating its command-line options, it
should call <ahref="1-ic.html#SP4"class="internal">Supervisor::declare_options</a> to add more. This allows all tools
containing the Supervisor to offer a unified set of command-line options to
the call to <ahref="1-ic.html#SP10"class="internal">Supervisor::go_operational</a> with a single call to <ahref="2-cps.html#SP11"class="internal">Copies::build</a>
<ulclass="footnotetexts"><liclass="footnote"id="fn:1"><pclass="inwebfootnote"><supid="fnref:1"><ahref="#fn:1"rel="footnote">1</a></sup> Compare <ahref="../inform7/M-rc.html"class="internal">Reference Card (in inform7)</a> and <ahref="../inbuild/M-rc.html"class="internal">Reference Card (in inbuild)</a>
to see the effect.
<ahref="#fnref:1"title="return to text">↩</a></p></li></ul>
<pclass="commentary firstcommentary"><aid="SP4"class="paragraph-anchor"></a><b>§4. Genre, work, edition, copy. </b>A "genre" is a category of software or artistic work for us to manage. For
example, "Inform 7 extension" and "website template" are both genres. Each
different genre is represented by an <ahref="2-gnr.html#SP1"class="internal">inbuild_genre</a> object, whose method
calls provide the behaviour distinctive to that genre. The currently seven
genre objects are created during <ahref="1-ic.html#SP3"class="internal">Supervisor::start</a>, which calls out to
<ahref="4-em.html#SP2"class="internal">ExtensionManager::start</a>, <ahref="4-km.html#SP1"class="internal">KitManager::start</a>, and so on: the seven
sections of <ahref="4-em.html"class="internal">Chapter 4: Genre Management</a> are exactly the method calls for the seven genre
objects.
</p>
<pclass="commentary">A "work" is a single artistic or programming creation; for example, the IF
story Bronze by Emily Short might be a work. Each different one we deal with
is represented by an <ahref="2-wrk.html#SP1"class="internal">inbuild_work</a> object. Works are identified by genre,
title and author name, but see <ahref="2-wrk.html#SP4"class="internal">Works::normalise_casing</a> for exactly how.
</p>
<pclass="commentary">An "edition" is a versioned work; for example, release 7 of Bronze by Emily
Short is an edition. These are represented by <ahref="2-edt.html#SP1"class="internal">inbuild_edition</a> objects.
Such objects carry with them a note of which virtual machine architectures
they work with: see <ahref="../arch-module/2-cmp.html"class="internal">Compatibility (in arch)</a> for more on this.
</p>
<pclass="commentary">A "copy" is an instance of an edition actually present somewhere in the file
system — note that we might have several copies of the same edition in
different places. Each copy known to the Supervisor is an <ahref="2-cps.html#SP1"class="internal">inbuild_copy</a> object.
</p>
<pclass="commentary">When copies are claimed, they are typically scanned — exactly how depends
on the genre — and this can reveal damage: if so, a <ahref="2-ce.html#SP1"class="internal">copy_error</a> object is
attached to the copy for each different defect turned up. These errors are not
necessarily reported at once, or at all: if they are reported, the function
<ahref="2-ce.html#SP5"class="internal">CopyErrors::write</a> is used to write a suitable command-line error, but it's
also possible for the parent to issue its own errors instead. <spanclass="extract"><spanclass="extract-syntax">inform7</span></span>
does this to convert copy errors into Inform problem messages: see
<ahref="../core-module/2-pwst.html"class="internal">Problems With Source Text (in core)</a>.<supid="fnref:2"><ahref="#fn:2"rel="footnote">2</a></sup>
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:2"><pclass="inwebfootnote"><supid="fnref:2"><ahref="#fn:2"rel="footnote">2</a></sup> Note that because it is <ahref="index.html"class="internal">supervisor</a> which causes source text to be read
in, and not <ahref="../core-module/index.html"class="internal">core</a>, lexical problems such as improperly paired comment
brackets or overly long quoted strings will come to light as copy errors,
as will blunders in identifying extensions. In general, though, a copy which
has no copy errors is not necessarily a correct program: only one which is
in good enough condition for the compiler to look at.
<ahref="#fnref:2"title="return to text">↩</a></p></li></ul>
<pclass="commentary firstcommentary"><aid="SP5"class="paragraph-anchor"></a><b>§5. Searches and requirements. </b>Copies may be strewn all over the user's file system, and it's not for us to
<ahref="1-ic.html#SP7"class="internal">Supervisor::option</a>, rather than by anything in the <ahref="../core-module/index.html"class="internal">core</a> module.
run would also be set. This would become whose genre is <spanclass="extract"><spanclass="ConsoleText-extract-syntax">project_bundle_genre</span></span>.
<pclass="commentary">Other copies would swiftly be needed — the definition of the English language
(found inside the Internal nest), the Standard Rules extension, and several more.
These are not explicitly named on the command line: instead, they are found by
searching through the nests. <ahref="index.html"class="internal">supervisor</a> does this by creating an
<ahref="2-rqr.html#SP1"class="internal">inbuild_requirement</a> object to specify what it wants, and then calling its
search engine <ahref="2-nst.html#SP7"class="internal">Nests::search_for</a>. This builds a list of <ahref="2-nst.html#SP5"class="internal">inbuild_search_result</a>
objects, each pointing to a new copy which matches the requirement given.
</p>
<pclass="commentary">Requirements can be quite flexible, and are converitble to and from text: see
<ahref="2-rqr.html#SP3"class="internal">Requirements::from_text</a> and <ahref="2-rqr.html#SP6"class="internal">Requirements::write</a>.<supid="fnref:4"><ahref="#fn:4"rel="footnote">4</a></sup> The crucial function
here is <ahref="2-rqr.html#SP7"class="internal">Requirements::meets</a>, which tests whether an edition meets the
requirement.
</p>
<ulclass="footnotetexts"><liclass="footnote"id="fn:3"><pclass="inwebfootnote"><supid="fnref:3"><ahref="#fn:3"rel="footnote">3</a></sup> Indeed, such a scan would violate sandboxing restrictions, for example
when <ahref="index.html"class="internal">supervisor</a> is running as part of <ahref="../inform7/index.html"class="internal">inform7</a> inside the MacOS Inform app.
<pclass="commentary firstcommentary"><aid="SP6"class="paragraph-anchor"></a><b>§6. </b>Although such searches can be used with vague requirements to scan for,
<pclass="commentary firstcommentary"><aid="SP7"class="paragraph-anchor"></a><b>§7. Discovery. </b>A copy is "claimed" when it is found in the file system: either by being
right where the user said it would be, or by a search.
</p>
<pclass="commentary">When the search engine wants to look for, say, kits in a given nest, it will
ask the kit genre how to do this, by a method call: and this will be handled
by <ahref="4-km.html#SP5"class="internal">KitManager::search_nest_for</a>. That enables kits to be looked for in
a different part of a nest than extensions, for example. Similarly, each
genre scans and generally vets a copy differently, attaching copy errors
for different reasons. But in general, a function like <ahref="4-km.html#SP3"class="internal">KitManager::new_copy</a>
will "claim" the copy.
</p>
<pclass="commentary">For most genres, we want each copy to be claimed only once. We might run
into the copy of version 1.2 of <spanclass="extract"><spanclass="ConsoleText-extract-syntax">WorldModelKit</span></span> at <spanclass="extract"><spanclass="ConsoleText-extract-syntax">inform7/Internal/Inter</span></span>
for multiple reasons, as a result of several different searches: we want to
return the same <ahref="2-cps.html#SP1"class="internal">inbuild_copy</a> object each time we do, rather than create
duplicates. This is done with a dictionary of pathnames: i.e., the Kit
Manager keeps a dictionary of which pathnames lead to copies it has already
claimed. Most other managers do the same.
</p>
<pclass="commentary">But if a new <ahref="2-cps.html#SP1"class="internal">inbuild_copy</a> is made, then we also give it a rich set of
genre-specific metadata by attaching "content". In this case, that will be
an <ahref="5-ks.html#SP1"class="internal">inform_kit</a> object, and code in <ahref="5-ks.html"class="internal">Kit Services</a> will provide
special functionality by working on this <ahref="5-ks.html#SP1"class="internal">inform_kit</a>. If <spanclass="extract"><spanclass="ConsoleText-extract-syntax">C</span></span> is a copy
which is a kit, then <spanclass="extract"><spanclass="ConsoleText-extract-syntax">KitManager::from_copy(C)</span></span> produces its <ahref="5-ks.html#SP1"class="internal">inform_kit</a>
object <spanclass="extract"><spanclass="ConsoleText-extract-syntax">K</span></span>; conversely, <spanclass="extract"><spanclass="ConsoleText-extract-syntax">K->as_copy</span></span> produces <spanclass="extract"><spanclass="ConsoleText-extract-syntax">C</span></span> again. They correspond in
a one-to-one fashion.
</p>
<pclass="commentary">This table summarises the genres, where they managed, what type of metadata
object is attached to each copy of that genre, and where such metadata is
handled. Note that the two Inform project genres — one for single files,
one for whole bundles — share a metadata format: a project is a project,
<pclass="commentary firstcommentary"><aid="SP8"class="paragraph-anchor"></a><b>§8. Build graph. </b>See <ahref="3-bg.html"class="internal">Build Graphs</a> for the infrastructure of how a dependency graph is stored.
Basically these consist of <ahref="3-bg.html#SP1"class="internal">build_vertex</a> objects joined together by edges,
represented by lists of other vertices — each vertex has two lists, one of
"use edges", the other of "build edges". See the manual at <ahref="../inbuild/M-ui.html"class="internal">Using Inbuild (in inbuild)</a>
for an explanation and examples.
</p>
<pclass="commentary">There are three "colours" of vertex: copy, file and requirement. Each copy
vertex corresponds to a single <ahref="2-cps.html#SP1"class="internal">inbuild_copy</a> and vice versa: thus, the
dependencies for a copy are represented by the component of the graph which
runs out from its vertex. File vertices correspond to single files needed
during a build process, and requirement vertices to unfilled requirements,
such as extensions which could not be found.
</p>
<pclass="commentary">The three colours of vertex are created by <ahref="3-bg.html#SP3"class="internal">Graphs::copy_vertex</a>,
<ahref="3-bg.html#SP2"class="internal">Graphs::file_vertex</a> and <ahref="3-bg.html#SP2"class="internal">Graphs::req_vertex</a> respectively, and the
two colours of edge by <ahref="3-bg.html#SP4"class="internal">Graphs::need_this_to_build</a> and <ahref="3-bg.html#SP4"class="internal">Graphs::need_this_to_use</a>.
<pclass="commentary firstcommentary"><aid="SP9"class="paragraph-anchor"></a><b>§9. </b>When are graphs actually built? It would be appealing to do this the moment a
<ahref="5-es.html#SP6"class="internal">Extensions::construct_graph</a> and <ahref="5-ps2.html#SP26"class="internal">Projects::construct_graph</a>. Kits are
<ulclass="footnotetexts"><liclass="footnote"id="fn:5"><pclass="inwebfootnote"><supid="fnref:5"><ahref="#fn:5"rel="footnote">5</a></sup> Arguably the speed hit would be worth it for the gain in simplicity,
but there's also another technicality: an extension's dependencies
<pclass="commentary firstcommentary"><aid="SP10"class="paragraph-anchor"></a><b>§10. Reading source text. </b>For any copy, <ahref="2-cps.html#SP7"class="internal">Copies::get_source_text</a> will instruct the Supervisor to
see <ahref="../words-module/3-tff.html"class="internal">Text From Files (in words)</a>. But it is <ahref="6-st.html#SP3"class="internal">SourceText::read_file</a> which
<ahref="../syntax-module/index.html"class="internal">syntax</a> module. (See <ahref="../syntax-module/3-snt.html"class="internal">Sentences (in syntax)</a> for details of how.) Once
<pclass="commentary firstcommentary"><aid="SP11"class="paragraph-anchor"></a><b>§11. </b>The definition of "structural sentence" is given in the form of Preform grammar
<pclass="commentary firstcommentary"><aid="SP12"class="paragraph-anchor"></a><b>§12. </b>What happens next involves is carefully timed. What we want is to look
<pclass="commentary firstcommentary"><aid="SP13"class="paragraph-anchor"></a><b>§13. </b>At any rate, when <ahref="6-inc.html#SP1"class="internal">Inclusions::traverse</a> finds an Include sentence which
<pclass="commentary firstcommentary"><aid="SP14"class="paragraph-anchor"></a><b>§14. </b>Finally comes the complicated business of rearranging the syntax tree due
<pclass="commentary firstcommentary"><aid="SP15"class="paragraph-anchor"></a><b>§15. </b>This is all quite a long road, and the way is strewn with potential errors.
What if a requested extension can't be found? Or is damaged? Or not compatible
with our VM? Or if a heading is "in place of" one which isn't where it claimed?
And so on. Such issues are converted into still more copy errors.
</p>
<pclass="commentary">If <ahref="index.html"class="internal">supervisor</a> is running in the parent <ahref="../inbuild/index.html"class="internal">inbuild</a>, then all errors are
all issued to the console when text reading is complete. But if it is running
in the parent <ahref="../inform7/index.html"class="internal">inform7</a>, they are suppressed for now, and will be picked
up later and issued as problem messages by <ahref="../core-module/2-pwst.html"class="internal">Problems With Source Text (in core)</a>.
<pclass="commentary firstcommentary"><aid="SP16"class="paragraph-anchor"></a><b>§16. </b>Now that we have read in the text of a project/extension, we know all of its
<pclass="commentary firstcommentary"><aid="SP17"class="paragraph-anchor"></a><b>§17. Incremental builds. </b>So, then, at this point we can determine the complete build graph for any copy.
<ulclass="items"><li>(a) Call <ahref="2-cps.html#SP12"class="internal">Copies::show_graph</a>, or <ahref="2-cps.html#SP12"class="internal">Copies::show_needs</a>, or <ahref="2-cps.html#SP12"class="internal">Copies::show_missing</a>,
</li><li>(b) Call <ahref="2-cps.html#SP13"class="internal">Copies::archive</a> to make archived copies of all dependent resources;
</li><li>(c) Or, the big one, call <ahref="2-cps.html#SP11"class="internal">Copies::build</a> or <ahref="2-cps.html#SP11"class="internal">Copies::rebuild</a> to perform
<pclass="commentary">A "build" is incremental, and uses time-stamps of files to avoid unnecessary
duplication of previous compilation work; a "rebuild" is not. They are otherwise
the same, both calling <ahref="3-ib.html#SP5"class="internal">IncrementalBuild::build</a>. This works rather like the
traditional Unix tool <spanclass="extract"><spanclass="ConsoleText-extract-syntax">make</span></span>: if it wants to build the resource which a vertex
represents, it first has to build the resources which that vertex depends on,
i.e., has edges out to.
</p>
<pclass="commentary">How does one "build a vertex", though? The answer is that if a vertex has been
given a <ahref="3-bs.html#SP1"class="internal">build_script</a>, one follows this script. The script is only a list
of <ahref="3-bs2.html#SP3"class="internal">build_step</a> objects, and each step is an application of a <ahref="3-bs2.html#SP1"class="internal">build_skill</a>.
There are only a few skills known to the Supervisor, created by <ahref="1-ic.html#SP3"class="internal">Supervisor::start</a>.
For example, assimilating a kit is a skill; but the need to apply this skill to
a particular copy of <spanclass="extract"><spanclass="ConsoleText-extract-syntax">WorldModelKit</span></span> is a build step.
</p>
<pclass="commentary">Some build steps can be carried out in two different ways: externally, by
issuing a command to the shell; or internally, by calling a function in some
module also present in the parent tool. The Supervisor chooses which way
according to the <ahref="3-bm.html#SP1"class="internal">build_methodology</a> object passed to <ahref="3-ib.html#SP5"class="internal">IncrementalBuild::build</a>
<pclass="commentary firstcommentary"><aid="SP18"class="paragraph-anchor"></a><b>§18. Extension census. </b>That's basically everything except for the lengthy but unimportant code in
<ahref="7-tm.html"class="internal">Chapter 7: Extension Indexing</a>, which constructs a mini-website of extension documentation for
use inside the GUI app. None of this affects how builds are made. See
<ahref="7-tm.html"class="internal">The Mini-Website</a> for the site's makeup. A little metadata is cached
between runs of <ahref="../inform7/index.html"class="internal">inform7</a> in a file called the <ahref="7-dct.html"class="internal">Dictionary</a>, and the
search for all installed extensions is called the <ahref="7-cns.html"class="internal">Census</a>.