gwenhywfar  5.10.1
buildctx_run.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Mon Feb 08 2021
3  copyright : (C) 2021 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * Please see toplevel file COPYING for license details *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #define DISABLE_DEBUGLOG
15 
16 
17 #include "gwenbuild/buildctx/buildctx_p.h"
21 
22 #include <gwenhywfar/debug.h>
23 #include <gwenhywfar/text.h>
24 #include <gwenhywfar/directory.h>
25 
26 #include <unistd.h>
27 #include <ctype.h>
28 
29 
30 #define GWB_BUILDCTX_PROCESS_WAIT_TIMEOUT 10.0
31 
32 
33 static void _setupCommands(GWB_BUILD_CONTEXT *bctx, int forPrepareCommands);
34 static void _createCommandQueues(GWB_BUILD_CONTEXT *bctx);
35 static int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed);
36 static int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles);
37 static int _checkRunningQueue(GWB_BUILD_CONTEXT *bctx);
38 static void _signalJobFinished(GWB_BUILD_CMD *bcmd);
39 static void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands);
40 static int _waitForRunningJobs(GWB_BUILD_CONTEXT *bctx);
41 static void _abortAllCommands(GWB_BUILD_CONTEXT *bctx);
42 static void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList);
43 
44 static int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles);
45 static void _finishCurrentCommand(GWB_BUILD_CONTEXT *bctx, GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *currentCommand);
46 
47 static int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName);
48 static int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl);
49 
50 static int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles);
51 static time_t _getHighestModificationTime(const GWEN_STRINGLIST *slFiles);
52 static time_t _getLowestModificationTime(const GWEN_STRINGLIST *slFiles);
53 static void _unlinkFilesInStringList(const GWEN_STRINGLIST *slFiles);
54 
55 
56 
57 
58 
59 int GWB_BuildCtx_Run(GWB_BUILD_CONTEXT *bctx, int maxConcurrentJobs, int usePrepareCommands, const char *builderName)
60 {
61  int rv;
62  int waitingJobs;
63  int runningJobs;
64 
66  _setupCommands(bctx, usePrepareCommands);
68  rv=GWB_BuildCtx_FillWaitingQueue(bctx, builderName);
69  if (rv<0) {
70  DBG_INFO(NULL, "here (%d)", rv);
71  return rv;
72  }
73 
74  if (GWB_BuildCmd_List2_GetSize(bctx->waitingQueue)==0) {
75  fprintf(stdout, "Nothing to do.\n");
76  return 0;
77  }
78 
79  waitingJobs=GWB_BuildCmd_List2_GetSize(bctx->waitingQueue);
80  runningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
81  while(waitingJobs+runningJobs) {
82  int startedCommands;
83  int changedCommands;
84 
85  startedCommands=_checkWaitingQueue(bctx, maxConcurrentJobs-runningJobs);
86  if (startedCommands<0) {
87  _waitForRunningJobs(bctx);
88  _abortAllCommands(bctx);
89  return GWEN_ERROR_GENERIC;
90  }
91 
92  changedCommands=_checkRunningQueue(bctx);
93  if (changedCommands<0) { /* error */
94  _waitForRunningJobs(bctx);
95  _abortAllCommands(bctx);
96  return GWEN_ERROR_GENERIC;
97  }
98 
99  if (startedCommands==0 && changedCommands==0) {
100  if (runningJobs==0) {
101  DBG_ERROR(NULL, "ERROR: No running jobs and none could be started, maybe circular dependencies?");
102  _waitForRunningJobs(bctx);
103  _abortAllCommands(bctx);
104  return GWEN_ERROR_GENERIC;
105  }
106  DBG_DEBUG(NULL, "Nothing changed, sleeping...");
107  sleep(3);
108  }
109 
110  waitingJobs=GWB_BuildCmd_List2_GetSize(bctx->waitingQueue);
111  runningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
112  } /* while */
113 
114  GWB_BuildCmd_List2_free(bctx->waitingQueue);
115  bctx->waitingQueue=NULL;
116  GWB_BuildCmd_List2_free(bctx->runningQueue);
117  bctx->runningQueue=NULL;
118  GWB_BuildCmd_List2_free(bctx->finishedQueue);
119  bctx->finishedQueue=NULL;
120 
121  return 0;
122 }
123 
124 
125 
127 {
128  int numRunningJobs;
129  time_t startTime;
130 
131  startTime=time(0);
132  numRunningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
133  if (numRunningJobs)
134  fprintf(stderr, "NOTICE: Waiting for %d jobs.\n", numRunningJobs);
135  while(numRunningJobs) {
136  int numChangedCommands;
137  time_t currentTime;
138 
139  numChangedCommands=_checkRunningQueue(bctx);
140  if (numChangedCommands<0) { /* error */
141  DBG_INFO(NULL, "Some jobs had errors");
142  }
143  numRunningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
144 
145  if (numRunningJobs>0) {
146  double delta;
147 
148  currentTime=time(0);
149  delta=difftime(currentTime, startTime);
151  DBG_ERROR(NULL, "%d jobs still running after %f.1 seconds, aborting", numRunningJobs, delta);
152  return GWEN_ERROR_TIMEOUT;
153  }
154  DBG_DEBUG(NULL, "Jobs still running, sleeping...");
155  sleep(1);
156  }
157 
158  } /* while */
159 
160  return 0;
161 }
162 
163 
164 
166 {
167  _abortCommandsInQueue(bctx->waitingQueue);
168  GWB_BuildCmd_List2_free(bctx->waitingQueue);
169  bctx->waitingQueue=NULL;
170 
171  _abortCommandsInQueue(bctx->runningQueue);
172  GWB_BuildCmd_List2_free(bctx->runningQueue);
173  bctx->runningQueue=NULL;
174 
175  _abortCommandsInQueue(bctx->finishedQueue);
176  GWB_BuildCmd_List2_free(bctx->finishedQueue);
177  bctx->finishedQueue=NULL;
178 }
179 
180 
181 
182 void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList)
183 {
184  GWB_BUILD_CMD *bcmd;
185 
186  while( (bcmd=GWB_BuildCmd_List2_GetFront(cmdList)) ) {
187  GWB_BuildCmd_List2_PopFront(cmdList);
189  } /* while */
190 }
191 
192 
193 
194 
195 void _setupCommands(GWB_BUILD_CONTEXT *bctx, int forPrepareCommands)
196 {
197  GWB_BUILD_CMD_LIST2_ITERATOR *it;
198 
199  it=GWB_BuildCmd_List2_First(bctx->commandList);
200  if (it) {
201  GWB_BUILD_CMD *bcmd;
202 
203  bcmd=GWB_BuildCmd_List2Iterator_Data(it);
204  while(bcmd) {
205  GWB_BUILD_SUBCMD_LIST *cmdList;
206 
207  if (forPrepareCommands)
209  else
210  cmdList=GWB_BuildCmd_GetBuildCommandList(bcmd);
211  if (cmdList)
212  GWB_BuildCmd_SetCurrentCommand(bcmd, GWB_BuildSubCmd_List_First(cmdList));
213  bcmd=GWB_BuildCmd_List2Iterator_Next(it);
214  }
215  GWB_BuildCmd_List2Iterator_free(it);
216  }
217 }
218 
219 
220 
222 {
223  bctx->waitingQueue=GWB_BuildCmd_List2_new();
224  bctx->finishedQueue=GWB_BuildCmd_List2_new();
225  bctx->runningQueue=GWB_BuildCmd_List2_new();
226 }
227 
228 
229 
230 int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed)
231 {
232  GWB_BUILD_CMD_LIST2 *oldQueue;
233  GWB_BUILD_CMD *bcmd;
234  int started=0;
235  int errors=0;
236 
237  oldQueue=bctx->waitingQueue;
238  bctx->waitingQueue=GWB_BuildCmd_List2_new();
239 
240  while( (bcmd=GWB_BuildCmd_List2_GetFront(oldQueue)) ) {
241 
242  GWB_BuildCmd_List2_PopFront(oldQueue);
243  if (started<maxStartAllowed) {
244  if (GWB_BuildCmd_GetBlockingFiles(bcmd)==0) {
245  int rv;
246  GWEN_STRINGLIST *slInFiles;
247  GWEN_STRINGLIST *slOutFiles;
248 
250  bctx->initialSourceDir);
252  bctx->initialSourceDir);
253  if (_needRunCurrentCommand(bcmd, slInFiles, slOutFiles)) {
254 
255  rv=_startCommand(bcmd, slOutFiles);
256  if (rv<0) {
257  GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
258  errors++;
259  }
260  else {
261  GWB_BuildCmd_List2_PushBack(bctx->runningQueue, bcmd);
262  started++;
263  }
264  }
265  else {
267  started++;
268  }
269  GWEN_StringList_free(slOutFiles);
270  GWEN_StringList_free(slInFiles);
271  }
272  else
273  GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
274  }
275  else
276  GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
277  } /* while */
278  GWB_BuildCmd_List2_free(oldQueue);
279 
280  if (errors)
281  return GWEN_ERROR_GENERIC;
282  return started;
283 }
284 
285 
286 
287 GWEN_STRINGLIST *_fileListToTopBuildDirStringList(const char *initialSourceDir, GWB_FILE_LIST2 *fileList)
288 {
289  GWB_FILE_LIST2_ITERATOR *it;
290 
291  it=GWB_File_List2_First(fileList);
292  if (it) {
293  GWEN_STRINGLIST *sl;
294  GWB_FILE *file;
295  GWEN_BUFFER *fbuf;
296 
297  sl=GWEN_StringList_new();
298  fbuf=GWEN_Buffer_new(0, 256, 0, 1);
299  file=GWB_File_List2Iterator_Data(it);
300  while(file) {
301  GWB_File_WriteFileNameToTopBuildDirString(file, initialSourceDir, fbuf);
303  GWEN_Buffer_Reset(fbuf);
304  file=GWB_File_List2Iterator_Next(it);
305  } /* while */
306  GWEN_Buffer_Reset(fbuf);
307  GWB_File_List2Iterator_free(it);
308 
309  if (GWEN_StringList_Count(sl)==0) {
311  return NULL;
312  }
313  return sl;
314  }
315 
316  return NULL;
317 }
318 
319 
320 
321 int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
322 {
323  GWB_BUILD_SUBCMD *currentCommand;
324 
325  currentCommand=GWB_BuildCmd_GetCurrentCommand(bcmd);
326  if (currentCommand) {
327  uint32_t cmdFlags;
328  uint32_t subCmdFlags;
329 
330  cmdFlags=GWB_BuildCmd_GetFlags(bcmd);
331  subCmdFlags=GWB_BuildSubCmd_GetFlags(currentCommand);
332 
333  if (cmdFlags & GWB_BUILD_CMD_FLAGS_CHECK_DATES) {
334  if (_inFilesNewerThanOutFiles(slInFiles, slOutFiles)) {
335  /* need rebuild */
336  DBG_INFO(NULL, "Input files newer than output files, rebuild needed");
337  return 1;
338  }
339  }
340  else
341  /* dont check dates, always rebuild */
342  return 1;
343 
344  if (subCmdFlags & GWB_BUILD_SUBCMD_FLAGS_CHECK_DEPENDS) {
345  int rv;
346 
347  rv=_checkDependencies(bcmd, currentCommand, GWEN_StringList_FirstString(slOutFiles));
348  if (rv==-1) {
349  DBG_INFO(NULL, "Dependencies flag NO rebuild needed (%d)", rv);
350  return 0;
351  }
352  DBG_INFO(NULL, "Dependencies flag rebuild needed (%d)", rv);
353  return 1;
354  }
355  }
356 
357  DBG_INFO(NULL, "Rebuild not needed");
358  return 0;
359 }
360 
361 
362 
363 /* return 0: no rebuild needed; 1: rebuild needed */
364 int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
365 {
366  time_t tiHighestInFileTime;
367  time_t tiLowestOutFileTime;
368 
369  tiHighestInFileTime=_getHighestModificationTime(slInFiles);
370  tiLowestOutFileTime=_getLowestModificationTime(slOutFiles);
371  if (tiHighestInFileTime==0 || tiLowestOutFileTime==0) {
372  DBG_INFO(NULL, "Either input or output time not available");
373  return 1;
374  }
375  if (tiHighestInFileTime>tiLowestOutFileTime)
376  return 1;
377  return 0;
378 }
379 
380 
381 
383 {
384  time_t tiLowest=0;
385 
386  if (slFiles) {
388 
389  se=GWEN_StringList_FirstEntry(slFiles);
390  while(se) {
391  const char *s;
392 
394  if (s && *s) {
395  time_t tiFile;
396 
398  if (tiFile>0) {
399  if (tiLowest==0)
400  tiLowest=tiFile;
401  else if (tiFile<tiLowest)
402  tiLowest=tiFile;
403  }
404  else {
405  DBG_INFO(NULL, "No modification time for \"%s\"", s);
406  return 0;
407  }
408  }
409 
411  }
412  }
413 
414  return tiLowest;
415 }
416 
417 
418 
420 {
421  time_t tiHighest=0;
422 
423  if (slFiles) {
425 
426  se=GWEN_StringList_FirstEntry(slFiles);
427  while(se) {
428  const char *s;
429 
431  if (s && *s) {
432  time_t tiFile;
433 
435  if (tiFile>0) {
436  if (tiHighest==0)
437  tiHighest=tiFile;
438  else if (tiFile>tiHighest)
439  tiHighest=tiFile;
440  }
441  else {
442  DBG_INFO(NULL, "No modification time for \"%s\"", s);
443  return 0;
444  }
445  }
446 
448  }
449  }
450 
451  return tiHighest;
452 }
453 
454 
455 
457 {
458  if (slFiles) {
460 
461  se=GWEN_StringList_FirstEntry(slFiles);
462  while(se) {
463  const char *s;
464 
466  if (s && *s) {
467  DBG_DEBUG(NULL, "Deleting \"%s\"", s);
468  unlink(s);
469  }
470 
472  }
473  }
474 }
475 
476 
477 
478 /* return 1: need rebuild, -1: Need no rebuild, 0: undecided */
479 int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName)
480 {
481  const char *depFileName;
482 
483  depFileName=GWB_BuildSubCmd_GetDepFilePath(subCmd);
484  if (depFileName && firstOutFileName) {
485  GWEN_STRINGLIST *sl;
486 
487  DBG_DEBUG(NULL, "Checking depend file \"%s\"", depFileName);
489  if (sl) {
490  int rv;
491 
492  //GWBUILD_Debug_PrintStringList(depFileName, sl, 2);
493  rv=_checkDatesOfFileAgainstList(firstOutFileName, sl);
495  return rv;
496  }
497  else {
498  DBG_DEBUG(NULL, "Could not load depend file \"%s\"", depFileName);
499  }
500  }
501  else {
502  if (depFileName==NULL) {
503  DBG_DEBUG(NULL, "No depFileName for %s", firstOutFileName?firstOutFileName:"<no outfile name>");
504  }
505  if (firstOutFileName==NULL) {
506  DBG_DEBUG(NULL, "No outFileName");
507  }
508  }
509 
510  return 0; /* indeterminate */
511 }
512 
513 
514 
515 int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl)
516 {
517  time_t tFile;
519 
520  tFile=GWBUILD_GetModificationTimeOfFile(fileName);
521  if (tFile==0) {
522  DBG_DEBUG(NULL, "%s: No modification time, need rebuild", fileName);
523  return 1; /* need rebuild */
524  }
526  if (se) {
527  while(se) {
528  const char *s;
529 
531  if (s && *s) {
532  time_t tCurrent;
533 
534  DBG_DEBUG(NULL, " Checking dep: %s", s);
536  if (tCurrent==0) {
537  DBG_DEBUG(NULL, "No modification time for dependency \"%s\", need rebuild", s);
538  return 1; /* need rebuild */
539  }
540  if (difftime(tFile, tCurrent)<0.0) {
541  DBG_DEBUG(NULL, "File \"%s\" is newer than \"%s\", rebuild needed", s, fileName);
542  return 1; /* definately need rebuild */
543  }
544  }
545 
547  }
548 
549  DBG_DEBUG(NULL, "No dependency is newer than file \"%s\", NO rebuild needed", fileName);
550  return -1; /* definately no need for rebuild */
551  }
552  else {
553  DBG_DEBUG(NULL, "Empty dependency list, rebuild needed");
554  }
555 
556  return 0;
557 }
558 
559 
560 
561 int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles)
562 {
563  GWB_BUILD_SUBCMD *currentCommand;
564 
565  currentCommand=GWB_BuildCmd_GetCurrentCommand(bcmd);
566  if (currentCommand) {
567  const char *folder;
568  const char *cmd;
569  const char *args;
570 
571  folder=GWB_BuildCmd_GetFolder(bcmd);
572  cmd=GWB_BuildSubCmd_GetCommand(currentCommand);
573  args=GWB_BuildSubCmd_GetArguments(currentCommand);
574 
575  if (cmd && *cmd) {
576  GWEN_PROCESS *process;
577  GWEN_PROCESS_STATE pstate;
578  const char *buildMessage;
579 
580  if (GWB_BuildSubCmd_List_Previous(currentCommand)==NULL) {
581  /* first command */
582  if (slOutFiles && (GWB_BuildCmd_GetFlags(bcmd) & GWB_BUILD_CMD_FLAGS_DEL_OUTFILES)) {
583  _unlinkFilesInStringList(slOutFiles);
584  }
585  }
586 
587  buildMessage=GWB_BuildSubCmd_GetBuildMessage(currentCommand);
588  if (buildMessage)
589  fprintf(stdout, "%s [%s]\n", buildMessage, cmd);
590  else
591  fprintf(stdout, "%s %s\n", cmd, args);
592 
593  process=GWEN_Process_new();
594  if (folder && *folder)
595  GWEN_Process_SetFolder(process, folder);
596  GWB_BuildCmd_SetCurrentProcess(bcmd, process);
597  pstate=GWEN_Process_Start(process, cmd, args);
598  if (pstate!=GWEN_ProcessStateRunning) {
599  DBG_ERROR(NULL, "Error starting command process (%d)", pstate);
601  return GWEN_ERROR_GENERIC;
602  }
603  DBG_DEBUG(NULL, "Process started");
604  return 0;
605  }
606  else {
607  DBG_ERROR(NULL, "No command in build command");
608  return GWEN_ERROR_GENERIC;
609  }
610  }
611  else {
612  DBG_ERROR(NULL, "No current command in build command");
613  return GWEN_ERROR_GENERIC;
614  }
615 }
616 
617 
618 
620 {
621  GWB_BUILD_CMD_LIST2 *oldRunningQueue;
622  GWB_BUILD_CMD *bcmd;
623  int changes=0;
624  int errors=0;
625 
626  oldRunningQueue=bctx->runningQueue;
627  bctx->runningQueue=GWB_BuildCmd_List2_new();
628 
629  while( (bcmd=GWB_BuildCmd_List2_GetFront(oldRunningQueue)) ) {
630  GWEN_PROCESS *process;
631  GWEN_PROCESS_STATE pstate;
632  GWB_BUILD_SUBCMD *currentCommand;
633 
634  GWB_BuildCmd_List2_PopFront(oldRunningQueue);
635  currentCommand=GWB_BuildCmd_GetCurrentCommand(bcmd);
636  process=GWB_BuildCmd_GetCurrentProcess(bcmd);
637  pstate=GWEN_Process_CheckState(process);
638  if (pstate!=GWEN_ProcessStateRunning) {
639  changes++;
640  if (pstate==GWEN_ProcessStateExited) {
641  int result;
642 
643  result=GWEN_Process_GetResult(process);
644  if (result && !(GWB_BuildSubCmd_GetFlags(currentCommand) & GWB_BUILD_SUBCMD_FLAGS_IGNORE_RESULT)) {
645  DBG_INFO(NULL, "Command exited with result %d", result);
646  GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
647  errors++;
648  }
649  else
650  _finishCurrentCommand(bctx, bcmd, currentCommand);
651  }
652  else {
653  DBG_ERROR(NULL, "Command aborted (status: %d)", pstate);
654  GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
655  errors++;
656  }
657  GWB_BuildCmd_SetCurrentProcess(bcmd, NULL); /* no longer running */
658  }
659  else
660  GWB_BuildCmd_List2_PushBack(bctx->runningQueue, bcmd); /* still running, put back */
661  } /* while still commands in running queue */
662 
663  GWB_BuildCmd_List2_free(oldRunningQueue);
664 
665  if (errors)
666  return GWEN_ERROR_GENERIC;
667  return changes;
668 }
669 
670 
671 
673 {
674  GWB_BUILD_SUBCMD *nextCommand;
675 
676  nextCommand=GWB_BuildSubCmd_List_Next(currentCommand);
677  GWB_BuildCmd_SetCurrentCommand(bcmd, nextCommand);
678  if (nextCommand)
679  GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
680  else {
681  _signalJobFinished(bcmd);
682  GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
683  }
684 }
685 
686 
687 
689 {
690  GWB_FILE_LIST2 *outFileList;
691 
692  outFileList=GWB_BuildCmd_GetOutFileList2(bcmd);
693  if (outFileList) {
694  GWB_FILE_LIST2_ITERATOR *it;
695 
696  it=GWB_File_List2_First(outFileList);
697  if (it) {
698  GWB_FILE *file;
699 
700  file=GWB_File_List2Iterator_Data(it);
701  while(file) {
702  GWB_BUILD_CMD_LIST2 *waitingCommands;
703 
704  waitingCommands=GWB_File_GetWaitingBuildCmdList2(file);
705  if (waitingCommands)
707  file=GWB_File_List2Iterator_Next(it);
708  }
709  GWB_File_List2Iterator_free(it);
710  }
711  }
712 
713 }
714 
715 
716 
717 void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands)
718 {
719  GWB_BUILD_CMD_LIST2_ITERATOR *it;
720 
721  it=GWB_BuildCmd_List2_First(waitingCommands);
722  if (it) {
723  GWB_BUILD_CMD *bcmd;
724 
725  bcmd=GWB_BuildCmd_List2Iterator_Data(it);
726  while(bcmd) {
728  bcmd=GWB_BuildCmd_List2Iterator_Next(it);
729  }
730 
731  GWB_BuildCmd_List2Iterator_free(it);
732  }
733 }
734 
735 
736 
const char * GWB_BuildSubCmd_GetCommand(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:100
static time_t _getHighestModificationTime(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:419
GWB_FILE_LIST2 * GWB_BuildCmd_GetInFileList2(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:255
static int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName)
Definition: buildctx_run.c:479
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetPrepareCommandList(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:196
const char * GWB_BuildSubCmd_GetDepFilePath(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:145
void GWB_BuildCmd_SetCurrentProcess(GWB_BUILD_CMD *bcmd, GWEN_PROCESS *process)
Definition: buildcmd.c:292
#define GWB_BUILD_SUBCMD_FLAGS_CHECK_DEPENDS
Definition: buildsubcmd.h:24
struct GWB_FILE GWB_FILE
Definition: file.h:18
struct GWB_BUILD_CONTEXT GWB_BUILD_CONTEXT
Definition: buildctx.h:16
static int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed)
Definition: buildctx_run.c:230
#define NULL
Definition: binreloc.c:300
static void _finishCurrentCommand(GWB_BUILD_CONTEXT *bctx, GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *currentCommand)
Definition: buildctx_run.c:672
static int _checkRunningQueue(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:619
int GWB_BuildCtx_FillWaitingQueue(GWB_BUILD_CONTEXT *bctx, const char *builderName)
const char * GWB_BuildCmd_GetFolder(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:166
#define GWB_BUILD_CMD_FLAGS_CHECK_DATES
Definition: buildcmd.h:25
GWB_BUILD_CMD_LIST2 * GWB_File_GetWaitingBuildCmdList2(const GWB_FILE *f)
Definition: file.c:246
#define GWB_BUILDCTX_PROCESS_WAIT_TIMEOUT
Definition: buildctx_run.c:30
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
GWEN_PROCESS_STATE
Definition: process.h:54
GWEN_STRINGLIST * GWB_BuildCtx_ReadAndTranslateDepfile(const char *folder, const char *fileName)
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
const char * GWB_BuildSubCmd_GetArguments(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:115
static int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:364
GWENHYWFAR_API GWEN_PROCESS_STATE GWEN_Process_CheckState(GWEN_PROCESS *pr)
GWEN_PROCESS * GWB_BuildCmd_GetCurrentProcess(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:285
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
int GWB_BuildCmd_DecBlockingFiles(GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:245
#define GWB_BUILD_CMD_FLAGS_DEL_OUTFILES
Definition: buildcmd.h:26
GWB_FILE_LIST2 * GWB_BuildCmd_GetOutFileList2(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:270
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
static void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList)
Definition: buildctx_run.c:182
#define GWEN_ERROR_GENERIC
Definition: error.h:62
const char * GWB_BuildSubCmd_GetBuildMessage(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:130
#define GWB_BUILD_SUBCMD_FLAGS_IGNORE_RESULT
Definition: buildsubcmd.h:23
GWENHYWFAR_API int GWEN_Process_GetResult(GWEN_PROCESS *pr)
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetBuildCommandList(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:210
struct GWB_BUILD_SUBCMD GWB_BUILD_SUBCMD
Definition: buildsubcmd.h:16
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
static int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl)
Definition: buildctx_run.c:515
static time_t _getLowestModificationTime(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:382
static int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:561
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:427
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
static void _abortAllCommands(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:165
GWENHYWFAR_API GWEN_PROCESS * GWEN_Process_new(void)
static int _waitForRunningJobs(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:126
const char * GWEN_StringList_FirstString(const GWEN_STRINGLIST *l)
Definition: stringlist.c:576
struct GWEN_PROCESS GWEN_PROCESS
Definition: process.h:49
static void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands)
Definition: buildctx_run.c:717
GWB_BUILD_SUBCMD * GWB_BuildCmd_GetCurrentCommand(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:306
uint32_t GWB_BuildSubCmd_GetFlags(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:72
time_t GWBUILD_GetModificationTimeOfFile(const char *filename)
Definition: gwenbuild.c:885
int GWB_BuildCtx_SetupDependencies(GWB_BUILD_CONTEXT *bctx)
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
void GWB_File_WriteFileNameToTopBuildDirString(const GWB_FILE *file, const char *initialSourceDir, GWEN_BUFFER *fbuf)
Definition: file.c:473
struct GWB_BUILD_CMD GWB_BUILD_CMD
Definition: buildcmd.h:20
GWEN_STRINGLIST * _fileListToTopBuildDirStringList(const char *initialSourceDir, GWB_FILE_LIST2 *fileList)
Definition: buildctx_run.c:287
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
GWENHYWFAR_API GWEN_PROCESS_STATE GWEN_Process_Start(GWEN_PROCESS *pr, const char *prg, const char *args)
static void _setupCommands(GWB_BUILD_CONTEXT *bctx, int forPrepareCommands)
Definition: buildctx_run.c:195
#define GWEN_ERROR_TIMEOUT
Definition: error.h:71
static int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:321
GWEN_STRINGLIST * GWB_File_FileListToTopBuildDirStringList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir)
Definition: file.c:494
static void _createCommandQueues(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:221
uint32_t GWB_BuildCmd_GetFlags(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:120
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
int GWB_BuildCmd_GetBlockingFiles(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:224
int GWB_BuildCtx_Run(GWB_BUILD_CONTEXT *bctx, int maxConcurrentJobs, int usePrepareCommands, const char *builderName)
Definition: buildctx_run.c:59
static void _unlinkFilesInStringList(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:456
GWENHYWFAR_API void GWEN_Process_SetFolder(GWEN_PROCESS *pr, const char *s)
static void _signalJobFinished(GWB_BUILD_CMD *bcmd)
Definition: buildctx_run.c:688
void GWB_BuildCmd_SetCurrentCommand(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *cmd)
Definition: buildcmd.c:313