Тёрка в тагах


Друзья

Его(2) Общие(0) Хотят дружить(0)


  • Atrinax

  • Blackoff

  • login

  • login

  • login

  • login

Враги

Его(0) Общие(0) Обиженные(1)

Большая Тёрка / Мысли / Личная лента olegchir /


olegchir

Day 3-6

alt

Status

1) Скорость прототипирования на C/C++ убогая.
2) Я увяз в написании чуть ли не новой платформы, потому что под кресты есть много хорошего, но это не собрано в искаробочное решение.
3) Возможно, стоит рассмотреть прототипирование на нормальных штуках с паралелльным написанием убер-платформы.
4) Олег: "занимаешься игрой - забудь о теке, занимаешься теком - забудь об игре". Конечно, я занимаюсь теком.

Читать далее




Забавные мелочи:



1) По поводу использования современных компиляторов: у gcc иногда случаются internal errors. Например, я не смог собрать им ICU. При сборке в режиме MacOSX/GCC и с компилятором "gcc (GCC) 4.9.0 20131122 (experimental)"
ругается: "Внутренняя ошибка компилятора" (Это хорошо видно - пишет именно так, по-русски, как он определил что я русский - не понимаю, в макоси выставлена английская локаль и страна проживания USA). Ну, тут, конечно, виноват и лютый говнокод в ICU, я не смог починить ошибку в коде и пересобрал более старым компилятором.

2) Qt из репозитория не компилируется с ––c++11. Причина – они а) просрали где-то внутри движка флаг ––no-warnings-are-errors, при этом не всегда пишут на 11-м стандарте (хотя по большей части на нем), поэтому сборка их же core валится с неисправимой ошибкой: "error: constant expression evaluates to -1 which cannot be narrowed to type 'unsigned int' [-Wc++11-narrowing]" и других в этом же духе.

3) На баше написал генератор запускалки платформы, который умеет локализацию (в стиле Андроида), проверку и даже установку зависимостей, и, оказывается, возможно написать кроссплатформенный getopt (работающий и в Linux, и в Mac) (раньше люто бесило писать две страницы разных вариантов).

пример реализации локализации: https://gist.github.com/olegchir/7653336
export DEPENDENCIES_OK_RU="Зависимости в порядке."
export DEPENDENCIES_OK_EN="Dependencies OK."
...
lp "DEPENDENCIES_OK"

а вот пример парсинга параметров: https://gist.github.com/olegchir/7653351

4) GNU/Linux FHS (http://ru.wikipedia.org/wiki/FHS) показалась неподходящей. Windows-way (или GoboLinux way) гораздо лучше. Собираемые из гита зависимости подбираются по такому правилу:

$REPODIR - может быть любым.
$PROJECT - название проекта
Каталог зависимости - $REPODIR/$PROJECT
Рабочий каталог репозитория - $REPODIR/$PROJECT/$PROJECT
(не $REPODIR/$PROJECT/$PROJECT для того, чтобы название проекта было в приветствии командной строки, и для совместимости с копипастой из интернетов)
Каталог сборки - $REPODIR/$PROJECT/build
Каталог установки - $REPODIR/$PROJECT/prefix

Оказалось, что иногда нужно нативное окружение макоси, а не аналоги из макпортов. Пример – компилирование того самого ICU.
Полезно добавить в .zshrc (.bashrc) скрипты по типу:

#Теперь macports важнее, чем macos
portsfirst() {
export PATH=/opt/local/bin:$PATH
}

#Используем свой собственный gcc, llvm и clang
newcpp() {
portsfirst
export PATH=/git/llvm/prefix/bin:/git/gcc/prefix/bin:$PATH
}


Дальше несколько инструкций, которые будут в вики по сборке.
(Они отличаются от аналогичных в других местах тем, что работают).
Все эти вещи НЕ предназначены для делания руками. Их делает скрипт, а этот текст – пояснение, что же он делает.


УСТАНОВКА GCC (работает)



Новый clang требует нового gcc. Дадим ему это.

Вначале скачаем:

mkdir -p $REPODIR/gcc
cd $REPODIR/gcc
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc

Теперь соберем и установим:

cd $REPODIR/gcc/gcc
./contrib/download_prerequisites
cd ..
mkdir build
cd build
$PWD/../gcc/configure --enable-languages=c,c++ --prefix=$REPODIR/gcc/prefix
mkdir -p $REPODIR/gcc/prefix
make -j8
make install

Важно!

1.
Сборка GCC занимает ДОЛГО. Можно успеть попить чаю, поесть и поспать.
Сборка занимает кучу ресурсов, поэтому компьютер будет шуметь вентиляторами и всем мешать.
Компьютер будет гресться, и что-нибудь с корпусом из пластика может расплавиться - надо ставить в холодное проветриваемое место :-)

2.
download_prerequisites скачивает GMP, MPFR and MPC.
По идее, мы должны скачать их самостоятельно для задекларированного обеспечения чистоты.
Но в документации GCC просят не делать этого.
Кто-то гораздо умнее нас имеет объяснение, почему так - да будет так.
(если мы умнее, то почему мы не разрабатываем компиляторы?)
(вот потому что умнее, потому и не разрабатываем :-)

3.
Эта инструкция пишется на MacOSX.
На каких-то старых системах нужно установить какую-нибудь версию gcc, newlib и binutils. Например, вот что по этому поводу говорит рассылка Cygwin: http://cygwin.com/ml/crossgcc/2002-12/msg00045.html

4. Не пропустите -j6 (собирать в 6 потоков, ну или сколько там ядер у процессора) и --enable-languages=c,c++, иначе сборка может занять вечность.

УСТАНОВКА LLVM/Clang (работает)



Скачать clang (+llvm)

mkdir -p $REPODIR/llvm
cd $REPODIR/llvm

svn co https://llvm.org/svn/llvm-project/cfe/trunk clang
svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm
svn co https://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra
svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
svn co https://llvm.org/svn/llvm-project/test-suite/trunk test-suite

mv -if ./clang ./llvm/tools/clang
mv -if ./extra ./llvm/tools/clang/tools/extra
mv -if ./compiler-rt ./llvm/projects/compiler-rt
mv -if ./test-suite ./llvm/projects/test-suite

mkdir build
cd ./build

../llvm/configure --prefix=$REPODIR/llvm/prefix --with-gcc-toolchain=$REPODIR/gcc/prefix --with-extra-ld-options=-Wl,-rpath,$REPODIR/gcc/prefix/lib CXX=$REPODIR/gcc/prefix/bin/g++ CC=$REPODIR/gcc/prefix/bin/gcc CPP=$REPODIR/gcc/prefix/bin/cpp

