- Initial support for #1925, does not affect C compilation yet, and doesn't try to link etc. Using "--emit-only"

This commit is contained in:
Christoffer Lerno
2025-06-29 23:50:17 +02:00
parent a13eb99962
commit e1a125e326
10 changed files with 32 additions and 3 deletions

View File

@@ -30,6 +30,7 @@
- Compile-time comparison of constant vectors. #1575.
- $member.get supports bitstructs.
- $member.set for setting members without the *& trick.
- Initial support for #1925, does not affect C compilation yet, and doesn't try to link etc. Using "--emit-only"
### Fixes
- `-2147483648`, MIN literals work correctly.

View File

@@ -565,6 +565,7 @@ typedef struct BuildOptions_
const char *header_out;
const char *obj_out;
const char *script_dir;
const char **emit_only;
RelocModel reloc_model;
X86VectorCapability x86_vector_capability;
X86CpuSet x86_cpu_set;
@@ -656,6 +657,7 @@ typedef struct
const char *header_file_dir;
const char *script_dir;
const char *run_dir;
const char **emit_only;
bool is_non_project;
bool run_after_compile;
bool delete_after_run;

View File

@@ -158,6 +158,7 @@ static void usage(bool full)
print_opt("--use-stdlib=<yes|no>", "Include the standard library (default: yes).");
print_opt("--link-libc=<yes|no>", "Link libc other default libraries (default: yes).");
print_opt("--emit-stdlib=<yes|no>", "Output files for the standard library. (default: yes)");
print_opt("--emit-only <file>", "Output only the file matching <file>.");
print_opt("--panicfn <name>", "Override the panic function name.");
print_opt("--testfn <name>", "Override the test runner function name.");
print_opt("--benchfn <name>", "Override the benchmark runner function name.");
@@ -879,6 +880,12 @@ static void parse_option(BuildOptions *options)
options->emit_stdlib = parse_opt_select(EmitStdlib, argopt, on_off);
return;
}
if (match_longopt("emit-only"))
{
if (at_end() || next_is_opt()) error_exit("error: --emit-only expects an output name, e.g. 'foo', to only output 'foo.o'.");
vec_add(options->emit_only, next_arg());
return;
}
if ((argopt = match_argopt("use-stdlib")))
{
options->use_stdlib = parse_opt_select(UseStdlib, argopt, on_off);

View File

@@ -477,7 +477,9 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
error_exit("Unable to detect the default target, please set an explicit --target value.");
}
target->emit_only = options->emit_only;
const char *target_name = arch_os_target[target->arch_os_target];
if (options->script_dir) target->script_dir = options->script_dir;
if (command_accepts_files(options->command))
{
target->build_dir = options->build_dir ? options->build_dir : ".build";
@@ -498,6 +500,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
}
if (!options->run_dir) options->run_dir = target->run_dir;
target->ir_file_dir = options->llvm_out;
target->asm_file_dir = options->asm_out;
target->header_file_dir = options->header_out;

View File

@@ -295,9 +295,10 @@ bool codegen_single_obj_output()
return compiler.build.single_module == SINGLE_MODULE_ON;
}
void codegen_setup_object_names(Module *module, const char **ir_filename, const char **asm_filename, const char **object_filename)
void codegen_setup_object_names(Module *module, const char **base_name, const char **ir_filename, const char **asm_filename, const char **object_filename)
{
const char *result = module_create_object_file_name(module);
*base_name = scratch_buffer_copy();
assert(compiler.build.object_file_dir);
if (codegen_single_obj_output())
{

View File

@@ -405,6 +405,16 @@ void compiler_parse(void)
compiler_parsing_time = bench_mark();
}
bool compiler_should_ouput_file(const char *file)
{
if (!vec_size(compiler.build.emit_only)) return true;
FOREACH(const char *, f, compiler.build.emit_only)
{
if (str_eq(file, f)) return true;
}
return false;
}
static void create_output_dir(const char *dir)
{
if (!dir) return;
@@ -669,6 +679,7 @@ void compiler_compile(void)
}
error_exit("Compilation produced no object files, maybe there was no code?");
}
if (vec_size(compiler.build.emit_only)) goto SKIP;
if (output_exe)
{
if (compiler.build.output_dir)
@@ -805,6 +816,7 @@ void compiler_compile(void)
}
else
{
SKIP:
compiler_print_bench();
}
free(obj_files);

View File

@@ -2418,6 +2418,7 @@ File *source_file_text_load(const char *filename, char *content);
File *compile_and_invoke(const char *file, const char *args, const char *stdin_data, size_t limit);
void compiler_parse(void);
bool compiler_should_ouput_file(const char *file);
void emit_json(void);
void stable_init(STable *table, uint32_t initial_size);
@@ -2445,7 +2446,7 @@ const char *symtab_preset(const char *data, TokenType type);
const char *symtab_add(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type);
const char *symtab_find(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type);
void *llvm_target_machine_create(void);
void codegen_setup_object_names(Module *module, const char **ir_filename, const char **asm_filename, const char **object_filename);
void codegen_setup_object_names(Module *module, const char **base_name, const char **ir_filename, const char **asm_filename, const char **object_filename);
void target_setup(BuildTarget *build_target);
int target_alloca_addr_space();
bool os_is_apple(OsType os_type);

View File

@@ -1068,6 +1068,7 @@ static inline void llvm_optimize(GenContext *c)
const char *llvm_codegen(void *context)
{
GenContext *c = context;
if (!compiler_should_ouput_file(c->base_name)) return NULL;
llvm_optimize(c);
// Serialize the LLVM IR, if requested, also verify the IR in this case

View File

@@ -96,6 +96,7 @@ typedef struct GenContext_
const char *ir_filename;
const char *object_filename;
const char *asm_filename;
const char *base_name;
LLVMTypeRef bool_type;
LLVMTypeRef byte_type;
LLVMTypeRef introspect_type;

View File

@@ -59,7 +59,7 @@ void gencontext_begin_module(GenContext *c)
{
ASSERT(!c->module && "Expected no module");
codegen_setup_object_names(c->code_module, &c->ir_filename, &c->asm_filename, &c->object_filename);
codegen_setup_object_names(c->code_module, &c->base_name, &c->ir_filename, &c->asm_filename, &c->object_filename);
DEBUG_LOG("Emit module %s.", c->code_module->name->module);
c->panic_var = compiler.context.panic_var;
c->panicf = compiler.context.panicf;