init kettle work from local
This commit is contained in:
commit
5070d51ad6
298
kettle.c
Normal file
298
kettle.c
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 <webmaster @ interfiber.dev>\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);
|
||||||
|
}
|
16
kettle.in
Normal file
16
kettle.in
Normal file
|
@ -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
|
Loading…
Reference in a new issue