Updates to the linker, tentative x86_64 support (and MacOS)

This commit is contained in:
Christoffer Lerno
2021-04-13 21:52:32 +02:00
committed by Christoffer Lerno
parent a3990f1b3d
commit fe3f7d427e
4 changed files with 139 additions and 24 deletions

View File

@@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v1
- name: (Linux) Download LLVM
run: |
sudo apt-get install libllvm11 llvm-11 llvm-11-dev llvm-11-runtime liblld-11-dev liblld-11
sudo apt-get install zlib1g zlib1g-dev clang-11 libllvm11 llvm-11 llvm-11-dev llvm-11-runtime liblld-11-dev liblld-11
- name: Build
run: |
mkdir build && cd build

View File

@@ -28,15 +28,10 @@ set(LLVM_LINK_COMPONENTS
Analysis
BitReader
Core
ExecutionEngine
InstCombine
Interpreter
MC
MCDisassembler
MCJIT
Object
OrcJIT
RuntimeDyld
ScalarOpts
Support
Target
@@ -46,10 +41,11 @@ set(LLVM_LINK_COMPONENTS
AsmPrinter
Linker
LTO
Option
WindowsManifest
DebugInfoPDB
LibDriver
Option
IrReader
)

View File

@@ -127,3 +127,32 @@ C3 on its dedicated Discord: https://discord.gg/qN76R87
- Discuss the language on discord to help iron out syntax.
- Stdlib work will soon start, do you want to help out building the C3 std lib?
- Do you want to do real compiler work? Everyone is welcome to contribute.
#### Installing on Ubuntu
(This installation has been tested on 20.10)
1. Make sure you have a C compiler that handles C11 and a C++ compiler, such as GCC or Clang. Git also needs to be installed.
2. Install CMake: `sudo apt install cmake`
3. Install LLVM 11: `sudo apt-get install clang-11 zlib1g zlib1g-dev libllvm11 llvm-11 llvm-11-dev llvm-11-runtime liblld-11-dev liblld-11`
4. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
5. Enter the C3C directory `cd c3c`.
6. Create a build directory `mkdir build`
7. Change directory to the build directory `cd build`
8. Set up CMake build for debug: `cmake -DLLVM_DIR=/usr/lib/llvm-11/cmake -DCMAKE_BUILD_TYPE=Debug ..`
9. Build: `cmake --build .`
You should now have a `c3c` executable.
You can try it out by running some sample code: `./c3c compile ../resources/examples/hash.c3`
#### Installing on OS X using Homebrew
2. Install CMake: `brew install cmake`
3. Install LLVM 11: `brew install llvm`
4. Clone the C3C github repository: `git clone https://github.com/c3lang/c3c.git`
5. Enter the C3C directory `cd c3c`.
6. Create a build directory `mkdir build`
7. Change directory to the build directory `cd build`
8. Set up CMake build for debug: `cmake ..`
9. Build: `cmake --build .`

View File

@@ -6,58 +6,125 @@ extern bool llvm_link_coff(const char **args, int arg_count, const char** error_
extern bool llvm_link_wasm(const char **args, int arg_count, const char** error_string);
extern bool llvm_link_mingw(const char **args, int arg_count, const char** error_string);
static void add_files(const char ***args, const char **files_to_link, unsigned file_count)
{
for (unsigned i = 0; i < file_count; i++)
{
vec_add(*args, files_to_link[i]);
}
}
static void link_exe(const char *output_file, const char **files_to_link, unsigned file_count)
{
int arg_count = (int)file_count + 2;
const char **args = NULL;
vec_add(args, "-o");
vec_add(args, output_file);
vec_add(args, "-m");
vec_add(args, platform_target.target_triple);
for (unsigned i = 0; i < file_count; i++)
{
args[i + 2] = files_to_link[i];
}
const char *error = NULL;
switch (platform_target.os)
{
case OS_TYPE_WIN32:
break;
case OS_TYPE_WATCHOS:
case OS_TYPE_MACOSX:
add_files(&args, files_to_link, file_count);
vec_add(args, "-lSystem");
vec_add(args, "-lm");
vec_add(args, "-syslibroot");
vec_add(args, "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk");
vec_add(args, platform_target.pie ? "-pie" : "-no_pie");
if (platform_target.pie)
{
vec_add(args, "-macosx_version_min");
vec_add(args, platform_target.arch == ARCH_TYPE_AARCH64 ? "11.0" : "10.8");
vec_add(args, "-pie");
}
else
{
vec_add(args, "-no_pie");
}
break;
case OS_TYPE_WATCHOS:
case OS_TYPE_IOS:
TODO
case OS_TYPE_WASI:
break;
case OS_TYPE_OPENBSD:
case OS_TYPE_NETBSD:
case OS_TYPE_FREE_BSD:
TODO
break;
case OS_TYPE_LINUX:
vec_add(args, "-m");
switch (platform_target.arch)
{
case ARCH_TYPE_X86_64:
vec_add(args, "elf_x86_64");
if (platform_target.pie || platform_target.pic)
{
vec_add(args, "--eh-frame-hdr");
vec_add(args, "/usr/lib/x86_64-linux-gnu/crt1.o");
vec_add(args, "/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o");
add_files(&args, files_to_link, file_count);
vec_add(args, "/usr/lib/x86_64-linux-gnu/crti.o");
vec_add(args, "/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o");
vec_add(args, "-pie");
}
else
{
vec_add(args, "/usr/lib/x86_64-linux-gnu/Scrt1.o");
vec_add(args, "/usr/lib/gcc/x86_64-linux-gnu/10/crtbegin.o");
add_files(&args, files_to_link, file_count);
vec_add(args, "-lc");
vec_add(args, "-lm");
vec_add(args, "/usr/lib/x86_64-linux-gnu/crti.o");
vec_add(args, "/usr/lib/gcc/x86_64-linux-gnu/10/crtend.o");
vec_add(args, "-no-pie");
}
vec_add(args, "/usr/lib/x86_64-linux-gnu/crtn.o");
vec_add(args, "-L/usr/lib/x86_64-linux-gnu/");
vec_add(args, "--dynamic-linker=/lib64/ld-linux-x86-64.so.2");
break;
case ARCH_TYPE_X86:
TODO
vec_add(args, "elf_i386");
break;
case ARCH_TYPE_AARCH64:
TODO
vec_add(args, "aarch64elf");
break;
case ARCH_TYPE_RISCV32:
TODO
vec_add(args, "elf32lriscv");
break;
case ARCH_TYPE_RISCV64:
vec_add(args, "elf64lriscv");
TODO
break;
default:
UNREACHABLE
}
vec_add(args, "-L/usr/lib/");
vec_add(args, "-L/lib/");
vec_add(args, "-lc");
vec_add(args, "-lm");
vec_add(args, platform_target.pie ? "-pie" : "-no-pie");
break;
default:
add_files(&args, files_to_link, file_count);
vec_add(args, platform_target.pie ? "-pie" : "-no_pie");
break;
}
vec_add(args, platform_target.pie ? "-pie" : "-no_pie");
bool success;
switch (platform_target.object_format)
{
case OBJ_FORMAT_COFF:
success = llvm_link_coff(args, arg_count, &error);
success = llvm_link_coff(args, (int)vec_size(args), &error);
break;
case OBJ_FORMAT_ELF:
success = llvm_link_elf(args, arg_count, &error);
success = llvm_link_elf(args, (int)vec_size(args), &error);
break;
case OBJ_FORMAT_MACHO:
success = llvm_link_macho(args, arg_count, &error);
success = llvm_link_macho(args, (int)vec_size(args), &error);
break;
case OBJ_FORMAT_WASM:
success = llvm_link_wasm(args, arg_count, &error);
success = llvm_link_wasm(args, (int)vec_size(args), &error);
break;
default:
UNREACHABLE
@@ -90,3 +157,26 @@ void linker(const char *output_file, const char **files, unsigned file_count)
{
link_exe(output_file, files, file_count);
}
/**
* From Clang
* .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64})
.Cases("aarch64elfb", "aarch64linuxb", {ELF64BEKind, EM_AARCH64})
.Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
.Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
.Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
.Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
.Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
.Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
.Cases("elf32lppc", "elf32lppclinux", {ELF32LEKind, EM_PPC})
.Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
.Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
.Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
.Case("elf64ppc", {ELF64BEKind, EM_PPC64})
.Case("elf64lppc", {ELF64LEKind, EM_PPC64})
.Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
.Case("elf_i386", {ELF32LEKind, EM_386})
.Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
.Case("elf64_sparc", {ELF64BEKind, EM_SPARCV9})
.Case("msp430elf", {ELF32LEKind, EM_MSP430})
*/