Is it possible to cross-compile D source code for MIPS? - d

Is it possible to cross-compile D source code for MIPS?
For example, I want to compile a D "Hello, world." program that will run on TI AR7-based devices, which have MIPS32 processor and typically run Linux 2.4.17 kernel with MontaVista patches and uClibc (using the MIPS I generic target; ELF 32-bit LSB executable, MIPS, MIPS-I version 1 SYSV).
http://en.wikipedia.org/wiki/TI-AR7

The reference compiler, DMD, does not generate MIPS code, so you'll have to use GDC and LDC2, which support generating code for whatever architectures their backends support (GCC and LLVM, respectively).
However, it's not a simple as generating the code. To get all of D's features workable, you'll need to port druntime and phobos to MIPS, as druntime is quite architecture specific. Without that, you'll be stuck without a GC, and all the features that entails.
So it is possible, but how possible definitely depends on how dedicated you are.

Related

What are the differences between C/C++ bare-metal compilation and compilation for a specific OS (Linux)?

Suppose you have a cross-compilation tool-chain that produces binaries for the ARM architecture.
Your tool-chain is like this (running on a X86_64 machine with Linux):
arm-linux-gnueabi-gcc.exe : for cross-compilation for Linux, running on ARM.
arm-gcc.exe : for bare-metal cross-compilation targeting ARM.
... and the plethora of other tools for cross-compilation on ARM.
Points that I'm interested in are:
(E)ABI differences between binaries (if any)
limitations in case of bare-metal (like dynamic memory allocations, usage of static constructors in case of C++, threading models, etc)
binary-level differences between the 2 cases in terms of information specific to each of them (like debug info support, etc);
ABI differences is up to how you invoke the compiler, for example GCC has -mabi and that can be one of ‘apcs-gnu’, ‘atpcs’, ‘aapcs’, ‘aapcs-linux’ and ‘iwmmxt’.
On bare-metal limitations for various runtime features exists because someone hasn't provided them. Be them initializing zero allocated areas or providing C++ features. If you can supply them, they will work.
Binary level differences is also up to how you invoke compiler.
You can check GCC ARM options online.
I recently started a little project to use a Linux standard C library in a bare-metal environment. I've been describing it on my blog: http://ellcc.org/blog/?page_id=289
Basically what I've done is set up a way to handle Linux system calls so that by implementing simplified versions of certain system calls I can use functions from the standard library. For example, the current state for the ARM implements simplified versions of read(), readv(), write(), writev() and brk(). This allows me to use printf(), fgets(), and malloc() unchanged.
I'm my case, I use the same compiler for targeting Linux and bare-metal. Since it is clang/LLVM based, I can also use the same compiler to target other processors. I'm working on a bare-metal example for the Mips right now.
So I guess the answer is that there doesn't have to be any difference.

Using LLVM as virtual machine - multiplatform and multiarchitecture coding

