added: linker wrapper for lld
This commit is contained in:
parent
6e59b7ac73
commit
ac813ae8bf
|
@ -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()
|
||||||
|
|
|
@ -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)
|
|
@ -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"
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue