プロジェクト

全般

プロフィール

A/I #28

未完了

Windowsネイティブ(MinGW)なGCC8を作る。long double型は80ビット精度必須

開発 次郎 さんが23日前に追加. 21日前に更新.

ステータス:
新規
優先度:
通常
担当者:
開始日:
2026/06/13
期日:
予定工数:

開発 次郎 さんが23日前に更新

構築メモ

MSVCRT を使いながら long double=80bit を実現することは “不可能”
れは GCC の制限ではなく、MSVCRT(Microsoft の C ランタイム)の仕様そのものが原因。

だから --with-default-msvcrt=ucrt を使う必要があるのではなく、
MSVCRT を選んだ瞬間に long double=64bit が確定してしまうという構造にする。

MSVCRT の long double は double と同じ 64bit で実装されている。

MSVCRT の ABI
→ long double = 64bit

MinGW-w64 の MSVCRT CRT
→ long double = 64bit

GCC の configure
→ long double のビット幅を変更できない
→ CRT の ABI に従うだけ

つまり:
MSVCRT を選ぶ = long double は 64bit に固定される
GCC 側でどう頑張っても変えられない。

UCRT は long double を 80bit として扱える ABI を持っている。
だから Rocky9 の mingw-w64 は UCRT + 80bit long double の構成になっていた。

つまり:

MSVCRT → 64bit long double(固定)

UCRT → 80bit long double(可能)

UCRT は Windows 7 以降で動作する。
Windows Update や VC++ 再頒布パッケージで配布されている。

✔️ MSVCRT より新しいが、互換性は高い
MSVCRT は古いが、
MSVCRT を使う理由は “古い Windows 互換性” ではなく “MinGW の歴史的理由”。

今は UCRT が標準。

開発 次郎 さんが21日前に更新

UCRT64 用 GCC 8.4.0 完全構築手順(最終版・Textile)

MSYS2 UCRT64 上で、UCRT 対応の x86_64-w64-mingw32 向け GCC 8.4.0 を、
stage1 → CRT → 最終 GCC の順で再構築するための完全版手順。

以下は Redmine Textile 用。コードブロックは指定どおりの形式を使う。

0. 前提パッケージ(MSYS2 UCRT64)

UCRT64 シェルで、必要なパッケージをインストールする。

pacman -S \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-gmp \
mingw-w64-ucrt-x86_64-mpfr \
mingw-w64-ucrt-x86_64-mpc \
mingw-w64-ucrt-x86_64-crt \
mingw-w64-ucrt-x86_64-headers

注意:

/ucrt64/include を削除しない(ホスト g++ の標準ヘッダが入っている)

1. ソース配置

前提とするディレクトリ構成:

/d/work/gcc8/
├ gcc-8.4.0/
└ mingw-w64/
├ mingw-w64-headers/
└ mingw-w64-crt/

2. mingw-w64 headers(ターゲット用)インストール

ターゲット用ヘッダを /ucrt64/x86_64-w64-mingw32 配下にインストールし、
古い GCC が期待する /ucrt64/mingw/include もシンボリックリンクで用意する。

cd /d/work/gcc8
rm -rf build-headers
mkdir build-headers
cd build-headers

../mingw-w64/mingw-w64-headers/configure \
--host=x86_64-w64-mingw32 \
--prefix=/ucrt64/x86_64-w64-mingw32

make -j1
make install

mkdir -p /ucrt64/mingw
ln -s /ucrt64/x86_64-w64-mingw32/include /ucrt64/mingw/include

3. stage1 GCC(C コンパイラ + libgcc)構築

C のみ・libgcc のみをビルドする stage1 を構築する。
ここでは all-stage1-gcc と all-stage1-target-libgcc のみに絞る。

cd /d/work/gcc8
rm -rf build-gcc-stage1
mkdir build-gcc-stage1
cd build-gcc-stage1

../gcc-8.4.0/configure \
--target=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
--with-sysroot=/ucrt64 \
--enable-languages=c \
--disable-multilib \
--disable-nls

make -j1 all-stage1-gcc all-stage1-target-libgcc

動作確認(コンパイルだけ通ればよい。生成 exe の実行は失敗しても問題なし):

cd /d/work/gcc8/build-gcc-stage1/gcc
./xgcc -v
echo "int main(){return 0;}" > t.c
./xgcc t.c -c

4. mingw-w64 CRT(ターゲット用)を stage1 でビルド

CRT は stage1 の xgcc を使ってビルドする。
CC に -B オプションを付けて、stage1 の libgcc / crt を見せることが重要。

cd /d/work/gcc8
rm -rf build-crt
mkdir build-crt
cd build-crt

../mingw-w64/mingw-w64-crt/configure \
--host=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
CC="/d/work/gcc8/build-gcc-stage1/gcc/xgcc -B/d/work/gcc8/build-gcc-stage1/gcc" 

make -j1
make install

dllcrt2.o が見つからない場合は、MSYS2 の dllcrt2.o を GCC が期待する場所にリンクする。

find /ucrt64 -name dllcrt2.o

