diff --git a/releasenotes.md b/releasenotes.md
index d41fb70be..c6960585d 100644
--- a/releasenotes.md
+++ b/releasenotes.md
@@ -24,6 +24,7 @@
- Deprecate `f32`, `f64` and `f128` suffixes.
- Allow recursive generic modules.
- Add deprecation for `@param foo "abc"`.
+- Add `--header-output` and `header-output` options for controlling header output folder.
### Fixes
- Assert triggered when casting from `int[2]` to `uint[2]` #2115
diff --git a/src/build/build.h b/src/build/build.h
index c05031df6..bc5f0c7cb 100644
--- a/src/build/build.h
+++ b/src/build/build.h
@@ -562,6 +562,7 @@ typedef struct BuildOptions_
const char *output_dir;
const char *llvm_out;
const char *asm_out;
+ const char *header_out;
const char *obj_out;
const char *script_dir;
RelocModel reloc_model;
@@ -651,6 +652,7 @@ typedef struct
const char *output_dir;
const char *ir_file_dir;
const char *asm_file_dir;
+ const char *header_file_dir;
const char *script_dir;
const char *run_dir;
bool is_non_project;
diff --git a/src/build/build_options.c b/src/build/build_options.c
index 502d3be82..65c80fd37 100644
--- a/src/build/build_options.c
+++ b/src/build/build_options.c
@@ -113,6 +113,7 @@ static void usage(bool full)
print_opt("--script-dir
", "Override the base directory for $exec.");
print_opt("--llvm-out ", "Override llvm output directory for '--emit-llvm'.");
print_opt("--asm-out ", "Override asm output directory for '--emit-asm'.");
+ print_opt("--header-output ", "Override header file output directory when building libraries.");
print_opt("--emit-llvm", "Emit LLVM IR as a .ll file per module.");
print_opt("--emit-asm", "Emit asm as a .s file per module.");
print_opt("--obj", "Emit object files. (Enabled by default)");
@@ -1172,6 +1173,12 @@ static void parse_option(BuildOptions *options)
options->asm_out = next_arg();
return;
}
+ if (match_longopt("header-output"))
+ {
+ if (at_end() || next_is_opt()) error_exit("error: --header-output needs a directory.");
+ options->header_out = next_arg();
+ return;
+ }
if (match_longopt("lib"))
{
if (at_end() || next_is_opt()) error_exit("error: --lib needs a name.");
diff --git a/src/build/builder.c b/src/build/builder.c
index bff211120..d96801bd0 100644
--- a/src/build/builder.c
+++ b/src/build/builder.c
@@ -494,6 +494,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
}
target->ir_file_dir = options->llvm_out;
target->asm_file_dir = options->asm_out;
+ target->header_file_dir = options->header_out;
target->object_file_dir = options->obj_out;
if (!target->ir_file_dir)
{
@@ -511,6 +512,10 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
{
target->object_file_dir = file_append_path(file_append_path(target->build_dir, "obj"), target_name);
}
+ if (!target->header_file_dir)
+ {
+ target->header_file_dir = target->output_dir ? target->output_dir : target->build_dir;
+ }
switch (options->compile_option)
{
diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c
index 21a0ccf0b..6b3589e30 100644
--- a/src/compiler/compiler.c
+++ b/src/compiler/compiler.c
@@ -438,9 +438,12 @@ void compiler_compile(void)
{
error_exit("No module to compile.");
}
-
if (compiler.build.output_headers)
{
+ if (compiler.build.header_file_dir)
+ {
+ create_output_dir(compiler.build.header_file_dir);
+ }
header_gen(modules, module_count);
}
diff --git a/src/compiler/headers.c b/src/compiler/headers.c
index 88e33ee16..15fe2bea3 100644
--- a/src/compiler/headers.c
+++ b/src/compiler/headers.c
@@ -765,7 +765,15 @@ void header_gen(Module **modules, unsigned module_count)
htable_init(&table1, 1024);
htable_init(&table2, 1024);
const char *name = build_base_name();
- const char *filename = str_printf("%s.h", name);
+ const char *filename;
+ if (compiler.build.header_file_dir)
+ {
+ filename = file_append_path(compiler.build.header_file_dir, str_printf("%s.h", name));
+ }
+ else
+ {
+ filename = str_printf("%s.h", name);
+ }
FILE *file = fopen(filename, "w");
HeaderContext context = { .file = file, .gen_def = &table1, .gen_decl = &table2 };
HeaderContext *c = &context;