14 #define DISABLE_DEBUGLOG 17 #include "gwenbuild/buildctx/buildctx_p.h" 21 #include <gwenhywfar/debug.h> 22 #include <gwenhywfar/text.h> 23 #include <gwenhywfar/directory.h> 74 if (GWB_BuildCmd_List2_GetSize(bctx->waitingQueue)==0) {
75 fprintf(stdout,
"Nothing to do.\n");
79 waitingJobs=GWB_BuildCmd_List2_GetSize(bctx->waitingQueue);
80 runningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
81 while(waitingJobs+runningJobs) {
86 if (startedCommands<0) {
92 if (changedCommands<0) {
97 if (startedCommands==0 && changedCommands==0) {
99 DBG_ERROR(
NULL,
"ERROR: No running jobs and none could be started, maybe circular dependencies?");
107 waitingJobs=GWB_BuildCmd_List2_GetSize(bctx->waitingQueue);
108 runningJobs=GWB_BuildCmd_List2_GetSize(bctx->runningQueue);
111 GWB_BuildCmd_List2_free(bctx->waitingQueue);
112 GWB_BuildCmd_List2_free(bctx->runningQueue);
113 GWB_BuildCmd_List2_free(bctx->finishedQueue);
123 GWB_BuildCmd_List2_free(bctx->waitingQueue);
126 GWB_BuildCmd_List2_free(bctx->runningQueue);
129 GWB_BuildCmd_List2_free(bctx->finishedQueue);
138 while( (bcmd=GWB_BuildCmd_List2_GetFront(cmdList)) ) {
139 GWB_BuildCmd_List2_PopFront(cmdList);
149 GWB_BUILD_CMD_LIST2_ITERATOR *it;
151 it=GWB_BuildCmd_List2_First(bctx->commandList);
155 bcmd=GWB_BuildCmd_List2Iterator_Data(it);
157 GWB_BUILD_SUBCMD_LIST *cmdList;
159 if (forPrepareCommands)
165 bcmd=GWB_BuildCmd_List2Iterator_Next(it);
167 GWB_BuildCmd_List2Iterator_free(it);
175 bctx->waitingQueue=GWB_BuildCmd_List2_new();
176 bctx->finishedQueue=GWB_BuildCmd_List2_new();
177 bctx->runningQueue=GWB_BuildCmd_List2_new();
184 GWB_BUILD_CMD_LIST2 *oldQueue;
189 oldQueue=bctx->waitingQueue;
190 bctx->waitingQueue=GWB_BuildCmd_List2_new();
192 while( (bcmd=GWB_BuildCmd_List2_GetFront(oldQueue)) ) {
194 GWB_BuildCmd_List2_PopFront(oldQueue);
195 if (started<maxStartAllowed) {
202 bctx->initialSourceDir);
204 bctx->initialSourceDir);
209 GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
213 GWB_BuildCmd_List2_PushBack(bctx->runningQueue, bcmd);
225 GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
228 GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
230 GWB_BuildCmd_List2_free(oldQueue);
241 GWB_FILE_LIST2_ITERATOR *it;
243 it=GWB_File_List2_First(fileList);
251 file=GWB_File_List2Iterator_Data(it);
256 file=GWB_File_List2Iterator_Next(it);
259 GWB_File_List2Iterator_free(it);
278 if (currentCommand) {
280 uint32_t subCmdFlags;
288 DBG_INFO(
NULL,
"Input files newer than output files, rebuild needed");
301 DBG_INFO(
NULL,
"Dependencies flag NO rebuild needed (%d)", rv);
304 DBG_INFO(
NULL,
"Dependencies flag rebuild needed (%d)", rv);
318 time_t tiHighestInFileTime;
319 time_t tiLowestOutFileTime;
323 if (tiHighestInFileTime==0 || tiLowestOutFileTime==0) {
324 DBG_INFO(
NULL,
"Either input or output time not available");
327 if (tiHighestInFileTime>tiLowestOutFileTime)
353 else if (tiFile<tiLowest)
390 else if (tiFile>tiHighest)
433 const char *depFileName;
436 if (depFileName && firstOutFileName) {
450 DBG_DEBUG(
NULL,
"Could not load depend file \"%s\"", depFileName);
454 if (depFileName==
NULL) {
455 DBG_DEBUG(
NULL,
"No depFileName for %s", firstOutFileName?firstOutFileName:
"<no outfile name>");
457 if (firstOutFileName==
NULL) {
474 DBG_DEBUG(
NULL,
"%s: No modification time, need rebuild", fileName);
489 DBG_DEBUG(
NULL,
"No modification time for dependency \"%s\", need rebuild", s);
492 if (difftime(tFile, tCurrent)<0.0) {
493 DBG_DEBUG(
NULL,
"File \"%s\" is newer than \"%s\", rebuild needed", s, fileName);
501 DBG_DEBUG(
NULL,
"No dependency is newer than file \"%s\", NO rebuild needed", fileName);
518 if (currentCommand) {
530 const char *buildMessage;
532 if (GWB_BuildSubCmd_List_Previous(currentCommand)==
NULL) {
541 fprintf(stdout,
"%s [%s]\n", buildMessage, cmd);
543 fprintf(stdout,
"%s %s\n", cmd, args);
546 if (folder && *folder)
551 DBG_ERROR(
NULL,
"Error starting command process (%d)", pstate);
573 GWB_BUILD_CMD_LIST2 *oldRunningQueue;
578 oldRunningQueue=bctx->runningQueue;
579 bctx->runningQueue=GWB_BuildCmd_List2_new();
581 while( (bcmd=GWB_BuildCmd_List2_GetFront(oldRunningQueue)) ) {
586 GWB_BuildCmd_List2_PopFront(oldRunningQueue);
598 GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
606 GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
612 GWB_BuildCmd_List2_PushBack(bctx->runningQueue, bcmd);
615 GWB_BuildCmd_List2_free(oldRunningQueue);
628 nextCommand=GWB_BuildSubCmd_List_Next(currentCommand);
631 GWB_BuildCmd_List2_PushBack(bctx->waitingQueue, bcmd);
634 GWB_BuildCmd_List2_PushBack(bctx->finishedQueue, bcmd);
642 GWB_FILE_LIST2 *outFileList;
646 GWB_FILE_LIST2_ITERATOR *it;
648 it=GWB_File_List2_First(outFileList);
652 file=GWB_File_List2Iterator_Data(it);
654 GWB_BUILD_CMD_LIST2 *waitingCommands;
659 file=GWB_File_List2Iterator_Next(it);
661 GWB_File_List2Iterator_free(it);
671 GWB_BUILD_CMD_LIST2_ITERATOR *it;
673 it=GWB_BuildCmd_List2_First(waitingCommands);
677 bcmd=GWB_BuildCmd_List2Iterator_Data(it);
680 bcmd=GWB_BuildCmd_List2Iterator_Next(it);
683 GWB_BuildCmd_List2Iterator_free(it);
735 if (slDependencies) {
737 return slDependencies;
775 extPtr=strrchr(s,
'/');
794 while(*sTmp && !isspace(*sTmp))
const char * GWB_BuildSubCmd_GetCommand(const GWB_BUILD_SUBCMD *cmd)
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
static time_t _getHighestModificationTime(const GWEN_STRINGLIST *slFiles)
GWB_FILE_LIST2 * GWB_BuildCmd_GetInFileList2(const GWB_BUILD_CMD *bcmd)
static int _checkDependencies(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *subCmd, const char *firstOutFileName)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
GWENHYWFAR_API int GWEN_Directory_GetAbsoluteFolderPath(const char *folder, GWEN_BUFFER *tbuf)
struct GWEN_STRINGLISTENTRYSTRUCT GWEN_STRINGLISTENTRY
#define GWEN_TEXT_FLAGS_DEL_TRAILING_BLANKS
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetPrepareCommandList(const GWB_BUILD_CMD *bcmd)
#define GWEN_DIR_SEPARATOR_S
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
const char * GWB_BuildSubCmd_GetDepFilePath(const GWB_BUILD_SUBCMD *cmd)
void GWB_BuildCmd_SetCurrentProcess(GWB_BUILD_CMD *bcmd, GWEN_PROCESS *process)
#define GWB_BUILD_SUBCMD_FLAGS_CHECK_DEPENDS
struct GWB_BUILD_CONTEXT GWB_BUILD_CONTEXT
static int _checkWaitingQueue(GWB_BUILD_CONTEXT *bctx, int maxStartAllowed)
int GWEN_SyncIo_Helper_ReadFile(const char *fName, GWEN_BUFFER *dbuf)
static void _finishCurrentCommand(GWB_BUILD_CONTEXT *bctx, GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *currentCommand)
static int _checkRunningQueue(GWB_BUILD_CONTEXT *bctx)
int GWB_BuildCtx_FillWaitingQueue(GWB_BUILD_CONTEXT *bctx, const char *builderName)
const char * GWB_BuildCmd_GetFolder(const GWB_BUILD_CMD *bcmd)
#define GWB_BUILD_CMD_FLAGS_CHECK_DATES
GWB_BUILD_CMD_LIST2 * GWB_File_GetWaitingBuildCmdList2(const GWB_FILE *f)
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
static GWEN_STRINGLIST * _getAbsoluteDeps(const char *folder, const char *fileName)
GWEN_STRINGLISTENTRY * GWEN_StringList_FirstEntry(const GWEN_STRINGLIST *sl)
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
const char * GWEN_StringListEntry_Data(const GWEN_STRINGLISTENTRY *se)
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
const char * GWB_BuildSubCmd_GetArguments(const GWB_BUILD_SUBCMD *cmd)
static int _inFilesNewerThanOutFiles(const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
GWENHYWFAR_API GWEN_PROCESS_STATE GWEN_Process_CheckState(GWEN_PROCESS *pr)
GWEN_PROCESS * GWB_BuildCmd_GetCurrentProcess(const GWB_BUILD_CMD *bcmd)
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
#define DBG_DEBUG(dbg_logger, format, args...)
int GWB_BuildCmd_DecBlockingFiles(GWB_BUILD_CMD *bcmd)
#define GWB_BUILD_CMD_FLAGS_DEL_OUTFILES
GWB_FILE_LIST2 * GWB_BuildCmd_GetOutFileList2(const GWB_BUILD_CMD *bcmd)
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
static void _abortCommandsInQueue(GWB_BUILD_CMD_LIST2 *cmdList)
#define GWEN_ERROR_GENERIC
static GWEN_STRINGLIST * _makeAbsolutePaths(GWEN_STRINGLIST *slInput, const char *folder)
#define GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS
const char * GWB_BuildSubCmd_GetBuildMessage(const GWB_BUILD_SUBCMD *cmd)
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
#define GWB_BUILD_SUBCMD_FLAGS_IGNORE_RESULT
GWENHYWFAR_API int GWEN_Process_GetResult(GWEN_PROCESS *pr)
GWB_BUILD_SUBCMD_LIST * GWB_BuildCmd_GetBuildCommandList(const GWB_BUILD_CMD *bcmd)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
struct GWB_BUILD_SUBCMD GWB_BUILD_SUBCMD
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
static int _checkDatesOfFileAgainstList(const char *fileName, const GWEN_STRINGLIST *sl)
static time_t _getLowestModificationTime(const GWEN_STRINGLIST *slFiles)
static int _startCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slOutFiles)
unsigned int GWEN_StringList_Count(const GWEN_STRINGLIST *sl)
#define DBG_ERROR(dbg_logger, format, args...)
static void _abortAllCommands(GWB_BUILD_CONTEXT *bctx)
GWENHYWFAR_API GWEN_PROCESS * GWEN_Process_new(void)
static GWEN_STRINGLIST * _readDepFile(const char *fileName)
const char * GWEN_StringList_FirstString(const GWEN_STRINGLIST *l)
struct GWEN_PROCESS GWEN_PROCESS
static void _decBlockingFilesInWaitingBuildCommands(GWB_BUILD_CMD_LIST2 *waitingCommands)
GWB_BUILD_SUBCMD * GWB_BuildCmd_GetCurrentCommand(const GWB_BUILD_CMD *bcmd)
uint32_t GWB_BuildSubCmd_GetFlags(const GWB_BUILD_SUBCMD *cmd)
time_t GWBUILD_GetModificationTimeOfFile(const char *filename)
int GWB_BuildCtx_SetupDependencies(GWB_BUILD_CONTEXT *bctx)
GWEN_STRINGLISTENTRY * GWEN_StringListEntry_Next(const GWEN_STRINGLISTENTRY *se)
void GWB_File_WriteFileNameToTopBuildDirString(const GWB_FILE *file, const char *initialSourceDir, GWEN_BUFFER *fbuf)
struct GWB_BUILD_CMD GWB_BUILD_CMD
GWEN_STRINGLIST * _fileListToTopBuildDirStringList(const char *initialSourceDir, GWB_FILE_LIST2 *fileList)
#define DBG_INFO(dbg_logger, format, args...)
#define GWEN_TEXT_FLAGS_DEL_QUOTES
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)
#define GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
static int _needRunCurrentCommand(GWB_BUILD_CMD *bcmd, const GWEN_STRINGLIST *slInFiles, const GWEN_STRINGLIST *slOutFiles)
GWEN_STRINGLIST * GWB_File_FileListToTopBuildDirStringList(const GWB_FILE_LIST2 *fileList, const char *initialSourceDir)
static void _createCommandQueues(GWB_BUILD_CONTEXT *bctx)
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
uint32_t GWB_BuildCmd_GetFlags(const GWB_BUILD_CMD *bcmd)
GWEN_STRINGLIST * GWEN_StringList_new(void)
int GWB_BuildCmd_GetBlockingFiles(const GWB_BUILD_CMD *bcmd)
int GWB_BuildCtx_Run(GWB_BUILD_CONTEXT *bctx, int maxConcurrentJobs, int usePrepareCommands, const char *builderName)
static void _unlinkFilesInStringList(const GWEN_STRINGLIST *slFiles)
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
GWENHYWFAR_API void GWEN_Process_SetFolder(GWEN_PROCESS *pr, const char *s)
static void _signalJobFinished(GWB_BUILD_CMD *bcmd)
void GWB_BuildCmd_SetCurrentCommand(GWB_BUILD_CMD *bcmd, GWB_BUILD_SUBCMD *cmd)