mirror of
https://github.com/ganelson/inform.git
synced 2024-07-01 06:24:58 +03:00
Rudimentary inbuild now incrementally builds kits
This commit is contained in:
parent
c6e8fcd813
commit
3a9365b2ce
|
@ -7,26 +7,130 @@ this plan out.
|
||||||
|
|
||||||
@d INTOOL_NAME "inbuild"
|
@d INTOOL_NAME "inbuild"
|
||||||
|
|
||||||
|
@e INSPECT_TTASK from 1
|
||||||
|
@e GRAPH_TTASK
|
||||||
|
@e BUILD_TTASK
|
||||||
|
@e REBUILD_TTASK
|
||||||
|
|
||||||
=
|
=
|
||||||
|
pathname *path_to_inbuild = NULL;
|
||||||
|
pathname *path_to_tools = NULL;
|
||||||
|
|
||||||
|
int inbuild_task = INSPECT_TTASK;
|
||||||
|
int dry_run_mode = FALSE;
|
||||||
|
linked_list *targets = NULL; /* of |inbuild_copy| */
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Foundation::start();
|
Foundation::start();
|
||||||
|
InbuildModule::start();
|
||||||
|
targets = NEW_LINKED_LIST(inbuild_copy);
|
||||||
@<Read the command line@>;
|
@<Read the command line@>;
|
||||||
|
path_to_inbuild = Pathnames::installation_path("INBUILD_PATH", I"inbuild");
|
||||||
|
build_methodology *BM;
|
||||||
|
if (path_to_tools) BM = BuildSteps::methodology(path_to_tools, FALSE);
|
||||||
|
else BM = BuildSteps::methodology(Pathnames::up(path_to_inbuild), TRUE);
|
||||||
|
if (dry_run_mode == FALSE) BM->methodology = SHELL_METHODOLOGY;
|
||||||
|
inbuild_copy *C;
|
||||||
|
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets) {
|
||||||
|
switch (inbuild_task) {
|
||||||
|
case INSPECT_TTASK: Graphs::describe(STDOUT, C->graph, FALSE); break;
|
||||||
|
case GRAPH_TTASK: Graphs::describe(STDOUT, C->graph, TRUE); break;
|
||||||
|
case BUILD_TTASK: Graphs::build(C->graph, BM); break;
|
||||||
|
case REBUILD_TTASK: Graphs::rebuild(C->graph, BM); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InbuildModule::end();
|
||||||
Foundation::end();
|
Foundation::end();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ We use Foundation to read the command line:
|
@ We use Foundation to read the command line:
|
||||||
|
|
||||||
|
@e BUILD_CLSW
|
||||||
|
@e REBUILD_CLSW
|
||||||
|
@e GRAPH_CLSW
|
||||||
|
@e INSPECT_CLSW
|
||||||
|
@e DRY_CLSW
|
||||||
|
@e TOOLS_CLSW
|
||||||
|
@e CONTENTS_OF_CLSW
|
||||||
|
|
||||||
@<Read the command line@> =
|
@<Read the command line@> =
|
||||||
CommandLine::declare_heading(
|
CommandLine::declare_heading(
|
||||||
L"[[Purpose]]\n\n"
|
L"[[Purpose]]\n\n"
|
||||||
L"usage: inbuild\n");
|
L"usage: inbuild [-TASK] TARGET1 TARGET2 ...\n");
|
||||||
|
CommandLine::declare_switch(BUILD_CLSW, L"build", 1,
|
||||||
|
L"incrementally build target(s)");
|
||||||
|
CommandLine::declare_switch(REBUILD_CLSW, L"rebuild", 1,
|
||||||
|
L"completely rebuild target(s)");
|
||||||
|
CommandLine::declare_switch(INSPECT_CLSW, L"inspect", 1,
|
||||||
|
L"show target(s) but take no action");
|
||||||
|
CommandLine::declare_switch(GRAPH_CLSW, L"graph", 1,
|
||||||
|
L"show dependency graph of target(s) but take no action");
|
||||||
|
CommandLine::declare_switch(TOOLS_CLSW, L"tools", 2,
|
||||||
|
L"make X the directory of intools executables, and exit developer mode");
|
||||||
|
CommandLine::declare_boolean_switch(DRY_CLSW, L"dry", 1,
|
||||||
|
L"make this a dry run (print but do not execute shell commands)");
|
||||||
|
CommandLine::declare_boolean_switch(CONTENTS_OF_CLSW, L"contents-of", 2,
|
||||||
|
L"apply to all targets in the directory X");
|
||||||
|
|
||||||
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
|
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
|
||||||
|
|
||||||
@ =
|
@ =
|
||||||
void Main::option(int id, int val, text_stream *arg, void *state) {
|
void Main::option(int id, int val, text_stream *arg, void *state) {
|
||||||
|
switch (id) {
|
||||||
|
case BUILD_CLSW: inbuild_task = BUILD_TTASK; break;
|
||||||
|
case REBUILD_CLSW: inbuild_task = REBUILD_TTASK; break;
|
||||||
|
case INSPECT_CLSW: inbuild_task = INSPECT_TTASK; break;
|
||||||
|
case GRAPH_CLSW: inbuild_task = GRAPH_TTASK; break;
|
||||||
|
case TOOLS_CLSW: path_to_tools = Pathnames::from_text(arg); break;
|
||||||
|
case CONTENTS_OF_CLSW: Main::load_many(Pathnames::from_text(arg)); break;
|
||||||
|
case DRY_CLSW: dry_run_mode = val; break;
|
||||||
|
default: internal_error("unimplemented switch");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Main::bareword(int id, text_stream *arg, void *state) {
|
void Main::bareword(int id, text_stream *arg, void *state) {
|
||||||
|
Main::load_one(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::load_many(pathname *P) {
|
||||||
|
scan_directory *D = Directories::open(P);
|
||||||
|
TEMPORARY_TEXT(LEAFNAME);
|
||||||
|
while (Directories::next(D, LEAFNAME)) {
|
||||||
|
TEMPORARY_TEXT(FILENAME);
|
||||||
|
WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, LEAFNAME);
|
||||||
|
Main::load_one(FILENAME);
|
||||||
|
DISCARD_TEXT(FILENAME);
|
||||||
|
}
|
||||||
|
DISCARD_TEXT(LEAFNAME);
|
||||||
|
Directories::close(D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Main::load_one(text_stream *arg) {
|
||||||
|
int pos = Str::len(arg) - 1, dotpos = -1;
|
||||||
|
while (pos >= 0) {
|
||||||
|
wchar_t c = Str::get_at(arg, pos);
|
||||||
|
if (c == FOLDER_SEPARATOR) break;
|
||||||
|
if (c == '.') dotpos = pos;
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
if (dotpos >= 0) {
|
||||||
|
TEMPORARY_TEXT(extension);
|
||||||
|
Str::substr(extension, Str::at(arg, dotpos+1), Str::end(arg));
|
||||||
|
if (Str::eq(extension, I"i7x")) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
DISCARD_TEXT(extension);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Str::get_last_char(arg) == FOLDER_SEPARATOR)
|
||||||
|
Str::delete_last_character(arg);
|
||||||
|
int kitpos = Str::len(arg) - 3;
|
||||||
|
if ((kitpos >= 0) && (Str::get_at(arg, kitpos) == 'K') &&
|
||||||
|
(Str::get_at(arg, kitpos+1) == 'i') &&
|
||||||
|
(Str::get_at(arg, kitpos+2) == 't')) {
|
||||||
|
pathname *P = Pathnames::from_text(arg);
|
||||||
|
inform_kit *K = Kits::load_at(Pathnames::directory_name(P), P);
|
||||||
|
ADD_TO_LINKED_LIST(K->as_copy, inbuild_copy, targets);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,31 @@ Setting up the use of this module.
|
||||||
@e inform_kit_MT
|
@e inform_kit_MT
|
||||||
@e inform_kit_ittt_MT
|
@e inform_kit_ittt_MT
|
||||||
@e element_activation_MT
|
@e element_activation_MT
|
||||||
|
@e inbuild_genre_MT
|
||||||
|
@e inbuild_work_MT
|
||||||
|
@e inbuild_edition_MT
|
||||||
|
@e inbuild_requirement_MT
|
||||||
|
@e inbuild_copy_MT
|
||||||
|
@e build_graph_MT
|
||||||
|
@e build_methodology_MT
|
||||||
|
@e build_script_MT
|
||||||
|
@e build_step_MT
|
||||||
|
|
||||||
=
|
=
|
||||||
ALLOCATE_INDIVIDUALLY(inform_kit)
|
ALLOCATE_INDIVIDUALLY(inform_kit)
|
||||||
ALLOCATE_INDIVIDUALLY(inform_kit_ittt)
|
ALLOCATE_INDIVIDUALLY(inform_kit_ittt)
|
||||||
ALLOCATE_INDIVIDUALLY(element_activation)
|
ALLOCATE_INDIVIDUALLY(element_activation)
|
||||||
|
ALLOCATE_INDIVIDUALLY(inbuild_genre)
|
||||||
|
ALLOCATE_INDIVIDUALLY(inbuild_work)
|
||||||
|
ALLOCATE_INDIVIDUALLY(inbuild_edition)
|
||||||
|
ALLOCATE_INDIVIDUALLY(inbuild_requirement)
|
||||||
|
ALLOCATE_INDIVIDUALLY(inbuild_copy)
|
||||||
|
ALLOCATE_INDIVIDUALLY(build_graph)
|
||||||
|
ALLOCATE_INDIVIDUALLY(build_methodology)
|
||||||
|
ALLOCATE_INDIVIDUALLY(build_script)
|
||||||
|
ALLOCATE_INDIVIDUALLY(build_step)
|
||||||
|
|
||||||
@h The beginning.
|
@h The beginning.
|
||||||
(The client doesn't need to call the start and end routines, because the
|
|
||||||
foundation module does that automatically.)
|
|
||||||
|
|
||||||
=
|
=
|
||||||
void InbuildModule::start(void) {
|
void InbuildModule::start(void) {
|
||||||
|
@ -28,6 +44,7 @@ void InbuildModule::start(void) {
|
||||||
@<Register this module's debugging log aspects@>;
|
@<Register this module's debugging log aspects@>;
|
||||||
@<Register this module's debugging log writers@>;
|
@<Register this module's debugging log writers@>;
|
||||||
@<Register this module's command line switches@>;
|
@<Register this module's command line switches@>;
|
||||||
|
Kits::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@
|
@
|
||||||
|
|
116
inbuild/inbuild-module/Chapter 2/Build Graphs.w
Normal file
116
inbuild/inbuild-module/Chapter 2/Build Graphs.w
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
[Graphs::] Build Graphs.
|
||||||
|
|
||||||
|
Graphs in which vertices correspond to files or copies, and arrows to
|
||||||
|
dependencies between them.
|
||||||
|
|
||||||
|
@h Build graphs.
|
||||||
|
These are directed acyclic graphs which show what depends on what in the
|
||||||
|
building process. If an arrow leads from A to B, then B must be built before
|
||||||
|
A can be built.
|
||||||
|
|
||||||
|
There can be two sorts of vertex in such a graph: copy vertices, each of which
|
||||||
|
belongs to a single copy, and internal vertices, each of which represents
|
||||||
|
a different file inside the copy.
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct build_graph {
|
||||||
|
struct inbuild_copy *buildable_if_copy;
|
||||||
|
struct filename *buildable_if_internal_file;
|
||||||
|
struct linked_list *arrows; /* of pointers to other |build_graph| nodes */
|
||||||
|
struct build_script *script;
|
||||||
|
time_t timestamp;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} build_graph;
|
||||||
|
|
||||||
|
build_graph *Graphs::internal_vertex(filename *F) {
|
||||||
|
build_graph *G = CREATE(build_graph);
|
||||||
|
G->buildable_if_copy = NULL;
|
||||||
|
G->buildable_if_internal_file = F;
|
||||||
|
G->arrows = NEW_LINKED_LIST(build_graph);
|
||||||
|
G->timestamp = (time_t) 0;
|
||||||
|
G->script = BuildSteps::new_script();
|
||||||
|
return G;
|
||||||
|
}
|
||||||
|
|
||||||
|
build_graph *Graphs::copy_vertex(inbuild_copy *C) {
|
||||||
|
if (C == NULL) internal_error("no copy");
|
||||||
|
if (C->graph == NULL) {
|
||||||
|
C->graph = Graphs::internal_vertex(NULL);
|
||||||
|
C->graph->buildable_if_copy = C;
|
||||||
|
}
|
||||||
|
return C->graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphs::arrow(build_graph *from, build_graph *to) {
|
||||||
|
if (from == NULL) internal_error("no from");
|
||||||
|
if (to == NULL) internal_error("no to");
|
||||||
|
if (from == to) internal_error("graph node depends on itself");
|
||||||
|
build_graph *G;
|
||||||
|
LOOP_OVER_LINKED_LIST(G, build_graph, from->arrows)
|
||||||
|
if (G == to) return;
|
||||||
|
ADD_TO_LINKED_LIST(to, build_graph, from->arrows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphs::describe(OUTPUT_STREAM, build_graph *G, int recurse) {
|
||||||
|
Graphs::describe_r(OUT, 0, G, recurse);
|
||||||
|
}
|
||||||
|
void Graphs::describe_r(OUTPUT_STREAM, int depth, build_graph *V, int recurse) {
|
||||||
|
for (int i=0; i<depth; i++) WRITE(" ");
|
||||||
|
if (V->buildable_if_copy) {
|
||||||
|
WRITE("[copy%d] ", V->allocation_id);
|
||||||
|
Model::write_work(OUT, V->buildable_if_copy->edition->work);
|
||||||
|
inbuild_version_number N = V->buildable_if_copy->edition->version;
|
||||||
|
if (VersionNumbers::is_null(N) == FALSE) {
|
||||||
|
WRITE(" v"); VersionNumbers::to_text(OUT, N);
|
||||||
|
}
|
||||||
|
WRITE("\n");
|
||||||
|
} else {
|
||||||
|
Graphs::update_timestamp(V);
|
||||||
|
WRITE("[int%d] %f", V->allocation_id, V->buildable_if_internal_file);
|
||||||
|
if (V->timestamp != (time_t) 0) WRITE(" %s", ctime(&(V->timestamp)));
|
||||||
|
else WRITE("\n");
|
||||||
|
}
|
||||||
|
if (recurse) {
|
||||||
|
build_graph *W;
|
||||||
|
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows)
|
||||||
|
Graphs::describe_r(OUT, depth+1, W, TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphs::update_timestamp(build_graph *V) {
|
||||||
|
if (V == NULL) return;
|
||||||
|
if (V->buildable_if_internal_file == NULL) return;
|
||||||
|
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
|
||||||
|
TEMPORARY_TEXT(FN);
|
||||||
|
WRITE_TO(FN, "%f", V->buildable_if_internal_file);
|
||||||
|
Str::copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
|
||||||
|
DISCARD_TEXT(FN);
|
||||||
|
struct stat filestat;
|
||||||
|
if (stat(transcoded_pathname, &filestat) == -1) { V->timestamp = (time_t) 0; return; }
|
||||||
|
V->timestamp = filestat.st_mtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphs::build(build_graph *G, build_methodology *meth) {
|
||||||
|
Graphs::build_r(FALSE, G, meth);
|
||||||
|
}
|
||||||
|
void Graphs::rebuild(build_graph *G, build_methodology *meth) {
|
||||||
|
Graphs::build_r(TRUE, G, meth);
|
||||||
|
}
|
||||||
|
void Graphs::build_r(int forcing_build, build_graph *V, build_methodology *meth) {
|
||||||
|
int needs_building = forcing_build;
|
||||||
|
if (V->buildable_if_internal_file)
|
||||||
|
if (TextFiles::exists(V->buildable_if_internal_file) == FALSE)
|
||||||
|
needs_building = TRUE;
|
||||||
|
build_graph *W;
|
||||||
|
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows)
|
||||||
|
Graphs::build_r(forcing_build, W, meth);
|
||||||
|
if (needs_building == FALSE) {
|
||||||
|
Graphs::update_timestamp(V);
|
||||||
|
LOOP_OVER_LINKED_LIST(W, build_graph, V->arrows) {
|
||||||
|
Graphs::update_timestamp(W);
|
||||||
|
double since = difftime(V->timestamp, W->timestamp);
|
||||||
|
if (since < 0) { needs_building = TRUE; break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needs_building) BuildSteps::execute(V->script, meth);
|
||||||
|
}
|
127
inbuild/inbuild-module/Chapter 2/Build Steps.w
Normal file
127
inbuild/inbuild-module/Chapter 2/Build Steps.w
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
[BuildSteps::] Build Steps.
|
||||||
|
|
||||||
|
Graphs in which vertices correspond to files or copies, and arrows to
|
||||||
|
dependencies between them.
|
||||||
|
|
||||||
|
@h Build graphs.
|
||||||
|
These are directed acyclic graphs which show what depends on what in the
|
||||||
|
building process. If an arrow leads from A to B, then B must be built before
|
||||||
|
A can be built.
|
||||||
|
|
||||||
|
There can be two sorts of vertex in such a graph: copy vertices, each of which
|
||||||
|
belongs to a single copy, and internal vertices, each of which represents
|
||||||
|
a different file inside the copy.
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct build_script {
|
||||||
|
struct linked_list *steps; /* of |build_step| */
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} build_script;
|
||||||
|
|
||||||
|
typedef struct build_step {
|
||||||
|
int what_to_do;
|
||||||
|
struct pathname *arg_p1;
|
||||||
|
struct text_stream *arg_t1;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} build_step;
|
||||||
|
|
||||||
|
@
|
||||||
|
|
||||||
|
@e ASSIMILATE_BSTEP from 1
|
||||||
|
|
||||||
|
=
|
||||||
|
build_script *BuildSteps::new_script(void) {
|
||||||
|
build_script *BS = CREATE(build_script);
|
||||||
|
BS->steps = NEW_LINKED_LIST(build_step);
|
||||||
|
return BS;
|
||||||
|
}
|
||||||
|
|
||||||
|
build_step *BuildSteps::new_step(int to_do, pathname *P, text_stream *T) {
|
||||||
|
build_step *S = CREATE(build_step);
|
||||||
|
S->what_to_do = to_do;
|
||||||
|
S->arg_p1 = P;
|
||||||
|
S->arg_t1 = T;
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildSteps::add_step(build_script *BS, build_step *S) {
|
||||||
|
ADD_TO_LINKED_LIST(S, build_step, BS->steps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildSteps::concatenate(build_script *BT, build_script *BF) {
|
||||||
|
build_step *S;
|
||||||
|
LOOP_OVER_LINKED_LIST(S, build_step, BF->steps)
|
||||||
|
BuildSteps::add_step(BT, S);
|
||||||
|
}
|
||||||
|
|
||||||
|
@
|
||||||
|
|
||||||
|
@e DRY_RUN_METHODOLOGY from 1
|
||||||
|
@e SHELL_METHODOLOGY
|
||||||
|
@e INTERNAL_METHODOLOGY
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct build_methodology {
|
||||||
|
filename *to_inter;
|
||||||
|
filename *to_inform6;
|
||||||
|
filename *to_inform7;
|
||||||
|
filename *to_inblorb;
|
||||||
|
int methodology;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} build_methodology;
|
||||||
|
|
||||||
|
build_methodology *BuildSteps::methodology(pathname *tools_path, int dev) {
|
||||||
|
build_methodology *meth = CREATE(build_methodology);
|
||||||
|
meth->methodology = DRY_RUN_METHODOLOGY;
|
||||||
|
pathname *inter_path = tools_path;
|
||||||
|
if (dev) {
|
||||||
|
inter_path = Pathnames::subfolder(inter_path, I"inter");
|
||||||
|
inter_path = Pathnames::subfolder(inter_path, I"Tangled");
|
||||||
|
}
|
||||||
|
meth->to_inter = Filenames::in_folder(inter_path, I"inter");
|
||||||
|
pathname *inform6_path = tools_path;
|
||||||
|
if (dev) {
|
||||||
|
inform6_path = Pathnames::subfolder(inform6_path, I"inform6");
|
||||||
|
inform6_path = Pathnames::subfolder(inform6_path, I"Tangled");
|
||||||
|
}
|
||||||
|
meth->to_inform6 = Filenames::in_folder(inform6_path, I"inform6");
|
||||||
|
pathname *inform7_path = tools_path;
|
||||||
|
if (dev) {
|
||||||
|
inform7_path = Pathnames::subfolder(inform7_path, I"inform7");
|
||||||
|
inform7_path = Pathnames::subfolder(inform7_path, I"Tangled");
|
||||||
|
}
|
||||||
|
meth->to_inform7 = Filenames::in_folder(inform7_path, I"inform7");
|
||||||
|
pathname *inblorb_path = tools_path;
|
||||||
|
if (dev) {
|
||||||
|
inblorb_path = Pathnames::subfolder(inblorb_path, I"inblorb");
|
||||||
|
inblorb_path = Pathnames::subfolder(inblorb_path, I"Tangled");
|
||||||
|
}
|
||||||
|
meth->to_inblorb = Filenames::in_folder(inblorb_path, I"inblorb");
|
||||||
|
return meth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildSteps::execute(build_script *BS, build_methodology *meth) {
|
||||||
|
build_step *S;
|
||||||
|
LOOP_OVER_LINKED_LIST(S, build_step, BS->steps) {
|
||||||
|
switch (meth->methodology) {
|
||||||
|
case DRY_RUN_METHODOLOGY:
|
||||||
|
case SHELL_METHODOLOGY: {
|
||||||
|
TEMPORARY_TEXT(command);
|
||||||
|
@<Write a shell command for the step@>;
|
||||||
|
WRITE_TO(STDOUT, "%S\n", command);
|
||||||
|
if (meth->methodology == SHELL_METHODOLOGY) Shell::run(command);
|
||||||
|
DISCARD_TEXT(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Write a shell command for the step@> =
|
||||||
|
switch (S->what_to_do) {
|
||||||
|
case ASSIMILATE_BSTEP:
|
||||||
|
Shell::quote_file(command, meth->to_inter);
|
||||||
|
WRITE_TO(command, " -architecture %S -assimilate ", S->arg_t1);
|
||||||
|
Shell::quote_path(command, S->arg_p1);
|
||||||
|
break;
|
||||||
|
default: internal_error("unimplemented step");
|
||||||
|
}
|
130
inbuild/inbuild-module/Chapter 2/Conceptual Model.w
Normal file
130
inbuild/inbuild-module/Chapter 2/Conceptual Model.w
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
[Model::] Conceptual Model.
|
||||||
|
|
||||||
|
The main concepts of inbuild.
|
||||||
|
|
||||||
|
@h Genres.
|
||||||
|
For example, "kit" and "extension" will both be both genres. There will be
|
||||||
|
few of these.
|
||||||
|
|
||||||
|
@e GENRE_WRITE_WORK_MTID
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_genre {
|
||||||
|
text_stream *genre_name;
|
||||||
|
METHOD_CALLS
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} inbuild_genre;
|
||||||
|
|
||||||
|
VMETHOD_TYPE(GENRE_WRITE_WORK_MTID, inbuild_genre *gen, text_stream *OUT, inbuild_work *work)
|
||||||
|
|
||||||
|
@ =
|
||||||
|
inbuild_genre *Model::genre(text_stream *name) {
|
||||||
|
inbuild_genre *gen;
|
||||||
|
LOOP_OVER(gen, inbuild_genre)
|
||||||
|
if (Str::eq(gen->genre_name, name))
|
||||||
|
return gen;
|
||||||
|
gen = CREATE(inbuild_genre);
|
||||||
|
gen->genre_name = Str::duplicate(name);
|
||||||
|
ENABLE_METHOD_CALLS(gen);
|
||||||
|
return gen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Works.
|
||||||
|
A "work" is a single creative work; for example, Bronze by Emily Short might
|
||||||
|
be a work. Mamy versions of this IF story may exist over time, but they will
|
||||||
|
all be versions of the same "work".
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_work {
|
||||||
|
struct inbuild_genre *genre;
|
||||||
|
struct text_stream *name;
|
||||||
|
struct text_stream *author;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} inbuild_work;
|
||||||
|
|
||||||
|
inbuild_work *Model::work(inbuild_genre *genre, text_stream *name, text_stream *author) {
|
||||||
|
inbuild_work *work = CREATE(inbuild_work);
|
||||||
|
work->genre = genre;
|
||||||
|
work->name = Str::duplicate(name);
|
||||||
|
work->author = Str::duplicate(author);
|
||||||
|
return work;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::write_work(OUTPUT_STREAM, inbuild_work *work) {
|
||||||
|
VMETHOD_CALL(work->genre, GENRE_WRITE_WORK_MTID, OUT, work);
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Editions.
|
||||||
|
An "edition" of a work is a particular version numbered form of it. For
|
||||||
|
example, release 7 of Bronze by Emily Short would be an edition of Bronze.
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_edition {
|
||||||
|
struct inbuild_work *work;
|
||||||
|
struct inbuild_version_number version;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} inbuild_edition;
|
||||||
|
|
||||||
|
inbuild_edition *Model::edition(inbuild_work *work, inbuild_version_number version) {
|
||||||
|
inbuild_edition *edition = CREATE(inbuild_edition);
|
||||||
|
edition->work = work;
|
||||||
|
edition->version = version;
|
||||||
|
return edition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Requirements.
|
||||||
|
A "requirement" is when we want to get hold of a work in some edition which
|
||||||
|
meets a range of possible versions. A null minimum version means "no minimum",
|
||||||
|
a null maximum means "no maximum".
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_requirement {
|
||||||
|
struct inbuild_work *work;
|
||||||
|
struct inbuild_version_number min_version;
|
||||||
|
struct inbuild_version_number max_version;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} inbuild_requirement;
|
||||||
|
|
||||||
|
inbuild_requirement *Model::requirement(inbuild_work *work,
|
||||||
|
inbuild_version_number min, inbuild_version_number max) {
|
||||||
|
inbuild_requirement *req = CREATE(inbuild_requirement);
|
||||||
|
req->work = work;
|
||||||
|
req->min_version = min;
|
||||||
|
req->max_version = max;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Copies.
|
||||||
|
A "copy" of a work exists in the file system when we've actually got hold of
|
||||||
|
some edition of it. For some genres, copies will be files; for others,
|
||||||
|
directories holding a set of files.
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_copy {
|
||||||
|
struct inbuild_edition *edition;
|
||||||
|
struct pathname *location_if_path;
|
||||||
|
struct filename *location_if_file;
|
||||||
|
general_pointer content; /* the type of which depends on the work's genre */
|
||||||
|
struct build_graph *graph;
|
||||||
|
MEMORY_MANAGEMENT
|
||||||
|
} inbuild_copy;
|
||||||
|
|
||||||
|
inbuild_copy *Model::copy_in_file(inbuild_edition *edition, filename *F, general_pointer C) {
|
||||||
|
inbuild_copy *copy = CREATE(inbuild_copy);
|
||||||
|
copy->edition = edition;
|
||||||
|
copy->location_if_path = NULL;
|
||||||
|
copy->location_if_file = F;
|
||||||
|
copy->content = C;
|
||||||
|
copy->graph = NULL;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
inbuild_copy *Model::copy_in_directory(inbuild_edition *edition, pathname *P, general_pointer C) {
|
||||||
|
inbuild_copy *copy = CREATE(inbuild_copy);
|
||||||
|
copy->edition = edition;
|
||||||
|
copy->location_if_path = P;
|
||||||
|
copy->location_if_file = NULL;
|
||||||
|
copy->content = C;
|
||||||
|
copy->graph = NULL;
|
||||||
|
return copy;
|
||||||
|
}
|
118
inbuild/inbuild-module/Chapter 2/Version Numbers.w
Normal file
118
inbuild/inbuild-module/Chapter 2/Version Numbers.w
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
[VersionNumbers::] Version Numbers.
|
||||||
|
|
||||||
|
Semantic version numbers such as 3.7.1.
|
||||||
|
|
||||||
|
@ For example, 4, 7.1, and 0.2.3 are all version numbers. Up to |VERSION_NUMBER_DEPTH|
|
||||||
|
components can be given. The tail of the array should be padded with |-1| values;
|
||||||
|
otherwise, components should all be non-negative integers.
|
||||||
|
|
||||||
|
@d VERSION_NUMBER_DEPTH 4
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct inbuild_version_number {
|
||||||
|
int version_numbers[VERSION_NUMBER_DEPTH];
|
||||||
|
} inbuild_version_number;
|
||||||
|
|
||||||
|
@ All invalid strings of numbers -- i.e., breaking the above rules -- are
|
||||||
|
called "null" versions, and can never be valid as the version of anything.
|
||||||
|
Instead they are used to represent the absence of a version number.
|
||||||
|
(In particular, a string of |-1|s is null.)
|
||||||
|
|
||||||
|
=
|
||||||
|
inbuild_version_number VersionNumbers::null(void) {
|
||||||
|
inbuild_version_number V;
|
||||||
|
for (int i=0; i<VERSION_NUMBER_DEPTH; i++) V.version_numbers[i] = -1;
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::is_null(inbuild_version_number V) {
|
||||||
|
for (int i=0, allow=TRUE; i<VERSION_NUMBER_DEPTH; i++) {
|
||||||
|
if (V.version_numbers[i] < -1)
|
||||||
|
return TRUE;
|
||||||
|
if (V.version_numbers[i] == -1)
|
||||||
|
allow = FALSE;
|
||||||
|
else if (allow == FALSE) return TRUE;
|
||||||
|
}
|
||||||
|
if (V.version_numbers[0] < 0) return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ Here we print and parse:
|
||||||
|
|
||||||
|
=
|
||||||
|
void VersionNumbers::to_text(OUTPUT_STREAM, inbuild_version_number V) {
|
||||||
|
if (VersionNumbers::is_null(V)) WRITE("null");
|
||||||
|
else
|
||||||
|
for (int i=0; (i<VERSION_NUMBER_DEPTH) && (V.version_numbers[i] >= 0); i++) {
|
||||||
|
if (i>0) WRITE(".");
|
||||||
|
WRITE("%d", V.version_numbers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inbuild_version_number VersionNumbers::from_text(text_stream *T) {
|
||||||
|
inbuild_version_number V;
|
||||||
|
int component = 0, val = -1;
|
||||||
|
LOOP_THROUGH_TEXT(pos, T) {
|
||||||
|
wchar_t c = Str::get(pos);
|
||||||
|
if (c == '.') {
|
||||||
|
if (val == -1) return VersionNumbers::null();
|
||||||
|
if (component >= VERSION_NUMBER_DEPTH) return VersionNumbers::null();
|
||||||
|
V.version_numbers[component] = val;
|
||||||
|
component++; val = -1;
|
||||||
|
} else if (Characters::isdigit(c)) {
|
||||||
|
int digit = c - '0';
|
||||||
|
if (val < 0) val = digit; else val = 10*val + digit;
|
||||||
|
} else return VersionNumbers::null();
|
||||||
|
}
|
||||||
|
if (val == -1) return VersionNumbers::null();
|
||||||
|
if (component >= VERSION_NUMBER_DEPTH) return VersionNumbers::null();
|
||||||
|
V.version_numbers[component] = val;
|
||||||
|
for (int i=component+1; i<VERSION_NUMBER_DEPTH; i++) V.version_numbers[i] = -1;
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ And now comparison operators. Note that all null versions are equal, and
|
||||||
|
are always both |<=| and |>=| all versions. This means our ordering is not
|
||||||
|
trichotomous (though it is on the set of non-null versions), but this
|
||||||
|
ensures that null versions can be used to mean "unlimited" in either direction.
|
||||||
|
|
||||||
|
=
|
||||||
|
int VersionNumbers::eq(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
if (VersionNumbers::is_null(V1)) return VersionNumbers::is_null(V2);
|
||||||
|
if (VersionNumbers::is_null(V2)) return FALSE;
|
||||||
|
for (int i=0; i<VERSION_NUMBER_DEPTH; i++)
|
||||||
|
if (V1.version_numbers[i] != V2.version_numbers[i])
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::ne(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
return (VersionNumbers::eq(V1, V2))?FALSE:TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::le(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
if (VersionNumbers::is_null(V1)) return TRUE;
|
||||||
|
if (VersionNumbers::is_null(V2)) return TRUE;
|
||||||
|
for (int i=0; i<VERSION_NUMBER_DEPTH; i++)
|
||||||
|
if (V1.version_numbers[i] > V2.version_numbers[i])
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::gt(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
return (VersionNumbers::le(V1, V2))?FALSE:TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::ge(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
if (VersionNumbers::is_null(V1)) return TRUE;
|
||||||
|
if (VersionNumbers::is_null(V2)) return TRUE;
|
||||||
|
for (int i=0; i<VERSION_NUMBER_DEPTH; i++)
|
||||||
|
if (V1.version_numbers[i] < V2.version_numbers[i])
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VersionNumbers::lt(inbuild_version_number V1, inbuild_version_number V2) {
|
||||||
|
return (VersionNumbers::ge(V1, V2))?FALSE:TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,19 @@ A kit is a combination of Inter code with an Inform 7 extension.
|
||||||
@h Kits.
|
@h Kits.
|
||||||
|
|
||||||
=
|
=
|
||||||
|
inbuild_genre *kit_genre = NULL;
|
||||||
|
void Kits::start(void) {
|
||||||
|
kit_genre = Model::genre(I"kit");
|
||||||
|
METHOD_ADD(kit_genre, GENRE_WRITE_WORK_MTID, Kits::write_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Kits::write_copy(inbuild_genre *gen, OUTPUT_STREAM, inbuild_work *work) {
|
||||||
|
WRITE("Kit %S", work->name);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct inform_kit {
|
typedef struct inform_kit {
|
||||||
|
struct inbuild_copy *as_copy;
|
||||||
struct text_stream *name;
|
struct text_stream *name;
|
||||||
struct pathname *location;
|
|
||||||
struct text_stream *attachment_point;
|
struct text_stream *attachment_point;
|
||||||
struct text_stream *early_source;
|
struct text_stream *early_source;
|
||||||
struct linked_list *ittt; /* of |inform_kit_ittt| */
|
struct linked_list *ittt; /* of |inform_kit_ittt| */
|
||||||
|
@ -15,6 +25,7 @@ typedef struct inform_kit {
|
||||||
struct linked_list *extensions; /* of |text_stream| */
|
struct linked_list *extensions; /* of |text_stream| */
|
||||||
struct linked_list *activations; /* of |element_activation| */
|
struct linked_list *activations; /* of |element_activation| */
|
||||||
struct text_stream *index_template;
|
struct text_stream *index_template;
|
||||||
|
struct inbuild_version_number version;
|
||||||
int defines_Main;
|
int defines_Main;
|
||||||
int supports_natural_language;
|
int supports_natural_language;
|
||||||
int priority;
|
int priority;
|
||||||
|
@ -48,7 +59,6 @@ inform_kit *Kits::load_at(text_stream *name, pathname *P) {
|
||||||
K->name = Str::duplicate(name);
|
K->name = Str::duplicate(name);
|
||||||
K->attachment_point = Str::new();
|
K->attachment_point = Str::new();
|
||||||
WRITE_TO(K->attachment_point, "/main/%S", name);
|
WRITE_TO(K->attachment_point, "/main/%S", name);
|
||||||
K->location = P;
|
|
||||||
K->early_source = NULL;
|
K->early_source = NULL;
|
||||||
K->priority = 10;
|
K->priority = 10;
|
||||||
K->ittt = NEW_LINKED_LIST(inform_kit_ittt);
|
K->ittt = NEW_LINKED_LIST(inform_kit_ittt);
|
||||||
|
@ -58,14 +68,63 @@ inform_kit *Kits::load_at(text_stream *name, pathname *P) {
|
||||||
K->defines_Main = FALSE;
|
K->defines_Main = FALSE;
|
||||||
K->supports_natural_language = FALSE;
|
K->supports_natural_language = FALSE;
|
||||||
K->index_template = NULL;
|
K->index_template = NULL;
|
||||||
|
K->version = VersionNumbers::null();
|
||||||
|
|
||||||
filename *F = Filenames::in_folder(K->location, I"kit_metadata.txt");
|
filename *F = Filenames::in_folder(P, I"kit_metadata.txt");
|
||||||
TextFiles::read(F, FALSE,
|
TextFiles::read(F, FALSE,
|
||||||
NULL, FALSE, Kits::read_metadata, NULL, (void *) K);
|
NULL, FALSE, Kits::read_metadata, NULL, (void *) K);
|
||||||
|
|
||||||
|
inbuild_work *work = Model::work(kit_genre, name, NULL);
|
||||||
|
inbuild_edition *edition = Model::edition(work, K->version);
|
||||||
|
K->as_copy = Model::copy_in_directory(edition, P, STORE_POINTER_inform_kit(K));
|
||||||
|
|
||||||
|
build_graph *KV = Graphs::copy_vertex(K->as_copy);
|
||||||
|
text_stream *archs[4] = { I"16", I"32", I"16d", I"32d" };
|
||||||
|
text_stream *binaries[4] = { I"arch-16.interb", I"arch-32.interb", I"arch-16d.interb", I"arch-32d.interb" };
|
||||||
|
build_graph *BV[4];
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
filename *FV = Filenames::in_folder(P, binaries[i]);
|
||||||
|
BV[i] = Graphs::internal_vertex(FV);
|
||||||
|
Graphs::arrow(KV, BV[i]);
|
||||||
|
build_step *BS = BuildSteps::new_step(ASSIMILATE_BSTEP, P, archs[i]);
|
||||||
|
BuildSteps::add_step(BV[i]->script, BS);
|
||||||
|
}
|
||||||
|
|
||||||
|
filename *contents_page = Filenames::in_folder(K->as_copy->location_if_path, I"Contents.w");
|
||||||
|
build_graph *CV = Graphs::internal_vertex(contents_page);
|
||||||
|
for (int i=0; i<4; i++) Graphs::arrow(BV[i], CV);
|
||||||
|
|
||||||
|
kit_contents_section_state CSS;
|
||||||
|
CSS.active = FALSE;
|
||||||
|
CSS.sects = NEW_LINKED_LIST(text_stream);
|
||||||
|
TextFiles::read(contents_page, FALSE, NULL, FALSE, Kits::read_contents, NULL, (void *) &CSS);
|
||||||
|
text_stream *segment;
|
||||||
|
LOOP_OVER_LINKED_LIST(segment, text_stream, CSS.sects) {
|
||||||
|
filename *SF = Filenames::in_folder(
|
||||||
|
Pathnames::subfolder(K->as_copy->location_if_path, I"Sections"), segment);
|
||||||
|
build_graph *SV = Graphs::internal_vertex(SF);
|
||||||
|
for (int i=0; i<4; i++) Graphs::arrow(BV[i], SV);
|
||||||
|
}
|
||||||
return K;
|
return K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct kit_contents_section_state {
|
||||||
|
struct linked_list *sects; /* of |text_stream| */
|
||||||
|
int active;
|
||||||
|
} kit_contents_section_state;
|
||||||
|
|
||||||
|
void Kits::read_contents(text_stream *text, text_file_position *tfp, void *state) {
|
||||||
|
kit_contents_section_state *CSS = (kit_contents_section_state *) state;
|
||||||
|
match_results mr = Regexp::create_mr();
|
||||||
|
if (Regexp::match(&mr, text, L"Sections"))
|
||||||
|
CSS->active = TRUE;
|
||||||
|
if ((Regexp::match(&mr, text, L" (%c+)")) && (CSS->active)) {
|
||||||
|
WRITE_TO(mr.exp[0], ".i6t");
|
||||||
|
ADD_TO_LINKED_LIST(Str::duplicate(mr.exp[0]), text_stream, CSS->sects);
|
||||||
|
}
|
||||||
|
Regexp::dispose_of(&mr);
|
||||||
|
}
|
||||||
|
|
||||||
inform_kit *Kits::load(text_stream *name, int N, pathname **PP) {
|
inform_kit *Kits::load(text_stream *name, int N, pathname **PP) {
|
||||||
pathname *P = Kits::find(name, N, PP);
|
pathname *P = Kits::find(name, N, PP);
|
||||||
if (P == NULL) Errors::fatal_with_text("cannot find kit", name);
|
if (P == NULL) Errors::fatal_with_text("cannot find kit", name);
|
||||||
|
@ -92,6 +151,8 @@ void Kits::read_metadata(text_stream *text, text_file_position *tfp, void *state
|
||||||
match_results mr = Regexp::create_mr();
|
match_results mr = Regexp::create_mr();
|
||||||
if ((Str::is_whitespace(text)) || (Regexp::match(&mr, text, L" *#%c*"))) {
|
if ((Str::is_whitespace(text)) || (Regexp::match(&mr, text, L" *#%c*"))) {
|
||||||
;
|
;
|
||||||
|
} else if (Regexp::match(&mr, text, L"version: (%C+)")) {
|
||||||
|
K->version = VersionNumbers::from_text(mr.exp[0]);
|
||||||
} else if (Regexp::match(&mr, text, L"defines Main: yes")) {
|
} else if (Regexp::match(&mr, text, L"defines Main: yes")) {
|
||||||
K->defines_Main = TRUE;
|
K->defines_Main = TRUE;
|
||||||
} else if (Regexp::match(&mr, text, L"defines Main: no")) {
|
} else if (Regexp::match(&mr, text, L"defines Main: no")) {
|
||||||
|
@ -192,7 +253,7 @@ void Kits::load_types(void) {
|
||||||
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
|
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
|
||||||
text_stream *segment;
|
text_stream *segment;
|
||||||
LOOP_OVER_LINKED_LIST(segment, text_stream, K->kind_definitions) {
|
LOOP_OVER_LINKED_LIST(segment, text_stream, K->kind_definitions) {
|
||||||
pathname *P = Pathnames::subfolder(K->location, I"kinds");
|
pathname *P = Pathnames::subfolder(K->as_copy->location_if_path, I"kinds");
|
||||||
filename *F = Filenames::in_folder(P, segment);
|
filename *F = Filenames::in_folder(P, segment);
|
||||||
LOG("Loading kinds definitions from %f\n", F);
|
LOG("Loading kinds definitions from %f\n", F);
|
||||||
I6T::interpret_kindt(F);
|
I6T::interpret_kindt(F);
|
||||||
|
@ -282,7 +343,7 @@ linked_list *Kits::list_of_inter_libraries(void) {
|
||||||
requirements_list = NEW_LINKED_LIST(link_instruction);
|
requirements_list = NEW_LINKED_LIST(link_instruction);
|
||||||
inform_kit *K;
|
inform_kit *K;
|
||||||
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
|
LOOP_OVER_LINKED_LIST(K, inform_kit, kits_to_include) {
|
||||||
link_instruction *link = CodeGen::LinkInstructions::new(K->location, K->attachment_point);
|
link_instruction *link = CodeGen::LinkInstructions::new(K->as_copy->location_if_path, K->attachment_point);
|
||||||
ADD_TO_LINKED_LIST(link, link_instruction, requirements_list);
|
ADD_TO_LINKED_LIST(link, link_instruction, requirements_list);
|
||||||
}
|
}
|
||||||
return requirements_list;
|
return requirements_list;
|
|
@ -7,5 +7,11 @@ Licence: Artistic License 2.0
|
||||||
Chapter 1: Setting Up
|
Chapter 1: Setting Up
|
||||||
Inbuild Module
|
Inbuild Module
|
||||||
|
|
||||||
Chapter 2: Everything Else
|
Chapter 2: Conceptual Framework
|
||||||
|
Version Numbers
|
||||||
|
Conceptual Model
|
||||||
|
Build Graphs
|
||||||
|
Build Steps
|
||||||
|
|
||||||
|
Chapter 3: The Genres
|
||||||
Kits
|
Kits
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
version: 1.0.2
|
||||||
priority: 0
|
priority: 0
|
||||||
extension: Basic Inform by Graham Nelson
|
extension: Basic Inform by Graham Nelson
|
||||||
dependency: if not WorldModelKit then BasicInformExtrasKit
|
dependency: if not WorldModelKit then BasicInformExtrasKit
|
||||||
|
|
|
@ -22,6 +22,7 @@ INTESTWEB = ../intest
|
||||||
INWEB = ../inweb/Tangled/inweb
|
INWEB = ../inweb/Tangled/inweb
|
||||||
INWEBX = ../inweb/Tangled/inweb
|
INWEBX = ../inweb/Tangled/inweb
|
||||||
INTERX = inter/Tangled/inter
|
INTERX = inter/Tangled/inter
|
||||||
|
INBUILDX = inbuild/Tangled/inbuild
|
||||||
|
|
||||||
# The "-" at the front here tells make to load this file if it exists, and
|
# The "-" at the front here tells make to load this file if it exists, and
|
||||||
# continue otherwise. If it does exist, it will define the symbol INTEGRATION.
|
# continue otherwise. If it does exist, it will define the symbol INTEGRATION.
|
||||||
|
@ -60,6 +61,7 @@ INTERX = inter/Tangled/inter
|
||||||
{module} INTER inter inter/inter-module
|
{module} INTER inter inter/inter-module
|
||||||
{module} BUILDING building inter/building-module
|
{module} BUILDING building inter/building-module
|
||||||
{module} CODEGEN codegen inter/codegen-module
|
{module} CODEGEN codegen inter/codegen-module
|
||||||
|
{module} INBUILD inbuild inbuild/inbuild-module
|
||||||
|
|
||||||
# First, the tools we need to make, using the same declaration notation.
|
# First, the tools we need to make, using the same declaration notation.
|
||||||
# In the eventual makefile, the symbol NAMEWEB is the location of NAME;
|
# In the eventual makefile, the symbol NAMEWEB is the location of NAME;
|
||||||
|
@ -95,8 +97,9 @@ INTERX = inter/Tangled/inter
|
||||||
{tool} INRTPS inrtps inrtps
|
{tool} INRTPS inrtps inrtps
|
||||||
{dep} INRTPS on FOUNDATION
|
{dep} INRTPS on FOUNDATION
|
||||||
|
|
||||||
{tool} INBUILD inbuild inbuild
|
{tool} INBUILDTOOL inbuild inbuild
|
||||||
{dep} INBUILD on FOUNDATION
|
{dep} INBUILDTOOL on FOUNDATION
|
||||||
|
{dep} INBUILDTOOL on INBUILD
|
||||||
|
|
||||||
{tool} INTERTOOL inter inter
|
{tool} INTERTOOL inter inter
|
||||||
{dep} INTERTOOL on FOUNDATION
|
{dep} INTERTOOL on FOUNDATION
|
||||||
|
@ -153,11 +156,11 @@ INFORM6X = inform6/Tangled/inform6
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
|
||||||
all: tools srules intertemplate localintegration
|
all: tools kits srules localintegration
|
||||||
|
|
||||||
.PHONY: force
|
.PHONY: force
|
||||||
|
|
||||||
force: forcetools forcesrules localintegration
|
force: forcetools forcekits forcesrules localintegration
|
||||||
|
|
||||||
.PHONY: localintegration
|
.PHONY: localintegration
|
||||||
localintegration: inform7/Internal/Languages/English/Syntax.preform
|
localintegration: inform7/Internal/Languages/English/Syntax.preform
|
||||||
|
@ -167,89 +170,6 @@ inform7/Internal/Languages/English/Syntax.preform: inform7/Tangled/Syntax.prefor
|
||||||
|
|
||||||
# (Of course those other four phony targets are yet to be defined.)
|
# (Of course those other four phony targets are yet to be defined.)
|
||||||
|
|
||||||
.PHONY: intertemplate
|
|
||||||
intertemplate: \
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-16d.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-16.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-32d.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-32.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-16d.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-16.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-32d.interb \
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-32.interb \
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb \
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-16.interb \
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb \
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb \
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-16d.interb \
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-16.interb \
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-32d.interb \
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-32.interb \
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-16d.interb \
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-16.interb \
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-32d.interb \
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-32.interb
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-16d.interb: inform7/Internal/Inter/BasicInformKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16d -assimilate inform7/Internal/Inter/BasicInformKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-16.interb: inform7/Internal/Inter/BasicInformKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16 -assimilate inform7/Internal/Inter/BasicInformKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-32d.interb: inform7/Internal/Inter/BasicInformKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32d -assimilate inform7/Internal/Inter/BasicInformKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformKit/arch-32.interb: inform7/Internal/Inter/BasicInformKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32 -assimilate inform7/Internal/Inter/BasicInformKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-16d.interb: inform7/Internal/Inter/BasicInformExtrasKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16d -assimilate inform7/Internal/Inter/BasicInformExtrasKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-16.interb: inform7/Internal/Inter/BasicInformExtrasKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16 -assimilate inform7/Internal/Inter/BasicInformExtrasKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-32d.interb: inform7/Internal/Inter/BasicInformExtrasKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32d -assimilate inform7/Internal/Inter/BasicInformExtrasKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/BasicInformExtrasKit/arch-32.interb: inform7/Internal/Inter/BasicInformExtrasKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32 -assimilate inform7/Internal/Inter/BasicInformExtrasKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-16d.interb: inform7/Internal/Inter/EnglishLanguageKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16d -assimilate inform7/Internal/Inter/EnglishLanguageKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-16.interb: inform7/Internal/Inter/EnglishLanguageKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16 -assimilate inform7/Internal/Inter/EnglishLanguageKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-32d.interb: inform7/Internal/Inter/EnglishLanguageKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32d -assimilate inform7/Internal/Inter/EnglishLanguageKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/EnglishLanguageKit/arch-32.interb: inform7/Internal/Inter/EnglishLanguageKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32 -assimilate inform7/Internal/Inter/EnglishLanguageKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-16d.interb: inform7/Internal/Inter/WorldModelKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16d -assimilate inform7/Internal/Inter/WorldModelKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-16.interb: inform7/Internal/Inter/WorldModelKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16 -assimilate inform7/Internal/Inter/WorldModelKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-32d.interb: inform7/Internal/Inter/WorldModelKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32d -assimilate inform7/Internal/Inter/WorldModelKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/WorldModelKit/arch-32.interb: inform7/Internal/Inter/WorldModelKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32 -assimilate inform7/Internal/Inter/WorldModelKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-16d.interb: inform7/Internal/Inter/CommandParserKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16d -assimilate inform7/Internal/Inter/CommandParserKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-16.interb: inform7/Internal/Inter/CommandParserKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 16 -assimilate inform7/Internal/Inter/CommandParserKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-32d.interb: inform7/Internal/Inter/CommandParserKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32d -assimilate inform7/Internal/Inter/CommandParserKit
|
|
||||||
|
|
||||||
inform7/Internal/Inter/CommandParserKit/arch-32.interb: inform7/Internal/Inter/CommandParserKit/Sections/*.i6t
|
|
||||||
$(INTERX) -architecture 32 -assimilate inform7/Internal/Inter/CommandParserKit
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Target "makers"
|
# Target "makers"
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@ -314,6 +234,20 @@ forcesrules:
|
||||||
$(INWEBX) inform7/extensions/standard_rules -tangle-to $(SRULES)
|
$(INWEBX) inform7/extensions/standard_rules -tangle-to $(SRULES)
|
||||||
$(INWEBX) inform7/extensions/basic_inform -tangle-to $(BINFORM)
|
$(INWEBX) inform7/extensions/basic_inform -tangle-to $(BINFORM)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Targets "kits" and "forcekits"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# These are easy because Inbuild performs a make-like service on them; that
|
||||||
|
# saves a great deal of messy make code here.
|
||||||
|
|
||||||
|
.PHONY: kits
|
||||||
|
kits:
|
||||||
|
$(INBUILDX) -build -contents-of inform7/Internal/Inter
|
||||||
|
|
||||||
|
.PHONY: forcekits
|
||||||
|
forcekits:
|
||||||
|
$(INBUILDX) -rebuild -contents-of inform7/Internal/Inter
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Target "tools"
|
# Target "tools"
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue