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
33static void _setupCommands(GWB_BUILD_CONTEXT *bctx, int forPrepareCommands);
35static int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed);
36static int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles);
38static void _signalJobFinished(GWB_BUILD_CMD *bcmd);
39static void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands);
41static void _abortAllCommands(GWB_BUILD_CONTEXT *bctx);
42static void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList);
43
44static int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles);
45static void _finishCurrentCommand(GWB_BUILD_CONTEXT *bctx, GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *currentCommand);
46
47static int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName);
48static int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl);
49
50static int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles);
51static time_t _getHighestModificationTime(const GWEN_STRINGLIST *slFiles);
52static time_t _getLowestModificationTime(const GWEN_STRINGLIST *slFiles);
53static void _unlinkFilesInStringList(const GWEN_STRINGLIST *slFiles);
54
55
56
57
58
59int 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) {
89 return GWEN_ERROR_GENERIC;
90 }
91
92 changedCommands=_checkRunningQueue(bctx);
93 if (changedCommands<0) { /* error */
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?");
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
182void _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
195void _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
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
230int _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
287GWEN_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
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
321int _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 */
364int _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 */
479int _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
515int _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
561int _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
717void _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
#define NULL
Definition: binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
GWB_FILE_LIST2 * GWB_BuildCmd_GetOutFileList2(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:270
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetPrepareCommandList(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:196
void GWB_BuildCmd_SetCurrentProcess(GWB_BUILD_CMD *bcmd, GWEN_PROCESS *process)
Definition: buildcmd.c:292
void GWB_BuildCmd_SetCurrentCommand(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *cmd)
Definition: buildcmd.c:313
uint32_t GWB_BuildCmd_GetFlags(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:120
GWB_FILE_LIST2 * GWB_BuildCmd_GetInFileList2(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:255
int GWB_BuildCmd_DecBlockingFiles(GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:245
GWB_BUILD_SUBCMD * GWB_BuildCmd_GetCurrentCommand(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:306
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetBuildCommandList(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:210
const char * GWB_BuildCmd_GetFolder(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:166
int GWB_BuildCmd_GetBlockingFiles(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:224
GWEN_PROCESS * GWB_BuildCmd_GetCurrentProcess(const GWB_BUILD_CMD *bcmd)
Definition: buildcmd.c:285
struct GWB_BUILD_CMD GWB_BUILD_CMD
Definition: buildcmd.h:20
#define GWB_BUILD_CMD_FLAGS_CHECK_DATES
Definition: buildcmd.h:25
#define GWB_BUILD_CMD_FLAGS_DEL_OUTFILES
Definition: buildcmd.h:26
struct GWB_BUILD_CONTEXT GWB_BUILD_CONTEXT
Definition: buildctx.h:16
int GWB_BuildCtx_FillWaitingQueue(GWB_BUILD_CONTEXT *bctx, const char *builderName)
int GWB_BuildCtx_SetupDependencies(GWB_BUILD_CONTEXT *bctx)
GWEN_STRINGLIST * GWB_BuildCtx_ReadAndTranslateDepfile(const char *folder, const char *fileName)
static int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed)
Definition: buildctx_run.c:230
static void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList)
Definition: buildctx_run.c:182
static void _signalJobFinished(GWB_BUILD_CMD *bcmd)
Definition: buildctx_run.c:688
static int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:321
static void _finishCurrentCommand(GWB_BUILD_CONTEXT *bctx, GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *currentCommand)
Definition: buildctx_run.c:672
int GWB_BuildCtx_Run(GWB_BUILD_CONTEXT *bctx, int maxConcurrentJobs, int usePrepareCommands, const char *builderName)
Definition: buildctx_run.c:59
static void _createCommandQueues(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:221
static time_t _getLowestModificationTime(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:382
static time_t _getHighestModificationTime(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:419
static void _unlinkFilesInStringList(const GWEN_STRINGLIST *slFiles)
Definition: buildctx_run.c:456
static void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands)
Definition: buildctx_run.c:717
static int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:364
static int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl)
Definition: buildctx_run.c:515
static int _checkRunningQueue(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:619
static void _abortAllCommands(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:165
static int _waitForRunningJobs(GWB_BUILD_CONTEXT *bctx)
Definition: buildctx_run.c:126
static int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles)
Definition: buildctx_run.c:561
GWEN_STRINGLIST * _fileListToTopBuildDirStringList(const char *initialSourceDir, GWB_FILE_LIST2 *fileList)
Definition: buildctx_run.c:287
static int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName)
Definition: buildctx_run.c:479
static void _setupCommands(GWB_BUILD_CONTEXT *bctx, int forPrepareCommands)
Definition: buildctx_run.c:195
#define GWB_BUILDCTX_PROCESS_WAIT_TIMEOUT
Definition: buildctx_run.c:30
uint32_t GWB_BuildSubCmd_GetFlags(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:72
const char * GWB_BuildSubCmd_GetArguments(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:115
const char * GWB_BuildSubCmd_GetDepFilePath(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:145
const char * GWB_BuildSubCmd_GetCommand(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:100
const char * GWB_BuildSubCmd_GetBuildMessage(const GWB_BUILD_SUBCMD *cmd)
Definition: buildsubcmd.c:130
#define GWB_BUILD_SUBCMD_FLAGS_CHECK_DEPENDS
Definition: buildsubcmd.h:24
struct GWB_BUILD_SUBCMD GWB_BUILD_SUBCMD
Definition: buildsubcmd.h:16
#define GWB_BUILD_SUBCMD_FLAGS_IGNORE_RESULT
Definition: buildsubcmd.h:23
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_TIMEOUT
Definition: error.h:71
#define GWEN_ERROR_GENERIC
Definition: error.h:62
void GWB_File_WriteFileNameToTopBuildDirString(const GWB_FILE *file, const char *initialSourceDir, GWEN_BUFFER *fbuf)
Definition: file.c:473
GWEN_STRINGLIST * GWB_File_FileListToTopBuildDirStringList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir)
Definition: file.c:494
GWB_BUILD_CMD_LIST2 * GWB_File_GetWaitingBuildCmdList2(const GWB_FILE *f)
Definition: file.c:246
struct GWB_FILE GWB_FILE
Definition: file.h:18
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
time_t GWBUILD_GetModificationTimeOfFile(const char *filename)
Definition: gwenbuild.c:885
GWENHYWFAR_API int GWEN_Process_GetResult(GWEN_PROCESS *pr)
GWENHYWFAR_API void GWEN_Process_SetFolder(GWEN_PROCESS *pr, const char *s)
GWENHYWFAR_API GWEN_PROCESS * GWEN_Process_new(void)
GWENHYWFAR_API GWEN_PROCESS_STATE GWEN_Process_Start(GWEN_PROCESS *pr, const char *prg, const char *args)
GWENHYWFAR_API GWEN_PROCESS_STATE GWEN_Process_CheckState(GWEN_PROCESS *pr)
struct GWEN_PROCESS GWEN_PROCESS
Definition: process.h:49
GWEN_PROCESS_STATE
Definition: process.h:54
@ GWEN_ProcessStateRunning
Definition: process.h:58
@ GWEN_ProcessStateExited
Definition: process.h:60
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:406
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
Definition: stringlist.c:398
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:427
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
const char * GWEN_StringList_FirstString(const GWEN_STRINGLIST *l)
Definition: stringlist.c:576
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
Definition: stringlist.c:390
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
Definition: stringlist.h:53
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56