16. 在Mac OS上编译安装不同版本的GCC

Installing i386-elf-gcc on MacOS X

I wanted to build a cross-compiler for MacOS X that would allow me to compile the ELF kernel image of my tiny operating system I’m developing without having to always use my Arch Linux distribution instead of just using OS X. Creating a cross-compiler is not that hard, but it requires following some instructions and it takes some time. The good thing is that once you build it, you can leave it in a folder installed and you won’t ever have to build it again. In this article I’ll describe how I compiled myself the i386-elf-gcc compiler on MacOS X El Capitan.

What is a cross-compiler anyway?

A cross compiler is a compiler that generates code for a different platform than the one is running in. As an example, in this article I’ll be creating a compiler for my Mac (x86_64-apple-darwin15.0.0) 1, that is able to create binaries for the i386-elf platform. By default the clang compiler that comes with OS X knows how to build binaries for OS X (Mach-O binaries), but if you ask it to build an ELF binary, it will just not know what to do!

Setting up a cross-compiler is a recommended task anyway when you do operating systems development. Yes, you can build i386-elf binaries using the i686-linux or x86_64-linux GCC that comes with your Linux distribution, but it will make a lot of assumptions about your target platform that you’ll need to override using flags. As an example, my Arch Linux box uses the x86-64 Linux GCC Compiler and I have to use a flag for making it generate 32 bit code instead of 64 bit code. By using a cross-compiler that targets just i86-elf*, all these assumptions are gone.

If you are using a different operating system or using a different processor architecture it might not even be possible to do that trick and setting up a cross compiler might be your only choice.

Setting up the environment

GCC has the following dependencies:

  • The GCC and the G++ compiler. Since a few OS X releases, the default compiler for OS X is actually clang 2, and running gcc actually spawns clang. It is compatible as I have had no problems building this on my machine. You might want to install the real GNU GCC from Homebrew or MacPorts.
  • The libraries GNU GMP, GNU MPFR, GNU MPC. ISL and CLOOG are optional dependencies. You can choose whether to install this now (via Homebrew, MacPorts or similar) or just wait, since the GCC buildscript is able to download and compile them on the fly as I’ll show you later.
  • A few other GNU dependencies such as Make, Bison, Flex and Texinfo. They probably either come preinstalled with the OS or are installed as part of the Xcode Command Line Tools, as I don’t remember installing them and Homebrew says it didn’t install them.

