love5an: (Default)
[personal profile] love5an
Я тут уже который раз в году пытаюсь пересобрать тулчейн MinGW(GCC, binutils, и необходимые библиотеки) на самом MinGW, но только вот недавно очередная попытка завершилась успехом.

Вообще, я писал в juick - пересборка всего этого дела - отличный способ выхода из запоя. Шутки шутками, конечно, но сразу скажу - натрахался на год вперед.

Вобщем, что получилось в итоге(сконфигурировано под i686-pc-mingw32, без NLS):
http://dl.dropbox.com/u/5521262/MinGW.tar.bz2

binutils-2.22
gcc-4.6.2
GCC и Binutils статически слинкованы со всеми необходимыми библиотеками.
Включены libgomp и lto.
Собраны компиляторы для c, c++, fortran, objc, objc-c++
Стандартные библиотеки собраны как статические, так и динамические.

w32api-3.17-2
mingwrt-3.20
zlib-1.2.5 (и статическая версия(.a), и DLL)
pthreads-w32-2-8-0 (GC2, DLL)
libiconv-1.14 (.a, .dll)
gettext-0.18.1.1 (.a, .dll)
expat-2.0.1 (.a, .dll)
gmp-5.0.2 (.dll)
mpfr-3.2.0-dev (.dll, собирался из SVN trunk)
mpc-1.0.0dev (.dll, SVN-версия)
ppl-0.11.2 (.dll)
cloog-ppl-0.15.11
make-3.82 (bin/i686-pc-mingw32-make.exe)
bzip2-1.0.6 (.a, .dll)
xz-5.0.3 (.a, .dll)
libtool-2.42
autoconf-2.68
automake-1.11.2

Кстати, я уже успел скомпилировать с помощью этого тулчейна новый SBCL из сорцов http://github.com/akovalenko/sbcl-win32-threads
вот: http://dl.dropbox.com/u/5521262/sbcl-1.0.55.1.mswinmt.1192-20b4d16.msi

А вот как все это собирать:


Сначала нам нужен уже существующий тулчейн MinGW, и MSYS.
Я устанавливал его с помощью mingw-get, в директорию C:/MinGW (а msys в C:/MinGW/msys/1.0)
От существующего MinGW нужны GCC, binutils, gmp, mpfr, mpc, ppl, cloog и zlib.

MSYS это минимальное unix-like окружение, необходимое, в частности, для корректной работы autotools и прочего подобного. Именно в MSYS будет происходить весь процесс сборки.

От MSYS надо много чего, я уже не помню что конкретно устанавливал для MSYS, но вобщем точно нужны bash, make, coreutils, cygutils, autotools, flex, bison, m4, texinfo. Устанавливайте, все что найдете в mingw-get на тему msys, кроме библиотек включенных в MinGW.

После установки msys надо запустить из нее скрипт /c/mingw/msys/1.0/postinstall/pi.sh, чтобы связать её с установленным MinGW.

Сборку я сделал в несколько ступеней. Причин несколько. Во-первых, по-другому GCC с полноценным трехступенчатым бутстрапом почему-то не собирается, сборка разваливается то где-то на stage-2 ada(хотя ada отключена), то в libgomp, то еще где. Во-вторых, это позволяет собрать GCC и binutils со статически влинкованными библиотеками поддержки. И в-третьих, это позволяет избавиться от зависимостей и конфликтов со "старым" MinGW(т.е. MinGW с сайта, использующимся для сборки) еще на раннем этапе.

Весь процесс сборки будет проходить в директории C:/MinGW-boot

В этой директории я создал несколько поддиректорий - src, куда складывал сорцы библиотек, release, куда устанавливается первая, промежуточная, стадия тулчейна, и три директории сборки - build-boot для первой стадии GCC и библиотек поддержки, build-new - для сборки библиотек поддержки и полноценных GCC и binutils новыми компиляторами, и build-final - для сборки библиотек уже новым тулчейном.

