added: linker file discovery
This commit is contained in:
parent
110946b1e1
commit
bd368f99ef
|
@ -107,32 +107,6 @@ TargetConfig* default_target_config() {
|
|||
return config;
|
||||
}
|
||||
|
||||
const char* get_absolute_link_path(const TargetConfig* config, const char* link_target_name) {
|
||||
|
||||
for (guint i = 0; i < config->link_search_paths->len; i++) {
|
||||
const char* link_directory_path = g_array_index(config->link_search_paths, char*, i);
|
||||
|
||||
char* path = g_build_filename(link_directory_path, link_target_name, NULL);
|
||||
char* cwd = g_get_current_dir();
|
||||
char* canonical = g_canonicalize_filename(path, cwd);
|
||||
|
||||
const gboolean exists = g_file_test(canonical, G_FILE_TEST_EXISTS);
|
||||
const gboolean is_dir = g_file_test(canonical, G_FILE_TEST_IS_DIR);
|
||||
|
||||
g_free(path);
|
||||
g_free(cwd);
|
||||
|
||||
if (exists && !is_dir) {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
g_free(canonical);
|
||||
}
|
||||
|
||||
// file not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TargetConfig* default_target_config_from_args() {
|
||||
DEBUG("generating default target from command line...");
|
||||
|
||||
|
|
|
@ -48,12 +48,21 @@ LLVMCodeGenOptLevel llvm_opt_from_int(int level) {
|
|||
PANIC("invalid code generation optimization level: %d", level);
|
||||
}
|
||||
|
||||
static char* create_target_output_name(const TargetConfig* config) {
|
||||
char* prefix = "";
|
||||
if (config->mode == Library) {
|
||||
prefix = "lib";
|
||||
}
|
||||
|
||||
return g_strjoin("", prefix, config->name, NULL);
|
||||
}
|
||||
|
||||
Target create_target_from_config(const TargetConfig* config) {
|
||||
DEBUG("Building target from configuration");
|
||||
|
||||
Target target = create_native_target();
|
||||
|
||||
target.name.str = config->name;
|
||||
target.name.str = create_target_output_name(config);
|
||||
target.name.allocation = NONE; // freed later by compiler
|
||||
|
||||
target.opt = llvm_opt_from_int(config->optimization_level);
|
||||
|
|
|
@ -3,4 +3,88 @@
|
|||
//
|
||||
|
||||
#include <llvm/link/lld.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
const char* get_absolute_link_path(const TargetConfig* config, const char* link_target_name) {
|
||||
|
||||
for (guint i = 0; i < config->link_search_paths->len; i++) {
|
||||
const char* link_directory_path = g_array_index(config->link_search_paths, char*, i);
|
||||
|
||||
char* path = g_build_filename(link_directory_path, link_target_name, NULL);
|
||||
char* cwd = g_get_current_dir();
|
||||
char* canonical = g_canonicalize_filename(path, cwd);
|
||||
|
||||
const gboolean exists = g_file_test(canonical, G_FILE_TEST_EXISTS);
|
||||
const gboolean is_dir = g_file_test(canonical, G_FILE_TEST_IS_DIR);
|
||||
|
||||
g_free(path);
|
||||
g_free(cwd);
|
||||
|
||||
if (exists && !is_dir) {
|
||||
return canonical;
|
||||
}
|
||||
|
||||
g_free(canonical);
|
||||
}
|
||||
|
||||
// file not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TargetLinkConfig* lld_create_link_config(const Target* target, const TargetConfig* target_config, const Module* module) {
|
||||
DEBUG("generating link configuration");
|
||||
|
||||
TargetLinkConfig* config = malloc(sizeof(TargetLinkConfig));
|
||||
|
||||
config->object_file_names = g_array_new(FALSE, FALSE, sizeof(char*));
|
||||
|
||||
// append build object file
|
||||
const char* target_object = get_absolute_link_path(target_config, (const char*) target->name.str);
|
||||
if (target_object == NULL) {
|
||||
ERROR("failed to resolve path to target object: %s", target->name.str);
|
||||
lld_delete_link_config(config);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_array_append_val(config->object_file_names, target_object);
|
||||
INFO("resolved path of target object: %s", target_object);
|
||||
|
||||
// resolve absolute paths to dependent library object files
|
||||
DEBUG("resolving target dependencies...");
|
||||
for (guint i = 0; i < module->imports->len; i++) {
|
||||
const char* dependency = g_array_index(module->imports, const char*, i);
|
||||
|
||||
const char* dependency_object = get_absolute_link_path(target_config, dependency);
|
||||
if (dependency_object == NULL) {
|
||||
ERROR("failed to resolve path to dependency object: %s", dependency);
|
||||
lld_delete_link_config(config);
|
||||
return NULL;
|
||||
}
|
||||
g_array_append_val(config->object_file_names, dependency_object);
|
||||
INFO("resolved path of target object: %s", dependency_object);
|
||||
}
|
||||
|
||||
INFO("resolved %d dependencies", config->object_file_names->len);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
BackendError lld_link_target(TargetLinkConfig* config) {
|
||||
BackendError err = SUCCESS;
|
||||
|
||||
char*
|
||||
|
||||
for (guint i = 0; i < config->object_file_names->len; i++) {
|
||||
const char* path = g_array_index(config->object_file_names, const char*, i);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void lld_delete_link_config(TargetLinkConfig* config) {
|
||||
for (guint i = 0; i < config->object_file_names->len; i++) {
|
||||
free((void*) g_array_index(config->object_file_names, const char*, i));
|
||||
}
|
||||
g_array_free(config->object_file_names, TRUE);
|
||||
free(config);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,10 @@
|
|||
#include <codegen/backend.h>
|
||||
#include <llvm/backend.h>
|
||||
|
||||
/**
|
||||
* @brief Link the target by its configuration to the final output.
|
||||
* @param target
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
BackendError link_target(const Target* target, const TargetConfig* config);
|
||||
TargetLinkConfig* lld_create_link_config(const Target * target, const TargetConfig* target_config, const Module* module);
|
||||
|
||||
BackendError lld_link_target(TargetLinkConfig* config);
|
||||
|
||||
void lld_delete_link_config(TargetLinkConfig* config);
|
||||
|
||||
#endif // LLVM_BACKEND_LLD_H
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/log.h>
|
||||
#include <llvm/link/lld.h>
|
||||
|
||||
BackendError export_IR(LLVMBackendCompileUnit* unit, const Target* target,
|
||||
const TargetConfig* config) {
|
||||
|
@ -242,6 +243,12 @@ BackendError parse_module(const Module* module, const TargetConfig* config) {
|
|||
|
||||
export_module(unit, &target, config);
|
||||
|
||||
TargetLinkConfig* link_config = lld_create_link_config(&target, target, module);
|
||||
|
||||
lld_link_target(link_config);
|
||||
|
||||
lld_delete_link_config(link_config);
|
||||
|
||||
delete_target(target);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue