魔術師見習いのノート

プロフィール

魔術師見習い
Author魔術師見習い-_-.
Twitter魔術師見習い

コンピュータ関係のメモを主に書きます.

MENU

sescutilsのコンパイル

投稿日:
タグ:

SESCのためのクロスコンパイラと他もろもろをコンパイル. 環境はSESCのコンパイルと同じ. 構築にはsescutilsという必要なソースとそれをコンパイルするためのスクリプトをまとめたものがあったので,それを利用した. 普通クロスコンパイラの構築には,シミュレートするISAなりエンディアンなりOSの情報なりが必要だが,そのあたりはスクリプトで設定されていたので,コンパイルを通すことだけに集中できた(一応事前にいろいろ調べたが). ただし私はこんなスクリプトを使ったのは初めてだったので,configureのエラーなのかmakeのエラーなのかが一瞬分かり辛かったりする弊害があった.

はじめに

説明は$HOME/workspace/に必要なものを解凍するところから始める.

uesr% tar jxf sescutils.tar.bz2
user% cd sescutils
全体の流れとしては,README.sescに書かれた通りに行う. ただしテキストで使用しているスクリプトの名前と実際のファイル名が微妙に違ったりする(というかテキストとスクリプトの名前が違うのはどうなんだろうか).
user% cd build-mipseb-linux/  
user% ls

build-1-binutils  build-3-glibc  build-5-gdb   build-gmp
build-2-gcc-core  build-4-gcc build-common
各スクリプトの名前には番号が降られており,基本的にこの順番に実行していけば良い. ただし今回はgdbのコンパイルは行わない. これらのスクリプトはsourceコマンドでbuild-commonにある変数を読み込み,それに従って実行する. そのため,README.sescの説明にもあるがbuild-commonの中身を自分用に書き換える必要がある.
Before:
      1 #!/bin/sh
      2 
      3 # common paths
      4 GNUSRC=$HOME/projs/gnu/src
      5 PREFIX=$HOME/projs/gnu/install
      6 PATH=$PREFIX/bin:$PATH
      7 KERNHEADERS=$GNUSRC/linux-headers
      8 
      9 # common parameters
     10 BUILD="`uname -p`-`uname -s | sed s/Linux/linux/ | sed
      s/Darwin/darwin/`"
After:
      1 #!/bin/sh
      2 
      3 # common paths
      4 GNUSRC=$HOME/workspace/sescutils/src
      5 PREFIX=$HOME/mypath
      6 PATH=$PREFIX/bin:$PATH
      7 KERNHEADERS=$GNUSRC/linux-headers
      8 
      9 # common parameters
     10 BUILD="`uname -p`-`uname -s | sed s/Linux/linux/ | sed
     s/Darwin/darwin/`"

binutils

1つ目はbinutilのコンパイル. 結論からいうとbinutilsは,コンパイル自体に手間はなかった. ただしconfigureやmakeを実行する前のスクリプトで躓いた.

user% ./build-1-binutils

./build-1-binutils: 3: source: not found
./build-1-binutils: 12: /binutils/configure: not found
./build-1-binutils: 13: all: not found
開始してすぐsourceがないと言われた. しかし,実行するシェルをZSHに変えたら即解決.
user% zsh ./build-1-binutils
スクリプト終了と共にprefixで指定した先にobjdumpなどのマニュアルやプログラムがインストールされる. 他のスクリプトも同様にsourceを使用しているので,zshで起動する.

gcc-core

2つ目はgcc-coreのコンパイル.

user% zsh ./build-2-gcc-core
	・
	・
	・
gcc -c   -g -O2 -DIN_GCC -DCROSS_COMPILE  -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long
-Wno-error  -DHAVE_CONFIG_H
-I. -I. -I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc
-I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc/. -I/home/user/workspace/sescutils/src/gcc-3.4/gcc/gcc/../include
c-parse.c -o c-parse.o
gcc: c-parse.c: そのようなファイルやディレクトリはありません
gcc: no input files
make[1]: *** [c-parse.o] エラー 1
make[1]: ディレクトリ
`/home/user/workspace/sescutils/build-mipseb-linux/obj/gcc-core-build/gcc'
から出ます
make: *** [all-gcc] エラー 2
スクリプトの出力を読んでいくと,無視されているエラーを発見(ここには載せてない部分). エラーはコンパイラコンパイラのBISONが原因だった. どうやらBISONの古いバージョンで読み取れていたものが新しいバージョンになって読み取れなくなったらしい(そうなった経緯は知らないが). BISONは前に扱う機会があったが,もう忘れているので素直にWEBで検索した. http://www.microchip.com/forums/m416697-print.aspx

