added: linker wrapper for lld

This commit is contained in:
Sven Vogel 2024-06-08 22:31:33 +02:00
parent 6e59b7ac73
commit ac813ae8bf
4 changed files with 120 additions and 12 deletions

View File

@ -76,6 +76,8 @@ include(FindPkgConfig)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_search_module(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
link_libraries(PkgConfig::GLIB)
# ------------------------------------------------ # # ------------------------------------------------ #
# TOML-C99 # # TOML-C99 #
# ------------------------------------------------ # # ------------------------------------------------ #
@ -96,6 +98,21 @@ set_target_properties(tomlc99
include_directories(${PROJECT_SOURCE_DIR}/dep/tomlc99) include_directories(${PROJECT_SOURCE_DIR}/dep/tomlc99)
link_libraries(tomlc99)
# ------------------------------------------------ #
# LLD-C-Layer #
# ------------------------------------------------ #
add_subdirectory(dep/lldcl)
# Link lld libs and C++ LIBC
link_libraries(lldcl
lldCommon
lldCOFF
lldELF
lldMinGW
stdc++)
# ------------------------------------------------ # # ------------------------------------------------ #
# LLVM backend # # LLVM backend #
@ -144,10 +161,6 @@ set_target_properties(release
OUTPUT_NAME "gsc" OUTPUT_NAME "gsc"
RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/release) RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/release)
target_link_libraries(release PkgConfig::GLIB)
target_link_libraries(release tomlc99)
# FIXME: cannot compile with /O2 because of /RTC1 flag # FIXME: cannot compile with /O2 because of /RTC1 flag
if (MSVC) if (MSVC)
set(RELEASE_FLAGS) set(RELEASE_FLAGS)
@ -183,10 +196,6 @@ set_target_properties(debug
OUTPUT_NAME "gsc" OUTPUT_NAME "gsc"
RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/debug) RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/debug)
target_link_libraries(debug PkgConfig::GLIB)
target_link_libraries(debug tomlc99)
if (MSVC) if (MSVC)
set(DEBUG_FLAGS /DEBUG) set(DEBUG_FLAGS /DEBUG)
else() else()
@ -216,10 +225,6 @@ set_target_properties(check
OUTPUT_NAME "gsc" OUTPUT_NAME "gsc"
RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/check) RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/check)
target_link_libraries(check PkgConfig::GLIB)
target_link_libraries(check tomlc99)
if (MSVC) if (MSVC)
set(CHECK_FLAGS /DEBUG /WX) set(CHECK_FLAGS /DEBUG /WX)
else() else()

36
dep/lldcl/CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.15...3.25)
project(gemstone
VERSION 0.1.0
DESCRIPTION "programming language compiler lld c++ layer"
LANGUAGES CXX)
set(GEMSTONE_BINARY_DIR ${PROJECT_SOURCE_DIR}/../../bin)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ------------------------------------------------ #
# LLVM #
# ------------------------------------------------ #
# Fetch LLVM link configuration
execute_process(COMMAND llvm-config --libs all
OUTPUT_VARIABLE LLVM_LIBS)
# Strip whitespace from output
string(STRIP "${LLVM_LIBS}" LLVM_LIBS)
# Link all targets to LLVM
link_libraries(${LLVM_LIBS})
execute_process(COMMAND llvm-config --includedir
OUTPUT_VARIABLE LLVM_INCLUDE_DIR)
string(STRIP "${LLVM_INCLUDE_DIR}" LLVM_INCLUDE_DIR)
include_directories(${LLVM_INCLUDE_DIR})
file(GLOB_RECURSE SOURCE_FILES *.cpp)
add_library(lldcl ${SOURCE_FILES})
target_link_libraries(lldcl)
set_target_properties(lldcl
PROPERTIES
OUTPUT_NAME "lldcl"
ARCHIVE_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/dep)

50
dep/lldcl/lldcl.cpp Normal file
View File

@ -0,0 +1,50 @@
//
// Created by servostar on 6/8/24.
//
// based on: https://github.com/llvm/llvm-project/blob/main/lld/unittests/AsLibAll/AllDrivers.cpp
// https://github.com/numba/llvmlite/blob/main/ffi/linker.cpp
#include <lld/Common/Driver.h>
#include <llvm/Support/raw_ostream.h>
/*
* Gemstone supports Windows (COFF, MinGW) and GNU/Linux (ELF)
*/
LLD_HAS_DRIVER(coff)
LLD_HAS_DRIVER(elf)
LLD_HAS_DRIVER(mingw)
// LLD_HAS_DRIVER(macho)
// LLD_HAS_DRIVER(wasm)
#define LLD_COFF_ELF_MINGW_DRIVER { {lld::WinLink, &lld::coff::link}, {lld::Gnu, &lld::elf::link}, {lld::MinGW, &lld::mingw::link} }
extern "C" {
/**
* @brief C-wrapper for lldMain which is written in C++
* @param Argc
* @param Argv
* @param outstr
* @return
*/
int lld_main(int Argc, const char **Argv, const char **outstr) {
// StdOut
std::string stdout;
llvm::raw_string_ostream stdout_stream(stdout);
// StdErr
std::string stderr;
llvm::raw_string_ostream stderr_stream(stderr);
// convert arguments
std::vector<const char *> Args(Argv, Argv + Argc);
lld::Result result = lld::lldMain(Args, stdout_stream, stderr_stream, LLD_COFF_ELF_MINGW_DRIVER);
*outstr = strdup(stdout.c_str());
return !result.retCode && result.canRunAgain;
}
} // extern "C"

View File

@ -5,6 +5,11 @@
#include <llvm/link/lld.h> #include <llvm/link/lld.h>
#include <sys/log.h> #include <sys/log.h>
/*
* call the LLD linker
*/
extern int lld_main(int Argc, const char **Argv, const char **outstr);
const char* get_absolute_link_path(const TargetConfig* config, const char* link_target_name) { 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++) { for (guint i = 0; i < config->link_search_paths->len; i++) {
@ -72,6 +77,18 @@ TargetLinkConfig* lld_create_link_config(const Target* target, const TargetConfi
BackendError lld_link_target(TargetLinkConfig* config) { BackendError lld_link_target(TargetLinkConfig* config) {
BackendError err = SUCCESS; BackendError err = SUCCESS;
const char* message = NULL;
int status = lld_main(0, NULL, &message);
if (message != NULL) {
print_message(Warning, "Message from LLD: %s", message);
free((void*) message);
}
if (status != 0) {
err = new_backend_impl_error(Implementation, NULL, "failed to link target");
}
return err; return err;
} }