Support of clangd for the project

This commit is contained in:
Patedam committed 2026-10-05 23:37:18 -04:00
1 parent 7075556bf2
commit 16ba641d8a
6 files changed
+613 -126

No files matched your search

+572 -124
View File
@@ -1551,163 +1551,608 @@ static void GenerateDeterministicGuid(const char* input, char* outputGuid) {
hash2 & 0xFFFFFFFFFFFFULL);
}
static int CommandGenVS(int argc, char* argv[])
static void clean_include_path(const char* in_path, char* out_path, size_t out_size)
{
if (argc < 3) {
printf("[ERROR] Usage: build_system gen_vs <plan_file>\n");
return 1;
}
const char* planFile = argv[2];
FileContent planContent = ReadEntireFile(planFile);
if (!planContent.Data) {
printf("[ERROR] Could not read VS plan: %s\n", planFile);
return 1;
}
char globalInclude[1024] = {0};
char globalDefCommon[1024] = {0};
char globalDefDebug[1024] = {0};
char globalDefProfile[1024] = {0};
char globalDefRelease[1024] = {0};
VSProject projects[16];
int projCount = 0;
VSSolution solutions[8];
int slnCount = 0;
assert(in_path != NULL);
assert(out_path != NULL);
assert(out_size > 0);
const char* pos = planContent.Data;
while (*pos) {
const char* lineStart = pos;
while (*pos && *pos != '\n' && *pos != '\r') pos++;
int lineLen = (int)(pos - lineStart);
if (lineLen > 0) {
if (lineLen > 15 && memcmp(lineStart, "GLOBAL_INCLUDE ", 15) == 0) {
int nLen = lineLen - 15;
if (nLen >= 1024) nLen = 1023;
memcpy(globalInclude, lineStart + 15, nLen);
globalInclude[nLen] = '\0';
const char* p = in_path;
const char* sln_prefix_win = "$(SolutionDir)..\\";
const char* sln_prefix_fwd = "$(SolutionDir)../";
if (strncmp(p, sln_prefix_win, 17) == 0 || strncmp(p, sln_prefix_fwd, 17) == 0)
{
p += 17;
}
else if (strncmp(p, "..\\", 3) == 0 || strncmp(p, "../", 3) == 0)
{
p += 3;
}
while (*p == '\\' || *p == '/')
{
p++;
}
size_t j = 0;
for (size_t i = 0; p[i] != '\0' && j + 1 < out_size; i++)
{
if (p[i] == '\\')
{
out_path[j++] = '/';
}
else
{
out_path[j++] = p[i];
}
}
out_path[j] = '\0';
while (j > 0 && out_path[j - 1] == '/')
{
out_path[--j] = '\0';
}
}
static void parse_semicolon_tokens(const char* input, char tokens[32][256], int* count)
{
assert(tokens != NULL);
assert(count != NULL);
*count = 0;
if (input == NULL || input[0] == '\0')
{
return;
}
const char* start = input;
while (*start != '\0')
{
while (*start == ' ' || *start == '\t' || *start == ';')
{
start++;
}
if (*start == '\0')
{
break;
}
const char* end = start;
while (*end != '\0' && *end != ';')
{
end++;
}
int len = (int)(end - start);
while (len > 0 && (start[len - 1] == ' ' || start[len - 1] == '\t' || start[len - 1] == '\r' || start[len - 1] == '\n'))
{
len--;
}
if (len > 0 && *count < 32)
{
int copy_len = len < 255 ? len : 255;
memcpy(tokens[*count], start, copy_len);
tokens[*count][copy_len] = '\0';
(*count)++;
}
start = end;
}
}
static void generate_compile_commands(
const VSProject* projects,
int proj_count,
const char* global_include,
const char* def_common,
const char* def_debug)
{
assert(projects != NULL);
assert(proj_count >= 0);
assert(global_include != NULL);
char cwd[MAX_PATH_LEN];
HANDLE dir_handle = CreateFileA(".", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (dir_handle != INVALID_HANDLE_VALUE)
{
char real_path[MAX_PATH_LEN];
DWORD len = GetFinalPathNameByHandleA(dir_handle, real_path, MAX_PATH_LEN, FILE_NAME_NORMALIZED);
CloseHandle(dir_handle);
if (len > 0 && len < MAX_PATH_LEN)
{
const char* p = real_path;
if (strncmp(p, "\\\\?\\", 4) == 0)
{
p += 4;
}
else if (lineLen > 11 && memcmp(lineStart, "DEF_COMMON ", 11) == 0) {
int nLen = lineLen - 11;
if (nLen >= 1024) nLen = 1023;
memcpy(globalDefCommon, lineStart + 11, nLen);
globalDefCommon[nLen] = '\0';
strncpy_s(cwd, sizeof(cwd), p, _TRUNCATE);
}
else
{
GetCurrentDirectoryA((DWORD)sizeof(cwd), cwd);
}
}
else
{
GetCurrentDirectoryA((DWORD)sizeof(cwd), cwd);
}
for (int i = 0; cwd[i] != '\0'; i++)
{
if (cwd[i] == '\\')
{
cwd[i] = '/';
}
}
size_t cwd_len = strlen(cwd);
while (cwd_len > 0 && cwd[cwd_len - 1] == '/')
{
cwd[--cwd_len] = '\0';
}
size_t buffer_size = 8 * 1024 * 1024;
char* json_buf = (char*)ArenaPush(buffer_size);
int offset = 0;
offset += sprintf_s(json_buf + offset, buffer_size - offset, "[\n");
bool is_first_entry = true;
for (int i = 0; i < proj_count; i++)
{
const VSProject* p = &projects[i];
const char* inc_str = p->IncludeSearch[0] != '\0' ? p->IncludeSearch : global_include;
char inc_tokens[32][256];
int inc_count = 0;
parse_semicolon_tokens(inc_str, inc_tokens, &inc_count);
char def_common_tokens[32][256];
int def_common_count = 0;
parse_semicolon_tokens(def_common, def_common_tokens, &def_common_count);
char def_debug_tokens[32][256];
int def_debug_count = 0;
parse_semicolon_tokens(def_debug, def_debug_tokens, &def_debug_count);
char def_extra_tokens[32][256];
int def_extra_count = 0;
parse_semicolon_tokens(p->ExtraDef, def_extra_tokens, &def_extra_count);
bool has_imgui_api = false;
for (int d = 0; d < def_extra_count; d++)
{
if (strncmp(def_extra_tokens[d], "IMGUI_API", 9) == 0)
{
has_imgui_api = true;
break;
}
else if (lineLen > 10 && memcmp(lineStart, "DEF_DEBUG ", 10) == 0) {
int nLen = lineLen - 10;
if (nLen >= 1024) nLen = 1023;
memcpy(globalDefDebug, lineStart + 10, nLen);
globalDefDebug[nLen] = '\0';
}
FilePathList* src_files = CreateFilePathList();
if (p->SrcCount > 0)
{
for (int s = 0; s < p->SrcCount; s++)
{
if (EndsWithNoCase(p->Srcs[s], ".cpp") || EndsWithNoCase(p->Srcs[s], ".c"))
{
FilePathListAdd(src_files, p->Srcs[s]);
}
}
else if (lineLen > 12 && memcmp(lineStart, "DEF_PROFILE ", 12) == 0) {
int nLen = lineLen - 12;
if (nLen >= 1024) nLen = 1023;
memcpy(globalDefProfile, lineStart + 12, nLen);
globalDefProfile[nLen] = '\0';
}
else
{
CollectFiles(p->Dir, NULL, ".cpp", src_files);
CollectFiles(p->Dir, NULL, ".c", src_files);
}
for (int f = 0; f < src_files->Count; f++)
{
const char* raw_path = src_files->Paths[f];
char clean_rel[MAX_PATH_LEN];
clean_include_path(raw_path, clean_rel, sizeof(clean_rel));
char full_path[MAX_PATH_LEN];
if ((clean_rel[1] == ':' && clean_rel[2] == '/') || (clean_rel[0] == '/'))
{
strncpy_s(full_path, sizeof(full_path), clean_rel, _TRUNCATE);
}
else if (lineLen > 12 && memcmp(lineStart, "DEF_RELEASE ", 12) == 0) {
int nLen = lineLen - 12;
if (nLen >= 1024) nLen = 1023;
memcpy(globalDefRelease, lineStart + 12, nLen);
globalDefRelease[nLen] = '\0';
else
{
snprintf(full_path, sizeof(full_path), "%s/%s", cwd, clean_rel);
}
else if (lineLen > 8 && memcmp(lineStart, "PROJECT ", 8) == 0) {
if (projCount < 16) {
VSProject* p = &projects[projCount++];
if (!is_first_entry)
{
offset += sprintf_s(json_buf + offset, buffer_size - offset, ",\n");
}
is_first_entry = false;
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" {\n"
" \"directory\": \"%s\",\n"
" \"file\": \"%s\",\n"
" \"arguments\": [\n"
" \"clang-cl.exe\",\n"
" \"--driver-mode=cl\",\n"
" \"/nologo\",\n"
" \"/std:c++20\",\n"
" \"/W4\",\n"
" \"/utf-8\",\n",
cwd, full_path);
for (int d = 0; d < def_common_count; d++)
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/D%s\",\n", def_common_tokens[d]);
}
for (int d = 0; d < def_debug_count; d++)
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/D%s\",\n", def_debug_tokens[d]);
}
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/DIMGUI_DEFINE_MATH_OPERATORS\",\n");
for (int d = 0; d < def_extra_count; d++)
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/D%s\",\n", def_extra_tokens[d]);
}
if (!has_imgui_api)
{
if (strcmp(p->Name, "Juliet") == 0 || strcmp(p->Name, "ImGui") == 0)
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/DIMGUI_API=__declspec(dllexport)\",\n");
}
else
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/DIMGUI_API=__declspec(dllimport)\",\n");
}
}
for (int c = 0; c < inc_count; c++)
{
char clean_inc[MAX_PATH_LEN];
clean_include_path(inc_tokens[c], clean_inc, sizeof(clean_inc));
if (clean_inc[0] != '\0')
{
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/I%s\",\n", clean_inc);
}
}
if (p->PchHeader[0] != '\0')
{
char clean_pch[MAX_PATH_LEN];
clean_include_path(p->PchHeader, clean_pch, sizeof(clean_pch));
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"/FI%s\",\n", clean_pch);
}
offset += sprintf_s(json_buf + offset, buffer_size - offset,
" \"-c\",\n"
" \"%s\"\n"
" ]\n"
" }",
full_path);
}
}
offset += sprintf_s(json_buf + offset, buffer_size - offset, "\n]\n");
WriteEntireFile("compile_commands.json", json_buf, offset);
printf("Generated compile_commands.json\n");
}
static bool parse_vs_plan(
const char* plan_file,
char* global_include,
size_t global_include_size,
char* global_def_common,
size_t global_def_common_size,
char* global_def_debug,
size_t global_def_debug_size,
char* global_def_profile,
size_t global_def_profile_size,
char* global_def_release,
size_t global_def_release_size,
VSProject* projects,
int* proj_count,
VSSolution* solutions,
int* sln_count)
{
assert(plan_file != NULL);
assert(projects != NULL);
assert(proj_count != NULL);
FileContent plan_content = ReadEntireFile(plan_file);
if (!plan_content.Data)
{
printf("[ERROR] Could not read VS plan: %s\n", plan_file);
return false;
}
*proj_count = 0;
if (sln_count != NULL)
{
*sln_count = 0;
}
const char* pos = plan_content.Data;
while (*pos != '\0')
{
const char* line_start = pos;
while (*pos != '\0' && *pos != '\n' && *pos != '\r')
{
pos++;
}
int line_len = (int)(pos - line_start);
if (line_len > 0)
{
if (line_len > 15 && memcmp(line_start, "GLOBAL_INCLUDE ", 15) == 0 && global_include != NULL)
{
int n_len = line_len - 15;
if ((size_t)n_len >= global_include_size)
{
n_len = (int)global_include_size - 1;
}
memcpy(global_include, line_start + 15, n_len);
global_include[n_len] = '\0';
}
else if (line_len > 11 && memcmp(line_start, "DEF_COMMON ", 11) == 0 && global_def_common != NULL)
{
int n_len = line_len - 11;
if ((size_t)n_len >= global_def_common_size)
{
n_len = (int)global_def_common_size - 1;
}
memcpy(global_def_common, line_start + 11, n_len);
global_def_common[n_len] = '\0';
}
else if (line_len > 10 && memcmp(line_start, "DEF_DEBUG ", 10) == 0 && global_def_debug != NULL)
{
int n_len = line_len - 10;
if ((size_t)n_len >= global_def_debug_size)
{
n_len = (int)global_def_debug_size - 1;
}
memcpy(global_def_debug, line_start + 10, n_len);
global_def_debug[n_len] = '\0';
}
else if (line_len > 12 && memcmp(line_start, "DEF_PROFILE ", 12) == 0 && global_def_profile != NULL)
{
int n_len = line_len - 12;
if ((size_t)n_len >= global_def_profile_size)
{
n_len = (int)global_def_profile_size - 1;
}
memcpy(global_def_profile, line_start + 12, n_len);
global_def_profile[n_len] = '\0';
}
else if (line_len > 12 && memcmp(line_start, "DEF_RELEASE ", 12) == 0 && global_def_release != NULL)
{
int n_len = line_len - 12;
if ((size_t)n_len >= global_def_release_size)
{
n_len = (int)global_def_release_size - 1;
}
memcpy(global_def_release, line_start + 12, n_len);
global_def_release[n_len] = '\0';
}
else if (line_len > 8 && memcmp(line_start, "PROJECT ", 8) == 0)
{
if (*proj_count < 16)
{
VSProject* p = &projects[(*proj_count)++];
memset(p, 0, sizeof(VSProject));
char lineBuf[1024];
int nLen = lineLen - 8;
if (nLen >= 1024) nLen = 1023;
memcpy(lineBuf, lineStart + 8, nLen);
lineBuf[nLen] = '\0';
int scanned = sscanf_s(lineBuf, "%s %s %s", p->Name, (unsigned)_countof(p->Name), p->Dir, (unsigned)_countof(p->Dir), p->Guid, (unsigned)_countof(p->Guid));
if (scanned < 2) {
char line_buf[1024];
int n_len = line_len - 8;
if (n_len >= 1024)
{
n_len = 1023;
}
memcpy(line_buf, line_start + 8, n_len);
line_buf[n_len] = '\0';
int scanned = sscanf_s(line_buf, "%s %s %s", p->Name, (unsigned)_countof(p->Name), p->Dir, (unsigned)_countof(p->Dir), p->Guid, (unsigned)_countof(p->Guid));
if (scanned < 2)
{
strcpy_s(p->Dir, sizeof(p->Dir), p->Name);
}
if (scanned < 3) {
if (scanned < 3)
{
GenerateDeterministicGuid(p->Name, p->Guid);
}
}
}
else if (lineLen > 12 && memcmp(lineStart, "PROJECT_SRC ", 12) == 0 && projCount > 0) {
VSProject* p = &projects[projCount - 1];
if (p->SrcCount < 64) {
int nLen = lineLen - 12;
if (nLen >= 256) nLen = 255;
memcpy(p->Srcs[p->SrcCount], lineStart + 12, nLen);
p->Srcs[p->SrcCount][nLen] = '\0';
else if (line_len > 12 && memcmp(line_start, "PROJECT_SRC ", 12) == 0 && *proj_count > 0)
{
VSProject* p = &projects[*proj_count - 1];
if (p->SrcCount < 64)
{
int n_len = line_len - 12;
if (n_len >= 256)
{
n_len = 255;
}
memcpy(p->Srcs[p->SrcCount], line_start + 12, n_len);
p->Srcs[p->SrcCount][n_len] = '\0';
p->SrcCount++;
}
}
else if (lineLen > 10 && memcmp(lineStart, "EXTRA_DEF ", 10) == 0 && projCount > 0) {
VSProject* p = &projects[projCount - 1];
int nLen = lineLen - 10;
if (nLen >= 1024) nLen = 1023;
memcpy(p->ExtraDef, lineStart + 10, nLen);
p->ExtraDef[nLen] = '\0';
else if (line_len > 10 && memcmp(line_start, "EXTRA_DEF ", 10) == 0 && *proj_count > 0)
{
VSProject* p = &projects[*proj_count - 1];
int n_len = line_len - 10;
if (n_len >= 1024)
{
n_len = 1023;
}
memcpy(p->ExtraDef, line_start + 10, n_len);
p->ExtraDef[n_len] = '\0';
}
else if (lineLen > 15 && memcmp(lineStart, "INCLUDE_SEARCH ", 15) == 0 && projCount > 0) {
VSProject* p = &projects[projCount - 1];
int nLen = lineLen - 15;
if (nLen >= 1024) nLen = 1023;
memcpy(p->IncludeSearch, lineStart + 15, nLen);
p->IncludeSearch[nLen] = '\0';
else if (line_len > 15 && memcmp(line_start, "INCLUDE_SEARCH ", 15) == 0 && *proj_count > 0)
{
VSProject* p = &projects[*proj_count - 1];
int n_len = line_len - 15;
if (n_len >= 1024)
{
n_len = 1023;
}
memcpy(p->IncludeSearch, line_start + 15, n_len);
p->IncludeSearch[n_len] = '\0';
}
else if (lineLen > 10 && memcmp(lineStart, "DEBUG_CMD ", 10) == 0 && projCount > 0) {
VSProject* p = &projects[projCount - 1];
int nLen = lineLen - 10;
if (nLen >= 1024) nLen = 1023;
memcpy(p->DebugCmd, lineStart + 10, nLen);
p->DebugCmd[nLen] = '\0';
else if (line_len > 10 && memcmp(line_start, "DEBUG_CMD ", 10) == 0 && *proj_count > 0)
{
VSProject* p = &projects[*proj_count - 1];
int n_len = line_len - 10;
if (n_len >= 1024)
{
n_len = 1023;
}
memcpy(p->DebugCmd, line_start + 10, n_len);
p->DebugCmd[n_len] = '\0';
}
else if (lineLen > 4 && memcmp(lineStart, "PCH ", 4) == 0 && projCount > 0) {
VSProject* p = &projects[projCount - 1];
char lineBuf[1024];
int nLen = lineLen - 4;
if (nLen >= 1024) nLen = 1023;
memcpy(lineBuf, lineStart + 4, nLen);
lineBuf[nLen] = '\0';
sscanf_s(lineBuf, "%s %s", p->PchHeader, (unsigned)_countof(p->PchHeader), p->PchSrc, (unsigned)_countof(p->PchSrc));
else if (line_len > 4 && memcmp(line_start, "PCH ", 4) == 0 && *proj_count > 0)
{
VSProject* p = &projects[*proj_count - 1];
char line_buf[1024];
int n_len = line_len - 4;
if (n_len >= 1024)
{
n_len = 1023;
}
memcpy(line_buf, line_start + 4, n_len);
line_buf[n_len] = '\0';
sscanf_s(line_buf, "%s %s", p->PchHeader, (unsigned)_countof(p->PchHeader), p->PchSrc, (unsigned)_countof(p->PchSrc));
}
else if (lineLen > 9 && memcmp(lineStart, "SOLUTION ", 9) == 0) {
if (slnCount < 8) {
VSSolution* s = &solutions[slnCount++];
else if (line_len > 9 && memcmp(line_start, "SOLUTION ", 9) == 0 && solutions != NULL && sln_count != NULL)
{
if (*sln_count < 8)
{
VSSolution* s = &solutions[(*sln_count)++];
memset(s, 0, sizeof(VSSolution));
int nLen = lineLen - 9;
if (nLen >= 64) nLen = 63;
memcpy(s->Name, lineStart + 9, nLen);
s->Name[nLen] = '\0';
int n_len = line_len - 9;
if (n_len >= 64)
{
n_len = 63;
}
memcpy(s->Name, line_start + 9, n_len);
s->Name[n_len] = '\0';
}
}
else if (lineLen > 9 && memcmp(lineStart, "SLN_PROJ ", 9) == 0 && slnCount > 0) {
VSSolution* s = &solutions[slnCount - 1];
if (s->ProjCount < 16) {
int nLen = lineLen - 9;
if (nLen >= 64) nLen = 63;
memcpy(s->Projects[s->ProjCount], lineStart + 9, nLen);
s->Projects[s->ProjCount][nLen] = '\0';
else if (line_len > 9 && memcmp(line_start, "SLN_PROJ ", 9) == 0 && sln_count != NULL && *sln_count > 0 && solutions != NULL)
{
VSSolution* s = &solutions[*sln_count - 1];
if (s->ProjCount < 16)
{
int n_len = line_len - 9;
if (n_len >= 64)
{
n_len = 63;
}
memcpy(s->Projects[s->ProjCount], line_start + 9, n_len);
s->Projects[s->ProjCount][n_len] = '\0';
s->ProjCount++;
}
}
}
while (*pos == '\n' || *pos == '\r') pos++;
while (*pos == '\n' || *pos == '\r')
{
pos++;
}
}
for (int i = 0; i < projCount; i++) {
return true;
}
static int CommandGenCompileCommands(int argc, char* argv[])
{
if (argc < 3)
{
printf("[ERROR] Usage: build_system gen_compile_commands <plan_file>\n");
return 1;
}
const char* plan_file = argv[2];
char global_include[1024] = {0};
char global_def_common[1024] = {0};
char global_def_debug[1024] = {0};
char global_def_profile[1024] = {0};
char global_def_release[1024] = {0};
VSProject projects[16];
int proj_count = 0;
if (!parse_vs_plan(plan_file,
global_include, sizeof(global_include),
global_def_common, sizeof(global_def_common),
global_def_debug, sizeof(global_def_debug),
global_def_profile, sizeof(global_def_profile),
global_def_release, sizeof(global_def_release),
projects, &proj_count, NULL, NULL))
{
return 1;
}
generate_compile_commands(projects, proj_count, global_include, global_def_common, global_def_debug);
return 0;
}
static int CommandGenVS(int argc, char* argv[])
{
if (argc < 3)
{
printf("[ERROR] Usage: build_system gen_vs <plan_file>\n");
return 1;
}
const char* plan_file = argv[2];
char global_include[1024] = {0};
char global_def_common[1024] = {0};
char global_def_debug[1024] = {0};
char global_def_profile[1024] = {0};
char global_def_release[1024] = {0};
VSProject projects[16];
int proj_count = 0;
VSSolution solutions[8];
int sln_count = 0;
if (!parse_vs_plan(plan_file,
global_include, sizeof(global_include),
global_def_common, sizeof(global_def_common),
global_def_debug, sizeof(global_def_debug),
global_def_profile, sizeof(global_def_profile),
global_def_release, sizeof(global_def_release),
projects, &proj_count, solutions, &sln_count))
{
return 1;
}
for (int i = 0; i < proj_count; i++)
{
VSProject* p = &projects[i];
const char* incs = p->IncludeSearch[0] != '\0' ? p->IncludeSearch : globalInclude;
GenerateProject(p->Name, p->Dir, p->Guid, incs, p->ExtraDef, p->DebugCmd, p->Srcs, p->SrcCount, globalDefCommon, globalDefDebug, globalDefProfile, globalDefRelease, p->PchHeader, p->PchSrc);
const char* incs = p->IncludeSearch[0] != '\0' ? p->IncludeSearch : global_include;
GenerateProject(p->Name, p->Dir, p->Guid, incs, p->ExtraDef, p->DebugCmd, p->Srcs, p->SrcCount, global_def_common, global_def_debug, global_def_profile, global_def_release, p->PchHeader, p->PchSrc);
}
for (int i = 0; i < slnCount; i++) {
for (int i = 0; i < sln_count; i++)
{
VSSolution* s = &solutions[i];
const char* pNames[16];
const char* pGuids[16];
for (int j = 0; j < s->ProjCount; j++) {
for (int j = 0; j < s->ProjCount; j++)
{
pNames[j] = s->Projects[j];
for (int k = 0; k < projCount; k++) {
if (strcmp(projects[k].Name, s->Projects[j]) == 0) {
for (int k = 0; k < proj_count; k++)
{
if (strcmp(projects[k].Name, s->Projects[j]) == 0)
{
pGuids[j] = projects[k].Guid;
break;
}
@@ -1715,7 +2160,8 @@ static int CommandGenVS(int argc, char* argv[])
}
GenerateSolution(s->Name, pNames, pGuids, s->ProjCount);
}
generate_compile_commands(projects, proj_count, global_include, global_def_common, global_def_debug);
return 0;
}
@@ -1728,9 +2174,10 @@ int main(int argc, char* argv[])
{
printf("Usage: build_system <command> [args...]\n");
printf("Commands:\n");
printf(" run_plan <plan_file> Run the build from a generated plan file\n");
printf(" gen_vs Generate Visual Studio project and solution files\n");
printf(" check_alive Returns 0 immediately to test execution\n");
printf(" run_plan <plan_file> Run the build from a generated plan file\n");
printf(" gen_vs <plan_file> Generate Visual Studio project, solution, and compile_commands files\n");
printf(" gen_compile_commands <plan_file> Generate compile_commands.json for Neovim/clangd\n");
printf(" check_alive Returns 0 immediately to test execution\n");
return 1;
}
@@ -1738,6 +2185,7 @@ int main(int argc, char* argv[])
if (strcmp(cmd, "check_alive") == 0) return 0;
if (strcmp(cmd, "run_plan") == 0) return CommandRunPlan(argc, argv);
if (strcmp(cmd, "gen_vs") == 0) return CommandGenVS(argc, argv);
if (strcmp(cmd, "gen_compile_commands") == 0) return CommandGenCompileCommands(argc, argv);
printf("[ERROR] Unknown command: %s\n", cmd);
return 1;