fix: binary not build properly
This commit is contained in:
parent
76f5a0fd7f
commit
0b1245b9cc
|
@ -17,6 +17,6 @@ print_asm = true
|
|||
print_ir = true
|
||||
print_ast = true
|
||||
|
||||
[[targets.dependencies]]
|
||||
[targets.dependencies]
|
||||
# link against system default libc shared library
|
||||
libc = { shared = true }
|
||||
libc = { library = "c", shared = true }
|
||||
|
|
|
@ -10,5 +10,5 @@ fun main()
|
|||
# entrypoint function
|
||||
fun _start() {
|
||||
main()
|
||||
exit(0 as i32)
|
||||
_exit(0 as i32)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,3 @@ include "types"
|
|||
|
||||
# from unistd.h
|
||||
fun _exit(in i32: code)
|
||||
|
||||
# Return control back to the operating system
|
||||
fun exit(in i32: code) {
|
||||
_exit(code)
|
||||
}
|
||||
|
|
|
@ -70,10 +70,10 @@ void AST_init() {
|
|||
|
||||
lookup_table[AST_Typedef] = "typedef";
|
||||
lookup_table[AST_Box] = "box";
|
||||
lookup_table[AST_FunDecl] = "fun";
|
||||
lookup_table[AST_FunDef] = "fun";
|
||||
lookup_table[AST_ProcDecl] = "fun";
|
||||
lookup_table[AST_ProcDef] = "fun";
|
||||
lookup_table[AST_FunDecl] = "fundef";
|
||||
lookup_table[AST_FunDef] = "fundecl";
|
||||
lookup_table[AST_ProcDecl] = "procdef";
|
||||
lookup_table[AST_ProcDef] = "procdef";
|
||||
|
||||
lookup_table[AST_Call] = "funcall";
|
||||
lookup_table[AST_Typecast] = "typecast";
|
||||
|
@ -340,11 +340,16 @@ void AST_import_module(AST_NODE_PTR dst, size_t k, AST_NODE_PTR src) {
|
|||
assert(dst != NULL);
|
||||
assert(src != NULL);
|
||||
|
||||
size_t d = 0;
|
||||
|
||||
size_t elements = src->children->len;
|
||||
for (size_t i = 0; i < elements; i++) {
|
||||
AST_NODE_PTR node = AST_remove_child(src, 0);
|
||||
|
||||
if (node->kind == AST_FunDef) {
|
||||
// TODO: resolve by public symbols
|
||||
switch (node->kind) {
|
||||
case AST_FunDef:
|
||||
{
|
||||
AST_NODE_PTR decl = AST_new_node(node->location, AST_FunDecl, NULL);
|
||||
|
||||
for (int u = 0; u < node->children->len - 1; u++) {
|
||||
|
@ -352,9 +357,30 @@ void AST_import_module(AST_NODE_PTR dst, size_t k, AST_NODE_PTR src) {
|
|||
}
|
||||
|
||||
node = decl;
|
||||
break;
|
||||
}
|
||||
case AST_ProcDef:
|
||||
{
|
||||
AST_NODE_PTR decl = AST_new_node(node->location, AST_ProcDecl, NULL);
|
||||
|
||||
for (int u = 0; u < node->children->len - 1; u++) {
|
||||
AST_push_node(decl, AST_get_node(node, u));
|
||||
}
|
||||
|
||||
AST_insert_node(dst, k + i, node);
|
||||
node = decl;
|
||||
break;
|
||||
}
|
||||
case AST_Typedef:
|
||||
case AST_Def:
|
||||
break;
|
||||
default:
|
||||
node = NULL;
|
||||
}
|
||||
|
||||
if (node != NULL) {
|
||||
AST_insert_node(dst, k + d, node);
|
||||
d++;
|
||||
}
|
||||
}
|
||||
AST_delete_node(src);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
static GHashTable* args = NULL;
|
||||
|
||||
static Dependency *new_dependency();
|
||||
|
||||
static void clean(void) {
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
@ -296,7 +298,7 @@ void print_help(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void get_bool(bool* boolean, const toml_table_t* table,
|
||||
static bool get_bool(bool* boolean, const toml_table_t* table,
|
||||
const char* name) {
|
||||
DEBUG("retrieving boolean %s", name);
|
||||
|
||||
|
@ -306,9 +308,11 @@ static void get_bool(bool* boolean, const toml_table_t* table,
|
|||
*boolean = datum.u.b;
|
||||
DEBUG("boolean has value: %d", datum.u.b);
|
||||
}
|
||||
|
||||
return (bool) datum.ok;
|
||||
}
|
||||
|
||||
static void get_str(char** string, const toml_table_t* table,
|
||||
static bool get_str(char** string, const toml_table_t* table,
|
||||
const char* name) {
|
||||
DEBUG("retrieving string %s", name);
|
||||
|
||||
|
@ -318,9 +322,11 @@ static void get_str(char** string, const toml_table_t* table,
|
|||
*string = datum.u.s;
|
||||
DEBUG("string has value: %s", datum.u.s);
|
||||
}
|
||||
|
||||
return (bool) datum.ok;
|
||||
}
|
||||
|
||||
static void get_int(int* integer, const toml_table_t* table, const char* name) {
|
||||
static bool get_int(int* integer, const toml_table_t* table, const char* name) {
|
||||
DEBUG("retrieving integer %s", name);
|
||||
|
||||
const toml_datum_t datum = toml_int_in(table, name);
|
||||
|
@ -329,6 +335,8 @@ static void get_int(int* integer, const toml_table_t* table, const char* name) {
|
|||
*integer = (int) datum.u.i;
|
||||
DEBUG("integer has value: %ld", datum.u.i);
|
||||
}
|
||||
|
||||
return (bool) datum.ok;
|
||||
}
|
||||
|
||||
static void get_array(GArray* array, const toml_table_t* table,
|
||||
|
@ -404,11 +412,28 @@ static int get_mode_from_str(TargetCompilationMode* mode, const char* name) {
|
|||
static int parse_dependency(Dependency* dependency, toml_table_t* table, char* name) {
|
||||
dependency->name = mem_strdup(MemoryNamespaceOpt, name);
|
||||
|
||||
get_str(&dependency->path, table, "path");
|
||||
get_str(&dependency->target, table, "target");
|
||||
bool is_project = false;
|
||||
is_project |= get_str(&dependency->mode.project.path, table, "build-path");
|
||||
is_project |= get_str(&dependency->mode.project.target, table, "target");
|
||||
|
||||
bool is_library = false;
|
||||
is_library |= get_str(&dependency->mode.library.name, table, "library");
|
||||
is_library |= get_bool(&dependency->mode.library.shared, table, "shared");
|
||||
|
||||
dependency->libraries = mem_new_g_array(MemoryNamespaceOpt, sizeof(char*));
|
||||
|
||||
dependency->kind = is_project ? GemstoneProject : NativeLibrary;
|
||||
|
||||
if (is_library && is_project) {
|
||||
print_message(Error, "Mutually exclusive configs found");
|
||||
return PROJECT_SEMANTIC_ERR;
|
||||
}
|
||||
|
||||
if (!(is_library || is_project)) {
|
||||
print_message(Error, "Missing dependency config");
|
||||
return PROJECT_SEMANTIC_ERR;
|
||||
}
|
||||
|
||||
return PROJECT_OK;
|
||||
}
|
||||
|
||||
|
@ -464,7 +489,7 @@ static int parse_target(const ProjectConfig* config,
|
|||
}
|
||||
|
||||
toml_table_t* dependency_table = toml_table_in(dependencies, key);
|
||||
Dependency* dependency = mem_alloc(MemoryNamespaceOpt, sizeof(Dependency));
|
||||
Dependency* dependency = new_dependency();
|
||||
if (parse_dependency(dependency, dependency_table, key) == PROJECT_SEMANTIC_ERR) {
|
||||
return PROJECT_SEMANTIC_ERR;
|
||||
}
|
||||
|
@ -476,6 +501,14 @@ static int parse_target(const ProjectConfig* config,
|
|||
return PROJECT_OK;
|
||||
}
|
||||
|
||||
static Dependency* new_dependency() {
|
||||
Dependency* dependency = mem_alloc(MemoryNamespaceOpt, sizeof(Dependency));
|
||||
|
||||
memset(dependency, 0, sizeof(Dependency));
|
||||
|
||||
return dependency;
|
||||
}
|
||||
|
||||
static int parse_targets(ProjectConfig* config, const toml_table_t* root) {
|
||||
DEBUG("parsing targets of project \"%s\"", config->name);
|
||||
|
||||
|
|
|
@ -34,10 +34,27 @@ typedef enum TargetCompilationMode_t {
|
|||
Library
|
||||
} TargetCompilationMode;
|
||||
|
||||
typedef enum DependencyKind_t {
|
||||
GemstoneProject,
|
||||
NativeLibrary
|
||||
} DependencyKind;
|
||||
|
||||
// Possible configuration modes:
|
||||
// - build project (local/git)
|
||||
// - native library (static/shared)
|
||||
typedef struct Dependency_t {
|
||||
char *name;
|
||||
DependencyKind kind;
|
||||
union {
|
||||
struct {
|
||||
char *path;
|
||||
char *target;
|
||||
} project;
|
||||
struct {
|
||||
char *name;
|
||||
bool shared;
|
||||
} library;
|
||||
} mode;
|
||||
GArray *libraries;
|
||||
} Dependency;
|
||||
|
||||
|
@ -114,6 +131,7 @@ typedef struct Option_t {
|
|||
* @return A pointer to a new target configuration.
|
||||
*/
|
||||
[[nodiscard("must be freed")]]
|
||||
|
||||
TargetConfig *default_target_config();
|
||||
|
||||
/**
|
||||
|
@ -122,6 +140,7 @@ TargetConfig* default_target_config();
|
|||
* @return A pointer to a new project configuration.
|
||||
*/
|
||||
[[nodiscard("must be freed")]]
|
||||
|
||||
ProjectConfig *default_project_config();
|
||||
|
||||
/**
|
||||
|
@ -130,6 +149,7 @@ ProjectConfig* default_project_config();
|
|||
* @return A default config with user specified values.
|
||||
*/
|
||||
[[nodiscard("must be freed")]]
|
||||
|
||||
TargetConfig *default_target_config_from_args();
|
||||
|
||||
/**
|
||||
|
@ -139,6 +159,7 @@ TargetConfig* default_target_config_from_args();
|
|||
* @return
|
||||
*/
|
||||
[[gnu::nonnull(1)]]
|
||||
|
||||
int load_project_config(ProjectConfig *config);
|
||||
|
||||
/**
|
||||
|
@ -151,12 +172,14 @@ void print_help(void);
|
|||
* @param config The config to free.
|
||||
*/
|
||||
[[gnu::nonnull(1)]]
|
||||
|
||||
void delete_project_config(ProjectConfig *config);
|
||||
|
||||
/**
|
||||
* @brief Delete a target configuration by deallocation.
|
||||
*/
|
||||
[[gnu::nonnull(1)]]
|
||||
|
||||
void delete_target_config(TargetConfig *);
|
||||
|
||||
/**
|
||||
|
@ -174,6 +197,7 @@ void parse_options(int argc, char* argv[]);
|
|||
* @return 1 if the options was set, 0 otherwise
|
||||
*/
|
||||
[[gnu::nonnull(1)]]
|
||||
|
||||
bool is_option_set(const char *option);
|
||||
|
||||
/**
|
||||
|
@ -183,6 +207,7 @@ bool is_option_set(const char* option);
|
|||
* @return A valid option struct or NULL if not found.
|
||||
*/
|
||||
[[gnu::nonnull(1)]]
|
||||
|
||||
const Option *get_option(const char *option);
|
||||
|
||||
/**
|
||||
|
@ -192,6 +217,7 @@ const Option* get_option(const char* option);
|
|||
* @return an array of options that followed command.
|
||||
*/
|
||||
[[gnu::nonnull(1)]] [[nodiscard("must be freed")]]
|
||||
|
||||
GArray *get_non_options_after(const char *command);
|
||||
|
||||
void init_toml();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <sys/log.h>
|
||||
#include <unistd.h>
|
||||
#include <yacc/parser.tab.h>
|
||||
#include <link/lib.h>
|
||||
|
||||
#define GRAPHVIZ_FILE_EXTENSION "gv"
|
||||
|
||||
|
@ -244,8 +245,10 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
Dependency* dependency =
|
||||
g_hash_table_lookup(target->dependencies, child->value);
|
||||
|
||||
switch (dependency->kind) {
|
||||
case GemstoneProject:
|
||||
gchar* cwd = g_get_current_dir();
|
||||
chdir(dependency->path);
|
||||
chdir(dependency->mode.project.path);
|
||||
|
||||
ProjectConfig* new_config = default_project_config();
|
||||
if (load_project_config(new_config)) {
|
||||
|
@ -254,21 +257,21 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
TargetConfig* dep_target = g_hash_table_lookup(new_config->targets, dependency->target);
|
||||
TargetConfig* dep_target = g_hash_table_lookup(new_config->targets, dependency->mode.project.target);
|
||||
if (build_target(unit, dep_target)) {
|
||||
print_message(Error, "Failed to build project config: `%s`",
|
||||
child->value);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
GPathBuf* buf = g_path_buf_new_from_path(dependency->path);
|
||||
TargetConfig* dep_conf = g_hash_table_lookup(new_config->targets, dependency->target);
|
||||
GPathBuf* buf = g_path_buf_new_from_path(dependency->mode.project.path);
|
||||
TargetConfig* dep_conf = g_hash_table_lookup(new_config->targets, dependency->mode.project.target);
|
||||
char* root_mod = dep_conf->root_module;
|
||||
g_path_buf_push(buf, root_mod);
|
||||
char* rel_path = g_path_buf_to_path(buf);
|
||||
|
||||
GPathBuf* dep_bin = g_path_buf_new();
|
||||
g_path_buf_push(dep_bin, dependency->path);
|
||||
g_path_buf_push(dep_bin, dependency->mode.project.path);
|
||||
g_path_buf_push(dep_bin, dep_conf->archive_directory);
|
||||
g_path_buf_push(dep_bin, g_strjoin(".", dep_conf->name, "o", NULL));
|
||||
char* dep_bin_path = g_path_buf_to_path(dep_bin);
|
||||
|
@ -286,7 +289,7 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
AST_NODE_PTR imported_module =
|
||||
AST_new_node(empty_location(imported_file), AST_Module, NULL);
|
||||
|
||||
if (compile_file_to_ast(imported_module, imported_file)
|
||||
if (compile_module_with_dependencies(unit, imported_file, dep_conf, imported_module)
|
||||
== EXIT_SUCCESS) {
|
||||
AST_import_module(root_module, i + 1, imported_module);
|
||||
} else {
|
||||
|
@ -304,6 +307,36 @@ static int compile_module_with_dependencies(ModuleFileStack* unit,
|
|||
|
||||
chdir(cwd);
|
||||
|
||||
GHashTableIter iter;
|
||||
|
||||
g_hash_table_iter_init(&iter, dep_target->dependencies);
|
||||
char* key;
|
||||
Dependency* dep;
|
||||
while (g_hash_table_iter_next(&iter, (gpointer) &key, (gpointer) &dep)) {
|
||||
if (dep->kind == GemstoneProject) {
|
||||
for (guint i = 0; i < dep->libraries->len; i++) {
|
||||
char* dep_lib = g_array_index(dep->libraries, char*, i);
|
||||
g_array_append_val(dependency->libraries, dep_lib);
|
||||
}
|
||||
} else if (dep->kind == NativeLibrary) {
|
||||
char* library_name = build_platform_library_name(dep->mode.library.name, dep->mode.library.shared);
|
||||
g_array_append_val(dependency->libraries, library_name);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NativeLibrary:
|
||||
|
||||
char* library_name = build_platform_library_name(dependency->mode.library.name, dependency->mode.library.shared);
|
||||
g_array_append_val(dependency->libraries, library_name);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
print_message(Error, "Cannot resolve path for import: `%s`",
|
||||
child->value);
|
||||
|
|
|
@ -72,3 +72,18 @@ void link_print_available_driver() {
|
|||
printf(" - %s\n", (char*) key);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* get_library_file_extension(bool shared) {
|
||||
if (shared) {
|
||||
return "so";
|
||||
} else {
|
||||
return "o";
|
||||
}
|
||||
}
|
||||
|
||||
char* build_platform_library_name(char* basename, bool shared) {
|
||||
char* library_name = g_strjoin("", "lib", basename, ".", get_library_file_extension(shared), NULL);
|
||||
char* cached_library_name = mem_strdup(MemoryNamespaceLld, library_name);
|
||||
g_free(library_name);
|
||||
return cached_library_name;
|
||||
}
|
||||
|
|
|
@ -15,4 +15,6 @@ bool link_run(TargetLinkConfig*);
|
|||
|
||||
void link_print_available_driver();
|
||||
|
||||
char* build_platform_library_name(char* basename, bool shared);
|
||||
|
||||
#endif // GEMSTONE_LIB_H
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
extern int lld_main(int Argc, const char **Argv, const char **outstr);
|
||||
|
||||
const char* FLAGS[] = {
|
||||
""
|
||||
"--fatal-warnings",
|
||||
"--Bdynamic",
|
||||
"--dynamic-linker=/usr/bin/ld.so"
|
||||
};
|
||||
|
||||
bool lldc_link(TargetLinkConfig* config) {
|
||||
|
@ -21,17 +23,17 @@ bool lldc_link(TargetLinkConfig* config) {
|
|||
char* linker = "ld.lld";
|
||||
g_array_append_val(arguments, linker);
|
||||
|
||||
for (guint i = 0; i < config->object_file_names->len; i++) {
|
||||
char* obj = g_array_index(config->object_file_names, char*, i);
|
||||
g_array_append_val(arguments, obj);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(FLAGS)/sizeof(char*); i++) {
|
||||
char* flag = (char*) FLAGS[i];
|
||||
|
||||
g_array_append_val(arguments, flag);
|
||||
}
|
||||
|
||||
for (guint i = 0; i < config->object_file_names->len; i++) {
|
||||
char* obj = g_array_index(config->object_file_names, char*, i);
|
||||
g_array_append_val(arguments, obj);
|
||||
}
|
||||
|
||||
char* output_flag = "-o";
|
||||
g_array_append_val(arguments, output_flag);
|
||||
g_array_append_val(arguments, config->output_file);
|
||||
|
|
|
@ -98,8 +98,21 @@ TargetLinkConfig* lld_create_link_config(__attribute__((unused))
|
|||
|
||||
for (guint k = 0; k < dep->libraries->len; k++) {
|
||||
char* lib = g_array_index(dep->libraries, char*, k);
|
||||
if (lib == NULL)
|
||||
continue;
|
||||
|
||||
// resolve path to object file
|
||||
if (g_file_test(lib, G_FILE_TEST_EXISTS)) {
|
||||
g_array_append_val(config->object_file_names, lib);
|
||||
continue;
|
||||
}
|
||||
|
||||
char* path = get_absolute_link_path(target_config, lib);
|
||||
if (path == NULL) {
|
||||
print_message(Error, "Unable to resolve dependency: %s", lib);
|
||||
} else {
|
||||
g_array_append_val(config->object_file_names, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ authors = [ "Sven Vogel <sven.vogel123@web.de>" ]
|
|||
[[targets]]
|
||||
name = "prime"
|
||||
import-paths = [ "." ]
|
||||
link-paths = [ "/usr/lib" ]
|
||||
root = "main.gsc"
|
||||
mode = "application"
|
||||
output = "bin"
|
||||
|
@ -18,4 +19,4 @@ print_ir = true
|
|||
print_ast = true
|
||||
|
||||
[targets.dependencies]
|
||||
std = { path = "../../lib/src", target = "gsc-libc" }
|
||||
std = { build-path = "../../lib/src", target = "gsc-libc" }
|
||||
|
|
Loading…
Reference in New Issue