Use the platform linker by default, which will just be a call to "cc" (the Win solution will be done later)

This commit is contained in:
Christoffer Lerno
2021-04-14 13:53:34 +02:00
committed by Christoffer Lerno
parent 9de932a24d
commit f028bc274f
13 changed files with 92 additions and 44 deletions

View File

@@ -230,4 +230,4 @@ typedef struct
BuildOptions parse_arguments(int argc, const char *argv[]); BuildOptions parse_arguments(int argc, const char *argv[]);
ArchOsTarget arch_os_target_from_string(const char *target); ArchOsTarget arch_os_target_from_string(const char *target);

View File

@@ -5,4 +5,4 @@
// a copy of which can be found in the LICENSE file. // a copy of which can be found in the LICENSE file.
struct BuildOptions_; struct BuildOptions_;
void create_project(struct BuildOptions_ *build_options); void create_project(struct BuildOptions_ *build_options);

View File

@@ -182,9 +182,20 @@ void compiler_compile(BuildTarget *target)
vec_add(obj_files, file_name); vec_add(obj_files, file_name);
} }
if (create_exe && obj_format_linking_supported(platform_target.object_format)) if (create_exe)
{ {
linker(target->name, obj_files, source_count); if (target->arch_os_target == ARCH_OS_TARGET_DEFAULT)
{
platform_linker(target->name, obj_files, source_count);
}
else
{
if (!obj_format_linking_supported(platform_target.object_format) || !linker(target->name, obj_files, source_count))
{
printf("No linking is performed due to missing linker support.");
target->run_after_compile = false;
}
}
if (target->run_after_compile) if (target->run_after_compile)
{ {
system(strformat("./%s", target->name)); system(strformat("./%s", target->name));

View File

@@ -1412,13 +1412,13 @@ extern const char *kw___trunc;
#define AST_NEW_TOKEN(_kind, _token) new_ast(_kind, source_span_from_token_id(_token.id)) #define AST_NEW_TOKEN(_kind, _token) new_ast(_kind, source_span_from_token_id(_token.id))
#define AST_NEW(_kind, _loc) new_ast(_kind, _loc) #define AST_NEW(_kind, _loc) new_ast(_kind, _loc)
ARENA_DEF(ast, Ast); ARENA_DEF(ast, Ast)
ARENA_DEF(expr, Expr); ARENA_DEF(expr, Expr)
ARENA_DEF(sourceloc, SourceLocation); ARENA_DEF(sourceloc, SourceLocation)
ARENA_DEF(toktype, char); ARENA_DEF(toktype, char)
ARENA_DEF(tokdata, TokenData); ARENA_DEF(tokdata, TokenData)
ARENA_DEF(decl, Decl); ARENA_DEF(decl, Decl)
ARENA_DEF(type_info, TypeInfo); ARENA_DEF(type_info, TypeInfo)
static inline bool ast_ok(Ast *ast) { return ast == NULL || ast->ast_kind != AST_POISONED; } static inline bool ast_ok(Ast *ast) { return ast == NULL || ast->ast_kind != AST_POISONED; }
static inline bool ast_poison(Ast *ast) { ast->ast_kind = AST_POISONED; return false; } static inline bool ast_poison(Ast *ast) { ast->ast_kind = AST_POISONED; return false; }
@@ -1998,8 +1998,8 @@ static inline size_t type_min_alignment(size_t a, size_t b)
} }
bool obj_format_linking_supported(ObjectFormatType format_type); bool obj_format_linking_supported(ObjectFormatType format_type);
void linker(const char *output_file, const char **files, unsigned file_count); bool linker(const char *output_file, const char **files, unsigned file_count);
void platform_linker(const char *output_file, const char **files, unsigned file_count);
#define TRY_AST_OR(_ast_stmt, _res) ({ Ast* _ast = (_ast_stmt); if (!ast_ok(_ast)) return _res; _ast; }) #define TRY_AST_OR(_ast_stmt, _res) ({ Ast* _ast = (_ast_stmt); if (!ast_ok(_ast)) return _res; _ast; })
#define TRY_EXPR_OR(_expr_stmt, _res) ({ Expr* _expr = (_expr_stmt); if (!expr_ok(_expr)) return _res; _expr; }) #define TRY_EXPR_OR(_expr_stmt, _res) ({ Expr* _expr = (_expr_stmt); if (!expr_ok(_expr)) return _res; _expr; })

View File

@@ -14,7 +14,7 @@ static void add_files(const char ***args, const char **files_to_link, unsigned f
} }
} }
static void link_exe(const char *output_file, const char **files_to_link, unsigned file_count) static bool link_exe(const char *output_file, const char **files_to_link, unsigned file_count)
{ {
const char **args = NULL; const char **args = NULL;
vec_add(args, "-o"); vec_add(args, "-o");
@@ -24,7 +24,7 @@ static void link_exe(const char *output_file, const char **files_to_link, unsign
switch (platform_target.os) switch (platform_target.os)
{ {
case OS_TYPE_WIN32: case OS_TYPE_WIN32:
break; return false;
case OS_TYPE_MACOSX: case OS_TYPE_MACOSX:
add_files(&args, files_to_link, file_count); add_files(&args, files_to_link, file_count);
vec_add(args, "-lSystem"); vec_add(args, "-lSystem");
@@ -44,14 +44,13 @@ static void link_exe(const char *output_file, const char **files_to_link, unsign
break; break;
case OS_TYPE_WATCHOS: case OS_TYPE_WATCHOS:
case OS_TYPE_IOS: case OS_TYPE_IOS:
TODO return false;
case OS_TYPE_WASI: case OS_TYPE_WASI:
break; return false;
case OS_TYPE_OPENBSD: case OS_TYPE_OPENBSD:
case OS_TYPE_NETBSD: case OS_TYPE_NETBSD:
case OS_TYPE_FREE_BSD: case OS_TYPE_FREE_BSD:
TODO return false;
break;
case OS_TYPE_LINUX: case OS_TYPE_LINUX:
vec_add(args, "-m"); vec_add(args, "-m");
switch (platform_target.arch) switch (platform_target.arch)
@@ -84,21 +83,17 @@ static void link_exe(const char *output_file, const char **files_to_link, unsign
vec_add(args, "--dynamic-linker=/lib64/ld-linux-x86-64.so.2"); vec_add(args, "--dynamic-linker=/lib64/ld-linux-x86-64.so.2");
break; break;
case ARCH_TYPE_X86: case ARCH_TYPE_X86:
TODO // vec_add(args, "elf_i386");
vec_add(args, "elf_i386"); return false;
break;
case ARCH_TYPE_AARCH64: case ARCH_TYPE_AARCH64:
TODO
vec_add(args, "aarch64elf"); vec_add(args, "aarch64elf");
break; return false;
case ARCH_TYPE_RISCV32: case ARCH_TYPE_RISCV32:
TODO
vec_add(args, "elf32lriscv"); vec_add(args, "elf32lriscv");
break; return false;
case ARCH_TYPE_RISCV64: case ARCH_TYPE_RISCV64:
vec_add(args, "elf64lriscv"); vec_add(args, "elf64lriscv");
TODO return false;
break;
default: default:
UNREACHABLE UNREACHABLE
} }
@@ -108,7 +103,7 @@ static void link_exe(const char *output_file, const char **files_to_link, unsign
default: default:
add_files(&args, files_to_link, file_count); add_files(&args, files_to_link, file_count);
vec_add(args, platform_target.pie ? "-pie" : "-no_pie"); vec_add(args, platform_target.pie ? "-pie" : "-no_pie");
break; return false;
} }
bool success; bool success;
@@ -133,6 +128,7 @@ static void link_exe(const char *output_file, const char **files_to_link, unsign
{ {
error_exit("Failed to create an executable: %s", error); error_exit("Failed to create an executable: %s", error);
} }
return true;
} }
bool obj_format_linking_supported(ObjectFormatType format_type) bool obj_format_linking_supported(ObjectFormatType format_type)
@@ -153,9 +149,47 @@ bool obj_format_linking_supported(ObjectFormatType format_type)
UNREACHABLE UNREACHABLE
} }
void linker(const char *output_file, const char **files, unsigned file_count)
const char *concat_string_parts(const char **args)
{ {
link_exe(output_file, files, file_count); unsigned size_needed = 0;
VECEACH(args, i)
{
size_needed += strlen(args[i]) + 1;
}
char *output = malloc_arena(size_needed);
char *ptr = output;
VECEACH(args, i)
{
unsigned len = strlen(args[i]);
memcpy(ptr, args[i], len);
ptr += len;
*(ptr++) = ' ';
}
ptr[-1] = '\0';
return output;
}
void platform_linker(const char *output_file, const char **files, unsigned file_count)
{
const char **parts = NULL;
vec_add(parts, "cc");
vec_add(parts, "-o");
vec_add(parts, output_file);
for (unsigned i = 0; i < file_count; i++)
{
vec_add(parts, files[i]);
}
const char *output = concat_string_parts(parts);
if (system(output) != 0)
{
error_exit("Failed to link executable '%s' using command '%s'.\n", output_file, output);
}
printf("Program linked to executable '%s'.\n", output_file);
}
bool linker(const char *output_file, const char **files, unsigned file_count)
{
return link_exe(output_file, files, file_count);
} }
/** /**

View File

@@ -10,22 +10,25 @@ static void diagnostics_handler(LLVMDiagnosticInfoRef ref, void *context)
{ {
char *message = LLVMGetDiagInfoDescription(ref); char *message = LLVMGetDiagInfoDescription(ref);
LLVMDiagnosticSeverity severity = LLVMGetDiagInfoSeverity(ref); LLVMDiagnosticSeverity severity = LLVMGetDiagInfoSeverity(ref);
const char *severerity_name = "unknown"; const char *severity_name;
switch (severity) switch (severity)
{ {
case LLVMDSError: case LLVMDSError:
error_exit("LLVM error generating code for %s: %s", ((GenContext *)context)->ast_context->module->name, message); error_exit("LLVM error generating code for %s: %s", ((GenContext *)context)->ast_context->module->name, message);
case LLVMDSWarning: case LLVMDSWarning:
severerity_name = "warning"; severity_name = "warning";
break; break;
case LLVMDSRemark: case LLVMDSRemark:
severerity_name = "remark"; severity_name = "remark";
break; break;
case LLVMDSNote: case LLVMDSNote:
severerity_name = "note"; severity_name = "note";
break;
default:
severity_name = "message";
break; break;
} }
DEBUG_LOG("LLVM message [%s]: %s ", severerity_name, message); DEBUG_LOG("LLVM %s: %s ", severity_name, message);
LLVMDisposeMessage(message); LLVMDisposeMessage(message);
} }

View File

@@ -367,4 +367,4 @@ typedef struct
} PlatformTarget; } PlatformTarget;
extern PlatformTarget platform_target; extern PlatformTarget platform_target;

View File

@@ -9,9 +9,9 @@ static int begin = 0;
void bench_begin(void) void bench_begin(void)
{ {
begin = clock(); begin = (int)clock();
} }
double bench_mark(void) double bench_mark(void)
{ {
return (double)(clock() - begin) / (double)CLOCKS_PER_SEC; return (double)(clock() - begin) / (double)CLOCKS_PER_SEC;
} }

View File

@@ -6,4 +6,4 @@
void bench_begin(void); void bench_begin(void);
double bench_mark(void); double bench_mark(void);

View File

@@ -5,4 +5,4 @@
// a copy of which can be found in the LICENSE file. // a copy of which can be found in the LICENSE file.
void compiler_tests(void); void compiler_tests(void);

View File

@@ -21,7 +21,7 @@ int main(int argc, const char *argv[])
// Parse arguments. // Parse arguments.
BuildOptions build_options = parse_arguments(argc, argv); BuildOptions build_options = parse_arguments(argc, argv);
BuildTarget build_target = {}; BuildTarget build_target = { .name = NULL };
switch (build_options.command) switch (build_options.command)
{ {

View File

@@ -26,4 +26,4 @@
#else #else
#define PLATFORM_WINDOWS 0 #define PLATFORM_WINDOWS 0
#define PLATFORM_POSIX 1 #define PLATFORM_POSIX 1
#endif #endif

View File

@@ -4,4 +4,4 @@
// Use of this source code is governed by a LGPLv3.0 // Use of this source code is governed by a LGPLv3.0
// a copy of which can be found in the LICENSE file. // a copy of which can be found in the LICENSE file.
const char *find_executable_path(void); const char *find_executable_path(void);