BISONのソースコード(../src/gcc-3.4/gcc/gcc/c-parse.in)を書き換える.

Before:
   1731 structsp_attr:
   1732     struct_head identifier '{'
   1733     { $$ = start_struct (RECORD_TYPE, $2);
   1734       /* Start scope of tag before parsing components.  */
   1735     }
   1736     component_decl_list '}' maybe_attribute
   1737     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1738               chainon ($1, $7)); }
   1739   | struct_head '{' component_decl_list '}' maybe_attribute
   1740     { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
   1741               nreverse ($3), chainon ($1, $5));
   1742     }
   1743   | union_head identifier '{'
   1744     { $$ = start_struct (UNION_TYPE, $2); }
   1745     component_decl_list '}' maybe_attribute
   1746     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1747               chainon ($1, $7)); }
   1748   | union_head '{' component_decl_list '}' maybe_attribute
   1749     { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
   1750               nreverse ($3), chainon ($1, $5));
   1751     }
   1752   | enum_head identifier '{'
   1753     { $$ = start_enum ($2); }
   1754     enumlist maybecomma_warn '}' maybe_attribute
   1755     { $$ = finish_enum ($<ttype>4, nreverse ($5),
   1756             chainon ($1, $8)); }
   1757   | enum_head '{'
   1758     { $$ = start_enum (NULL_TREE); }
   1759     enumlist maybecomma_warn '}' maybe_attribute
   1760     { $$ = finish_enum ($<ttype>3, nreverse ($4),
   1761             chainon ($1, $7)); }
After:
   1731 structsp_attr:
   1732     struct_head identifier '{'
   1733 //    { $$ = start_struct (RECORD_TYPE, $2);
   1734     { $<ttype>$ = start_struct (RECORD_TYPE, $2);
   1735       /* Start scope of tag before parsing components.  */
   1736     }
   1737     component_decl_list '}' maybe_attribute
   1738     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1739               chainon ($1, $7)); }
   1740   | struct_head '{' component_decl_list '}' maybe_attribute
   1741     { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
   1742               nreverse ($3), chainon ($1, $5));
   1743     }
   1744   | union_head identifier '{'
   1745 //    { $$ = start_struct (UNION_TYPE, $2); }
   1746     { $<ttype>$ = start_struct (UNION_TYPE, $2); }
   1747     component_decl_list '}' maybe_attribute
   1748     { $$ = finish_struct ($<ttype>4, nreverse ($5),
   1749               chainon ($1, $7)); }
   1750   | union_head '{' component_decl_list '}' maybe_attribute
   1751     { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
   1752               nreverse ($3), chainon ($1, $5));
   1753     }
   1754   | enum_head identifier '{'
   1755 //    { $$ = start_enum ($2); }
   1756     { $<ttype>$ = start_enum ($2); }
   1757     enumlist maybecomma_warn '}' maybe_attribute
   1758     { $$ = finish_enum ($<ttype>4, nreverse ($5),
   1759             chainon ($1, $8)); }
   1760   | enum_head '{'
   1761 //    { $$ = start_enum (NULL_TREE); }
   1762     { $<ttype>$ = start_enum (NULL_TREE); }
   1763     enumlist maybecomma_warn '}' maybe_attribute
   1764     { $$ = finish_enum ($<ttype>3, nreverse ($4),
   1765             chainon ($1, $7)); }
書き換え後再びスクリプトを実行し,無事終了した.

glibc

3つ目はglibcのコンパイル. 先に言うとglibcの2箇所の修正を行う.

