スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[gcc備忘録] C/C++プログラムを Ubuntu 64bitでコンパイルし、Windows 64bitで動かす(その1)

Windowsで動くプログラムを、Linuxでコンパイルするための、MinGW-w64クロスコンパイラ(x86_64-w64-mingw32)を構築してみた。
 ・クロスコンパイラが動く環境:Linux(今回は Ubuntu 64bit)
 ・クロスコンパイラによってコンパイルされたプログラムが動く環境:Windows 64bit(今回は Windows 7)

後に出てくる用語を整理しておくと、
 ・target:クロスコンパイラによってコンパイルされたプログラムが動く環境(=Windows)
 ・host:クロスコンパイラが動く環境(=Linux)
 ・build:クロスコンパイラをビルドする環境(=Linux)

●記事修正
(2011/2/18) インストール先を「/usr/local」から「/opt」に変更し、インストールを再検証しました。

●関連記事

[gcc備忘録] C/C++プログラムを Ubuntu 64bitでコンパイルし、Windows 64bitで動かす(その2:MSMPI編)
MS-MPIをリンクするプログラムのクロスコンパイルを試みます。この記事の続編です。

[gcc備忘録] C/C++プログラムを Ubuntu 64bitでコンパイルし、Windows 32bitで動かす(その1)
今回の記事の 32bitバージョンです。

●インストールの(私の)方針

今回インストールするクロスコンパイラは、gcc-4.5.2 である。
「/opt/mingw-4.5.2」にインストールすることにする。

クロスコンパイラのビルドに使用したコンパイラは、以下のように「gcc 4.4.3」である。

$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


●手順1(Linux側):binutilsのコンパイル/インストール
入手先:http://ftp.gnu.org/gnu/binutils/
  最新バージョン「binutils-2.21.tar.gz」(ソース)を入手した。

①「binutils-2.21.tar.gz」をホームディレクトリに置き、端末で以下を実行。

cd
tar zxf binutils-2.21.tar.gz
cd binutils-2.21
mkdir build
cd build
../configure --target=x86_64-w64-mingw32 --disable-multilib \
--with-sysroot=/opt/mingw-4.5.2 --prefix=/opt/mingw-4.5.2 \
--with-windres
make
sudo make install
sudo cp /opt/mingw-4.5.2/bin/x86_64-w64-mingw32-windmc \
/opt/mingw-4.5.2/x86_64-w64-mingw32/bin/windmc
sudo cp /opt/mingw-4.5.2/bin/x86_64-w64-mingw32-windres \
/opt/mingw-4.5.2/x86_64-w64-mingw32/bin/windres


「/opt/mingw-4.5.2/bin」の下に、「x86_64-w64-mingw32-ar」等がコピーされればインストール成功。

●手順2(Linux側):「mingw-w64 toolchain」の中の、headerをインストール
入手先:http://sourceforge.net/projects/mingw-w64/
  「mingw-w64-v1.0-snapshot-20101003.tar.bz2」を入手した。

①「mingw-w64-v1.0-snapshot-20101003.tar.bz2」をホームディレクトリに置き、端末で以下を実行。

cd
tar jxf mingw-w64-v1.0-snapshot-20101003.tar.bz2
cd mingw-w64-v1.0-20101003
mkdir build-header
cd build-header
../mingw-w64-headers/configure --host=x86_64-w64-mingw32 \
--prefix=/opt/mingw-4.5.2
sudo make install
cd /opt/mingw-4.5.2
sudo ln -s x86_64-w64-mingw32 mingw
cd mingw
sudo ln -s lib lib64


「/opt/mingw-4.5.2/x86_64-w64-mingw32/include」の下に、ヘッダファイルがコピーされればインストール成功。

私は最初、hostは Linux、targetは Windowsのはずだから、configureのオプションで--hostを省略し、「--target=x86_64-w64-mingw32」と与えていた。ところが、これではちっともうまくいかず、思い切りハマってしまった。試行錯誤の結果、--targetの代わりに「--host=x86_64-w64-mingw32」とすればうまくいくことが判明した(理屈はわからない)。

●手順3(Linux側):gcc(クロスコンパイラ)のコア部分のコンパイル/インストール
入手先:ftp://ftp.gnu.org/gnu/gcc/
  最新バージョン「gcc-4.5.2.tar.gz」(ソース)を入手した。

①「gcc-4.5.2.tar.gz」をホームディレクトリに置き、以下を実行。

私の環境には、gccのインストールに必要な m4、gmp、mpfr、mpc が、すでに「/usr/local」にインストールされていた。
これらのインストール法については、http://kanedaq.blog24.fc2.com/blog-entry-1.html を参照。

