5 Commits

Author SHA1 Message Date
anth64 aefd962baf chore: bump version to 0.1.3 2026-02-25 22:45:58 +01:00
anth64 983f9b7393 feat(module.c): add optional module metadata support
- Add tight-packed arrays with index mappings for name, version, and description
- Resolve optional metadata symbols at load time via platform_get_symbol
- Add setter functions for metadata symbol name overrides
2026-02-25 22:31:22 +01:00
anth64 13067902a8 feat: add buffer constants and setters for optional module metadata 2026-02-25 21:37:05 +01:00
anth64 345cd35f19 chore: bump version to 0.1.2 2026-02-15 23:05:18 +01:00
anth64 c2b9571c2d fix(platform,core,test): fix Windows compatibility issues
- platform_mkdir now checks if directory exists before creating
- Add FILE_ATTRIBUTE_HIDDEN for dot-prefixed directories on Windows
- Create parent mods directory before temp directory
- Move module unload before copy in reload sequence to fix issue on Windows
- Force CMD shell in test makefile on Windows

Test makefile now uses cmd.exe instead of bash on Windows, fixing
syntax errors when running via build.bat.
2026-02-15 22:53:12 +01:00
8 changed files with 413 additions and 15 deletions
+28 -3
View File
@@ -7,7 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.1.1] - 2026-02-15
## [0.1.3] - 2026-02-25
### Added
- **Module Metadata**: Optional metadata support for modules
- `stk_mod_name` - human-readable module name
- `stk_mod_version` - semantic version string
- `stk_mod_description` - module description
- All three are optional, missing symbols are not errors
- Metadata stored in tight-packed arrays with index mappings
- Setter functions to override default symbol names before `stk_init()`
## [0.1.2] - 2026-02-15
### Fixed
- **Windows**
- Module reload now works correctly, idk how it was broken
- Temp directory creation fixed
- `.tmp` directory now hidden via FILE_ATTRIBUTE_HIDDEN
- Test build fixed
- Force cmd.exe shell in gmake.mk
- Fix bash syntax errors when running build.bat
- **All Platforms**: platform_mkdir now checks if directory exists before creating
## [0.1.1] - 2026-02-14
### Fixed
- **Logging**: Corrected log level severity order in enum
@@ -15,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixes filtering logic where ERROR/WARN were incorrectly blocked
- Default INFO level now properly shows INFO, WARN, and ERROR while filtering DEBUG
## [0.1.0] - 2026-02-15
## [0.1.0] - 2026-02-14
### Fixed
- **C89 Compliance**: Removed stdint.h dependency (C99 feature)
@@ -92,7 +115,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dependency management and versioning not yet implemented
- API is unstable and subject to change in future releases
[Unreleased]: https://github.com/anth64/stk/compare/v0.1.1...HEAD
[Unreleased]: https://github.com/anth64/stk/compare/v0.1.2...HEAD
[0.1.2]: https://github.com/anth64/stk/releases/tag/v0.1.2
[0.1.1]: https://github.com/anth64/stk/releases/tag/v0.1.1
[0.1.1]: https://github.com/anth64/stk/releases/tag/v0.1.1
[0.1.0]: https://github.com/anth64/stk/releases/tag/v0.1.0
[0.0.4]: https://github.com/anth64/stk/releases/tag/v0.0.4
+11 -2
View File
@@ -146,6 +146,15 @@ stk_set_module_init_fn("my_init");
/* Set custom shutdown function name (default: "stk_mod_shutdown") */
stk_set_module_shutdown_fn("my_shutdown");
/* Set function name to get module name */
stk_set_module_name_fn("my_mod_name");
/* Set function name to get module version */
stk_set_module_version_fn("my_mod_version");
/* Set functio name to get module description */
stk_set_module_description_fn("my_mod_description");
/*
* All the above functions must be called before stk_init()
* if the defaults need to be changed.
@@ -182,9 +191,9 @@ stk_init();
## Project Status
**Current Version:** 0.1.1 (Pre-release)
**Current Version:** 0.1.2 (Pre-release)
This release brings C89 compliance fixes and a complete logging system rewrite with levels, timestamps, and runtime configuration.
Fixed Windows compatibility issues.
### What Works
- Cross-platform module loading and hot-reloading
+6
View File
@@ -6,8 +6,11 @@
/* Buffers */
#define STK_LOG_PREFIX_BUFFER 64
#define STK_MOD_DESC_BUFFER 256
#define STK_MOD_DIR_BUFFER 256
#define STK_MOD_ID_BUFFER 64
#define STK_MOD_NAME_BUFFER 128
#define STK_MOD_VERSION_BUFFER 32
#define STK_PATH_MAX 256
#define STK_PATH_MAX_OS 4096
@@ -68,6 +71,9 @@ void stk_set_tmp_dir_name(const char *name);
void stk_set_module_init_fn(const char *name);
void stk_set_module_shutdown_fn(const char *name);
void stk_set_logging_enabled(unsigned char enabled);
void stk_set_module_name_fn(const char *name);
void stk_set_module_version_fn(const char *name);
void stk_set_module_description_fn(const char *name);
unsigned char stk_is_logging_enabled(void);
#ifdef __cplusplus
+1 -1
View File
@@ -3,7 +3,7 @@
#define STK_VERSION_MAJOR 0
#define STK_VERSION_MINOR 1
#define STK_VERSION_PATCH 1
#define STK_VERSION_PATCH 3
#define STK_STRINGIFY_HELPER(x) #x
#define STK_STRINGIFY(x) STK_STRINGIFY_HELPER(x)
+338 -4
View File
@@ -17,11 +17,26 @@ void **stk_handles = NULL;
stk_init_mod_func *stk_inits = NULL;
stk_shutdown_mod_func *stk_shutdowns = NULL;
char (*stk_meta_names)[STK_MOD_NAME_BUFFER] = NULL;
size_t *stk_meta_name_indices = NULL;
size_t stk_meta_name_count = 0;
char (*stk_meta_versions)[STK_MOD_VERSION_BUFFER] = NULL;
size_t *stk_meta_version_indices = NULL;
size_t stk_meta_version_count = 0;
char (*stk_meta_descs)[STK_MOD_DESC_BUFFER] = NULL;
size_t *stk_meta_desc_indices = NULL;
size_t stk_meta_desc_count = 0;
extern unsigned char stk_flags;
static char stk_mod_init_name[STK_MOD_FUNC_NAME_BUFFER] = "stk_mod_init";
static char stk_mod_shutdown_name[STK_MOD_FUNC_NAME_BUFFER] =
"stk_mod_shutdown";
static char stk_mod_name_fn[STK_MOD_NAME_BUFFER] = "stk_mod_name";
static char stk_mod_version_fn[STK_MOD_VERSION_BUFFER] = "stk_mod_version";
static char stk_mod_description_fn[STK_MOD_DESC_BUFFER] = "stk_mod_description";
size_t module_count = 0;
@@ -81,8 +96,17 @@ unsigned char stk_module_load(const char *path, int index)
void *obj;
stk_init_mod_func init_func;
stk_shutdown_mod_func shutdown_func;
const char *(*meta_func)(void);
} u;
size_t len;
const char *meta_str;
char (*new_meta_names)[STK_MOD_NAME_BUFFER] = NULL;
size_t *new_meta_name_indices = NULL;
char (*new_meta_versions)[STK_MOD_VERSION_BUFFER] = NULL;
size_t *new_meta_version_indices = NULL;
char (*new_meta_descs)[STK_MOD_DESC_BUFFER] = NULL;
size_t *new_meta_desc_indices = NULL;
handle = platform_load_library(path);
if (!handle)
@@ -117,6 +141,79 @@ unsigned char stk_module_load(const char *path, int index)
stk_inits[index] = init_func;
stk_shutdowns[index] = shutdown_func;
u.obj = platform_get_symbol(handle, stk_mod_name_fn);
if (!u.obj)
goto skip_name;
meta_str = u.meta_func();
if (!meta_str)
goto skip_name;
new_meta_names = realloc(stk_meta_names, (stk_meta_name_count + 1) *
sizeof(*stk_meta_names));
new_meta_name_indices = realloc(
stk_meta_name_indices, (stk_meta_name_count + 1) * sizeof(size_t));
if (!new_meta_names || !new_meta_name_indices)
goto skip_name;
stk_meta_names = new_meta_names;
stk_meta_name_indices = new_meta_name_indices;
strncpy(stk_meta_names[stk_meta_name_count], meta_str,
STK_MOD_NAME_BUFFER - 1);
stk_meta_names[stk_meta_name_count][STK_MOD_NAME_BUFFER - 1] = '\0';
stk_meta_name_indices[stk_meta_name_count] = (size_t)index;
stk_meta_name_count++;
skip_name:
u.obj = platform_get_symbol(handle, stk_mod_version_fn);
if (!u.obj)
goto skip_version;
meta_str = u.meta_func();
if (!meta_str)
goto skip_version;
new_meta_versions =
realloc(stk_meta_versions,
(stk_meta_version_count + 1) * sizeof(*stk_meta_versions));
new_meta_version_indices =
realloc(stk_meta_version_indices,
(stk_meta_version_count + 1) * sizeof(size_t));
if (!new_meta_versions || !new_meta_version_indices)
goto skip_version;
stk_meta_versions = new_meta_versions;
stk_meta_version_indices = new_meta_version_indices;
strncpy(stk_meta_versions[stk_meta_version_count], meta_str,
STK_MOD_VERSION_BUFFER - 1);
stk_meta_versions[stk_meta_version_count][STK_MOD_VERSION_BUFFER - 1] =
'\0';
stk_meta_version_indices[stk_meta_version_count] = (size_t)index;
stk_meta_version_count++;
skip_version:
u.obj = platform_get_symbol(handle, stk_mod_description_fn);
if (!u.obj)
goto skip_description;
meta_str = u.meta_func();
if (!meta_str)
goto skip_description;
new_meta_descs = realloc(stk_meta_descs, (stk_meta_desc_count + 1) *
sizeof(*stk_meta_descs));
new_meta_desc_indices = realloc(
stk_meta_desc_indices, (stk_meta_desc_count + 1) * sizeof(size_t));
if (!new_meta_descs || !new_meta_desc_indices)
goto skip_description;
stk_meta_descs = new_meta_descs;
stk_meta_desc_indices = new_meta_desc_indices;
strncpy(stk_meta_descs[stk_meta_desc_count], meta_str,
STK_MOD_DESC_BUFFER - 1);
stk_meta_descs[stk_meta_desc_count][STK_MOD_DESC_BUFFER - 1] = '\0';
stk_meta_desc_indices[stk_meta_desc_count] = (size_t)index;
stk_meta_desc_count++;
skip_description:
return STK_MOD_INIT_SUCCESS;
}
@@ -133,12 +230,112 @@ unsigned char stk_module_load_init(const char *path, int index)
void stk_module_unload(size_t index)
{
size_t i;
char (*new_meta_names)[STK_MOD_NAME_BUFFER] = NULL;
size_t *new_meta_name_indices = NULL;
char (*new_meta_versions)[STK_MOD_VERSION_BUFFER] = NULL;
size_t *new_meta_version_indices = NULL;
char (*new_meta_descs)[STK_MOD_DESC_BUFFER] = NULL;
size_t *new_meta_desc_indices = NULL;
size_t new_count;
stk_shutdowns[index]();
platform_unload_library(stk_handles[index]);
stk_handles[index] = NULL;
stk_inits[index] = NULL;
stk_shutdowns[index] = NULL;
stk_module_ids[index][0] = '\0';
new_count = 0;
for (i = 0; i < stk_meta_name_count; i++)
if (stk_meta_name_indices[i] != index)
new_count++;
if (new_count == 0)
goto clear_names;
new_meta_names = malloc(new_count * sizeof(*new_meta_names));
new_meta_name_indices = malloc(new_count * sizeof(size_t));
if (!new_meta_names || !new_meta_name_indices)
goto clear_names;
new_count = 0;
for (i = 0; i < stk_meta_name_count; i++) {
if (stk_meta_name_indices[i] == index)
continue;
memcpy(new_meta_names[new_count], stk_meta_names[i],
STK_MOD_NAME_BUFFER);
new_meta_name_indices[new_count] = stk_meta_name_indices[i];
new_count++;
}
clear_names:
free(stk_meta_names);
free(stk_meta_name_indices);
stk_meta_names = new_meta_names;
stk_meta_name_indices = new_meta_name_indices;
stk_meta_name_count = new_count;
new_count = 0;
for (i = 0; i < stk_meta_version_count; i++)
if (stk_meta_version_indices[i] != index)
new_count++;
if (new_count == 0)
goto clear_versions;
new_meta_versions = malloc(new_count * sizeof(*new_meta_versions));
new_meta_version_indices = malloc(new_count * sizeof(size_t));
if (!new_meta_versions || !new_meta_version_indices)
goto clear_versions;
new_count = 0;
for (i = 0; i < stk_meta_version_count; i++) {
if (stk_meta_version_indices[i] == index)
continue;
memcpy(new_meta_versions[new_count], stk_meta_versions[i],
STK_MOD_VERSION_BUFFER);
new_meta_version_indices[new_count] =
stk_meta_version_indices[i];
new_count++;
}
clear_versions:
free(stk_meta_versions);
free(stk_meta_version_indices);
stk_meta_versions = new_meta_versions;
stk_meta_version_indices = new_meta_version_indices;
stk_meta_version_count = new_count;
new_count = 0;
for (i = 0; i < stk_meta_desc_count; i++)
if (stk_meta_desc_indices[i] != index)
new_count++;
if (new_count == 0)
goto clear_descs;
new_meta_descs = malloc(new_count * sizeof(*new_meta_descs));
new_meta_desc_indices = malloc(new_count * sizeof(size_t));
if (!new_meta_descs || !new_meta_desc_indices)
goto clear_descs;
new_count = 0;
for (i = 0; i < stk_meta_desc_count; i++) {
if (stk_meta_desc_indices[i] == index)
continue;
memcpy(new_meta_descs[new_count], stk_meta_descs[i],
STK_MOD_DESC_BUFFER);
new_meta_desc_indices[new_count] = stk_meta_desc_indices[i];
new_count++;
}
clear_descs:
free(stk_meta_descs);
free(stk_meta_desc_indices);
stk_meta_descs = new_meta_descs;
stk_meta_desc_indices = new_meta_desc_indices;
stk_meta_desc_count = new_count;
}
void stk_module_free_memory(void)
@@ -152,6 +349,23 @@ void stk_module_free_memory(void)
stk_handles = NULL;
stk_inits = NULL;
stk_shutdowns = NULL;
free(stk_meta_names);
free(stk_meta_name_indices);
free(stk_meta_versions);
free(stk_meta_version_indices);
free(stk_meta_descs);
free(stk_meta_desc_indices);
stk_meta_names = NULL;
stk_meta_name_indices = NULL;
stk_meta_name_count = 0;
stk_meta_versions = NULL;
stk_meta_version_indices = NULL;
stk_meta_version_count = 0;
stk_meta_descs = NULL;
stk_meta_desc_indices = NULL;
stk_meta_desc_count = 0;
}
unsigned char stk_module_init_memory(size_t capacity)
@@ -166,6 +380,16 @@ unsigned char stk_module_init_memory(size_t capacity)
return STK_INIT_MEMORY_ERROR;
}
stk_meta_names = NULL;
stk_meta_name_indices = NULL;
stk_meta_name_count = 0;
stk_meta_versions = NULL;
stk_meta_version_indices = NULL;
stk_meta_version_count = 0;
stk_meta_descs = NULL;
stk_meta_desc_indices = NULL;
stk_meta_desc_count = 0;
return STK_INIT_SUCCESS;
}
@@ -175,6 +399,12 @@ unsigned char stk_module_realloc_memory(size_t new_capacity)
void **new_handles = NULL;
stk_init_mod_func *new_inits = NULL;
stk_shutdown_mod_func *new_shutdowns = NULL;
char (*new_meta_names)[STK_MOD_NAME_BUFFER] = NULL;
size_t *new_meta_name_indices = NULL;
char (*new_meta_versions)[STK_MOD_VERSION_BUFFER] = NULL;
size_t *new_meta_version_indices = NULL;
char (*new_meta_descs)[STK_MOD_DESC_BUFFER] = NULL;
size_t *new_meta_desc_indices = NULL;
size_t i, copy_count;
if (new_capacity == 0) {
@@ -190,16 +420,12 @@ unsigned char stk_module_realloc_memory(size_t new_capacity)
if (!new_module_ids || !new_handles || !new_inits || !new_shutdowns) {
if (new_module_ids)
free(new_module_ids);
if (new_handles)
free(new_handles);
if (new_inits)
free(new_inits);
if (new_shutdowns)
free(new_shutdowns);
return STK_MOD_REALLOC_FAILURE;
}
@@ -232,6 +458,80 @@ unsigned char stk_module_realloc_memory(size_t new_capacity)
new_shutdowns[i] = NULL;
}
if (stk_meta_name_count == 0)
goto skip_meta_names;
new_meta_names = malloc(stk_meta_name_count * sizeof(*stk_meta_names));
new_meta_name_indices = malloc(stk_meta_name_count * sizeof(size_t));
if (!new_meta_names || !new_meta_name_indices) {
if (new_meta_names)
free(new_meta_names);
if (new_meta_name_indices)
free(new_meta_name_indices);
new_meta_names = NULL;
new_meta_name_indices = NULL;
goto skip_meta_names;
}
for (i = 0; i < stk_meta_name_count; i++) {
strncpy(new_meta_names[i], stk_meta_names[i],
STK_MOD_NAME_BUFFER - 1);
new_meta_names[i][STK_MOD_NAME_BUFFER - 1] = '\0';
new_meta_name_indices[i] = stk_meta_name_indices[i];
}
skip_meta_names:
if (stk_meta_version_count == 0)
goto skip_meta_versions;
new_meta_versions =
malloc(stk_meta_version_count * sizeof(*stk_meta_versions));
new_meta_version_indices =
malloc(stk_meta_version_count * sizeof(size_t));
if (!new_meta_versions || !new_meta_version_indices) {
if (new_meta_versions)
free(new_meta_versions);
if (new_meta_version_indices)
free(new_meta_version_indices);
new_meta_versions = NULL;
new_meta_version_indices = NULL;
goto skip_meta_versions;
}
for (i = 0; i < stk_meta_version_count; i++) {
strncpy(new_meta_versions[i], stk_meta_versions[i],
STK_MOD_VERSION_BUFFER - 1);
new_meta_versions[i][STK_MOD_VERSION_BUFFER - 1] = '\0';
new_meta_version_indices[i] = stk_meta_version_indices[i];
}
skip_meta_versions:
if (stk_meta_desc_count == 0)
goto skip_meta_descs;
new_meta_descs = malloc(stk_meta_desc_count * sizeof(*stk_meta_descs));
new_meta_desc_indices = malloc(stk_meta_desc_count * sizeof(size_t));
if (!new_meta_descs || !new_meta_desc_indices) {
if (new_meta_descs)
free(new_meta_descs);
if (new_meta_desc_indices)
free(new_meta_desc_indices);
new_meta_descs = NULL;
new_meta_desc_indices = NULL;
goto skip_meta_descs;
}
for (i = 0; i < stk_meta_desc_count; i++) {
strncpy(new_meta_descs[i], stk_meta_descs[i],
STK_MOD_DESC_BUFFER - 1);
new_meta_descs[i][STK_MOD_DESC_BUFFER - 1] = '\0';
new_meta_desc_indices[i] = stk_meta_desc_indices[i];
}
skip_meta_descs:
stk_module_free_memory();
stk_module_ids = new_module_ids;
@@ -239,6 +539,13 @@ unsigned char stk_module_realloc_memory(size_t new_capacity)
stk_inits = new_inits;
stk_shutdowns = new_shutdowns;
stk_meta_names = new_meta_names;
stk_meta_name_indices = new_meta_name_indices;
stk_meta_versions = new_meta_versions;
stk_meta_version_indices = new_meta_version_indices;
stk_meta_descs = new_meta_descs;
stk_meta_desc_indices = new_meta_desc_indices;
return 0;
}
@@ -268,3 +575,30 @@ void stk_set_module_shutdown_fn(const char *name)
strncpy(stk_mod_shutdown_name, name, STK_MOD_FUNC_NAME_BUFFER - 1);
stk_mod_shutdown_name[STK_MOD_FUNC_NAME_BUFFER - 1] = '\0';
}
void stk_set_module_name_fn(const char *name)
{
if (!name || (stk_flags & STK_FLAG_INITIALIZED))
return;
strncpy(stk_mod_name_fn, name, STK_MOD_NAME_BUFFER - 1);
stk_mod_name_fn[STK_MOD_NAME_BUFFER - 1] = '\0';
}
void stk_set_module_version_fn(const char *name)
{
if (!name || (stk_flags & STK_FLAG_INITIALIZED))
return;
strncpy(stk_mod_version_fn, name, STK_MOD_VERSION_BUFFER - 1);
stk_mod_version_fn[STK_MOD_VERSION_BUFFER - 1] = '\0';
}
void stk_set_module_description_fn(const char *name)
{
if (!name || (stk_flags & STK_FLAG_INITIALIZED))
return;
strncpy(stk_mod_description_fn, name, STK_MOD_DESC_BUFFER - 1);
stk_mod_description_fn[STK_MOD_DESC_BUFFER - 1] = '\0';
}
+22 -2
View File
@@ -107,9 +107,29 @@ typedef struct {
unsigned char platform_mkdir(const char *path)
{
#ifdef _WIN32
return CreateDirectoryA(path, NULL) ? STK_PLATFORM_OPERATION_SUCCESS
: STK_PLATFORM_MKDIR_ERROR;
DWORD attrib;
attrib = GetFileAttributesA(path);
if (attrib != INVALID_FILE_ATTRIBUTES &&
(attrib & FILE_ATTRIBUTE_DIRECTORY))
return STK_PLATFORM_OPERATION_SUCCESS;
if (!CreateDirectoryA(path, NULL))
return STK_PLATFORM_MKDIR_ERROR;
if (strrchr(path, '\\') && *(strrchr(path, '\\') + 1) == '.')
SetFileAttributesA(path, FILE_ATTRIBUTE_HIDDEN);
else if (!strrchr(path, '\\') && path[0] == '.')
SetFileAttributesA(path, FILE_ATTRIBUTE_HIDDEN);
return STK_PLATFORM_OPERATION_SUCCESS;
#else
struct stat st;
if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
return STK_PLATFORM_OPERATION_SUCCESS;
return mkdir(path, 0755) == 0 ? STK_PLATFORM_OPERATION_SUCCESS
: STK_PLATFORM_MKDIR_ERROR;
#endif
+5 -3
View File
@@ -19,7 +19,7 @@ unsigned char stk_flags = STK_FLAG_LOGGING_ENABLED;
static char stk_mod_dir[STK_PATH_MAX_OS] = "mods";
static char stk_tmp_name[STK_MOD_ID_BUFFER] = ".tmp";
static char stk_tmp_dir[STK_PATH_MAX_OS] = "mods/.tmp";
static char stk_tmp_dir[STK_PATH_MAX_OS] = "";
static void *watch_handle = NULL;
char (*platform_directory_init_scan(const char *path,
@@ -77,6 +77,8 @@ unsigned char stk_init(void)
char tmp_path[STK_PATH_MAX_OS];
int load_result;
platform_mkdir(stk_mod_dir);
build_path(stk_tmp_dir, sizeof(stk_tmp_dir), stk_mod_dir, stk_tmp_name);
if (platform_mkdir(stk_tmp_dir) != STK_PLATFORM_OPERATION_SUCCESS) {
char (*test_scan)[STK_PATH_MAX];
size_t test_count;
@@ -263,6 +265,8 @@ begin_operations:
build_path(tmp_path, sizeof(tmp_path), stk_tmp_dir,
file_list[file_index]);
stk_module_unload(mod_index);
if (platform_copy_file(full_path, tmp_path) !=
STK_PLATFORM_OPERATION_SUCCESS) {
stk_log(STK_LOG_ERROR, "Failed to copy %s for reload",
@@ -270,8 +274,6 @@ begin_operations:
continue;
}
stk_module_unload(mod_index);
load_result = stk_module_load(tmp_path, mod_index);
if (load_result != STK_MOD_INIT_SUCCESS) {
stk_log(STK_LOG_ERROR, "Failed to reload module %s: %s",
+2
View File
@@ -3,6 +3,8 @@ CFLAGS = -Wall -Wpedantic -I../include -std=c89
LDFLAGS = -L../bin/debug -lstk
ifeq ($(OS),Windows_NT)
SHELL := cmd.exe
.SHELLFLAGS := /c
MODULE_EXT = .dll
EXE_EXT = .exe
else