試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

x86_64上ではwinegccが正常に動作しない?(後半)

(2009/2/15)この記事の問題はバージョン1.1.15のWineでは解決されている。

x86_64上ではwinegccが正常に動作しない?(前半)」の続き。x86_32上でビルドされたwinegccコマンドを使用してx86_64上でwimeをビルドしようとしたが失敗し、環境変数WINEBUILDにwinebuildコマンドのラッパースクリプトを指定して--ld-cmdオプションを渡そうともしたが、何故かうまくいかないというところ。
ソースを見ると
[引用]ファイル名: wine-1.1.10/tools/winegcc/winegcc.c より

    const char* winebuild = getenv("WINEBUILD");
(中略)
    if (!winebuild) winebuild = "winebuild";
(中略)
    /* run winebuild to generate the .spec.o file */
    spec_args = strarray_alloc();
    spec_o_name = get_temp_file(output_name, ".spec.o");
    strarray_add(spec_args, winebuild);
    if (verbose) strarray_add(spec_args, "-v");
    if (keep_generated) strarray_add(spec_args, "--save-temps");
    strarray_add(spec_args, "--as-cmd");
    strarray_add(spec_args, AS);
    strarray_add(spec_args, "--ld-cmd");
    strarray_add(spec_args, LD);
(以下略)

--ld-cmdオプションへの値は固定されていて、それ(マクロ「LD」)は
[引用]ファイル名: wine-1.1.10/tools/winegcc/Makefile.in

DEFS = \
	-DINCLUDEDIR="\"$(includedir)\"" \
	-DDLLDIR="\"$(dlldir)\"" \
	-DLIBDIR="\"$(libdir)\"" \
	-DDLLFLAGS="\"@DLLFLAGS@\"" \
	-DLDDLLFLAGS="\"@LDDLLFLAGS@\"" \
	-DAS="\"$(AS)\"" \
	-DCC="\"$(CC)\"" \
	-DCPP="\"@CPPBIN@\"" \
	-DCXX="\"@CXX@\"" \
	-DLD="\"$(LD)\"" \
	-DNM="\"$(NM)\"" \
	-DPRELINK="\"$(PRELINK)\""

上を見る限りでは、ビルド時に決められてしまっているようだ。以前x86_64版Gentoo LinuxでビルドしてインストールしたWineで問題が起きなかった原因はここにあり、x86_64上でビルドしたWineでは、この部分が「ld -m elf_i386」に固定されるが、x86_32上でビルドされたものでは-m elf_i386オプションが付かないため、何をどう指定しようとx86_64向けのリンク操作を行ってしまう。

回避策

根本的にはwinegcc内のwinebuildコマンドへのオプションまわりの処理を改善するか、あるいはx86_32上でのビルド時にも-m elf_i386オプションを付けるようにconfigure.acを修正する*1ことが望ましいが、回避策としては、Wine本体のソースツリーを用いてwinegccのみをビルドして取り出し、置き換えるのが楽。configureスクリプトには--prefixオプションで現在のインストール場所を指定する(ディストリのパッケージなら/usrが多い)。*2

$ tar jxf [wine-[バージョン].tar.bz2の場所]
$ cd wine-[バージョン]/
$ ./configure --prefix=/usr --without-x --without-freetype [必要に応じて--without-xxxを追加]
$ make depend
$ make -C libs
$ make -C tools/winegcc

ビルドできたら好きなように置き換える。

(既存のファイルを上書き・ディストリのパッケージをバージョンアップすると上書きされるかも)
$ sudo mv /usr/bin/winegcc{,.orig}
$ sudo install -s -m 755 tools/winegcc/winegcc /usr/bin/
(別の名前で追加・ビルド時にコマンド名を置き換えて使用)
$ sudo install -s -m 755 tools/winegcc/winegcc /usr/local/bin/winegcc32

winegcc32として保存した場合、「x86_64上ではwinegccが正常に動作しない?(前半)」のwimeの例では

$ find -name Makefile -exec sed -i 's:winegcc:winegcc32:' {} \;
$ make

のようにして全てのMakefileに対してコマンド名部分を置き換えることでビルドは通るようになる。
なお、もし同様にwineg++wineg++32にしたいのであれば

(ビルド前の作業・wineg++32をg++として通すための修正)
[wine-[バージョン]]$ sed -i 's:\(else if (strendswith(argv\[0\], "++\)\(")) opts.processor = proc_cxx;\):\132\2:' tools/winegcc/winegcc.c
(インストール後の作業)
[wine-[バージョン]]$ cd /usr/local/bin/
[/usr/local/bin]$ sudo ln -s wine{gcc,g++}32

のようにする。

使用したバージョン:

  • Wine 1.1.10 (libwine-devel 1.1.10-1mdv2009.0)

*1:「case $host_cpu in *i345678986*)」の下あたりに「LD="${LD:-ld} -m elf_i386"」を書くなど

*2:インストール場所と一致しないと「/usr/bin/ld: cannot find -lmsvcrt」となり、Wineのライブラリが見つからない