Several fixes for .o files and -o output, improving handling and naming, checking for existence of sub-folders before output. Warning on using .o and -o output when not single module etc. Fix to static lib regression. Info about asm / llvm / obj output.

This commit is contained in:
Christoffer Lerno
2025-02-25 14:05:00 +01:00
parent 062a67fe75
commit 31096531e1
7 changed files with 60 additions and 10 deletions

View File

@@ -201,7 +201,7 @@ fn Path! Path.tappend(self, String filename) => self.append(tmem(), filename);
fn usz! start_of_base_name(String str, PathEnv path_env) @local
{
if (!str.len) return PathResult.INVALID_PATH?;
if (!str.len) return 0;
usz! start_slash = str.rindex_of_char('/');
if (path_env != PathEnv.WIN32) return start_slash + 1 ?? 0;
if (try index = str.rindex_of_char('\\'))

View File

@@ -24,6 +24,7 @@
- Correctly handle in/out when interacting with inout.
- Don't delete .o files not produced by the compiler.
- Fix optional jumps in expression lists, #1942.
- Several fixes for .o files and -o output, improving handling and naming.
### Stdlib changes

View File

@@ -314,7 +314,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
break;
case COMMAND_STATIC_LIB:
target->type = TARGET_TYPE_STATIC_LIB;
target->single_module = true;
target->single_module = SINGLE_MODULE_ON;
break;
default:
target->run_after_compile = false;
@@ -504,9 +504,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
}
if (!target->object_file_dir)
{
target->object_file_dir = options->build_dir
? file_append_path(file_append_path(options->build_dir, "obj"), target_name)
: file_append_path("obj", target_name);
target->object_file_dir = file_append_path(file_append_path(target->build_dir, "obj"), target_name);
}
switch (options->compile_option)
@@ -558,6 +556,11 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
{
target->emit_object_files = false;
}
if (options->output_name && target->emit_object_files
&& target->single_module != SINGLE_MODULE_ON && target->type == TARGET_TYPE_OBJECT_FILES)
{
error_exit("'-o' cannot be used when generating multiple output files, try using '--single-module=yes' to compile into a single object file.");
}
for (int i = 0; i < options->lib_dir_count; i++)
{
vec_add(target->libdirs, options->lib_dir[i]);
@@ -572,6 +575,7 @@ static void update_build_target_from_options(BuildTarget *target, BuildOptions *
{
target->link_libc = libc_from_arch_os(target->arch_os_target);
}
}
void init_default_build_target(BuildTarget *target, BuildOptions *options)

View File

@@ -288,16 +288,44 @@ AlignSize type_alloca_alignment(Type *type)
return align;
}
bool codegen_single_obj_output()
{
if (!compiler.build.output_name) return false;
if (compiler.build.type != TARGET_TYPE_OBJECT_FILES) return false;
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)
{
const char *result = module_create_object_file_name(module);
assert(compiler.build.object_file_dir);
if (codegen_single_obj_output())
{
const char *ext = get_object_extension();
if (!str_has_suffix(result, ext))
{
result = str_printf("%s%s", result, ext);
}
compiler.obj_output = *object_filename = file_append_path(compiler.build.output_dir ? compiler.build.output_dir : ".", result);
char *dir_path = NULL;
char *filename = NULL;
file_get_dir_and_filename_from_full(compiler.obj_output, &filename, &dir_path);
if (dir_path && strlen(dir_path) && !file_is_dir(dir_path))
{
error_exit("Can't output '%s', the directory '%s' could not be found.", compiler.obj_output, dir_path);
}
result = str_remove_suffix(filename, ext);
}
else
{
*object_filename = file_append_path(compiler.build.object_file_dir, str_printf("%s%s", result, get_object_extension()));
}
*ir_filename = str_printf(compiler.build.backend == BACKEND_LLVM ? "%s.ll" : "%s.ir", result);
if (compiler.build.ir_file_dir) *ir_filename = file_append_path(compiler.build.ir_file_dir, *ir_filename);
*object_filename = str_printf("%s%s", result, get_object_extension());
if (compiler.build.emit_asm)
{
*asm_filename = str_printf("%s.s", result);
if (compiler.build.asm_file_dir) *asm_filename = file_append_path(compiler.build.asm_file_dir, *asm_filename);
}
if (compiler.build.object_file_dir) *object_filename = file_append_path(compiler.build.object_file_dir, *object_filename);
}

View File

@@ -491,7 +491,6 @@ void compiler_compile(void)
UNREACHABLE
}
compiler_ir_gen_time = bench_mark();
const char *output_exe = NULL;
const char *output_static = NULL;
const char *output_dynamic = NULL;
@@ -518,6 +517,12 @@ void compiler_compile(void)
output_dynamic = dynamic_lib_name();
break;
case TARGET_TYPE_OBJECT_FILES:
if (compiler.obj_output)
{
OUTF("Object file %s created.\n", compiler.obj_output);
break;
}
OUTF("Object files written to %s.\n", compiler.build.object_file_dir);
break;
case TARGET_TYPE_PREPARE:
break;
@@ -525,7 +530,14 @@ void compiler_compile(void)
UNREACHABLE
}
}
if (compiler.build.emit_llvm)
{
OUTF("LLVM files written to %s.\n", compiler.build.ir_file_dir);
}
if (compiler.build.emit_asm)
{
OUTF("Asm files written to %s.\n", compiler.build.asm_file_dir);
}
free_arenas();
uint32_t output_file_count = vec_size(gen_contexts);
@@ -537,6 +549,7 @@ void compiler_compile(void)
cfiles_library += vec_size(lib->csources);
}
unsigned total_output = output_file_count + cfiles + cfiles_library + external_objfile_count;
if (total_output > MAX_OUTPUT_FILES)
{
error_exit("Too many output files.");
@@ -1430,6 +1443,9 @@ const char *get_object_extension(void)
{
case ANY_WINDOWS_ARCH_OS:
return ".obj";
case WASM32:
case WASM64:
return ".wasm";
default:
return ".o";
}

View File

@@ -1876,6 +1876,7 @@ typedef struct
PlatformTarget platform;
Linking linking;
GlobalContext context;
const char *obj_output;
} CompilerState;
extern CompilerState compiler;

View File

@@ -717,7 +717,7 @@ void gencontext_print_llvm_ir(GenContext *context)
char *err = NULL;
if (LLVMPrintModuleToFile(context->module, context->ir_filename, &err))
{
error_exit("Could not emit ir to file: %s", err);
error_exit("Could not emit ir '%s' to file: %s", context->ir_filename, err);
}
}