Subject: make gcc on Solaris2 without gcc-binaries-2.5.6
From: [email-masked] (YAMAMORI Takenori)
Date: 21 Dec 1996 10:25:48 GMT
Newsgroups: fj.sys.sun

このグループは初登場です。山森と申します。

  SunSPARCstation2 を所有していまして、SunOS4.1.4 と Solaris2.5.1 の両方が
ブート可能な状態で使用しています。このたび、Solaris2 上に gcc-binaries の
力を借りずに gcc を make することが出来ましたので、そのことについて
報告します。

長文ですが何らかのお役に立てば幸いです。

（OS 名として、慣習的に SunOS4, Solaris2 と言ういい方を使います）

-------
  Solaris2 では cc がバンドルされておらず、一般的には gcc-binaries-2.5.6 を
取り寄せ、これを使って gcc の最新版をコンパイルすることが多いと思います。

  しかし、せっかく SunOS4 上には gcc があるので、これを使って gcc-binaries
の力を借りず、自力で Solaris2 上に gcc を立ち上げることは出来ないかと
考えました。

-------
最初に考えた方法

  互換ライブラリにより、Solaris2 上でも SunOS4 用のバイナリは一応
実行できます。それなら、SunOS4 用の gcc が Solaris2 上で何とか動かないか、
という発想です。つまり、

    gcc （ドライバー）         -----  SunOS4 用を互換ライブラリで使う
    /.../gcc-lib/.../.../cpp   -----  SunOS4 用を互換ライブラリで使う
    /.../gcc-lib/.../.../cc1   -----  SunOS4 用を互換ライブラリで使う
    as                         -----  /usr/ccs/bin/as を使う
    ld                         -----  /usr/ccs/bin/ld を使う

ということです。しかし問題があります。
    * cpp に渡されるあらかじめ define された定数が、SunOS4 と Solaris2 では
      違い、SunOS4 の gcc を流用すると SunOS4 の define になってしまう。
    * CPU は同じであるが、アセンブラの書式（疑似命令?）が、SunOS4 と
      Solaris2 で、若干違うようである。

ということで、この方法も可能性はあると思いますが、別の方法として
素直にクロスコンパイラを作ることにしました。

  クロスコンパイラを作るつもりなら、何も SunOS4 からでなくても、
gcc がサポートしている他のプラットフォームからでも、そこに Solaris2 の
コードを出力するクロスコンパイラを作れば良いと考えられます。

  しかし、SunOS4-->Solaris2 のクロスコンパイラ自体、何かと役立つかも
知れないし、また、クロスコンパイラの make 自体にも興味があるので、
この方法で進めることにしました。

