An alternative guide to installing clang, g++, gcc and llvm for mac users(M1) for cross-compilations
Published: 2022-09-18 13:32:18

Hey, guys. Welcome to another blog post!
I came across an error
![error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epe3c5kzfqt6p6suicwt.png) when I was compiling mediasoup in a rust project and I spent two days figuring out what caused the error. 
This error is caused by compatibility issues with computer's architecture and the dependency's support.

Before we go into solving the error what are g++, clang, llvm, llc and gcc? What are these terms?

## What is g++? 
g++ is another name for GNU C++, a freely redistributable C++ compiler produced by the Free Software Foundation plus dozens of skilled volunteers. 

## What is gcc?
gcc is another name for GNU C Compiler ( gcc ). It is a compiler in Linux which is used to compile C programs. It compiles files with extension. It compiles both files with extension .c and .cpp as C++ files.

## What is llvm?
According to LLVM.org 

> The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines. The name "LLVM" itself is not an acronym; it is the full name of the project.

It is a library that is used to construct, optimise and produce intermediate and/or binary machine code.

## What is clang?
Clang is a front end for the C, C++, Objective-C, and Objective-C++ programming languages, as well as the OpenMP, OpenCL, RenderScript, CUDA, and HIP frameworks. It can parse C, C++, Objective-C to LLVM.

Clang is considered to be a production quality C, Objective-C, C++ and Objective-C++ compiler when targeting X86-32, X86-64, and ARM and other targets which might have some bugs but are easy to fix.

## What is llc?

The llc command compiles LLVM source inputs into assembly language for a specified architecture. The assembly language output can then be passed through a native assembler and linker to generate a native executable.

Now that we are a bit familiar with all these terms I hope they pique your interest into going further.

**Install Homebrew**

Apple has a set of tools called "command-line tools". It contains most of these software out of the box, but the problem is the version most likely not compatible. 

Homebrew is an alternative solution to this problem, we can download other version's of software without it tampering with command-line tools. Let's install Homebrew into a directory.

```
cd /opt
```
Then 

```
mkdir homebrew
```
Do this if you don't have this directory.

Then

```
sudo chmod go+w homebrew
```

This is give the right access to write into the directory.

```
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
```
This downloads homebrew into this directory

**Export homebrew directory:**

After installing homebrew, we need to make it a default directory. Run the following command if you're using zsh. 

```
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
```

or do this if you're using bash

```
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.bash_profile
```

Next install clang, llvm, llc and gcc with the following commands.

In this case I installed version 14 because at this time of writing llvm hasn't released version 15 yet but the latest rust compiler already has this, so I had to downgrade my rustc and reinstall the GNU tools so that they are in the same version, therefore making the compilation compatible.

When you're installing these software, be sure to note their versions

```
brew install clang
brew install llc
brew install llvm
brew install gcc
```

To install a specific version, for example, llvm.

```
brew install llvm@14
```

To downgrade rustc to the version compatible with llvm@14 and llc@14, run the following:

```
rustup install 1.60
rustup default 1.60
```

Note, The llc command compiles LLVM bytecode into assembly language for a specified architecture.

After that, you will have all the lovely GNU Compiler Collection (GCC) of tools in /usr/local/bin so you need to export it, open up your config file(.zsh or .bash_profile) and put it at the beginning or at least near it.

```
export PATH=/usr/local/bin:$PATH
```

**Now link them up.**

```
 cd /usr/local/bin
rm gcc
ln -s  gcc-VERSION_INSTALLED  gcc 
```

Open a new terminal to confirm if you've set the correct gcc to the default compiler

```
 gcc --version  
```

You should see something like this:

![gcc new version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i2acj8ag2k6q8xevddb.png)

For compilers to find llvm you may need to set:
```
  export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
```

Now let's move on into the rusty part!
Type the following command into your terminal

```
rustc --version --verbose
```

This will show the rust version installed in your Mac, its host, the llvm compiler verison and other info. 

This is how it looks like: 

![rustc verbose version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kjaiufx0fn3bz1ndgt3l.png)

To check the llc version:

```
llc --version
```

You should see the following:

```
Homebrew LLVM version 14.0.6
  Optimized build.
  Default target: arm64-apple-darwin21.5.0
  Host CPU: cyclone
....
```

To check llvm version:

```
llvm-config --version
```

You should see this or whatever version you installed

```
14.0.6

```


In conclusion, versions checks are very important especially the versions with breaking changes, they can cause bugs especially dealing with rust which has a strict compiler, you need to be careful when dealing with this. If you're cross-compiling, be sure to cross-check the versions too!


I hope this post helps, These are the steps I followed to solve my errors, I'm not saying it's the ultimate solution, It's just a solution to try out:wave: