static void cachehit_callback(struct NODE *node, struct CACHENODE *cachenode, void *user) { struct CACHERUNINFO *info = (struct CACHERUNINFO *)user; /* check if the file has been removed */ struct NODE *existing_node = node_find_byhash(node->graph, cachenode->hashid); if(existing_node) { struct NODE *newnode = node_add_dependency (node, existing_node); dependency_cpp_run(info->context, newnode, info->callback, info->userdata); } else { time_t timestamp = file_timestamp(cachenode->filename); if(timestamp) { /* this shouldn't be able to fail */ struct NODE *newnode; node_create(&newnode, info->context->graph, cachenode->filename, NULL, timestamp); node_add_dependency (node, newnode); /* recurse the dependency checking */ dependency_cpp_run(info->context, newnode, info->callback, info->userdata); } else { node->dirty = NODEDIRTY_MISSING; } } }
static void callback_addjob_deps(lua_State *L, void *user) { struct JOB *job = (struct JOB *)user; struct NODELINK *link; const char *filename; luaL_checktype(L, -1, LUA_TSTRING); filename = lua_tostring(L, -1); for(link = job->firstoutput; link; link = link->next) node_add_dependency(link->node, filename); }
static int dependency_cpp_callback(struct NODE *node, void *user, const char *filename, int sys) { struct CPPDEPINFO *depinfo = (struct CPPDEPINFO *)user; struct CPPDEPINFO recurseinfo; char buf[MAX_PATH_LENGTH]; int check_system = sys; int found = 0; struct NODE *depnode = NULL; time_t timestamp = 0; if(!sys) { /* "normal.header" */ int flen = strlen(node->filename)-1; while(flen) { if(node->filename[flen] == '/') break; flen--; } path_join(node->filename, flen, filename, -1, buf, sizeof(buf)); if(node_findfile(node->graph, buf, &depnode, ×tamp)) found = 1; else { /* file does not exist */ check_system = 1; } } if(check_system) { /* <system.header> */ if(path_isabs(filename)) { if(node_findfile(node->graph, filename, &depnode, ×tamp)) { strcpy(buf, filename); found = 1; } } else { struct STRINGLIST *cur; int flen = strlen(filename); for(cur = depinfo->paths; cur; cur = cur->next) { path_join(cur->str, cur->len, filename, flen, buf, sizeof(buf)); if(node_findfile(node->graph, buf, &depnode, ×tamp)) { found = 1; break; } } } } /* */ if(found) { path_normalize(buf); if(!depnode) node_create(&depnode, node->graph, buf, NULL, timestamp); if(node_add_dependency (node, depnode) == NULL) return 2; if(!depnode) return 3; /* do the dependency walk */ if(!depnode->depchecked) { recurseinfo.paths = depinfo->paths; recurseinfo.context = depinfo->context; if(dependency_cpp_run(depinfo->context, depnode, dependency_cpp_callback, &recurseinfo) != 0) return 4; } } return 0; }
static int bam_setup(struct CONTEXT *context, const char *scriptfile, const char **targets, int num_targets) { /* */ if(session.verbose) printf("%s: setup started\n", session.name); /* set filename */ context->filename = scriptfile; /* set global timestamp to the script file */ context->globaltimestamp = file_timestamp(scriptfile); /* */ context->forced = option_force; /* fetch script directory */ { char cwd[MAX_PATH_LENGTH]; char path[MAX_PATH_LENGTH]; if(!getcwd(cwd, sizeof(cwd))) { printf("%s: error: couldn't get current working directory\n", session.name); return -1; } if(path_directory(context->filename, path, sizeof(path))) { printf("%s: error: path too long '%s'\n", session.name, path); return -1; } if(path_join(cwd, -1, path, -1, context->script_directory, sizeof(context->script_directory))) { printf("%s: error: path too long when joining '%s' and '%s'\n", session.name, cwd, path); return -1; } } /* register all functions */ event_begin(0, "lua setup", NULL); if(register_lua_globals(context->lua, context->script_directory, context->filename) != 0) { printf("%s: error: registering of lua functions failed\n", session.name); return -1; } event_end(0, "lua setup", NULL); /* load script */ if(session.verbose) printf("%s: reading script from '%s'\n", session.name, scriptfile); event_begin(0, "script load", NULL); /* push error function to stack and load the script */ lua_getglobal(context->lua, "errorfunc"); switch(luaL_loadfile(context->lua, scriptfile)) { case 0: break; case LUA_ERRSYNTAX: lf_errorfunc(context->lua); return -1; case LUA_ERRMEM: printf("%s: memory allocation error\n", session.name); return -1; case LUA_ERRFILE: printf("%s: error opening '%s'\n", session.name, scriptfile); return -1; default: printf("%s: unknown error\n", session.name); return -1; } event_end(0, "script load", NULL); /* start the background stat thread */ node_graph_start_statthread(context->graph); /* call the code chunk */ event_begin(0, "script run", NULL); if(lua_pcall(context->lua, 0, LUA_MULTRET, -2) != 0) { node_graph_end_statthread(context->graph); printf("%s: script error (-t for more detail)\n", session.name); return -1; } event_end(0, "script run", NULL); /* stop the background stat thread */ event_begin(0, "stat", NULL); node_graph_end_statthread(context->graph); event_end(0, "stat", NULL); /* run deferred functions */ event_begin(0, "deferred cpp dependencies", NULL); if(run_deferred_functions(context, context->firstdeferred_cpp) != 0) return -1; event_end(0, "deferred cpp dependencies", NULL); event_begin(0, "deferred search dependencies", NULL); if(run_deferred_functions(context, context->firstdeferred_search) != 0) return -1; event_end(0, "deferred search dependencies", NULL); /* */ if(session.verbose) printf("%s: making build target\n", session.name); /* make build target */ { struct NODE *node; int all_target = 0; int i; if(node_create(&context->target, context->graph, "_bam_buildtarget", NULL, TIMESTAMP_PSEUDO)) return -1; if(num_targets) { /* search for all target */ for(i = 0; i < num_targets; i++) { if(strcmp(targets[i], "all") == 0) { all_target = 1; break; } } } /* default too all if we have no targets or default target */ if(num_targets == 0 && !context->defaulttarget) all_target = 1; if(all_target) { /* build the all target */ for(node = context->graph->first; node; node = node->next) { if(node->firstparent == NULL && node != context->target) { if(!node_add_dependency (context->target, node)) return -1; } } } else { if(num_targets) { for(i = 0; i < num_targets; i++) { struct NODE *node = node_find(context->graph, targets[i]); if(!node) { printf("%s: target '%s' not found\n", session.name, targets[i]); return -1; } if(option_dependent) { /* TODO: this should perhaps do a reverse walk up in the tree to find all dependent node with commandline */ struct NODELINK *parent; for(parent = node->firstparent; parent; parent = parent->next) { if(!node_add_dependency (context->target, parent->node)) return -1; } } else { if(!node_add_dependency (context->target, node)) return -1; } } } else { if(!node_add_dependency (context->target, context->defaulttarget)) return -1; } } } /* zero out the global timestamp if we don't want to use it */ if(option_no_scripttimestamp) context->globaltimestamp = 0; /* */ if(session.verbose) printf("%s: setup done\n", session.name); /* return success */ return 0; }