例: /ucrt64/lib/dllcrt2.o にある場合
mkdir -p /ucrt64/x86_64-w64-mingw32/lib
ln -s /ucrt64/lib/dllcrt2.o /ucrt64/x86_64-w64-mingw32/lib/dllcrt2.o

5. UCRT 対応のための libgcc リンクライン修正

GCC 8.4.0 の mingw 用設定は MSVCRT 前提になっており、
UCRT CRT(dllcrt2.o)が必要とする ucrtbase.dll がリンクされないため、
_initterm_e の未定義参照が発生する。

これを解決するために、config/i386/t-mingw32 の SHLIB_LC を修正する。

対象ファイル:

/d/work/gcc8/gcc-8.4.0/libgcc/config/i386/t-mingw32

修正前(例):


MinGW-specific parts of LIB_SPEC
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32

修正後(UCRT 対応版・推奨):


MinGW-specific parts of LIB_SPEC
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lucrtbase -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32

あるいは、MSVCRT を完全に外して UCRT のみに寄せる場合:


MinGW-specific parts of LIB_SPEC
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lucrtbase -ladvapi32 -lshell32 -luser32 -lkernel32

6. 最終 GCC(C/C++)構築

CRT とヘッダ、libgcc のリンクライン修正が完了したら、
最終的な GCC 8.4.0(C/C++)を構築する。

cd /d/work/gcc8
rm -rf build-gcc-final
mkdir build-gcc-final
cd build-gcc-final

../gcc-8.4.0/configure \
--target=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
--with-sysroot=/ucrt64 \
--enable-languages=c,c++ \
--disable-multilib \
--disable-nls

make -j1
make install

LTO 周りでトラブルが出る場合は、configure に --disable-lto を追加してもよい。

../gcc-8.4.0/configure \
--target=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
--with-sysroot=/ucrt64 \
--enable-languages=c,c++ \
--disable-multilib \
--disable-nls \
--disable-lto

7. 完成したツールチェーンの確認

UCRT64 シェルで、インストールされた GCC を確認する。

/ucrt64/bin/x86_64-w64-mingw32-gcc -v
/ucrt64/bin/x86_64-w64-mingw32-g++ -v

簡単な C/C++ プログラムをビルド・実行して、
UCRT ベースの exe が正常に動作することを確認する。

cat > hello.c <<EOF
#include <stdio.h>
int main(void) {
printf("hello from UCRT GCC 8.4.0\n");
return 0;
}
EOF

/ucrt64/bin/x86_64-w64-mingw32-gcc hello.c -o hello.exe
./hello.exe

8. この手順で避けられるハマりポイント

/ucrt64/include を消してしまい、<algorithm> などが消える問題

gmp/mpfr/mpc 未インストールによる configure 失敗

dllcrt2.o が /ucrt64/x86_64-w64-mingw32/lib に無くて libgcc_s.dll のリンクに失敗

stage1 xgcc でリンクテストを行い、"cannot compute suffix of object files" で落ちる問題

→ CC に -B build-gcc-stage1/gcc を付けて解決

UCRT CRT と MSVCRT の混在により、_initterm_e 未定義で libgcc_s.dll のリンクが失敗

→ config/i386/t-mingw32 の SHLIB_LC に -lucrtbase を追加して解決

開発 次郎 さんが21日前に更新

UCRT64 用 GCC 8.4.0 完全構築手順(最終版・LTO 無効)

MSYS2 UCRT64 上で、UCRT 対応の x86_64-w64-mingw32 向け GCC 8.4.0 を
stage1 → CRT → 最終 GCC の順で構築するための、現時点での安定版手順。
LTO まわりのトラブルを避けるため、最終 GCC は LTO 無効 (--disable-lto) とする。

0. 前提パッケージ(MSYS2 UCRT64)

UCRT64 シェルで、必要なパッケージをインストールする。

pacman -S \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-gmp \
mingw-w64-ucrt-x86_64-mpfr \
mingw-w64-ucrt-x86_64-mpc \
mingw-w64-ucrt-x86_64-crt \
mingw-w64-ucrt-x86_64-headers

注意:

/ucrt64/include を削除しない(ホスト g++ の標準ヘッダが入っている)

1. ソース配置

前提とするディレクトリ構成:

/d/work/gcc8/
├ gcc-8.4.0/
└ mingw-w64/
├ mingw-w64-headers/
└ mingw-w64-crt/

2. mingw-w64 headers(ターゲット用)インストール

ターゲット用ヘッダを /ucrt64/x86_64-w64-mingw32 配下にインストールし、
古い GCC が期待する /ucrt64/mingw/include もシンボリックリンクで用意する。

cd /d/work/gcc8
rm -rf build-headers
mkdir build-headers
cd build-headers

../mingw-w64/mingw-w64-headers/configure \
--host=x86_64-w64-mingw32 \
--prefix=/ucrt64/x86_64-w64-mingw32

make -j1
make install

mkdir -p /ucrt64/mingw
ln -s /ucrt64/x86_64-w64-mingw32/include /ucrt64/mingw/include