I'm currently working in a pet programming language (for learning purposes), and have gone through a lot of research over the past year, and I think its time to finally start modelling the concepts of such a languague. First of all I want it to compile to some intermediate form, such as JVM or .NET bytecode, the goal being multiplatform/architecture compatibily. Second, I want it to be fast (I also have many other things in mind, but its not the purpose of this topic to discuss those).
The best options that came to my mind were:
Compile to JVM bytecode and use OpenJDK as runtime environment,
Compile to .NET bytecode and use Mono as runtime environment,
Compile to LLVM IR and use LLVM as runtime environment.
As you may have imagined, I've chosen LLVM. Why? because its blazing fast. I did a little benchmark using the C++ N-Body code, and achieved 7s in my machine with lli jitted IR, in contrast with 27s with clang native compiled code (I know clang first make IR then machine code).
So, here is my question: Is there any redistributable version of the LLVM basic toolset (I just need lli) that I can use? Or I must compile my own? If the latter, can you provide me with any hints on how to do it? If I really must do it, I'm thinking is cross-compiling them from my machine (Intel Mac), and generating some installers (say, an .msi for windows, .rpm and .deb for popular linux distros and .pkg for Macs). Remember, I only need a minimal subset of LLVM, such that this subset is capable of acting like a VM, by using "lli ". The real question here is how to use LLVM as a typical virtual machine.
First, I think all 3 options - LLVM IR + LLVM, Java Bytecode + OpenJDK, and .NET CIL + Mono - are excellent options, and I agree deciding between them is not easy.
If you go for LLVM and you just want to use lli, you can compile LLVM to your target platform and pack the resulting lli executable with your distribution, it should work.
Another way to write a JIT compiler via LLVM is to use an execution engine - see the handy examples in the Kaleidoscope tutorial. That means that you write your own program which will JIT-compile your own language, compile it to whatever platform you want while statically linking it with LLVM, and then distribute it.
In any case, since a JIT compiler requires copying an LLVM binary to the client side, make sure to attach a copyright notice with your distribution (you don't have to open-source your distribution, though).

What platform can I compile binaries for, using LLVM (Low Level Virtual Machine)?

I am interested in using the LLVM's Clang compiler. LLVM claims to be cross-platform however it is not clear which platforms can be targeted. I have done quite a lot of Googling on this but there doesn't seem to be much information about LLVM's supported platforms. The only thing I did find was "this" which is kinda confusing. I am not sure if it means I can compile binaries for those platforms using LLVM or if it just runs on those platforms (or both). Could someone who knows more about the LLVM/Clang compiler tell me which platforms I can target using Clang or any other LLVM front ends? I want specific information (like "It supports Windows 32bit, Windows 64bit, Linux 32bit, Linux 64bit, etc). Thanks!
EDIT:
Ok, I think I am just confused about what LLVM really is. From what I just figured out LLVM is simply a byte-code interpreter. Since LLVM is interpreted how much slower is LLVM binaries compared to executable binaries? So if performance is important LLVM is not the right choice? "Here" I found the architectures it supports but it did not say what operating systems it supports. Does it run on all operating systems if I avoid platform dependent code? I will look for more articles that explain LLVM in more detail if I can find any.
With llvm installed type
llc -version
and you will see something like
Registered Targets:
alpha - Alpha [experimental]
arm - ARM
bfin - Analog Devices Blackfin [experimental]
c - C backend
cellspu - STI CBEA Cell SPU [experimental]
cpp - C++ backend
mblaze - MBlaze
mips - Mips
mipsel - Mipsel
msp430 - MSP430 [experimental]
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ptx32 - PTX (32-bit) [Experimental]
ptx64 - PTX (64-bit) [Experimental]
sparc - Sparc
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
Go to github.com and search for mbed_samples to see llvm and clang being used to cross compile for ARM. Somewhere around blinker03 or 04 is where it comes in. LLVM works the same way for any platform, the llc step is where you choose your target, the compiling merging, optimizing, etc are all platform independent (well you might use -m32 for example to choose the int size) then llc gets you to platform dependent assembler.
There are many possible applications of LLVM in terms of target machine.
GPGPU (GPU). There are approaches like GPUOcelot for retargeting to gpu, here is an example : LLVM to PTX Backend.
According to OpenCL wikipedia at 2011-09: "The Apple,[22] Nvidia,[23] RapidMind[24] and Gallium3D[25] implementations of OpenCL are all based on the LLVM Compiler technology and use the Clang Compiler as its frontend."
Javascript as LLVM Target ! - Yes, tool, that is does it Emscripten - Emscripten GitHub homepage wiki with Demos, blog note about Emscripten 1.0, Emscripten documentation paper,
According to the clang manual clang can target X86, Arm with partial support for PPC, SPARC and MSP430.
Clang can also generate LLVM bytecode though. LLVM can run on quite a few more platforms.
So if you want native machine code then the list is pretty small. If you want LLVM bytecode you have a broader choice of platforms.
I'm only answering the edit's question here (it would probably be more appropriate to make a new question).
This is a good architectural overview of LLVM. This page also contains a ton of documentations on all aspects of LLVM.
The short version is that LLVM is the optimizer and backend of a traditionnal compiler. It operates on a bytecode which is essentially it's intermediate representation of the code and is used to optimize and generate the final binary. The LLVM frontends are independent and uses there own internal ASTs to eventually generate bytecode.
LLVM is actually pretty flexible when it comes to when you want to generate the final binary. You can either do it right away or delay it until the program is being installed. I believe you can even use its JIT to generate the final binary during execution (not 100% sure of this). The main advantage of delaying like this is that it can apply optimizations that are specific to the environment it is executing on.

Running/compiling executable Linux vs Solaris

if i have code compiled under Solaris 8 and 10 and now have a vendor that wants to use my bin/exe under Linux. Could there be compatibility issues?
I am pretty sure i would need to compile/link under Linux OS for it to work 100% but i just wanted to know if someone can give me the breakdown as to why it would not work on Linux even though the exe has everything and there is nothing dynamic about it, as in it should not need anything further to run it. Unless we talking runtime libs, that if there is a mismatch might cause the exe to fail.
You have to recompile your application on Linux.
Linux is a completely different run-time compared to Solaris. Even if you have compiled your application statically, there's the interface/system calls to the kernel that is different among these two operating systems. The processor architecture might be different too, e.g. SPARC vs X86.
Both Solaris and Linux support most of the standard C and Posix APIs, so if you've not used any APIs exclusive to Solaris, recompiling on Linux is often not that big a deal - but you surly should test everything throughly, and be aware of any endianess, and potential 64 bit vs 32 bit issues.
Other things that I think will not allow your Solaris binary to run on Linux out of the box are:
the hardware architecture:
1.1 Solaris usually runs on Sun's own SPARC machines, especially 8 - 10 can run on Intel architectures as well;
1.2 Linux usually runs on Intel machines (although it can run on Sparc machines).
the compilers:
2.1 Solaris 8 uses Sun's own compilers (Sun WorkShop 6+) & standard library implementation (so you'll have different library names, ABI incompatibilities and so on). Solaris 10 actually comes with gcc but you're probably not using it (I gather you're building on Solaris 8 only);
2.2 Linux uses g++, same as above for library names, ABI incompatibilities & so on.

c++ compiler that creates object code for two different machines

Are there c++ compilers that I can run on a brand x system that will create machine code that will run on a brand y system? Would this be considered a cross compiler?
Yes, that's exactly what a cross compiler is.
The GNU Compiler Collection (which includes gcc and g++) are a prime example of a portable cross compiler with hundreds of supported CPU types.
There are many ways to configure GCC to be a cross compiler. Most of it depends on the target machine and what's available from it - mostly because of the C runtime environment. For example, compiling GCC for an ARM Linux target requires an ARM Linux glibc pre-compiled to build the cross compiler libstdc++.
This is quite common using gcc.
There are a number of tutorials around that describe building your own cross-compiler environment.
This is one, but a quick google will probably provide a link to someone doing exactly the mix of environments that you're after.
edit:
This is a more thorough tutorial, using crosstool
Yes there are such compilers; yes, they are called cross compilers. For example, GCC can be configured in this manner, so that I can run the compiler on a 32-bit x86 system, but produce 64-bit code for an x64 system, and that's just the tip of the iceberg.
Crosstool is a really handy tool suite for creating a cross-compiling GCC.
HTH,
Eric Melski
Electric Cloud, Inc.
Yes this is what cross-compilation is about (although I would say "brand X" isn't appropriate classification term).