cd
tar zxf gcc-4.5.2.tar.gz
cd gcc-4.5.2
mkdir build
cd build
../configure --target=x86_64-w64-mingw32 --disable-multilib \
--prefix=/opt/mingw-4.5.2 --with-sysroot=/opt/mingw-4.5.2 \
--with-gmp=/usr/local
make all-gcc
sudo make install-gcc


「/opt/mingw-4.5.2/bin」の下に、「x86_64-w64-mingw32-gcc」等がコピーされればインストール成功。

●手順4(Linux側):「mingw-w64 toolchain」の中の、crt関連をインストール

①「$HOME/.bashrc」の最後に、以下の2行を追加しておく。

#### MinGW-w64 Cross Compiler (64bit)
export PATH=$PATH:/opt/mingw-4.5.2/bin



② 端末で以下を実行。

export PATH=$PATH:/opt/mingw-4.5.2/bin
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
cd
cd mingw-w64-v1.0-20101003
mkdir build-crt
cd build-crt
../mingw-w64-crt/configure --host=x86_64-w64-mingw32 \
--prefix=/opt/mingw-4.5.2 --with-sysroot=/opt/mingw-4.5.2
make
sudo make install



「sudo make install」を実行したとき、以下のエラーが出た。

/bin/bash: line 5: x86_64-w64-mingw32-ranlib: コマンドが見つかりません



whichで調べてみると、

$ which x86_64-w64-mingw32-ranlib
/opt/mingw-4.5.2/bin/x86_64-w64-mingw32-ranlib



コマンドへのPATHは通っている。
エラーを回避するため、Makefileを修正することにした。
エディタで「ranlib」(小文字)を検索し、以下のように ranlibをフルパスで指定した。

RANLIB = x86_64-w64-mingw32-ranlib
  ↓ 変更
RANLIB = /opt/mingw-4.5.2/bin/x86_64-w64-mingw32-ranlib



再び以下を実行したら、インストールできた。

sudo make install


「/opt/mingw-4.5.2/x86_64-w64-mingw32/lib」の下に、lib*.aがコピーされればインストール成功。

●手順5(Linux側):gcc(クロスコンパイラ)の残りをコンパイル/インストール

① 端末で以下を実行。

cd
cd gcc-4.5.2/build
make
sudo make install


「/opt/mingw-4.5.2/bin」の下に、「libstdc++-6.dll」等のdllがコピーされればインストール成功。

●手順6(Linux側):ファイル修正

① float.hを修正。

以下のページの手順3によると、float.hの修正が必要らしい。
http://www.symscape.com/openfoam-1-7-x-on-windows-64-mpi

この手順に従い、以下のファイルを修正する。
/opt/mingw-4.5.2/lib/gcc/x86_64-w64-mingw32/4.5.2/include/float.h

エディタでファイルの末尾に行き、「#endif /* _FLOAT_H___ */」の前にinclude_next文を追加した。

#endif /* __STDC_WANT_DEC_FP__ */

#endif /* _FLOAT_H___ */

  ↓ 変更

#endif /* __STDC_WANT_DEC_FP__ */

#include_next <float.h>

#endif /* _FLOAT_H___ */



●手順7:DLLを Windows環境に転送

①「/opt/mingw-4.5.2/bin/*.dll」を Windows環境に転送し、PATHを通す。

●後始末(Linux側)

① ホームディレクトリの下の、ターボールを展開した以下のディレクトリは、ディレクトリごと削除した。

binutils-2.21
mingw-w64-v1.0-20101003
gcc-4.5.2



●テスト

① Linux側で「hello.cpp」を作成した。

#include <iostream>

int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}



② Linuxの端末で以下を実行し、クロスコンパイルした。
「-static」オプションを与えると、スタティックリンクされる。

x86_64-w64-mingw32-g++ -o hello_d.exe hello.cpp
x86_64-w64-mingw32-g++ -o hello_s.exe hello.cpp -static


生成された exeを Windows上(コマンドプロンプト)で動かしてみたら、いずれも動いた。
ダイナミックリンクの exeは、libstdc++-6.dllと libgcc_s_sjlj-1.dllが必要だった。
スタティックリンクの exeは、これらの dllがなくても動いた。

●課題

・boostのインストール
  必要に迫られたら試したい。
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

カネダック

Author:カネダック
 
普通のC++プログラマですが、業務で流体解析をやっていて格子職人と呼ばれています。
J.S.バッハ等、古楽をピリオド楽器による演奏で聴くのが好き。
リュート演奏にあこがれつつ、クラシックギターを弾きます。

保有資格
・中小企業診断士
・Oracle Master 8 Platinum(今のGold相当)

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。