commit 5070d51ad6da1f5dd32897c557db3c0b664e4937 Author: Hunter Stasonis Date: Sat Mar 29 09:29:45 2025 -0400 init kettle work from local diff --git a/kettle b/kettle new file mode 100755 index 0000000..22f7444 Binary files /dev/null and b/kettle differ diff --git a/kettle.c b/kettle.c new file mode 100644 index 0000000..868b43c --- /dev/null +++ b/kettle.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include + +/** + * Kettle - Build system for HLSL and GLSL shaders + * Copyright (c) 2025 Hunter Stasonis + * Licensed under the MIT license + */ + +/// Type of file +typedef enum { e_kettle_file_hlsl, e_kettle_file_glsl } kettle_file; + +typedef enum { e_kettle_compiler_dxc, e_kettle_compiler_glslc } kettle_compiler; + +/** + * File information + */ +typedef struct { + const char *pFileName; + kettle_file eFileType; +} kettle_file_info_t; + +typedef struct { + kettle_compiler eCompilerType; + + const char *pCompilerPath; +} kettle_compiler_t; + +typedef struct { + int numFiles; + kettle_file_info_t *pFiles; + + int numIncludeDirs; + + /// List of directories to -I in this batch + char **pIncludeDirs; + + /// Directory that all files are located in + const char *pWorkingDir; +} kettle_compiler_batch_t; + +typedef struct { + int numCompilerBatches; + + /// Compiler batch list + kettle_compiler_batch_t *pCompilerBatches; + + /// Current compiler batch + kettle_compiler_batch_t *pCurrentCompilerBatch; + + /// List of compilers + int numCompilers; + kettle_compiler_t *pCompilers; +} kettle_input_t; + +typedef struct { +} kettle_reg_t; + +typedef struct { + int numArgs; + char **pArgs; +} kettle_arg_list_t; + +void kettle_help() { + printf("Kettle Build System\n"); + printf("Description: Compiles kettle information files and prints the result " + "to stderr\n"); + printf("Author: Hunter Stasonis \n"); + printf("Options: \n"); + printf("\t infile : Input kettle description file\n"); + printf("No arguments provided! Exiting\n"); +} + +/** + * Remove leading spaces from a string + * @param pInput Pointer to a string to trim + * @return Newly allocated string with spaces removed from the start + */ +char *kettle_trim(const char *pInput) { + int startIndex = 0; + int size = strlen(pInput) + 1; + + // Find starting index: Loop over characters until we get a non-space + for (int i = 0; i < size; i++) { + if (pInput[i] != ' ') { + startIndex = i; + break; + } + } + + // Copy the rest of the string into the new allocated buffer + + int newSize = size - startIndex; + + char *newStr = (char *)malloc(newSize * sizeof(char)); + strncpy(newStr, pInput + startIndex, newSize); + + return newStr; +} + +char *kettle_pop_index(const char *pInput, int index) { + int size = strlen(pInput); + int newSize = size - 1; + + char *newStr = (char *)malloc(newSize * sizeof(char)); + memmove(&newStr[index], &pInput[index + 1], strlen(pInput) - index); + + return newStr; +} + +kettle_arg_list_t kettle_make_arg_list(const char *pInput) { + int size = strlen(pInput); + + char *pCopyInput = (char *)malloc(size * sizeof(char)); + memcpy(pCopyInput, pInput, size * sizeof(char)); + + char **args = NULL; + int cArgSize = 0; + int cArgIndex = 0; + + char *tok = strtok(pCopyInput, " "); + while (tok != NULL) { + cArgSize++; + + args = (char **)realloc(args, (cArgSize + 1) * sizeof(char *)); + args[cArgIndex] = tok; + + cArgIndex++; + + tok = strtok(NULL, " "); + } + + kettle_arg_list_t argList; + argList.numArgs = cArgSize; + argList.pArgs = args; + + return argList; +} + +kettle_compiler_t *kettle_input_get_compiler(const kettle_input_t *pInput, + kettle_compiler eCompilerType) { + for (int i = 0; i < pInput->numCompilers; i++) { + if (pInput->pCompilers[i].eCompilerType == eCompilerType) + return &pInput->pCompilers[i]; + } + + return NULL; +} + +void kettle_handle_cmd(kettle_arg_list_t argList, kettle_input_t *pInput) { + const char *pCmd = argList.pArgs[0]; + + if (strcmp(pCmd, "AddVariant") == 0 && argList.numArgs == 2) { + printf("> Adding variant with define: %s\n", argList.pArgs[1]); + } else if (strcmp(pCmd, "AddCompiler") == 0 && argList.numArgs == 3) { + printf("> Adding compiler with type '%s' with path '%s'\n", + argList.pArgs[1], argList.pArgs[2]); + + kettle_compiler_t compiler; + compiler.pCompilerPath = argList.pArgs[2]; + + if (strcmp(argList.pArgs[1], "dxc") == 0) { + compiler.eCompilerType = e_kettle_compiler_dxc; + } else if (strcmp(argList.pArgs[1], "glslc") == 0) { + compiler.eCompilerType = e_kettle_compiler_glslc; + } else { + printf("> Invalid compiler identifier for AddCompiler call. Expected " + "'glslc', or 'dxc'\n"); + exit(EXIT_FAILURE); + } + + // Grow compiler array + + pInput->numCompilers++; + pInput->pCompilers = (kettle_compiler_t *)realloc( + pInput->pCompilers, sizeof(kettle_compiler_t) * (pInput->numCompilers)); + + pInput->pCompilers[pInput->numCompilers - 1] = compiler; + + } else if (strcmp(pCmd, "CompilerBatch") == 0 && argList.numArgs == 3) { + printf("> Starting compiler batch with type '%s' with workingDir of '%s'\n", + argList.pArgs[1], argList.pArgs[2]); + + kettle_compiler_batch_t batch; + memset(&batch, 0, sizeof(batch)); + + batch.pWorkingDir = argList.pArgs[2]; + + // Grow compiler batch array + pInput->numCompilerBatches++; + + pInput->pCompilerBatches = (kettle_compiler_batch_t *)realloc( + pInput->pCompilerBatches, + sizeof(kettle_compiler_batch_t) * pInput->numCompilerBatches); + + pInput->pCompilerBatches[pInput->numCompilerBatches - 1] = batch; + + // Activate this compiler batch + pInput->pCurrentCompilerBatch = + &pInput->pCompilerBatches[pInput->numCompilerBatches - 1]; + + } else if (strcmp(pCmd, "EndCompilerBatch") == 0) { + printf("> Ending active compiler batch\n"); + + if (pInput->pCurrentCompilerBatch == NULL) { + printf("> Error: Cannot end compiler batch when no batch is active!\n"); + exit(EXIT_FAILURE); + } + + // Deactivate current compiler batch + pInput->pCurrentCompilerBatch = NULL; + } else if (strcmp(pCmd, "Include") == 0 && argList.numArgs == 2) { + if (pInput->pCurrentCompilerBatch == NULL) { + printf("> Error: No active compiler batch for 'Include' command!\n"); + exit(EXIT_FAILURE); + } + + // The new include dir may not exist, this will be checked during actual + // shader build time. + + // Insert new include dir into the list + + pInput->pCurrentCompilerBatch->numIncludeDirs++; + + pInput->pCurrentCompilerBatch->pIncludeDirs = (char **)realloc( + pInput->pCurrentCompilerBatch->pIncludeDirs, + sizeof(char *) * pInput->pCurrentCompilerBatch->numIncludeDirs); + + pInput->pCurrentCompilerBatch + ->pIncludeDirs[pInput->pCurrentCompilerBatch->numIncludeDirs - 1] = + argList.pArgs[1]; + } else if (strcmp(pCmd, "AddShader") == 0 && argList.numArgs == 2) { + if (pInput->pCurrentCompilerBatch == NULL) { + printf("> Error: Cannot add shader when no compiler batch is active!\n"); + exit(EXIT_FAILURE); + } + } else { + printf("> Warning: Cannot process unknown compiler command '%s'\n", pCmd); + } +} + +kettle_input_t kettle_read_input(const char *pInput) { + FILE *fInput = fopen(pInput, "r"); + + kettle_input_t input; + memset(&input, 0, sizeof(input)); + + // Read file line, by line + char lineTmp[256]; + + while (fgets(lineTmp, sizeof(lineTmp), fInput)) { + char *line = kettle_trim(lineTmp); + int lineLength = strlen(line); + line[strcspn(line, "\n")] = 0; + + lineLength = strlen(line); + + if (lineLength == 0) + continue; + + if (lineLength >= 2) { + if (line[0] == '/' && line[1] == '/') { + continue; + } else if (line[0] == '$') { + const char *pCmd = kettle_pop_index(line, 0); + const kettle_arg_list_t argList = kettle_make_arg_list(pCmd); + + kettle_handle_cmd(argList, &input); + } else { + printf("Error: Line '%s' is neither a comment, or a compiler " + "instruction!\n", + line); + + exit(EXIT_FAILURE); + } + } + } + + fclose(fInput); + + return input; +} + +int main(int argc, char **argv) { + if (argc <= 1) { + kettle_help(); + exit(EXIT_FAILURE); + } + + const char *inFile = argv[1]; + + printf("> Will process input file: %s\n", inFile); + + kettle_read_input(inFile); +} diff --git a/kettle.in b/kettle.in new file mode 100644 index 0000000..7c2eaef --- /dev/null +++ b/kettle.in @@ -0,0 +1,16 @@ +$AddVariant SHADOW_MAPPER_ENABLED + +// Compiler Setup +// Format: TYPE, FILEPATH +$AddCompiler dxc /home/hunterstasonis/.local/share/IBAtechSoftware/Fusion/SDK/DirectXShaderCompiler/bin/dxc + +// Compile a batch of Vertex shaders +$CompilerBatch Vertex /home/hunterstasonis/git/Fusion/shaders + + // Include shared stuff + $Include Shared + + // Add a shader, the extension will be automatically detected + $AddShader VertexShaders/HDR.hlsl + +$EndCompilerBatch