adding hash library + multi windows support being started

This commit is contained in:
Patedam committed 2026-10-24 17:05:55 -04:00
1 parent f96b2e99cf
commit 7e8e626e24
17 files changed
+384 -137

No files matched your search

+154 -74
View File
@@ -251,7 +251,7 @@ static void get_normalized_cwd(char* out_cwd, size_t out_cwd_size, char* out_rea
static int32 get_layer_order_from_main(char layers[32][64])
{
int32 count = 0;
FILE* file = fopen("Juliet/appbin/appbin_main.c", "rb");
FILE* file = fopen("Juliet/julietapp/julietapp_main.c", "rb");
if (file != NULL)
{
char line[512];
@@ -324,7 +324,7 @@ static int32 get_layer_order_from_main(char layers[32][64])
count++;
}
// Discover any other directories in Juliet/ that have <dir>_inc.h but weren't in appbin_main.c yet
// Discover any other directories in Juliet/ that have <dir>_inc.h but weren't in julietapp_main.c yet
WIN32_FIND_DATAA find_data;
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
if (find_handle != INVALID_HANDLE_VALUE)
@@ -339,7 +339,14 @@ static int32 get_layer_order_from_main(char layers[32][64])
{
if (_stricmp(find_data.cFileName, "src") == 0 ||
_stricmp(find_data.cFileName, "include") == 0 ||
_stricmp(find_data.cFileName, "appbin") == 0)
_stricmp(find_data.cFileName, "external") == 0 ||
_stricmp(find_data.cFileName, "win32") == 0)
{
continue;
}
char inc_check_path[512];
snprintf(inc_check_path, sizeof(inc_check_path), "Juliet\\%s\\%s_inc.h", find_data.cFileName, find_data.cFileName);
if (GetFileAttributesA(inc_check_path) == INVALID_FILE_ATTRIBUTES)
{
continue;
}
@@ -369,25 +376,20 @@ static int32 find_layer_index_for_file(const char* file_path, char layers[32][64
{
Assert(file_path != NULL);
if (strstr(file_path, "win32/core") != NULL || strstr(file_path, "win32\\core") != NULL)
{
for (int32 i = 0; i < layer_count; ++i)
{
if (_stricmp(layers[i], "core") == 0)
{
return i;
}
}
}
for (int32 i = 0; i < layer_count; ++i)
{
char prefix1[128];
char prefix2[128];
char win32_prefix1[128];
char win32_prefix2[128];
snprintf(prefix1, sizeof(prefix1), "Juliet/%s/", layers[i]);
snprintf(prefix2, sizeof(prefix2), "Juliet\\%s\\", layers[i]);
snprintf(win32_prefix1, sizeof(win32_prefix1), "Juliet/win32/%s/", layers[i]);
snprintf(win32_prefix2, sizeof(win32_prefix2), "Juliet\\win32\\%s\\", layers[i]);
if (_strnicmp(file_path, prefix1, strlen(prefix1)) == 0 ||
_strnicmp(file_path, prefix2, strlen(prefix2)) == 0)
_strnicmp(file_path, prefix2, strlen(prefix2)) == 0 ||
_strnicmp(file_path, win32_prefix1, strlen(win32_prefix1)) == 0 ||
_strnicmp(file_path, win32_prefix2, strlen(win32_prefix2)) == 0)
{
return i;
}
@@ -396,6 +398,73 @@ static int32 find_layer_index_for_file(const char* file_path, char layers[32][64
return -1;
}
static bool file_directly_includes_target(const char* header_disk_path, const char* header_layer_name, const char* target_file_path)
{
Assert(header_disk_path != NULL);
Assert(header_layer_name != NULL);
Assert(target_file_path != NULL);
FILE* file = fopen(header_disk_path, "rb");
if (file == NULL)
{
return false;
}
bool found = false;
char line[512];
while (fgets(line, sizeof(line), file) != NULL)
{
char* hash = strchr(line, '#');
if (hash == NULL)
{
continue;
}
char* inc_pos = strstr(hash, "include");
if (inc_pos == NULL)
{
continue;
}
char* quote_start = strchr(inc_pos, '"');
if (quote_start == NULL)
{
continue;
}
quote_start++;
char* quote_end = strchr(quote_start, '"');
if (quote_end == NULL)
{
continue;
}
size_t inc_file_len = (size_t)(quote_end - quote_start);
if (inc_file_len == 0 || inc_file_len >= 256)
{
continue;
}
char inc_file[256];
memcpy(inc_file, quote_start, inc_file_len);
inc_file[inc_file_len] = '\0';
normalize_path_slashes_forward(inc_file);
char candidate_layer[512];
snprintf(candidate_layer, sizeof(candidate_layer), "Juliet/%s/%s", header_layer_name, inc_file);
normalize_path_slashes_forward(candidate_layer);
char candidate_root[512];
snprintf(candidate_root, sizeof(candidate_root), "Juliet/%s", inc_file);
normalize_path_slashes_forward(candidate_root);
if (_stricmp(candidate_layer, target_file_path) == 0 ||
_stricmp(candidate_root, target_file_path) == 0)
{
found = true;
break;
}
}
fclose(file);
return found;
}
static void get_preceding_includes_from_inc_h(const char* layer_name, const char* target_file_path, char* out_flags, size_t out_flags_size)
{
Assert(layer_name != NULL);
@@ -448,35 +517,33 @@ static void get_preceding_includes_from_inc_h(const char* layer_name, const char
inc_file[inc_file_len] = '\0';
normalize_path_slashes_forward(inc_file);
char candidate_in_layer[512];
snprintf(candidate_in_layer, sizeof(candidate_in_layer), "Juliet/%s/%s", layer_name, inc_file);
normalize_path_slashes_forward(candidate_in_layer);
char full_inc_path[512];
if (strstr(inc_file, "/") != NULL)
char fi_rel_path[512];
if (GetFileAttributesA(candidate_in_layer) != INVALID_FILE_ATTRIBUTES)
{
snprintf(full_inc_path, sizeof(full_inc_path), "Juliet/%s", inc_file);
strncpy_s(full_inc_path, sizeof(full_inc_path), candidate_in_layer, _TRUNCATE);
snprintf(fi_rel_path, sizeof(fi_rel_path), "%s/%s", layer_name, inc_file);
}
else
{
snprintf(full_inc_path, sizeof(full_inc_path), "Juliet/%s/%s", layer_name, inc_file);
snprintf(full_inc_path, sizeof(full_inc_path), "Juliet/%s", inc_file);
strncpy_s(fi_rel_path, sizeof(fi_rel_path), inc_file, _TRUNCATE);
}
normalize_path_slashes_forward(full_inc_path);
char expected_suffix[256];
snprintf(expected_suffix, sizeof(expected_suffix), "/%s", inc_file);
normalize_path_slashes_forward(fi_rel_path);
if (_stricmp(full_inc_path, target_file_path) == 0 ||
str_ends_with_no_case(target_file_path, expected_suffix))
file_directly_includes_target(full_inc_path, layer_name, target_file_path))
{
break;
}
char flag[512];
if (strstr(inc_file, "/") != NULL)
{
snprintf(flag, sizeof(flag), " \"/FI%s\",\n", inc_file);
}
else
{
snprintf(flag, sizeof(flag), " \"/FI%s/%s\",\n", layer_name, inc_file);
}
snprintf(flag, sizeof(flag), " \"/FI%s\",\n", fi_rel_path);
strncat_s(out_flags, out_flags_size, flag, _TRUNCATE);
}
@@ -501,7 +568,7 @@ static void generate_compile_commands(void)
char layers[32][64];
int32 layer_count = get_layer_order_from_main(layers);
// 1. Scan new Juliet modules (core, render, ui, appbin, etc.)
// 1. Scan new Juliet modules (core, window_manager, render, julietapp, etc.)
WIN32_FIND_DATAA find_data;
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
if (find_handle != INVALID_HANDLE_VALUE)
@@ -515,7 +582,9 @@ static void generate_compile_commands(void)
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (_stricmp(find_data.cFileName, "src") == 0 || _stricmp(find_data.cFileName, "include") == 0)
if (_stricmp(find_data.cFileName, "src") == 0 ||
_stricmp(find_data.cFileName, "include") == 0 ||
_stricmp(find_data.cFileName, "external") == 0)
{
continue;
}
@@ -531,11 +600,12 @@ static void generate_compile_commands(void)
char forced_inc_flags[1024] = "";
int32 file_layer_idx = find_layer_index_for_file(node->path, layers, layer_count);
if (file_layer_idx >= 0 && _stricmp(layers[file_layer_idx], "appbin") != 0)
if (file_layer_idx >= 0 && !str_ends_with_no_case(node->path, "_main.c"))
{
for (int32 i = 0; i <= file_layer_idx; ++i)
if (is_c_source_file(node->path))
{
if (i < file_layer_idx)
// In the unity build, all layer _inc.h headers are included before any _inc.c file
for (int32 i = 0; i < layer_count; ++i)
{
char inc_disk_path[512];
snprintf(inc_disk_path, sizeof(inc_disk_path), "Juliet\\%s\\%s_inc.h", layers[i], layers[i]);
@@ -546,9 +616,12 @@ static void generate_compile_commands(void)
strncat_s(forced_inc_flags, sizeof(forced_inc_flags), flag, _TRUNCATE);
}
}
else
}
else
{
for (int32 i = 0; i <= file_layer_idx; ++i)
{
if (is_c_source_file(node->path))
if (i < file_layer_idx)
{
char inc_disk_path[512];
snprintf(inc_disk_path, sizeof(inc_disk_path), "Juliet\\%s\\%s_inc.h", layers[i], layers[i]);
@@ -595,7 +668,12 @@ static void generate_compile_commands(void)
" \"/nologo\",\n"
" \"/clang:-std=c11\",\n"
" \"/W4\",\n"
" \"/Wno-unused-function\",\n"
" \"-Wno-unused-function\",\n"
" \"-Wno-unused-parameter\",\n"
" \"-Wno-unused-variable\",\n"
" \"-Wno-missing-braces\",\n"
" \"-Wno-missing-field-initializers\",\n"
" \"-Wno-cast-function-type-mismatch\",\n"
" \"/clang:-Wno-initializer-overrides\",\n"
" \"/utf-8\",\n"
" \"/DBUILD_DEBUG=1\",\n"
@@ -718,11 +796,11 @@ static void generate_vs_files(void)
CreateDirectoryA("vs", NULL);
// Discover modules in Juliet/
ProjectInfo appbin_project = {0};
strncpy_s(appbin_project.name, sizeof(appbin_project.name), "appbin", _TRUNCATE);
generate_deterministic_guid(appbin_project.name, appbin_project.guid, sizeof(appbin_project.guid));
ProjectInfo julietapp_project = {0};
strncpy_s(julietapp_project.name, sizeof(julietapp_project.name), "julietapp", _TRUNCATE);
generate_deterministic_guid(julietapp_project.name, julietapp_project.guid, sizeof(julietapp_project.guid));
// Gather all new module files for appbin project
// Gather all new module files for julietapp project
WIN32_FIND_DATAA find_data;
HANDLE find_handle = FindFirstFileA("Juliet\\*", &find_data);
if (find_handle != INVALID_HANDLE_VALUE)
@@ -736,7 +814,9 @@ static void generate_vs_files(void)
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (_stricmp(find_data.cFileName, "src") == 0 || _stricmp(find_data.cFileName, "include") == 0)
if (_stricmp(find_data.cFileName, "src") == 0 ||
_stricmp(find_data.cFileName, "include") == 0 ||
_stricmp(find_data.cFileName, "external") == 0)
{
continue;
}
@@ -751,11 +831,11 @@ static void generate_vs_files(void)
{
if (is_c_source_file(node->path))
{
file_list_push(&appbin_project.c_files, node->path);
file_list_push(&julietapp_project.c_files, node->path);
}
else if (is_c_header_file(node->path))
{
file_list_push(&appbin_project.h_files, node->path);
file_list_push(&julietapp_project.h_files, node->path);
}
}
@@ -766,7 +846,7 @@ static void generate_vs_files(void)
FindClose(find_handle);
}
// 1. Generate vs/appbin.vcxproj
// 1. Generate vs/julietapp.vcxproj
size_t buf_cap = 2 * 1024 * 1024;
char* vcxproj_buf = (char*)malloc(buf_cap);
Assert(vcxproj_buf != NULL);
@@ -788,7 +868,7 @@ static void generate_vs_files(void)
" <PropertyGroup Label=\"Globals\">\n"
" <ProjectGuid>{%s}</ProjectGuid>\n"
" <Keyword>MakeFileProj</Keyword>\n"
" <ProjectName>appbin</ProjectName>\n"
" <ProjectName>julietapp</ProjectName>\n"
" </PropertyGroup>\n"
" <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n"
" <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n"
@@ -804,25 +884,25 @@ static void generate_vs_files(void)
" <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n"
" <ImportGroup Label=\"ExtensionSettings\" />\n"
" <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n"
" <NMakeBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat appbin debug</NMakeBuildCommandLine>\n"
" <NMakeReBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean &amp; new_build.bat appbin debug</NMakeReBuildCommandLine>\n"
" <NMakeBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat julietapp debug</NMakeBuildCommandLine>\n"
" <NMakeReBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean &amp; new_build.bat julietapp debug</NMakeReBuildCommandLine>\n"
" <NMakeCleanCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean</NMakeCleanCommandLine>\n"
" <NMakeOutput>$(SolutionDir)..\\build\\appbin.exe</NMakeOutput>\n"
" <NMakeOutput>$(SolutionDir)..\\build\\julietapp.exe</NMakeOutput>\n"
" <NMakeIncludeSearchPath>$(SolutionDir)..\\Juliet;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>\n"
" <NMakePreprocessorDefinitions>BUILD_DEBUG=1;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>\n"
" </PropertyGroup>\n"
" <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n"
" <NMakeBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat appbin release</NMakeBuildCommandLine>\n"
" <NMakeReBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean &amp; new_build.bat appbin release</NMakeReBuildCommandLine>\n"
" <NMakeBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat julietapp release</NMakeBuildCommandLine>\n"
" <NMakeReBuildCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean &amp; new_build.bat julietapp release</NMakeReBuildCommandLine>\n"
" <NMakeCleanCommandLine>cd $(SolutionDir)..\\ &amp; new_build.bat clean</NMakeCleanCommandLine>\n"
" <NMakeOutput>$(SolutionDir)..\\build\\appbin.exe</NMakeOutput>\n"
" <NMakeOutput>$(SolutionDir)..\\build\\julietapp.exe</NMakeOutput>\n"
" <NMakeIncludeSearchPath>$(SolutionDir)..\\Juliet;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>\n"
" <NMakePreprocessorDefinitions>BUILD_DEBUG=0;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>\n"
" </PropertyGroup>\n"
" <ItemGroup>\n",
appbin_project.guid);
julietapp_project.guid);
for (FileNode* node = appbin_project.c_files.first; node != NULL; node = node->next)
for (FileNode* node = julietapp_project.c_files.first; node != NULL; node = node->next)
{
char backslash_path[512];
strncpy_s(backslash_path, sizeof(backslash_path), node->path, _TRUNCATE);
@@ -832,7 +912,7 @@ static void generate_vs_files(void)
}
offset += snprintf(vcxproj_buf + offset, buf_cap - offset, " </ItemGroup>\n <ItemGroup>\n");
for (FileNode* node = appbin_project.h_files.first; node != NULL; node = node->next)
for (FileNode* node = julietapp_project.h_files.first; node != NULL; node = node->next)
{
char backslash_path[512];
strncpy_s(backslash_path, sizeof(backslash_path), node->path, _TRUNCATE);
@@ -855,11 +935,11 @@ static void generate_vs_files(void)
" <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n"
"</Project>\n");
write_entire_file("vs\\appbin.vcxproj", vcxproj_buf, offset);
printf("[SUCCESS] Generated vs\\appbin.vcxproj\n");
write_entire_file("vs\\julietapp.vcxproj", vcxproj_buf, offset);
printf("[SUCCESS] Generated vs\\julietapp.vcxproj\n");
free(vcxproj_buf);
// 2. Generate vs/appbin.vcxproj.filters
// 2. Generate vs/julietapp.vcxproj.filters
char* filters_buf = (char*)malloc(buf_cap);
Assert(filters_buf != NULL);
@@ -869,17 +949,17 @@ static void generate_vs_files(void)
"<Project ToolsVersion=\"17.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"
" <ItemGroup>\n"
" <Filter Include=\"core\" />\n"
" <Filter Include=\"appbin\" />\n"
" <Filter Include=\"julietapp\" />\n"
" </ItemGroup>\n"
" <ItemGroup>\n");
for (FileNode* node = appbin_project.c_files.first; node != NULL; node = node->next)
for (FileNode* node = julietapp_project.c_files.first; node != NULL; node = node->next)
{
char backslash_path[512];
strncpy_s(backslash_path, sizeof(backslash_path), node->path, _TRUNCATE);
normalize_path_slashes_backward(backslash_path);
const char* filter = strstr(node->path, "core/") ? "core" : "appbin";
const char* filter = strstr(node->path, "core/") ? "core" : "julietapp";
f_offset += snprintf(filters_buf + f_offset, buf_cap - f_offset,
" <ClCompile Include=\"..\\%s\">\n"
" <Filter>%s</Filter>\n"
@@ -887,13 +967,13 @@ static void generate_vs_files(void)
}
f_offset += snprintf(filters_buf + f_offset, buf_cap - f_offset, " </ItemGroup>\n <ItemGroup>\n");
for (FileNode* node = appbin_project.h_files.first; node != NULL; node = node->next)
for (FileNode* node = julietapp_project.h_files.first; node != NULL; node = node->next)
{
char backslash_path[512];
strncpy_s(backslash_path, sizeof(backslash_path), node->path, _TRUNCATE);
normalize_path_slashes_backward(backslash_path);
const char* filter = strstr(node->path, "core/") ? "core" : "appbin";
const char* filter = strstr(node->path, "core/") ? "core" : "julietapp";
f_offset += snprintf(filters_buf + f_offset, buf_cap - f_offset,
" <ClInclude Include=\"..\\%s\">\n"
" <Filter>%s</Filter>\n"
@@ -919,8 +999,8 @@ static void generate_vs_files(void)
f_offset += snprintf(filters_buf + f_offset, buf_cap - f_offset, "</Project>\n");
write_entire_file("vs\\appbin.vcxproj.filters", filters_buf, f_offset);
printf("[SUCCESS] Generated vs\\appbin.vcxproj.filters\n");
write_entire_file("vs\\julietapp.vcxproj.filters", filters_buf, f_offset);
printf("[SUCCESS] Generated vs\\julietapp.vcxproj.filters\n");
free(filters_buf);
// 3. Generate vs/new_Juliet.sln
@@ -930,7 +1010,7 @@ static void generate_vs_files(void)
"# Visual Studio Version 17\n"
"VisualStudioVersion = 17.0.31903.59\n"
"MinimumVisualStudioVersion = 10.0.40219.1\n"
"Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"appbin\", \"appbin.vcxproj\", \"{%s}\"\n"
"Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"julietapp\", \"julietapp.vcxproj\", \"{%s}\"\n"
"EndProject\n"
"Global\n"
" GlobalSection(SolutionConfigurationPlatforms) = preSolution\n"
@@ -947,17 +1027,17 @@ static void generate_vs_files(void)
" HideSolutionNode = FALSE\n"
" EndGlobalSection\n"
"EndGlobal\n",
appbin_project.guid,
appbin_project.guid,
appbin_project.guid,
appbin_project.guid,
appbin_project.guid);
julietapp_project.guid,
julietapp_project.guid,
julietapp_project.guid,
julietapp_project.guid,
julietapp_project.guid);
write_entire_file("vs\\new_Juliet.sln", sln_buf, s_offset);
printf("[SUCCESS] Generated vs\\new_Juliet.sln\n");
file_list_free(&appbin_project.c_files);
file_list_free(&appbin_project.h_files);
file_list_free(&julietapp_project.c_files);
file_list_free(&julietapp_project.h_files);
}
int main(int argc, char** argv)