mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
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:
committed by
Christoffer Lerno
parent
9de932a24d
commit
f028bc274f
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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; })
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -367,4 +367,4 @@ typedef struct
|
|||||||
} PlatformTarget;
|
} PlatformTarget;
|
||||||
|
|
||||||
|
|
||||||
extern PlatformTarget platform_target;
|
extern PlatformTarget platform_target;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,4 @@
|
|||||||
|
|
||||||
|
|
||||||
void bench_begin(void);
|
void bench_begin(void);
|
||||||
double bench_mark(void);
|
double bench_mark(void);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,4 +26,4 @@
|
|||||||
#else
|
#else
|
||||||
#define PLATFORM_WINDOWS 0
|
#define PLATFORM_WINDOWS 0
|
||||||
#define PLATFORM_POSIX 1
|
#define PLATFORM_POSIX 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user