mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +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"
|
||||
|
||||
@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) {
|
||||
Foundation::start();
|
||||
InbuildModule::start();
|
||||
targets = NEW_LINKED_LIST(inbuild_copy);
|
||||
@<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();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ 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@> =
|
||||
CommandLine::declare_heading(
|
||||
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);
|
||||
|
||||
@ =
|
||||
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) {
|
||||
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_ittt_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_ittt)
|
||||
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.
|
||||
(The client doesn't need to call the start and end routines, because the
|
||||
foundation module does that automatically.)
|
||||
|
||||
=
|
||||
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 writers@>;
|
||||
@<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.
|
||||
|
||||
=
|
||||
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 {
|
||||
struct inbuild_copy *as_copy;
|
||||
struct text_stream *name;
|
||||
struct pathname *location;
|
||||
struct text_stream *attachment_point;
|
||||
struct text_stream *early_source;
|
||||
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 *activations; /* of |element_activation| */
|
||||
struct text_stream *index_template;
|
||||
struct inbuild_version_number version;
|
||||
int defines_Main;
|
||||
int supports_natural_language;
|
||||
int priority;
|
||||
|
@ -48,7 +59,6 @@ inform_kit *Kits::load_at(text_stream *name, pathname *P) {
|
|||
K->name = Str::duplicate(name);
|
||||
K->attachment_point = Str::new();
|
||||
WRITE_TO(K->attachment_point, "/main/%S", name);
|
||||
K->location = P;
|
||||
K->early_source = NULL;
|
||||
K->priority = 10;
|
||||
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->supports_natural_language = FALSE;
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
pathname *P = Kits::find(name, N, PP);
|
||||
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();
|
||||
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")) {
|
||||
K->defines_Main = TRUE;
|
||||
} 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) {
|
||||
text_stream *segment;
|
||||
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);
|
||||
LOG("Loading kinds definitions from %f\n", F);
|
||||
I6T::interpret_kindt(F);
|
||||
|
@ -282,7 +343,7 @@ linked_list *Kits::list_of_inter_libraries(void) {
|
|||
requirements_list = NEW_LINKED_LIST(link_instruction);
|
||||
inform_kit *K;
|
||||
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);
|
||||
}
|
||||
return requirements_list;
|
|
@ -7,5 +7,11 @@ Licence: Artistic License 2.0
|
|||
Chapter 1: Setting Up
|
||||
Inbuild Module
|
||||
|
||||
Chapter 2: Everything Else
|
||||
Chapter 2: Conceptual Framework
|
||||
Version Numbers
|
||||
Conceptual Model
|
||||
Build Graphs
|
||||
Build Steps
|
||||
|
||||
Chapter 3: The Genres
|
||||
Kits
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
version: 1.0.2
|
||||
priority: 0
|
||||
extension: Basic Inform by Graham Nelson
|
||||
dependency: if not WorldModelKit then BasicInformExtrasKit
|
||||
|
|
|
@ -22,6 +22,7 @@ INTESTWEB = ../intest
|
|||
INWEB = ../inweb/Tangled/inweb
|
||||
INWEBX = ../inweb/Tangled/inweb
|
||||
INTERX = inter/Tangled/inter
|
||||
INBUILDX = inbuild/Tangled/inbuild
|
||||
|
||||
# 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.
|
||||
|
@ -60,6 +61,7 @@ INTERX = inter/Tangled/inter
|
|||
{module} INTER inter inter/inter-module
|
||||
{module} BUILDING building inter/building-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.
|
||||
# In the eventual makefile, the symbol NAMEWEB is the location of NAME;
|
||||
|
@ -95,8 +97,9 @@ INTERX = inter/Tangled/inter
|
|||
{tool} INRTPS inrtps inrtps
|
||||
{dep} INRTPS on FOUNDATION
|
||||
|
||||
{tool} INBUILD inbuild inbuild
|
||||
{dep} INBUILD on FOUNDATION
|
||||
{tool} INBUILDTOOL inbuild inbuild
|
||||
{dep} INBUILDTOOL on FOUNDATION
|
||||
{dep} INBUILDTOOL on INBUILD
|
||||
|
||||
{tool} INTERTOOL inter inter
|
||||
{dep} INTERTOOL on FOUNDATION
|
||||
|
@ -153,11 +156,11 @@ INFORM6X = inform6/Tangled/inform6
|
|||
|
||||
.PHONY: all
|
||||
|
||||
all: tools srules intertemplate localintegration
|
||||
all: tools kits srules localintegration
|
||||
|
||||
.PHONY: force
|
||||
|
||||
force: forcetools forcesrules localintegration
|
||||
force: forcetools forcekits forcesrules localintegration
|
||||
|
||||
.PHONY: localintegration
|
||||
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.)
|
||||
|
||||
.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"
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -314,6 +234,20 @@ forcesrules:
|
|||
$(INWEBX) inform7/extensions/standard_rules -tangle-to $(SRULES)
|
||||
$(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"
|
||||
# -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue