mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Add the option to export dependencies as JSON.
This commit is contained in:
@@ -694,6 +694,12 @@ enum TimingsExportFormat : i32 {
|
|||||||
TimingsExportCSV = 2,
|
TimingsExportCSV = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DependenciesExportFormat : i32 {
|
||||||
|
DependenciesExportUnspecified = 0,
|
||||||
|
DependenciesExportMake = 1,
|
||||||
|
DependenciesExportJson = 2,
|
||||||
|
};
|
||||||
|
|
||||||
enum ErrorPosStyle {
|
enum ErrorPosStyle {
|
||||||
ErrorPosStyle_Default, // path(line:column) msg
|
ErrorPosStyle_Default, // path(line:column) msg
|
||||||
ErrorPosStyle_Unix, // path:line:column: msg
|
ErrorPosStyle_Unix, // path:line:column: msg
|
||||||
@@ -831,6 +837,7 @@ struct BuildContext {
|
|||||||
bool show_timings;
|
bool show_timings;
|
||||||
TimingsExportFormat export_timings_format;
|
TimingsExportFormat export_timings_format;
|
||||||
String export_timings_file;
|
String export_timings_file;
|
||||||
|
DependenciesExportFormat export_dependencies_format;
|
||||||
String export_dependencies_file;
|
String export_dependencies_file;
|
||||||
bool show_unused;
|
bool show_unused;
|
||||||
bool show_unused_with_location;
|
bool show_unused_with_location;
|
||||||
|
|||||||
+113
-51
@@ -235,6 +235,7 @@ enum BuildFlagKind {
|
|||||||
BuildFlag_ExportTimings,
|
BuildFlag_ExportTimings,
|
||||||
BuildFlag_ExportTimingsFile,
|
BuildFlag_ExportTimingsFile,
|
||||||
BuildFlag_ExportDependencies,
|
BuildFlag_ExportDependencies,
|
||||||
|
BuildFlag_ExportDependenciesFile,
|
||||||
BuildFlag_ShowSystemCalls,
|
BuildFlag_ShowSystemCalls,
|
||||||
BuildFlag_ThreadCount,
|
BuildFlag_ThreadCount,
|
||||||
BuildFlag_KeepTempFiles,
|
BuildFlag_KeepTempFiles,
|
||||||
@@ -427,7 +428,8 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check);
|
add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check);
|
||||||
add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check);
|
add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check);
|
||||||
add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check);
|
add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check);
|
||||||
add_flag(&build_flags, BuildFlag_ExportDependencies, str_lit("export-dependencies"), BuildFlagParam_String, Command__does_check);
|
add_flag(&build_flags, BuildFlag_ExportDependencies, str_lit("export-dependencies"), BuildFlagParam_String, Command__does_build);
|
||||||
|
add_flag(&build_flags, BuildFlag_ExportDependenciesFile, str_lit("export-dependencies-file"), BuildFlagParam_String, Command__does_build);
|
||||||
add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check);
|
add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check);
|
||||||
add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check);
|
add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check);
|
||||||
add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all);
|
add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all);
|
||||||
@@ -757,6 +759,23 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
case BuildFlag_ExportDependencies: {
|
case BuildFlag_ExportDependencies: {
|
||||||
GB_ASSERT(value.kind == ExactValue_String);
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
|
|
||||||
|
if (value.value_string == "make") {
|
||||||
|
build_context.export_dependencies_format = DependenciesExportMake;
|
||||||
|
} else if (value.value_string == "json") {
|
||||||
|
build_context.export_dependencies_format = DependenciesExportJson;
|
||||||
|
} else {
|
||||||
|
gb_printf_err("Invalid export format for -export-dependencies:<string>, got %.*s\n", LIT(value.value_string));
|
||||||
|
gb_printf_err("Valid export formats:\n");
|
||||||
|
gb_printf_err("\tmake\n");
|
||||||
|
gb_printf_err("\tjson\n");
|
||||||
|
bad_flags = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BuildFlag_ExportDependenciesFile: {
|
||||||
|
GB_ASSERT(value.kind == ExactValue_String);
|
||||||
|
|
||||||
String export_path = string_trim_whitespace(value.value_string);
|
String export_path = string_trim_whitespace(value.value_string);
|
||||||
if (is_build_flag_path_valid(export_path)) {
|
if (is_build_flag_path_valid(export_path)) {
|
||||||
build_context.export_dependencies_file = path_to_full_path(heap_allocator(), export_path);
|
build_context.export_dependencies_file = path_to_full_path(heap_allocator(), export_path);
|
||||||
@@ -764,8 +783,8 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
|||||||
gb_printf_err("Invalid -export-dependencies path, got %.*s\n", LIT(export_path));
|
gb_printf_err("Invalid -export-dependencies path, got %.*s\n", LIT(export_path));
|
||||||
bad_flags = true;
|
bad_flags = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BuildFlag_ShowSystemCalls: {
|
case BuildFlag_ShowSystemCalls: {
|
||||||
GB_ASSERT(value.kind == ExactValue_Invalid);
|
GB_ASSERT(value.kind == ExactValue_Invalid);
|
||||||
@@ -1649,6 +1668,74 @@ gb_internal void show_timings(Checker *c, Timings *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void export_dependencies(Parser *p) {
|
||||||
|
GB_ASSERT(build_context.export_dependencies_format != DependenciesExportUnspecified);
|
||||||
|
|
||||||
|
if (build_context.export_dependencies_file.len <= 0) {
|
||||||
|
gb_printf_err("No dependency file specified with `-export-dependencies-file`\n");
|
||||||
|
exit_with_errors();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gbFile f = {};
|
||||||
|
char * fileName = (char *)build_context.export_dependencies_file.text;
|
||||||
|
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, fileName);
|
||||||
|
if (err != gbFileError_None) {
|
||||||
|
gb_printf_err("Failed to export dependencies to: %s\n", fileName);
|
||||||
|
exit_with_errors();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
defer (gb_file_close(&f));
|
||||||
|
|
||||||
|
if (build_context.export_dependencies_format == DependenciesExportMake) {
|
||||||
|
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
||||||
|
defer (gb_free(heap_allocator(), exe_name.text));
|
||||||
|
|
||||||
|
gb_fprintf(&f, "%.*s:", LIT(exe_name));
|
||||||
|
|
||||||
|
isize current_line_length = exe_name.len + 1;
|
||||||
|
|
||||||
|
for(AstPackage *pkg : p->packages) {
|
||||||
|
for(AstFile *file : pkg->files) {
|
||||||
|
/* Arbitrary line break value. Maybe make this better? */
|
||||||
|
if (current_line_length >= 80-2) {
|
||||||
|
gb_file_write(&f, " \\\n ", 4);
|
||||||
|
current_line_length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gb_file_write(&f, " ", 1);
|
||||||
|
current_line_length++;
|
||||||
|
|
||||||
|
for (isize k = 0; k < file->fullpath.len; k++) {
|
||||||
|
char part = file->fullpath.text[k];
|
||||||
|
if (part == ' ') {
|
||||||
|
gb_file_write(&f, "\\", 1);
|
||||||
|
current_line_length++;
|
||||||
|
}
|
||||||
|
gb_file_write(&f, &part, 1);
|
||||||
|
current_line_length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gb_fprintf(&f, "\n");
|
||||||
|
} else if (build_context.export_dependencies_format == DependenciesExportJson) {
|
||||||
|
gb_fprintf(&f, "{\n");
|
||||||
|
|
||||||
|
gb_fprintf(&f, "\t\"source_files\": [\n");
|
||||||
|
|
||||||
|
for(AstPackage *pkg : p->packages) {
|
||||||
|
for(AstFile *file : pkg->files) {
|
||||||
|
gb_fprintf(&f, "\t\t\"%.*s\",\n", LIT(file->fullpath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gb_fprintf(&f, "\t],\n");
|
||||||
|
|
||||||
|
gb_fprintf(&f, "}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gb_internal void remove_temp_files(lbGenerator *gen) {
|
gb_internal void remove_temp_files(lbGenerator *gen) {
|
||||||
if (build_context.keep_temp_files) return;
|
if (build_context.keep_temp_files) return;
|
||||||
|
|
||||||
@@ -1804,9 +1891,16 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
|||||||
print_usage_line(2, "Example: -export-timings-file:timings.json");
|
print_usage_line(2, "Example: -export-timings-file:timings.json");
|
||||||
print_usage_line(0, "");
|
print_usage_line(0, "");
|
||||||
|
|
||||||
print_usage_line(1, "-export-dependencies:<filename>");
|
print_usage_line(1, "-export-dependencies:<format>");
|
||||||
print_usage_line(2, "Exports all source files used to create the output file in Make format.");
|
print_usage_line(2, "Exports dependencies to one of a few formats. Requires `-export-dependencies-file`.");
|
||||||
print_usage_line(2, "Example: -export-dependencies:odin.d");
|
print_usage_line(2, "Available options:");
|
||||||
|
print_usage_line(3, "-export-dependencies:make Exports in Makefile format");
|
||||||
|
print_usage_line(3, "-export-dependencies:json Exports in JSON format");
|
||||||
|
print_usage_line(0, "");
|
||||||
|
|
||||||
|
print_usage_line(1, "-export-dependencies-file:<filename>");
|
||||||
|
print_usage_line(2, "Specifies the filename for `-export-dependencies`.");
|
||||||
|
print_usage_line(2, "Example: -export-dependencies-file:dependencies.d");
|
||||||
print_usage_line(0, "");
|
print_usage_line(0, "");
|
||||||
|
|
||||||
print_usage_line(1, "-thread-count:<integer>");
|
print_usage_line(1, "-thread-count:<integer>");
|
||||||
@@ -2900,6 +2994,10 @@ int main(int arg_count, char const **arg_ptr) {
|
|||||||
if (build_context.show_timings) {
|
if (build_context.show_timings) {
|
||||||
show_timings(checker, &global_timings);
|
show_timings(checker, &global_timings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||||
|
export_dependencies(parser);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2922,6 +3020,10 @@ int main(int arg_count, char const **arg_ptr) {
|
|||||||
if (build_context.show_timings) {
|
if (build_context.show_timings) {
|
||||||
show_timings(checker, &global_timings);
|
show_timings(checker, &global_timings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||||
|
export_dependencies(parser);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2935,54 +3037,14 @@ int main(int arg_count, char const **arg_ptr) {
|
|||||||
show_timings(checker, &global_timings);
|
show_timings(checker, &global_timings);
|
||||||
}
|
}
|
||||||
|
|
||||||
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
if (build_context.export_dependencies_format != DependenciesExportUnspecified) {
|
||||||
defer (gb_free(heap_allocator(), exe_name.text));
|
export_dependencies(parser);
|
||||||
|
|
||||||
if (build_context.export_dependencies_file.len > 0) {
|
|
||||||
gbFile f = {};
|
|
||||||
char * fileName = (char *)build_context.export_dependencies_file.text;
|
|
||||||
gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, fileName);
|
|
||||||
if (err != gbFileError_None) {
|
|
||||||
gb_printf_err("Failed to export dependencies to: %s\n", fileName);
|
|
||||||
exit_with_errors();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
defer (gb_file_close(&f));
|
|
||||||
|
|
||||||
gb_fprintf(&f, "%.*s:", LIT(exe_name));
|
|
||||||
|
|
||||||
isize current_line_length = exe_name.len + 1;
|
|
||||||
|
|
||||||
for (isize i = parser->packages.count-1; i >= 0; i--) {
|
|
||||||
AstPackage *pkg = parser->packages[i];
|
|
||||||
for (isize j = pkg->files.count-1; j >= 0; j--) {
|
|
||||||
AstFile *file = pkg->files[j];
|
|
||||||
|
|
||||||
/* Arbitrary line break value. Maybe make this better? */
|
|
||||||
if (current_line_length >= 80-2) {
|
|
||||||
gb_file_write(&f, " \\\n ", 4);
|
|
||||||
current_line_length = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
gb_file_write(&f, " ", 1);
|
|
||||||
current_line_length++;
|
|
||||||
|
|
||||||
for (isize k = 0; k < file->fullpath.len; k++) {
|
|
||||||
char part = file->fullpath.text[k];
|
|
||||||
if (part == ' ') {
|
|
||||||
gb_file_write(&f, "\\", 1);
|
|
||||||
current_line_length++;
|
|
||||||
}
|
|
||||||
gb_file_write(&f, &part, 1);
|
|
||||||
current_line_length++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gb_fprintf(&f, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run_output) {
|
if (run_output) {
|
||||||
|
String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]);
|
||||||
|
defer (gb_free(heap_allocator(), exe_name.text));
|
||||||
|
|
||||||
return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string));
|
return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user