Важно, что в GNU ld есть -Wl,-R, а в Xcode ld есть -rpath
Вот скрипт для замены:
gsed -i.orig -e '/-Wl,-R/ { s/-Wl,-R/-Wl,-rpath,/; }' configure
(https://trac.macports.org/ticket/29982)

make -j8
make install

POSTGRESQL (работает, на Mac – без сборки манов)



MacOSX: sudo port install openjade
sudo ln -s /opt/local/bin/openjade /opt/local/bin/jade

mkdir -p $REPODIR/postgresql
cd $REPODIR/postgresql
git clone git://git.postgresql.org/git/postgresql.git ./postgresql
mkdir ./build
cd ./build
../postgresql/configure --prefix=$REPODIR/postgresql/prefix

MacOSX:
make
make install
cd contrib
make
make install

Non-MacOSX:
gmake world
gmake install-world

ICU (работает под стабильным gcc)



MacOSX:

mkdir -p $REPODIR/icu
cd $REPODIR/icu
svn co http://source.icu-project.org/repos/icu/icu/trunk ./icu
mkdir build
cd build

List platforms:

MacOSX:
../icu/source/runConfigureICU MacOSX/GCC --prefix=$REPODIR/icu/prefix
Linux:
../icu/source/runConfigureICU Linux --prefix=$REPODIR/icu/prefix

make install

СБОРКА QT (работает с нюансами и оговорками)



Вначале нам нужны зависимости.
Зависмости от языков, использующихся при сборке Qt (perl, python, ruby), и непосредственно от библиотек (GNU). Часть из них будет поставлена пакетным менеджером, но нужно держать в уме, что эти зависимости существуют, и могут начать охотиться на нас во время выпуска релиза (пакет для Debian, например).

Четкий список зависимостей для всех ОС есть здесь: http://qt-project.org/wiki/Building-Qt-5-from-Git

Чтобы скачать хоть что-то скачать нам определенно нужен git.
MacOSX Macports: sudo port install git-\*

Для сборки qt нам особо не важно, какая версия сборщиков в системе, лишь бы там было вот это:

Git (>= 1.6.x)
Perl (>=5.14)
Python (>=2.6.x)
Ruby
Рабочий компилятор

Поэтому можно с чистой совестью установить их из пакетного менеджера.
Версии библиотек GNU тоже не часто меняются, так что тоже отдаем на откуп пакетнику.

Отдельный вопрос про Ruby - если вы на нем разрабатываете, то наверняка имеете rvm и нужно использовать его. Если нет - то можно поставить пакетником, один фиг нету никакого девелоперского окружения, которое установка из пакетов может сломать.

Сборка OpenSSL, iconv и других вещей под Windows может оказаться сложной (об этом написано в другом моем гиде: http://users.livejournal.com/__hedin/535325.html). Но мы договорились не использовать Windows. В Linux/Mac OpenSSL идет прямо в пакетном менеджере.

Специально для MacOSX нужно установить XQuartz: http://xquartz.macosforge.org/landing/

MacOSX:
sudo port selfupdate
sudo port install perl5.18 python27
sudo port select --set python python27
sudo port install gmake cmake bison flex gperf grep libiconv zlib openssl dbus
sudo port install icu harfbuzz-icu

//sudo port install xcb xorg-libxcb xorg-xcb-proto xorg-xcb-util xorg-xcb-util-image xorg-xcb-util-keysyms xorg-xcb-util-renderutil xorg-xcb-util-wm
//закомментировано, т.к. все равно не поможет, xcb в macports кривые

sudo port install mariadb postgresql93 mysql55
sudo port install glib2 glibmm glib-networking

(по умолчанию порт perl5 указывает на какую-то древнюю протухшую версию, поэтому с помощью `port search perl5` надо самостоятельно посмотреть, какая версия последняя, и установить ее. На момент написания этого текста последнем был порт perl5.18. То же самоле про pyhton2, portgresql9, mysql5)

mkdir -p $REPODIR/qt5
git clone git://gitorious.org/qt/qt5.git ./qt5

(Клонирование _очень_ быстрое, т.к. так почти нет файлов.
Так и должно быть)

Инициализируем репозиторий
(это добавит субмодули гита и скачает много дополнительного кода):

perl init-repository

Инструкции по работе с репозиторием Qt5:

Когда в будущем мы захотим обновить qt5, надо выполнить следующее в корне репозитория qt5:
git clean -dfx
git submodule foreach --recursive "git clean -dfx"
git pull
git submodule sync
git submodule update --recursive

Переключение на ветку dev (ПРЕДУПРЕЖДАЮ – это смертельный номер, замучаетесь зависимости разруливать):
git clean -dfx
git reset --hard HEAD
git checkout dev
git submodule foreach --recursive "git clean -dfx"
git submodule foreach --recursive "git reset --hard HEAD"
git pull
git submodule sync
git submodule foreach --recursive "git checkout dev || true"
git submodule update --recursive

Переключение на ветку stable (если не были в dev-ветке, оно и не нужно, по-умолчанию качается stable):
git clean -dfx
git reset --hard HEAD
git checkout stable
git submodule foreach --recursive "git clean -dfx"
git submodule foreach --recursive "git reset --hard HEAD"
git pull
git submodule sync
git submodule foreach --recursive "git checkout master || git checkout stable || true"
git submodule update --recursive

Если что-то пошло не так во время последующей сборки(например, в момент configure и make, который скоро будет), нужно выполнить следующее в корне репозитория qt5:
git clean -dfx
git reset --hard HEAD
git submodule foreach --recursive "git clean -dfx"
git submodule foreach --recursive "git reset --hard HEAD"


Когда скачали репозиторий, переключились куда надо, запускаем сборку.

cd ..
mkdir build
cd build

Конфигурим:
../qt5/configure --prefix=/git/qt5/prefix -v -release -c++11 -no-warnings-are-errors -nomake examples -nomake tests -opensource -confirm-license -shared -largefile -javascript-jit -qml-debug -accessibility -no-sql-db2 -no-sql-ibase -qt-sql-sqlite -qt-sql-mysql -qt-sql-psql -plugin-sql-sqlite -plugin-sql-mysql -plugin-sql-psql -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -no-xcb -openssl -process -audio-backend -icu -gui -widgets -rpath -fontconfig -pch -dbus -no-separate-debug-info -directfb -opengl -no-system-proxies -glib -framework -sdk macosx10.9 -I/git/icu/prefix/include -L/git/icu/prefix/lib -I/opt/local/include -I/opt/local/include/mysql55 -I/opt/local/include/mysql55/mysql -I/opt/local/include/postgresql93 -I/opt/local/include/postgresql93/server -L/opt/local/lib -L/opt/local/lib/mysql55/mysql -L/opt/local/lib/postgresql93

(внимательно прочитать строчку конфигура, блеать! не копипастать просто так, будут кровь-кишки! Пример дан для MacOSX, как исправить для линукса – в конце списка нюансов)

НО ЕСТЬ НЮАНСЫ

MacOSX:

смотрим выхлоп команды
xcodebuild -showsdks
и добавляем в конец нижеследующего конфигура строчку типа
-sdk macosx10.9

У нас есть куча дополнительных инклудов, связанных с макпортами и нашей базовой системой.
Билд Qt не рассчитан на то, что система будет билдиться тремя разными версиями разных компиляторов, поэтому придется попотеть.

Вначале макпорты.

-I/opt/local/include
-L/opt/local/lib

Потом базы данных из макпортов.

-I/opt/local/include/mysql55
-I/opt/local/include/mysql55/mysql
-L/opt/local/lib/mysql55/mysql

-I/opt/local/include/postgresql93
-I/opt/local/include/postgresql93/server
-L/opt/local/lib/postgresql93

Потом то, что мы хотим подключить руками:

-I/git/icu/prefix/include
-L/git/icu/prefix/lib

Или, например, если Postgresql не из портов, а свой, то такое тоже:
-I/git/postgresql/prefix/include
-I/git/postgresql/prefix/include/server
-L/git/postgresql/prefix/lib

Если бы мы передавали это вручную компилятору, надо было бы набрать нечто типа этого:

-I/opt/local/include -I/opt/local/include/mysql55/ -I/opt/local/include/mysql55mysql -I/opt/local/include/postgresql93 -I/opt/local/include/postgresql93/server -L/opt/local/lib -L/opt/local/lib/mysql55/mysql -L/opt/local/lib/postgresql93

Плюс нужно пропатчить все .pro-файлы
а) жестко отключить ворнинги, т.к. флаг --no-warnings-are-errors потерялся
б) добавить все наши опциональные самосборные зависимости

