These instructions are on building an OS Specific Toolchain using LLVM and clang instead of GCC.
Operating systems: Linux, Windows, Mac OS X, Android, iOS, Qualcomm QuRT GPU Compute APIs: CUDA, OpenCL, OpenGL Compute Shaders, Apple Metal, Microsoft Direct X 12 Rather than being a standalone programming language, Halide is embedded in C. HexagonOS is an open-source and freely distributed GNU/Linux distribution based on the popular Ubuntu Linux operating system, yet designed to be light, fast, modern, and intuitive for everyone by using a highly customized lightweight Xfce desktop environment. Boot options, supported architectures. IOS - OS X Prerequisites Mac® OS X® 110.9 (Mavericks) or higher 2 GB RAM minimum, 4 GB RAM recommended 1280 x 800 minimum screen resolution Safari web browser To install apps onto a device, you must be a member of Apple's iOS Developer Program Installation Java Development Kit (JDK) 7 Downlo. These instructions add your operating system as a new target. By following these instructions, hopefully you will have a LLVM-based toolchain for building applications that run under your OS! Note that LLVM is developed in C11 and uses many of the language's modern features, and there have been reported difficulties compiling some components.
THIS IS A WORK IN PROGRESS - DON'T FOLLOW THESE YET!
Note that LLVM by default builds cross-compilers for all targets, the right target simply have to be activated (why is there a LLVM Cross-Compiler page?) These instructions add your operating system as a new target. By following these instructions, hopefully you will have a LLVM-based toolchain for building applications that run under your OS!
Note that LLVM is developed in C++11 and uses many of the language's modern features, and there have been reported difficulties compiling some components on other compilers (such as GCC). If you run into trouble, you can try compiling LLVM with Clang.
|
These are the tools (built on LLVM) that we will be building and using:
First we must check out the source code and create the basic structure. We'll assume we want two directories - a 'llvm' directory containing the source code, and 'build' containing our build toolchain.
Check out the source LLVM+Clang source code:
Make a build directory
NEED REWRITE TO CMAKE
The first step is to get LLVM to recognize your OS as a platform. Like the other tutorial, we'll assume your OS is called MyOS. Of course, you'd replace MyOS with your own operating system's name (unless your OS is called MyOS).
In the enum called OSType (around line 120), add your OS:
In the function Triple::getOSTypeName (around line 135) add your OS:
In the function parseOS (around line 326), add your OS:
Around line 414 is getDefaultFormat that returns the default executable format type for a platform. The fallback is ELF, but if you want to use PE or MachO (or maybe your own) you can stick it here.
There is some platform specific stuff in llvm/lib/Support/* (particularly Hosts.cpp and the subdirectories), but they appear to be support files for the platform the compiler runs on, not targets.
ADD EXAMPLE LLD KOLIBRI
If your operating system uses its own executable format, you can find the relevant code under llvm/projects/lld/lib/ReaderWriter/, but this is a much more difficult job than porting using a common executable format like ELF, MachO, or PE.
NOTE: I am a different contributor (not MessiahAndrw), and my OS does use a different executable format. I will document my progress on that later.
We need to create a target so Clang knows a little bit about the platform it's compiling for, so we will create a TargetInfo object called MyOSTargetInfo. You can override some compiler internals here (such as setting the size of long ints) - look at what the other targets do for example.
Somewhere in this file, above AllocateTarget, create your target object:
In AllocateTarget, you'll need to add your OS in switch(Triple.getArch()):
Example: https://raw.githubusercontent.com/lexasub/llvm-project-kos/main/clang/lib/Driver/ToolChains/Kolibri.h
Next, we have to create a toolchain object that Clang uses to figure out how to connect to the other toolchain components (namely the linker and assembler) for our target.
Add this somewhere:
Note that we're inheriting from the Generic_ELF toolchain, but you can look at some other examples (Windows, Mac OS) for alternatives.
Example: https://raw.githubusercontent.com/lexasub/llvm-project-kos/main/clang/lib/Driver/ToolChains/Kolibri.cpp
Here's the code for the toolchain object, insert it somewhere in this file:
Note in the constructor that we have the ability to add default include paths, which are sent to our assembler and linker. We'll comment them out now so our system doesn't automatically try to add our host system's libraries when we compile code for our OS.
In the function InitHeaderSearch::AddDefaultCIncludePaths, add this somewhere, so we don't automatically add /usr/local/include as an include path:
If you want your target to automatically add default include paths, you can customize this file. Add your target under AddDefaultCIncludePaths, AddDefaultCPlusPlusIncludePaths, AddDefaultIncludePaths, etc.
We need make LLVM use our toolchain object when it targets our OS, so in Driver::getToolChain, add your OS to switch (Target.getOS()):
WHAT FILE IN NEW LLVM?MAY BE NEED REPLACED TO LLD CUSTOM
In here, we define the Assemble and Link classes that our toolchain object references:
TODO: We're inheriting from GnuTool, use LLD and LLVM-as.
WHAT FILE IN NEW LLVM?MAY BE NEED REPLACED TO LLD CUSTOM
Here's the code for our Assemble and Compile - they invoke 'as' and 'ld'.
TODO: Replace with LLD and LLVM-as.
Some Common options:
-DLLVM_ENABLE_PROJECTS='...' --- semicolon-separated list of the LLVM sub-projects you'd like to additionally build. Can include any of: clang, clang-tools-extra, libcxx, libcxxabi, libunwind, lldb, compiler-rt, lld, polly, or debuginfo-tests.
For example, to build LLVM, Clang, libcxx, and libcxxabi, use -DLLVM_ENABLE_PROJECTS='clang;libcxx;libcxxabi'.
-DCMAKE_INSTALL_PREFIX=directory --- Specify for directory the full path name of where you want the LLVM tools and libraries to be installed (default /usr/local).-DCMAKE_BUILD_TYPE=type --- Valid options for type are Debug, Release, RelWithDebInfo, and MinSizeRel. Default is Debug.-DLLVM_ENABLE_ASSERTIONS=On --- Compile with assertion checks enabled (default is Yes for Debug builds, No for all other build types).
The default target (i.e. ninja or make) will build all of LLVM.
The check-all target (i.e. ninja check-all) will run the regression tests to ensure everything is in working order.
CMake will generate targets for each tool and library, and most LLVM sub-projects generate their own check-<project> target.
Running a serial build will be slow. To improve speed, try running a parallel build. That's done by default in Ninja; for make, use the option -j NNN, where NNN is the number of parallel jobs, e.g. the number of CPUs you have.
sudo cmake install
Let's test out the compiler! Create a simple C file:
And compile it with the Clang system you just built: (Use --target=x86_64-myos if you added your OS as a 64-bit platform.)
TODO: The -c option tells us to just compile, because we haven't finished with the linker yet.
This is great, but you will notice you can't just start including <stdio.h> because you'll need to port a C library first. If you don't want to use the C library (you won't be able to use LibC++/the C++ library - and many of the fancier C++11 features that require runtime support) you can stop here.
At some point you'll likely want a C Library. Libc++ depends on a functioning C library.
TODO: Any Clang specific stuff here.
This section is for compiling the LLVM toolchain to run under your OS, rather than just build programs for your OS.
TODO: I haven't gotten this far yet!