We will also create the folder where our compiler will live in. You probably won’t want to install the compiler to /usr/bin or /usr/local/bin as it might conflict with other files for your host compiler. I use /opt/local for these kind of things, although you can use any other folder such as *HOME/opt/* in case you don’t have enough rights on your system. We’ll be making this folder as thePREFIX variable to use it later and we’ll add $PREFIX/bin to our PATH.

$ export PREFIX=/opt/local
$ sudo mkdir -p $PREFIX
$ sudo chown danirod $PREFIX
$ export PATH="$PREFIX/bin:$PATH"

Download GNU Binutils and GNU GCC. I’ll be using Binutils 2.25 and GCC 5.2.0. The trickiest part of this is that not every version of Binutils is compatible with every version of GCC. Therefore, care must be taken to use a correct version. Get the packages from the GNU FTP site and extract them in a folder such as ~/src.

$ mkdir -p $HOME/src
$ cd $HOME/src
$ wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.gz
$ wget ftp://ftp.gnu.org/gnu/gcc/gcc-5.2.0/gcc-5.2.0.tar.gz
$ for pkg in *.tar.gz; do tar zxf $pkg; done

Compiling GNU Binutils

Our first stop will be building binutils. It has to be done in a different folder. Make sure you provide the configure script these arguments.

$ mkdir build-binutils
$ cd build-binutils
$ ../binutils-2.25/configure --prefix=$PREFIX \
   --target=i386-elf --disable-multilib \
   --disable-nls --disable-werror
$ make
$ make install

Some of the arguments we provided to the configure script will make the software be compiled without some unrequired features, such as multiple target support (--disable-multilib) or internationalization (--disable-nls).

You can test that the package has been successfully installed by issuing the command i386-elf-as --version and checking that you get something that makes sense.

If you are done, let’s get to building the GCC Compiler.

Compiling GNU GCC

GCC has a few dependencies. You need the gmp, mpc and mpfr libraries to compile GCC. You can get them using Homebrew or MacPorts if you wish. Alternatively, there is an script in the GCC distribution that will automatically download them for you. It has to be executed right inside the GCC folder.

$ cd $HOME/src/gcc-5.2.0
$ ./contrib/download_prerequisites

It will take a few moments as it has to download a few packages and then extract them. The buildscript for GCC will detect these folders when compiling GCC and therefore will compile them on the fly so that they can be used to “compile the compiler”. Note that if you don’t do this step, you’ll have to install the libraries by yourself. Otherwise, you’ll get errors.

GCC has to be built from a different directory as well. Go ahead and compile it using the flags described in configure. You don’t want to actually make everything so we are just making two targets: all-gcc and all-target-libgcc. The first one is our compiler. The second one is the shared library that GCC uses:

 mkdir build-gcc
$ cd build-gcc
$ ../gcc-5.2.0/configure --prefix=$PREFIX --target=i386-elf \
   --disable-multilib --disable-nls --disable-werror \
   --without-headers --enable-languages=c,c++
$ make all-gcc install-gcc
$ make all-target-libgcc install-target-libgcc

This is going to take some time, so let’s talk about the flags while it is compiling. --disable-multilib, --disable-nls and --disable-werror were already present in the GNU Binutils build.

The most important new flag here is --enable-languages=c,c++. GCC is actually a compiler collection that comes with support for many programming languages: C, C++, FORTRAN, Java, Go… we have to tell the configure script only to create a C compiler and a C++ compiler. We don’t need any other compiler at this point.

Once this is installed, you can test that it works as well by checking that the i386-elf-gcc command gives you something useful and not just an error about command not found.

Testing the setup

If I tried to compile my kernel image using the standard x86_64-darwin clang compiler, I would get some errors when linking the image:

$ make
~ [Lots of output from the compiling process...]
~ ld -melf_i386 -nostdlib -T linker.ld [...]
~ ld: unknown option: -melf_i386

However, if I modify the buildscript so that it uses i386-elf-gcc as the linker (gcc also links), and I remove all the undesired flags, such as -m32 on the compiler or -melf_i386 on the linker (it’s an i386-elf linker, I don’t need to tell it that), it will just work.

Does this work on other OS?

I have successfully done this on Linux as well. On Linux one has to double check that the required dependencies are installed. The building process is similar.

I want to test this both on FreeBSD and on Windows. On FreeBSD might not be hard since is a UNIX environment as well. Probably setting this on Windows requires manually installing some UNIX environment such as MSYS or Cygwin. I don’t know, I’m not that interested on Windows at the moment.

    1. You can get this information by running gcc -dumpmachine. Depending on the operating system or processor you are using you might get a different output.
    1. Assuming you have the Xcode Command Line tools installed, which being a developer you probably have. Although you can always run on your terminal gcc: if you don’t, you’ll be prompted with a dialog asking whether you want to install them or not.

上述下载的gcc和binutils可以根据自己需求选择,我装了(gcc-4.8.2和binutils-2.24)。

原文参考:https://www.danirod.es/blog/2015/i386-elf-gcc-on-mac

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 我们应该都记得我们初恋是什么时候,跟什么人,有过哪些不愉快又有过哪些小浪漫,之所以我们都记得这些是因为,初恋让我们...
    林沐沐阅读 196评论 0 0
  • 最近想用python批量处理数据,把自己网上找答案的过程整理了一下,希望对大家有用。问题: 一个文件夹中有38个t...
    和黑黑阅读 17,228评论 1 5
  • 写作让明霞走上了一条生命自觉与专业精进的道路。她说她没有写作的天赋,她反对无底线得发表文章。写文章不是为了发表、为...
    红点子阅读 489评论 2 1
  • 周黑鸭相信大多数年轻人都吃过,那味道真的让人回味无穷。据我所游,江门蓬江区我只知道两家周黑鸭专卖店: 一、汇悦城负...
    气球_2499阅读 240评论 0 0
  • 春茶园中几点红, 农人炒翻在锅中, 送君一杯碧绿水, 立饮龙井赛仙翁。 在西湖龙井茶庄,农妇采来新鲜的茶叶,在锅中...
    岗岗hg阅读 267评论 1 4