-----------------------------------------------------------------------------
SunOS4 上にクロスコンパイラを作り、それを使って Solaris2 gcc を作成する方法。

                                                       山森丈範
                                          Dec. 21 1996 [email-masked]

  * まず、クロスアセンブラ等を作成。
      SunOS4 上で、binutils-2.7 を、configure --target=sparc-sun-solaris2.5.1
      として configure し、make し、インストールする。
        /usr/local/sparc-sun-solaris2.5.1/bin の下に、
          as,ld,ar 等がインストールされ、それらは
        /usr/local/bin の下の、
          sparc-sun-solaris2.5.1-as
          sparc-sun-solaris2.5.1-ld
          sparc-sun-solaris2.5.1-ar
        等として、ハードリンクされる。
  
  * Solaris2 インクルードファイルの準備。
      マウント、シンボリックリンク等の方法を使い、
      solaris2:/usr/include 以下のインクルードファイルが、
      sunos4:/usr/local/sparc-sun-solaris2.5.1/include 以下に
      見えるようにする。

  * Solaris2 ライブラリの準備。
      マウント、シンボリックリンク等の方法を使い、
      solaris2:/usr/lib 以下のライブラリが、
      sunos4:/usr/local/sparc-sun-solaris2.5.1/lib 以下に
      見えるようにする。

  * クロスコンパイラの作成。
      SunOS4 上で、gcc-2.7.2.1 を、configure --target=sparc-sun-solaris2.5.1
      で configure する。その後追加として solaris2:/usr/ccs/lib/values-Xa.o
      のみ、カレントディレクトリにコピーする。
      （Solaris2 では、crt*.o がバンドルされていないが、gcc のソースでは、
        Solaris2 用に crt*.asm というソースをちゃんと用意してくれている）
      これで準備が整ったので次のスクリプトで make を行なう。
          -----------------------------------
          #!/bin/sh -x
          (
            date
            time make -j3 LANGUAGES=c \
              CC=gcc \
              CFLAGS='-O2 -pipe -s' \
              AS=sparc-sun-solaris2.5.1-as \
              LIBGCC1_TEST=''
            date
          ) 2>&1 | tee -a stage1-log
          -----------------------------------
      ここで、AS=sparc-sun-solaris2.5.1-as と指定しているのは、
      この AS の値は crt*.asm をアセンブルする時に使われ、
      これを指定しないと、as （SunOS4ネイティブアセンブラ）が
      誤って使われてエラーになってしまうため。
        さらに、LIBGCC1_TEST='' として、libgcc1.a のテストを抑制する。
      Solaris2 では（SunOS4 でも）libgcc1.a は必要ない（libgcc2.a のみ必要）
      ということがわかっているが、クロスコンパイラの make 環境では
      libgcc1.a のテストがエラーになってしまうので、このようにする。

      make 中に Solaris2 用の fix-include も行なわれる。ただし、原理的に
      float.h の fix は正しくは行なわれない。

      以上で、make は正常に行なわれ、クロスコンパイラが作成される。

      クロスコンパイラなので、このまま（いわゆる stage1）でインストールする。
      インストール後、values-Xa.o のみ手作業で
      /usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2.1 にコピーする。
      クロスコンパイラは、コマンド名 sparc-sun-solaris2.5.1-gcc として
      または、gcc -b sparc-sun-solaris2.5.1 とオプションを付けて実行できる。

  * クロスコンパイラの簡単なテスト。
      SunOS4 上で、sparc-sun-solaris2.5.1-gcc を実行して簡単なソースを
      コンパイルしてみる。その時、-v オプションも付けてインクルードファイルや
      ライブラリ等も正しく Solaris2 用のものが参照されていることを確認する。
      クロスコンパイルした結果を Solaris2 上で実行できることを確認する。

  * クロスコンパイラを使って Solaris2.5.1 ネイティブコンパイラの作成。
      SunOS4 上の新しい作業ディレクトリで、gcc-2.7.2.1 を、
        configure --build=sparc-sun-sunos4.1.4 --host=sparc-sun-solaris2.5.1
      で configure する。

      make は以下のスクリプトで行なう。
          -----------------------------------
          #!/bin/sh -x
          (
            date
            time make -j3 LANGUAGES=c \
              CC=sparc-sun-solaris2.5.1-gcc \
              CFLAGS='-O2 -pipe -s' \
              AS=sparc-sun-solaris2.5.1-as \
              LIBGCC1_TEST=''
              GCC_FOR_TARGET=sparc-sun-solaris2.5.1-gcc 
            date
          ) 2>&1 | tee -a stage1-log
          -----------------------------------
      AS および LIBGCC1_TEST を指定するのはクロスコンパイラ作成の時と同様。
      さらに、GCC_FOR_TARGET を指定するのがポイント。
      これを指定しないと、make 中で libgcc.a 等を作成する際に、make の過程で
      出来たばかりの ./xgcc を起動しようとする。これは Solaris2 用の
      バイナリであり、SunOS4 上では当然実行出来ずエラーになってしまう。

      以上で、make は正常に行なわれ、Solaris2 ネイティブコンパイラが
      SunOS4 上で作成されたことになる。

  * そして Solaris2 へ
      これで SunOS4 上の作業をひとまず終え、Solaris2 をブートし直す。
    作成されたネイティブコンパイラは、そのままインストールしてもいいし、
    これを stage1 としてさらに stage2, stage3 を make してもいい。
    ただし、float.h の fix-include が正常に行なわれていないので、
    もう一度、fix-include し直した方がいい。
    また、gcc の再 make 時には LANGUAGES の指定を外し、C++ 等も make する。
    （最初に Solaris2 上で不自由しないように、SunOS4 上のクロスコンパイラで
      あらかじめ GNU make-3.75 等、必要なものを make しておくという
      方法も考えられる）

      さらに、Solaris2 上で binutils-2.7 を make し、それを使って
    gcc を make し直し、それを使って binutils を make し直す、、
    と、こだわることも出来る。

  * 考慮事項
    * gcc-2.7.2.1/config/sparc/t-sol2 によると、
        『crtstuff.c(crtbegin.o, crtend.o のソース）のコンパイル時に
          -fPIC を付けたいが、GNU as が PIC にまだ対応していないため、
          crtstuff.c のコンパイル時に限り、たとえ GNU as がインストール
          されていても /usr/ccs/bin/as を強制的に使う。ただし、
          クロスコンパイル時には（不可能なので）-fPIC をあきらめる』
      とあり、確かにクロスコンパイラ make 時の stage1-log を見ると -fPIC は
      使われていない。
        しかし、binutils-2.7 の as を見る限りでは PIC はサポートされて
      いるようで、それならば、Makefile を修正して crtstuff.c も -fPIC で
      コンパイルした方がいいのかも知れない。
        また、Solaris2 上でのネイティブ gcc の make 時にも、
      /usr/ccs/bin/as を一切使いたくないということであれば、同様に Makefile を
      修正して、GNU as のみが使われるようにした方がいいのかも知れない。

    * Makefile 中に、OLDCC = cc という行があり、これは libgcc1.a の
      作成の場合に使用される。しかし、SunOS4 も Solaris2 も、libgcc1.a は
      必要なく、結果的に cc は使われない。しかし、だからと言って、
      OLDCC = gcc などと書き換えてはいけない。OLDCC の値と、CC (=gcc) の値が
      Makefile の別の場所で sh の case 文で比較されていて、これが同じだと、
      alloca.o という、空のオブジェクト（実際には不要）が余分にリンク
      されてしまう。心配なら、OLDCC = xxx （あり得ないコマンド名）とでも
      すると良い。

    * gcc-2.7.2.1, binutils-2.7 等、同じソースに対し異なる configure で
      複数の make を行なう場合、ソースを展開したディレクトリはリードオンリー
      （CD-ROM 状態）にして、別の作業ディレクトリから、
         (ソースディレクトリ)/configure
      とすると良い。（今回、実際にそうした）

                                                                    以上
-----------------------------------------------------------------------------
-------------------------------
山森丈範  [email-masked]
-------------------------------