CONFIG += warn_off
QMAKE_CFLAGS_WARN_ON -= -Wall -Wc++11-narrowing
QMAKE_CXXFLAGS_WARN_ON -= -Wall -Wc++11-narrowing
INCLUDEPATH += /git/icu/prefix/include
LIBS += -L/git/icu/prefix/lib

Делать это руками стремно, поэтому юзаем перл.
(Почему не сед? Потому что в bash/zsh огромные проблемы с переносами строк и их экранированием.)
Слеши итп нужно заэкранировать как в нижеследующем примере.
Если есть боязнь угробить файлы, то убрать ключ -i у перла. -i – это in-place edit mode.
Ну а если угробили, то см. выше инструкцию как сбрасывать репозиторий без перескачивания всего.

find . -type f -name '*.pro' -exec perl -i -pe 'eof && do{chomp; print "$_ \nCONFIG += warn_off\nQMAKE_CFLAGS_WARN_ON -= -Wall -Wc++11-narrowing\nQMAKE_CXXFLAGS_WARN_ON -= -Wall -Wc++11-narrowing\nINCLUDEPATH += \/git\/icu\/prefix\/include\nLIBS += -L\/git\/icu\/prefix\/lib\n"; exit}' {} \;

Насчет ворнингов.
Форсировать QMake не использовать ворнинги можно "правильно", "Qt'ish way":
CONFIG += warn_off

