Improve custom output location for LLVM-IR, OBJ + ASM

Fixes #6926.

If `build` is a subdirectory in the current directory, then `odin build . -out:build` will place `.S`, `.obj` and `.ll` files there if the corresponding `-build-mode` is given.
This commit is contained in:
Jeroen van Rijn
2026-07-02 14:19:56 +02:00
parent eee06be76f
commit 03652d7423
2 changed files with 44 additions and 11 deletions

View File

@@ -2409,12 +2409,32 @@ gb_internal bool init_build_paths(String init_filename) {
GB_PANIC("Unhandled build mode/target combination.\n");
}
bool output_should_be_directory = false;
if (bc->out_filepath.len > 0) {
bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath);
if (build_context.metrics.os == TargetOs_windows) {
String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]);
defer (gb_free(ha, output_file.text));
if (path_is_directory(bc->build_paths[BuildPath_Output])) {
bool output_is_directory = path_is_directory(bc->build_paths[BuildPath_Output]);
String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]);
defer (gb_free(ha, output_file.text));
// NOTE(Jeroen): For LLVM-IR, we want `-out` to specify a directory.
// For other outputs we expect it to be a file path.
if (build_context.build_mode == BuildMode_LLVM_IR) {
if (!output_is_directory) {
gb_printf_err("Output path %.*s should be a directory for LLVM-IR output.\n", LIT(output_file));
return false;
}
output_should_be_directory = true;
} else if (build_context.build_mode == BuildMode_Object) {
// Both directory or filename prefix allowed
} else if (build_context.build_mode == BuildMode_Assembly) {
// Both directory or filename prefix allowed
} else if (build_context.metrics.os == TargetOs_windows) {
if (output_is_directory) {
gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file));
return false;
} else if (bc->build_paths[BuildPath_Output].ext.len == 0) {
@@ -2525,7 +2545,11 @@ gb_internal bool init_build_paths(String init_filename) {
// Do we have an extension? We might not if the output filename was supplied.
if (bc->build_paths[BuildPath_Output].ext.len == 0) {
if (build_context.metrics.os == TargetOs_windows || is_arch_wasm() || build_context.build_mode != BuildMode_Executable) {
bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension);
// NOTE(Jeroen): If build mode is LLVM_IR and a custom output was set
if (!output_should_be_directory) {
bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension);
}
}
}
@@ -2533,7 +2557,7 @@ gb_internal bool init_build_paths(String init_filename) {
defer (gb_free(ha, output_file.text));
// Check if output path is a directory.
if (path_is_directory(bc->build_paths[BuildPath_Output])) {
if (!output_should_be_directory && path_is_directory(bc->build_paths[BuildPath_Output])) {
gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file));
return false;
}