Сборка первой стадии:
Для начала нам нужны сорцы. Сорцы я брал с ftp.gnu.org, а также с официальных сайтов библиотек.
Конкретно нужно:
binutils-2.22
gcc-4.6.2
gmp-5.0.2
mpfr-3.1.0
mpc-0.8.2
libiconv-1.14 (libiconv вроде не обязательна, учитывая что сборка идет без NLS, но я ее тоже собирал)
ppl-0.11.2
cloog-ppl-0.15.11 (ppl и cloog опциональны, но они нужны для Graphite-оптимизаций в GCC, http://gcc.gnu.org/wiki/Graphite)

Первая стадия собирается в c:/MinGW-boot/build-boot
Собирается все статически, и в таком порядке: gmp, mpfr, mpc, ppl, cloog, libiconv, binutils, gcc
Для каждой библиотеки из перечисленных я создавал поддиректорию с соответствующим именем, и создавал там файл runconfigure.sh, в котором идет обращение к скрипту configure, находящемуся в директории с сорцами библиотеки.

Вот например runconfigure.sh для gmp(вызывается когда msys находится в директории сборки gmp, как понятно):
../../src/gmp-5.0.2/configure --prefix=/c/mingw-boot/release \
                              --build=i686-pc-mingw32 \
                              --enable-cxx \
                              --enable-fat \
                              --disable-shared \
                              --enable-static \
                              CFLAGS='-g -O2' \
                              CXXFLAGS='-g -O2' \
                              CPPFLAGS='-fexceptions'

--enable-cxx означает поддержку C++ обертки над GMP
--enable-fat - для того чтобы GMP мог в рантайме выбирать процедуры в зависимости от типа процессора(это повышает производительность и позволяет собирать GMP под "обобщенные" build/host, типа i686 как у меня тут)
--enable-static --disable-shared - отключает сборку DLL-версий библиотек и оставляет только статические.
CFLAGS, CXXFLAGS, CPPFLAGS - флаги компиляторов, использующиеся при сборке. Как видно, тут есть -fexceptions - это надо для поддержки C++ных исключений сишным кодом, а это в свою очередь, в данном случае нужно для корректной работы ppl, которая зависит от GMP. Вообще, остальные библиотеки собирать с -fexceptions не обязательно, но я в дальнейшем все их собирал с этим флагом. '-g' означает что в коде будет отладочная информация(на производительность она _не_ влияет), а '-O2' - что оптимизации компилятора будут с упором на скорость работы.

Запускаем runconfigure.sh
Потом вызываем make. Тут надо сказать, у меня GMP почему-то часто конфигурируется и собирается криво, поэтому надо обязательно сделать make check после этого.
После - делаем make install, и gmp устанавливается в c:/MinGW-boot/release
У меня вся строчка которая собирает gmp выглядит так:
./runconfigure.sh && make -j 2 > make.my.log && make -j 2 check > make.check.my.log && make install

Флаг -j 2 в make означает распараллеливание сборки. У меня на ноуте 2 ядра, поэтому 2. Если у кого четыре - соответственно оптимально будет использовать -j 4. (если число больше количества ядер/процессоров в системе, выполнение будет не оптимальным). Ну и, как видно, я перенаправляю stdout в файлы, чтобы процесс сборки не захламлял терминал.

runconfigure.sh для mpfr:
../../src/mpfr-3.1.0/configure --prefix=/c/mingw-boot/release \
                               --build=i686-pc-mingw32 \
                               --disable-shared \
                               --enable-static \
                               --enable-thread-safe \
                               --with-gmp=/c/mingw-boot/release \
                               CFLAGS='-g -O2' \
                               CPPFLAGS='-fexceptions'

--with-gmp указывает, куда была установлена GMP.
Сборка(учитываем что мы находимся в директории сборки. с т.е.
cd /c/mingw-boot/build-boot/mpfr
- в дальнейшем я про это упоминать не буду):
./runconfigure.sh && make -j 2 > make.my.log && make -j 2 check > make.check.my.log && make install


mpc:
../../src/mpc-0.8.2/configure --prefix=/c/mingw-boot/release \
                              --build=i686-pc-mingw32 \
                              --disable-shared \
                              --enable-static \
                              --with-mpfr=/c/mingw-boot/release \
                              --with-gmp=/c/mingw-boot/release \
                              CFLAGS='-g -O2' \
                              CPPFLAGS='-fexceptions'

./runconfigure.sh && make -j 2 > make.my.log && make -j 2 check > make.check.my.log && make install


libiconv:
../../src/libiconv-1.14/configure --prefix=/c/mingw-boot/release \
                                  --build=i686-pc-mingw32 \
                                  --disable-shared \
                                  --enable-static \
                                  --disable-nls \
                                  --enable-extra-encodings \
                                  CFLAGS='-g -O2' \
                                  CPPFLAGS='-fexceptions' \
                                  LDFLAGS='-s -static-libgcc'

--disable-nls означает, что мы отключаем поддержку National Language Support, т.е. локализации. Причины такие: во-первых, NLS все-равно работает криво, по крайней мере у меня на Win7, и часто выдает иероглифы вместо русских, например, букв, во-вторых, ему нужен gettext, а это внесло бы зависимость от динамических библиотек из старого тулчейна, и в третьих - мне лично как-то удобнее когда утилиты общаются на английском - в документации например сразу понятно куда смотреть, и все такое.

LDFLAGS - флаги линкера. Они используются при компоновке исполняемых файлов. '-s' значит использование strip, т.е. удаление всей отладочной информации и других не особо нужных символов из итогового файла, а -static-libgcc означает линковку со статической библиотекой поддержки GCC. Конкретно в случае iconv, libgcc вроде бы не используется, но для других программ, особенно программ на C++, какие будут в PPL - это очень важный флаг, он позволяет избавиться от зависимостей от "старого" GCC.

./runconfigure.sh && make -j 2 > make.my.log && make install

Как видно, я тут не делаю check. Причина такая - несмотря на то что iconv в общем и целом, работает и собирается отлично, тест с одной из редких кодировок он все-таки не проходит, по непонятным мне причинам(я пытался разобраться, но так и не понял до конца).

ppl:
../../src/ppl-0.11.2/configure --prefix=/c/mingw-boot/release \
                               --build=i686-pc-mingw32 \
                               --disable-shared \
                               --enable-static \
                               --enable-threads \
                               --disable-debugging \
                               --disable-nls \
                               --with-gmp-prefix=/c/mingw-boot/release \
                               --with-cflags='-g -O2' \
                               --with-cxxflags='-g -O2' \
                               CPPFLAGS='-fexceptions' \
                               LDFLAGS='-s -static-libstdc++ -static-libgcc'

--enable-threads - поддержка многопоточности
--disable-debugging - отключение дополнительной отладочной информации(все-равно мы добавляем в флаги -g)
--with-gmp-prefix - директория, куда установлена GMP.
./runconfigure.sh && make -j 2 > make.my.log && make install

make check я тут тоже не делаю, но причина только в том, что PPL проходит тесты очень долго. Нет, даже не так. ОЧЕНЬ ДОЛГО. Натурально, я как-то замерял - это было дольше, чем сборка GCC с полноценным трехступенчатым бутстрапом.

cloog:
../../src/cloog-ppl-0.15.11/configure --prefix=/c/mingw-boot/release \
                                      --build=i686-pc-mingw32 \
                                      --disable-shared \
                                      --enable-static \
                                      --with-ppl=/c/mingw-boot/release \
                                      --with-gmp=/c/mingw-boot/release \
                                      --with-host-libstdcxx='/mingw/lib/gcc/mingw32/4.6.1/libstdc++.a' \
                                      CFLAGS='-g -O2' \
                                      CPPFLAGS='-fexceptions' \
                                      LDFLAGS='-s -static-libgcc'


Флаг --with-host-libstdxx необходим для библиотек и исполняемых файлов, которые используют статическую сборку PPL, но сами написаны не на C++, а на Си. Он указывает, где брать стандартную библиотеку C++. У меня старый тулчейн MinGW был с GCC 4.6.1, поэтому директория соответствующая. Если у вас libstdc++.a лежит в другом месте, прописывайте свой путь.
./runconfigure.sh && make -j 2 > make.my.log && make -j 2 check > make.check.my.log && make install


Теперь надо собрать binutils - это утилиты типа линкера(ld.exe), ассемблера(as.exe), и другого подобного:
../../src/binutils-2.22/configure --prefix=/c/mingw-boot/release \
                                  --build=i686-pc-mingw32 \
                                  --disable-nls \
                                  --disable-shared \
                                  --enable-static \
                                  --enable-threads \
                                  --with-gmp=/c/mingw-boot/release \
                                  --with-mpfr=/c/mingw-boot/release \
                                  --with-mpc=/c/mingw-boot/release \
                                  --with-ppl=/c/mingw-boot/release \
                                  --with-cloog=/c/mingw-boot/release \
                                  --with-host-libstdcxx='/mingw/lib/gcc/mingw32/4.6.1/libstdc++.a' \
                                  CFLAGS='-g -O2' \
                                  CXXFLAGS='-g -O2' \
                                  CPPFLAGS='-fexceptions' \
                                  LDFLAGS='-s -static-libgcc -static-libstdc++ -Wl,-Bstatic,-lz'

Тут очень важный момент - в LDFLAGS добавляется "-Wl,-Bstatic,-lz" - это значит, что утилиты должны линковаться со статической версией zlib. По умолчанию они линкуются с динамической, а если мы хотим избавиться от зависимостей, это нам не нужно.
make делается так:
make -j 2 tooldir=/c/mingw-boot/release > make.my.log && make tooldir=/c/mingw-boot/release install

Мы переопределяем tooldir, чтобы все утилиты устанавливались в ${prefix}/bin и ${prefix}/lib, а не в отдельные директории ${prefix}/i686-pc-mingw32/bin и соответственно lib. В последнем случае, утилиты в ${prefix} тоже бы установились, но зачем нам отдельные копии в разных директориях? Вообще, по задумке авторов, сами утилиты устанавливаются именно в tooldir, и в prefix делаются символьные ссылки на них - но под виндой, в частности у MSYS, с этим некоторые проблемы, так что было бы простое копирование.

Конфигурация GCC:
../../src/gcc-4.6.2/configure --prefix=/c/mingw-boot/release \
                              --build=i686-pc-mingw32 \
                              --libexecdir=/c/mingw-boot/release/lib \
                              --disable-bootstrap \
                              --disable-multilib \
                              --disable-sjlj-exceptions \
                              --disable-libgomp \
                              --enable-threads=win32 \
                              --disable-shared \
                              --enable-languages=c,c++ \
                              --with-dwarf2 \
                              --disable-win32-registry \
                              --disable-nls \
                              --enable-version-specific-runtime-libs \
                              --with-gmp=/c/mingw-boot/release \
                              --with-mpfr=/c/mingw-boot/release \
                              --with-mpc=/c/mingw-boot/release \
                              --with-ppl=/c/mingw-boot/release \
                              --with-cloog=/c/mingw-boot/release \
                              --with-libiconv-prefix=/c/mingw-boot/release \
                              --with-stage1-ldflags='-s -static-libstdc++ -static-libgcc' \
                              --with-host-libstdcxx='/mingw/lib/gcc/mingw32/4.6.1/libstdc++.a' \
                              CFLAGS='-g -O2' \
                              CXXFLAGS='-g -O2' \
                              CPPFLAGS='-fexceptions' \
                              LDFLAGS='-s -static-libstdc++ -static-libgcc'

--disable-win32-registry указывает, что GCC не нужно использовать реестр Windows для определения своего местоположения.

--disable-bootstrap - Вообще, "родной"(всмысле не кросс-компилятор) GCC обычно собирается так: каким-то ANSI-C совместимым компилятором собирается stage1. Потом stage1 Компилирует сам себя, и получается stage2. stage2 компилирует самого себя, опять же, и получается stage3. Потом, stage2 и stage3 сравниваются друг с другом(это такая проверка, правильно ли все собралось), и после этого stage3 собирает библиотеки поддержки для включенных языков программирования - libstdc++, libgfortran, и другие подобное.

Мы собираем промежуточную версию GCC, необходимую только и исключительно для бутстрапа полноценной. Как я уже выше писал - "старым" тулчейном полноценный GCC, с полноценным трехступенчатым бутстрапом, не собирается, поэтому приходится сначала собирать промежуточную версию, и продолжать уже с ней.

--disable-libgomp - для нашего промежуточного GCC OMP не нужно.

--enable-version-specific-runtime-libs - означает, куда складывать стандартные библиотеки подключенных языков. С этим флагом они ставятся в ${prefix}/lib/gcc/${target}/${версия}/, а без него просто в ${prefix}/lib

--enable-languages=c,c++ - для промежуточного GCC нам нужны только Си и C++

--disable-sjlj-exceptions
--with-dwarf2
Указывают, что GCC должен использовать табличную информацию в dwarf2 о C++ исключениях, вместо исключений, основанных на setjmp/longjmp. Вообще, это делает GCC'шный C++ довольно несовместимым с родной моделью исключений Windows(SEH/VEH. Хотя, я не до конца уверен, что sj/lj в GCC основаны на SEH.), но тем не менее, снижает расходы на их установку и обработку. А вообще, мне таки не понятно - почему GCC под виндой не использует эти самые родные механизмы обработки исключений, и мне интересно, будет ли когда-нибудь вообще это делать. VEH, например, это тоже табличная модель, и она более-менее одинакова и на Win32 и на Win64(кстати, на Win64 вообще SEH нет, только VEH)

--disable-multilib - если у вас GCC вдруг поддерживает кросскомпиляцию, или вы компилируете вообще из x86-64, то этот флаг указывает что полученный GCC будет поддерживать только i686-pc-mingw32.

--libexecdir указывает, куда установятся исполняемые файлы компиляторов(cc1.exe cc1plus.exe и т.п). В данном случае, они будут находится там же, где и стандартные библиотеки.

./runconfigure.sh && make -j 2 > make.my.log && make install


Теперь у нас в /c/mingw-boot/release лежит более-менее полноценные GCC, binutils и некоторые библиотеки. Этот GCC пока не может компилировать программы и DLL'ки, потому что у нас еще нет заголовочных файлов и библиотек WinAPI и рантайма MinGW, но тем не менее.

Что со всем этим делать дальше - расскажу в следующей части.

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

love5an: (Default)
Dmitry Ignatiev

June 2020

S M T W T F S
 123456
78910 111213
14151617181920
21222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 12th, 2025 04:29 am
Powered by Dreamwidth Studios