Но если не канает, есть и более прямой способ (который по идее должен использовать только сам QMake):
QMAKE_CFLAGS_WARN_ON -= -Wall
QMAKE_CXXFLAGS_WARN_ON -= -Wall
(Не уверен, что оно действительно отключит всё, т.к. здесь отключается только -Wall. UB. Есть куча других флагов, можно пробовать отключать их по-отдельности)

Не попробовал играться с вот этим, но оно тоже есть: QMAKE_CXXFLAGS_WARN_OFF

Ошибки на соответствие 11-му стандарту могут вылезать даже в случае жестоких мер, описанных выше (перлом пропатчить все .pro-файлы на отключение ворнингов). Поэтому некоторы ворнинги нужно фиксать руками, иначе они станут ошибкой:
sublime /git/qt5/qt5/qtbase/src/gui/text/qtextengine.cpp
ctrl+G:1127
Заменить -1 на static_cast(-1)
Как говорит Страуструп, статик каст выглядит так уродливо именно затем, чтобы его было легко найти в коде :3

Насчет зависимостей.

Баг Macports:
https://bugreports.qt-project.org/browse/QTBUG-34902?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel
(Qt4 в общем include path).
С моей точки зрения, это именно баг, то ли в самой FHS портов, то ли конкретно в пакете Qt4.
С одной стороны, можно вообще отказаться от портов и собрать все зависимости вручную.
Но мне лениво, поэтому просто искореним qt4, нафиг оно нужно-то на сервере:
sudo port uninstall qt4-mac qt4-mac-mysql5-plugin

4.
Счастливчикам заменить -v на -silent
Не-OSX убрать: -no-xcb -no-pch
Не-OSX добавить: -xcb -qt-xcb -qt-xkbcommon -kms -eglfs -opengl es2
Linux добавить: -linuxfb
Linux заменить: -release на -debug (На MacOSX при попытке собрать -debug будет такая ошибка: Error: debug-only framework builds are not supported. Configure with -no-framework if you want a pure debug build. С другой стороны, текущий билд не собирается без флага -framework).

5.
Флаг -developer-build собирает более годную версию, но может отключать -no-warnings-are-errors. Что может привести к невозможности собрать говнокод. Если использовать -developer-build и не указывать значения -no-warnings-are-errors, то точно будет использоваться -warnings-are-errors, т.е. любой ворнинг остановит сборку и она вылетит с ошибкой.

6. Возможны непредвиденные ворнинги и ошибки, которые нельзя отфильтровать автоматически. Их нужно исправлять руками.