2020-01-29 21:58:43 +02:00
|
|
|
[BuildSteps::] Build Steps.
|
|
|
|
|
2020-02-24 01:49:56 +02:00
|
|
|
A build step is a task which exercises one of the build skills.
|
2020-01-29 21:58:43 +02:00
|
|
|
|
2020-02-24 01:49:56 +02:00
|
|
|
@h Build skills.
|
2020-03-30 14:23:06 +03:00
|
|
|
A "skill" is a single atomic task which we know how to perform. For example,
|
|
|
|
assimilating a binary for a kit is a skill.
|
|
|
|
|
|
|
|
Each different skill is an instance of:
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
=
|
|
|
|
typedef struct build_skill {
|
|
|
|
struct text_stream *name;
|
2020-05-09 15:07:39 +03:00
|
|
|
struct method_set *methods;
|
|
|
|
CLASS_DEFINITION
|
2020-02-24 01:49:56 +02:00
|
|
|
} build_skill;
|
|
|
|
|
|
|
|
build_skill *BuildSteps::new_skill(text_stream *name) {
|
|
|
|
build_skill *S = CREATE(build_skill);
|
|
|
|
S->name = Str::duplicate(name);
|
2020-05-09 15:07:39 +03:00
|
|
|
S->methods = Methods::new_set();
|
2020-02-24 01:49:56 +02:00
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@ Skills provide two method functions: one constructs a shell command to
|
|
|
|
perform the skill, and the other performs the skill directly by calling some
|
|
|
|
function within the current executable. These methods are optional, and if
|
|
|
|
one is absent then the skill can't be performed that way.
|
2020-01-29 21:58:43 +02:00
|
|
|
|
2020-02-24 01:49:56 +02:00
|
|
|
@e BUILD_SKILL_COMMAND_MTID
|
|
|
|
@e BUILD_SKILL_INTERNAL_MTID
|
|
|
|
|
|
|
|
=
|
2020-05-09 15:07:39 +03:00
|
|
|
VOID_METHOD_TYPE(BUILD_SKILL_COMMAND_MTID,
|
2020-05-05 23:59:02 +03:00
|
|
|
build_skill *S, build_step *BS, text_stream *command, build_methodology *meth,
|
|
|
|
linked_list *search)
|
2020-05-09 15:07:39 +03:00
|
|
|
INT_METHOD_TYPE(BUILD_SKILL_INTERNAL_MTID,
|
2020-05-05 23:59:02 +03:00
|
|
|
build_skill *S, build_step *BS, build_methodology *meth, linked_list *search)
|
2020-02-24 01:49:56 +02:00
|
|
|
|
|
|
|
@h Build steps.
|
2020-03-30 14:23:06 +03:00
|
|
|
These are essentially just skills, but with a docket of contextual data. The
|
2020-05-05 23:59:02 +03:00
|
|
|
idea is that a function outside the //supervisor// module can carry out a skill
|
2020-03-30 14:23:06 +03:00
|
|
|
for us using only the contextual information in this structure, without having
|
|
|
|
to access any of |inbuild|'s variables directly.
|
2020-01-29 21:58:43 +02:00
|
|
|
|
|
|
|
=
|
|
|
|
typedef struct build_step {
|
2020-02-24 01:49:56 +02:00
|
|
|
struct build_skill *what_to_do;
|
2020-03-30 14:23:06 +03:00
|
|
|
struct build_vertex *vertex; /* what to do it to */
|
2020-02-22 16:09:13 +02:00
|
|
|
struct target_vm *for_vm;
|
|
|
|
struct inter_architecture *for_arch;
|
|
|
|
int for_release;
|
2020-03-30 14:23:06 +03:00
|
|
|
struct inbuild_copy *associated_copy; /* e.g., the Inform project causing this work */
|
2020-05-09 15:07:39 +03:00
|
|
|
CLASS_DEFINITION
|
2020-01-29 21:58:43 +02:00
|
|
|
} build_step;
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@ We build scripts for a vertex by attaching one step at a time to it:
|
2020-01-29 21:58:43 +02:00
|
|
|
|
|
|
|
=
|
2020-05-05 23:59:02 +03:00
|
|
|
build_step *BuildSteps::attach(build_vertex *vertex, build_skill *to_do,
|
2020-02-22 16:09:13 +02:00
|
|
|
int rel, target_vm *VM, inter_architecture *arch, inbuild_copy *assoc) {
|
2020-01-29 21:58:43 +02:00
|
|
|
build_step *S = CREATE(build_step);
|
|
|
|
S->what_to_do = to_do;
|
2020-03-30 14:23:06 +03:00
|
|
|
S->vertex = vertex;
|
2020-02-22 16:09:13 +02:00
|
|
|
S->for_vm = VM;
|
|
|
|
S->for_arch = arch;
|
|
|
|
if ((VM) && (arch == NULL)) S->for_arch = TargetVMs::get_architecture(VM);
|
|
|
|
S->for_release = rel;
|
|
|
|
S->associated_copy = assoc;
|
|
|
|
BuildScripts::add_step(vertex->script, S);
|
2020-01-29 21:58:43 +02:00
|
|
|
return S;
|
|
|
|
}
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@h Execution.
|
|
|
|
Note that this prints a log of shell commands generated to |stdout| when
|
|
|
|
we are running inside Inbuild at the command line, but not when we are running
|
|
|
|
inside the |inform7| executable, where we are silent throughout.
|
|
|
|
|
|
|
|
=
|
2020-05-05 23:59:02 +03:00
|
|
|
int BuildSteps::execute(build_vertex *V, build_step *S, build_methodology *BM,
|
|
|
|
linked_list *search_list) {
|
2020-02-22 16:09:13 +02:00
|
|
|
int rv = TRUE;
|
2020-06-28 01:18:54 +03:00
|
|
|
TEMPORARY_TEXT(command)
|
2020-03-30 14:23:06 +03:00
|
|
|
@<Work out a shell command, and perhaps print or call it@>;
|
|
|
|
@<Perform the skill internally if that's called for@>;
|
2020-03-02 14:55:33 +02:00
|
|
|
#ifndef CORE_MODULE
|
2020-02-22 16:09:13 +02:00
|
|
|
if (rv == FALSE) WRITE_TO(STDERR, "Build failed at '%S'\n", command);
|
2020-03-02 14:55:33 +02:00
|
|
|
#endif
|
2020-06-28 01:18:54 +03:00
|
|
|
DISCARD_TEXT(command)
|
2020-02-22 16:09:13 +02:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2020-03-30 14:23:06 +03:00
|
|
|
@<Work out a shell command, and perhaps print or call it@> =
|
2020-05-09 15:07:39 +03:00
|
|
|
VOID_METHOD_CALL(S->what_to_do, BUILD_SKILL_COMMAND_MTID, S, command, BM, search_list);
|
2020-03-30 14:23:06 +03:00
|
|
|
if (Str::len(command) > 0) rv = BuildSteps::shell(command, BM);
|
|
|
|
|
|
|
|
@<Perform the skill internally if that's called for@> =
|
|
|
|
if (BM->methodology == INTERNAL_METHODOLOGY) {
|
|
|
|
int returned = 0;
|
2020-05-09 15:07:39 +03:00
|
|
|
INT_METHOD_CALL(returned, S->what_to_do, BUILD_SKILL_INTERNAL_MTID, S, BM, search_list);
|
2020-03-30 14:23:06 +03:00
|
|
|
if (returned != TRUE) rv = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
@ This prints a shell command to |stdout| (except when inside |inform7|)
|
|
|
|
and also executes it if the methodology allows, returning the result. Note
|
|
|
|
that shell commands return 0 to indicate happiness.
|
|
|
|
|
|
|
|
=
|
|
|
|
int BuildSteps::shell(text_stream *command, build_methodology *BM) {
|
2020-02-22 16:09:13 +02:00
|
|
|
int rv = TRUE;
|
2020-03-07 10:46:43 +02:00
|
|
|
#ifndef CORE_MODULE
|
2020-02-22 16:09:13 +02:00
|
|
|
WRITE_TO(STDOUT, "%S\n", command);
|
2020-03-07 10:46:43 +02:00
|
|
|
#endif
|
2020-03-30 14:23:06 +03:00
|
|
|
if (BM->methodology == SHELL_METHODOLOGY)
|
|
|
|
rv = (Shell::run(command) == 0)?TRUE:FALSE;
|
2020-02-22 16:09:13 +02:00
|
|
|
return rv;
|
2020-01-29 21:58:43 +02:00
|
|
|
}
|