3. stage1 GCC(C コンパイラ + libgcc)構築

C のみ・libgcc のみをビルドする stage1 を構築する。
ここでは all-stage1-gcc と all-stage1-target-libgcc のみに絞る。

cd /d/work/gcc8
rm -rf build-gcc-stage1
mkdir build-gcc-stage1
cd build-gcc-stage1

../gcc-8.4.0/configure \
--target=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
--with-sysroot=/ucrt64 \
--enable-languages=c \
--disable-multilib \
--disable-nls

make -j1 all-stage1-gcc all-stage1-target-libgcc

動作確認(コンパイルだけ通ればよい。生成 exe の実行は失敗しても問題なし):

cd /d/work/gcc8/build-gcc-stage1/gcc
./xgcc -v
echo "int main(){return 0;}" > t.c
./xgcc t.c -c

4. mingw-w64 CRT(ターゲット用)を stage1 でビルド

CRT は stage1 の xgcc を使ってビルドする。
CC に -B オプションを付けて、stage1 の libgcc / crt を見せることが重要。

cd /d/work/gcc8
rm -rf build-crt
mkdir build-crt
cd build-crt

../mingw-w64/mingw-w64-crt/configure \
--host=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
CC="/d/work/gcc8/build-gcc-stage1/gcc/xgcc -B/d/work/gcc8/build-gcc-stage1/gcc" 

make -j1
make install

dllcrt2.o が見つからない場合は、MSYS2 の dllcrt2.o を GCC が期待する場所にリンクする。

find /ucrt64 -name dllcrt2.o

例: /ucrt64/lib/dllcrt2.o にある場合
mkdir -p /ucrt64/x86_64-w64-mingw32/lib
ln -s /ucrt64/lib/dllcrt2.o /ucrt64/x86_64-w64-mingw32/lib/dllcrt2.o

5. UCRT 対応のための libgcc リンクライン修正

GCC 8.4.0 の mingw 用設定は MSVCRT 前提になっており、
UCRT CRT(dllcrt2.o)が必要とする ucrtbase.dll がリンクされないため、
_initterm_e の未定義参照が発生する。

これを解決するために、config/i386/t-mingw32 の SHLIB_LC を修正する。

対象ファイル:

/d/work/gcc8/gcc-8.4.0/libgcc/config/i386/t-mingw32

修正前(例):


MinGW-specific parts of LIB_SPEC
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32

修正後(UCRT 対応版・推奨):


MinGW-specific parts of LIB_SPEC
SHLIB_LC = -lmingwthrd -lmingw32 -lmingwex -lmoldname -lucrtbase -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32

(MSVCRT を完全に外すなら、-lmsvcrt を削除してもよい)

6. 最終 GCC(C/C++、LTO 無効)構築

CRT とヘッダ、libgcc のリンクライン修正が完了したら、
最終的な GCC 8.4.0(C/C++)を構築する。
LTO まわりのホスト側トラブルを避けるため、--disable-lto を付ける。

cd /d/work/gcc8
rm -rf build-gcc-final
mkdir build-gcc-final
cd build-gcc-final

../gcc-8.4.0/configure \
--target=x86_64-w64-mingw32 \
--prefix=/ucrt64 \
--with-sysroot=/ucrt64 \
--enable-languages=c,c++ \
--disable-multilib \
--disable-nls \
--disable-lto

make -j1
make install

これにより、ホスト側 gcc 16 がビルドする lto-plugin がビルド対象から外れ、
dllcrt2.o + _initterm_e まわりの LTO 特有のエラーを回避できる。

7. 完成したツールチェーンの確認

UCRT64 シェルで、インストールされた GCC を確認する。

/ucrt64/bin/x86_64-w64-mingw32-gcc -v
/ucrt64/bin/x86_64-w64-mingw32-g++ -v

簡単な C プログラムをビルド・実行して、
UCRT ベースの exe が正常に動作することを確認する。

cat > hello.c <<EOF
#include <stdio.h>
int main(void) {
printf("hello from UCRT GCC 8.4.0\n");
return 0;
}
EOF

/ucrt64/bin/x86_64-w64-mingw32-gcc hello.c -o hello.exe
./hello.exe

8. この手順で避けられるハマりポイント

/ucrt64/include を消してしまい、<algorithm> などが消える問題

gmp/mpfr/mpc 未インストールによる configure 失敗

dllcrt2.o が /ucrt64/x86_64-w64-mingw32/lib に無くて libgcc_s.dll のリンクに失敗

stage1 xgcc でリンクテストを行い、"cannot compute suffix of object files" で落ちる問題

→ CC に -B build-gcc-stage1/gcc を付けて解決

UCRT CRT と MSVCRT の混在により、_initterm_e 未定義で libgcc_s.dll のリンクが失敗

→ config/i386/t-mingw32 の SHLIB_LC に -lucrtbase を追加して解決

ホスト側 gcc 16 がビルドする lto-plugin で、dllcrt2.o + _initterm_e で落ちる問題

→ 最終 GCC では --disable-lto を指定して LTO 自体を無効化

他の形式にエクスポート: Atom PDF