user% zsh build-3-glibc
checking build system type... Invalid configuration `unknown-linux':
machine `unknown' not recognized
configure: error: /bin/bash
/home/user/workspace/sescutils/src/glibc-2.3.2/scripts/config.sub
unknown-linux failed
make: *** ターゲット `all' を make するルールがありません.  中止.
構築対象のマシンが分からないと言われた. ぱっと見修正箇所が分からなかったので調べてみた. 原因はbuild-3-glibcのBUILD変数の値だった(World's Appreciated Kitsh!より). このページではBUILD変数をi686-linuxに書き換えていたが,自分の環境ではgccのvオプションでがx86_64-linux-gnuになっていたので,それに書き換えた.
Before:
      1 #!/bin/sh
      2 
      3 source ./build-common
      4 
      5 GLIBC=glibc-2.3.2
      6 GLIBC_THREADS=glibc-linuxthreads-2.2.5
      7 GLIBC_HEADERS=glibc-kernheaders-2.4.15pre9
      8 GLIBC_BUILD_DIR=obj/glibc-build
      9 
     10 rm -rf $GLIBC_BUILD_DIR
     11 mkdir -p $GLIBC_BUILD_DIR
     12 cd $GLIBC_BUILD_DIR
     13 export CFLAGS="-O2 -mips2 -mabi=32 -fno-PIC -mno-abicalls"
     14 export CZFLAGS="-mips2 -mabi=32 -fno-PIC -mno-abicalls"
     15 $GNUSRC/$GLIBC/configure --build=${BUILD} --host=${TARGET}
      --prefix=${PREFIX}/${TARGET} \
     16   --disable-shared --with-headers=$KERNHEADERS --enable-add-ons
      --enable-static-nss \
     17   --disable-profile 2>1 | tee ../glibc.conf.log
     18 $MAKE all install 2>1 | tee ../glibc.gmake.log
     19 cd ../..
     20 
After:
      1 #!/bin/sh
      2 
      3 source ./build-common
      4 
      5 GLIBC=glibc-2.3.2
      6 GLIBC_THREADS=glibc-linuxthreads-2.2.5
      7 GLIBC_HEADERS=glibc-kernheaders-2.4.15pre9
      8 GLIBC_BUILD_DIR=obj/glibc-build
      9 
     10 rm -rf $GLIBC_BUILD_DIR
     11 mkdir -p $GLIBC_BUILD_DIR
     12 cd $GLIBC_BUILD_DIR
     13 export CFLAGS="-O2 -mips2 -mabi=32 -fno-PIC -mno-abicalls"
     14 export CZFLAGS="-mips2 -mabi=32 -fno-PIC -mno-abicalls"
     15 $GNUSRC/$GLIBC/configure --build=x86_64-linux-gnu --host=${TARGET}
      --prefix=${PREFIX}/${TARGET} \
     16   --disable-shared --with-headers=$KERNHEADERS --enable-add-ons
      --enable-static-nss \
     17   --disable-profile 2>1 | tee ../glibc.conf.log
     18 $MAKE all install 2>1 | tee ../glibc.gmake.log
     19 cd ../..
     20 

修正して再びコンパイルするも,また失敗.

	・
	・
	・
In file included from version.c:33:
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:1:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:2:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:3:
	error: missing terminating " character
/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version-info.h:4:
	error: missing terminating " character
version.c:40: error: syntax error before string constant
make[2]: ***
	[/home/user/workspace/sescutils/build-mipseb-linux/obj/glibc-build/csu/version.o]
	エラー 1
make[2]: ディレクトリ
	`/home/user/workspace/sescutils/src/glibc-2.3.2/csu'
	から出ます
make[1]: *** [csu/subdir_lib] エラー 2
make[1]: ディレクトリ
	`/home/user/workspace/sescutils/src/glibc-2.3.2' か
	ら出ます
make: *** [all] エラー 2
verion-info.hが原因らしいが,今度もまた分かり辛いエラーだった. しかし,幸いこれも同様に先ほどのページに解決方法が書いてあった. ../src/glibc-2.3.2/csu/version.cのversion-info.hを取り込む部分をコメントアウトするだけで良いらしい(普通こんなことしたらコンパイルが通らなそうだが結果から言えばコンパイルが通った上に今のところ実行にも支障はない).
Before:
     32 Compiled by GNU CC version "__VERSION__".\n"
     33 #include "version-info.h"
     34 #ifdef GLIBC_OLDEST_ABI
     35 "The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n"
     36 #endif
After:
     32 Compiled by GNU CC version "__VERSION__".\n"
     33 //#include "version-info.h"
     34 #ifdef GLIBC_OLDEST_ABI
     35 "The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n"
     36 #endif

gcc

最後にgccのコンパイルを行ったが,これは何のトラブルもなかったので省略する.

実行確認

以上まででクロスコンパイラの構築は終わりで,次からはクロスコンパイラが正常かのテストである. 冗長に関数を使ったコードを書いてコンパイルし,それをsescで実行してみた. 実行したソースコードは以下の通りである.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char &argv[])
{
  write(1, "Hello, World\n", strlen("Hello, World\n"));
  exit(0);
  return 0;
}
PATHを通し,いざコンパイル. README.sescによると,gccに使用するオプションを加えたものが次の通りである.
user% mipseb-linux-gcc -mips2 -mabi=32 -Wa,-non_shared
-mno-abicalls --static
-Wl,--script=/home/user/mypath/mipseb-linux/lib/ldscripts/mint.x 
試しに実行すると無事コンパイルもsescでの実行もできたので,引数を受け取れるように変更して.zshrcに加えた.

一覧