Cross compiling for Win32 under Linux/ru: what changed
Revision 3 to 4. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | ## Заметки по кросс-компиляции исполняемых файлов Win32 из Linux | |
| 2 | 2 | ||
| 3 | 3 | Начиная с 0.9.10 существует rpm 'fpc-crosswin32', который устанавливает необходимые утилиты binutils (например кросс ассемблер, кросс линкер), fpc .ppu файлы скомпилированные для win32 и вносит изменения в /etc/fpc.cfg. | |
| 4 | 4 | ||
| 5 | 5 | Он не включает кросс-скомпилированные LCL .ppu файлы. Вам нужно скомпилировать их самостоятельно после установки, fpc-crosswin32. | |
| 6 | 6 | ||
| 7 | 7 | Также существует быстрый способ описанный тут: <http://wiki.lazarus.freepascal.org/Cross_compiling/ru> | |
| 8 | 8 | ||
| 9 | 9 | ## Lazarus и Free Pascal Compiler | |
| 10 | 10 | ||
| 11 | 11 | ### О кросс-компиляции - понимайте то что вы делаете | |
| 12 | 12 | ||
| 13 | 13 | Это короткое введение для новичков. В последующих разделах описывается как настроить систему для кросс-компиляции, имеется ввиду работая под linux создавать исполняемые файлы win32 (или freebsd, или dawin, или...) Почему кросс-компиляция: FreePascal это компилятор, преобразующий исходный код в исполняемые файлы (на машинном языке). Эти исполняемые файлы, кроме всего прочего, содержат информацию о том как операционная система запускает их на выполнение. Поэтому исполняемые файлы являются платформенно-зависимыми. Сам FreePascal не требует различных дистрибутивов. Он может создавать исполняемые файлы для многих платформ. Просто укажите ему это. Но компилятор - это только одна часть. Существует ещё ассемблер и линкер. И эти утилиты не способны создавать кроссплатформенный код. Поэтому были созданы специальные утилиты линкер 'ld' и ассемблер 'as' для каждой целевой платформы. Это binutils. После создания кроссплатформенных утилит все модули fpc pascal будут кросс-компилированы. Например, для каждой из целевых платформ существует отдельный файл system.ppu. Затем ваш конфигурационный файл fpc.cfg будет перенастроен, таким образом кросс-компиляция станет настолько лёгкой, что вы сможете забыть обо всех мелочах. То же самое нужно проделать и с LCL - lazarus component library. И после этого вы сможете кросс-компилировать программы на паскале для win32. Затем проверить их при помощи wine или скопировать на машину с Windows и протестировать на ней. | |
| 14 | 14 | ||
| 15 | 15 | ### Почему из *nix в windows а не по-другому. | |
| 16 | 16 | ||
| 17 | 17 | Основная причина - генерирование unix-бинарников на другой платформе (другой unix или Linux) более сложно. Более сложное статическое связывание, не говоря уж об остальном. | |
| 18 | 18 | ||
| 19 | 19 | Придется использовать библиотеки из целевой платформы (gtk, glib, libc и т.д.), и множество дополнительных настроек для ld. (пути к библиотекам, путь к линкеру и т.д.) | |
| 20 | 20 | ||
| 21 | 21 | Это было частично сделано (в статическом случае), но это сложно т.к. требует внесения изменений в файлы линкера и командную строку линкера, а также глубокого понимания о сборке бинарников Unix. | |
| 22 | 22 | ||
| 23 | 23 | ### Скачивание исходных кодов FPC | |
| 24 | 24 | ||
| 25 | 25 | Исполняемых файлов недостаточно, вам потребуются все исходники fpc. Обратитесь к www.freepascal.org. Вы можете использовать SVN или ежедневные сборки. Для следующих примеров исходники fpc были скачены в папку ~/sources/fpc. | |
| 26 | 26 | ||
| 27 | 27 | ### Скачивание gnu binutils. | |
| 28 | 28 | ||
| 29 | 29 | Например, binutils-2.18.tar.gz скачайте в ~/download/binutils-2.18.tar.gz. | |
| 30 | 30 | ||
| 31 | 31 | ### Кроссплатформенная сборка binutils | |
| 32 | 32 | ||
| 33 | 33 | В репозитории fpcbuild существует скрипт для сборки binutils для всех поддерживаемых целевых платформ: install/cross/buildcrossbinutils | |
| 34 | 34 | ||
| 35 | 35 | Скачиваем инсталлятор fpcbuild: | |
| 36 | 36 | ||
| 37 | - | ||
| 38 | - | ||
| 37 | + | ```text | |
| 38 | + | []$ cd ~ | |
| 39 | + | []$ svn co http://svn.freepascal.org/svn/fpcbuild/branches/fixes_2_4/install install | |
| 40 | + | ``` | |
| 39 | 41 | ||
| 40 | 42 | Создаём копию скрипта: | |
| 41 | 43 | ||
| 42 | - | ||
| 43 | - | ||
| 44 | + | ```text | |
| 45 | + | []$ cd ~/install/cross/ | |
| 46 | + | []$ cp buildcrossbinutils buildcrossbinutils.sh | |
| 47 | + | ``` | |
| 44 | 48 | ||
| 45 | 49 | Правим переменные в начале нового скрипта. | |
| 46 | 50 | ||
| 47 | 51 | Переменная BASE указывает на директорию сборки и установки. Директория должна быть пустой. Например: | |
| 48 | 52 | ||
| 49 | - | ||
| 53 | + | ```text | |
| 54 | + | BASE=~/cross_fpc | |
| 55 | + | ``` | |
| 50 | 56 | ||
| 51 | 57 | Теперь разберёмся со скачанным файлом binutils. Если путь к скачанному файлу ~/download/binutils-2.18.tar.gz то укажем | |
| 52 | 58 | ||
| 53 | - | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 59 | + | ```text | |
| 60 | + | BINUTILSPATH=~/download/ | |
| 61 | + | BINUTILSBASE=binutils | |
| 62 | + | BINUTILSVERSION=2.18 | |
| 63 | + | BINUTILS_GZIP=yes | |
| 64 | + | ``` | |
| 57 | 65 | ||
| 58 | 66 | Скрипт будет автоматически соберёт это в ~/download/binutils-2.18.tar.gz. Остальные переменные определяют какие целевые платформы мы имеем. По умолчанию их довольно много, поэтому компиляция может занять много времени (часы на слабых машинах). Для кросс-компиляции для Windows вам потребуется только | |
| 59 | 67 | ||
| 60 | - | ||
| 61 | - | ||
| 68 | + | ```text | |
| 69 | + | TARGETS_WIN="mingw32" | |
| 70 | + | ``` | |
| 62 | 71 | ||
| 63 | 72 | и закомментировать все остальные: | |
| 64 | 73 | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 74 | + | ```text | |
| 75 | + | #BSD="freebsd netbsd openbsd" | |
| 76 | + | #TARGETS_WIN="cygwin mingw32 msdosdjgpp" | |
| 77 | + | #TARGETS_I386="${BSD} linux solaris darwin" | |
| 78 | + | #TARGETS_POWERPC="${BSD} linux darwin" | |
| 79 | + | #TARGETS_SPARC="${BSD} linux solaris" | |
| 80 | + | #TARGETS_M68k= | |
| 81 | + | ``` | |
| 71 | 82 | ||
| 72 | 83 | Затем запустите скрипт: | |
| 73 | 84 | ||
| 74 | - | ||
| 85 | + | ```text | |
| 86 | + | []$ sh buildcrossbinutils.sh | |
| 87 | + | ``` | |
| 75 | 88 | ||
| 76 | 89 | Скрипт создаст поддиректорию 'logs' с соответствующим содержимым. В случае чего, начните поиски оттуда. | |
| 77 | 90 | ||
| 78 | 91 | Заметьте что для некоторых платформ (Linux,FreeBSD, win32) утилиты доступны в скомпилированном виде. Смотрите <ftp://freepascal.stack.nl/pub/fpc/contrib/cross/> | |
| 79 | 92 | ||
| 80 | 93 | ### Кроссплатформенная сборка FPC | |
| 81 | 94 | ||
| 82 | 95 | В рекозитории fpcbuild существует скрипт для сборки fpc под все поддерживаемые целевые платформы: install/cross/buildcrosssnapshot Создайте копию скрипта | |
| 83 | 96 | ||
| 84 | - | ||
| 85 | - | ||
| 97 | + | ```text | |
| 98 | + | []$ cd ~/install/cross/ | |
| 99 | + | []$ cp buildcrosssnapshot buildcrosssnapshot.sh | |
| 100 | + | ``` | |
| 86 | 101 | ||
| 87 | 102 | Исправьте переменные в начале нового скрипта. | |
| 88 | 103 | ||
| 89 | 104 | Вам потребуется изменить всего лишь CROSSTOOLSROOT, FPCCVS, DESTDIR, TARGETS_OS и TARGETS_CPU. Например: | |
| 90 | 105 | ||
| 91 | - | ||
| 92 | - | ||
| 93 | - | ||
| 94 | - | ||
| 95 | - | ||
| 96 | - | ||
| 106 | + | ```text | |
| 107 | + | CROSSTOOLSROOT=~/cross_fpc/cross | |
| 108 | + | FPCCVS=~/sources/fpc | |
| 109 | + | TARGETS_OS="win32" | |
| 110 | + | TARGETS_CPU="i386" | |
| 111 | + | DESTDIR=~/cross_fpc/ | |
| 112 | + | ``` | |
| 97 | 113 | ||
| 98 | 114 | Затем запустите скрипт: | |
| 99 | 115 | ||
| 100 | - | ||
| 116 | + | ```text | |
| 117 | + | []$ sh buildcrosssnapshot.sh | |
| 118 | + | ``` | |
| 101 | 119 | ||
| 102 | 120 | После этого вы получите кросс-компилированные модули в ~/cross_fpc/ | |
| 103 | 121 | ||
| 104 | 122 | ### Конфигурирование вашего fpc.cfg | |
| 105 | 123 | ||
| 106 | 124 | Откройте с правами рута /etc/fpc.cfg или создайте копию /etc/fpc.cfg to ~/fpc.cfg и отредактируйте этот файл. Найдите в файле пути поиска модулей. | |
| 107 | 125 | ||
| 108 | 126 | Примечание: В более старых версиях FPC вместо \$fpcversion и \$fpctarget использовались \$version и \$target. | |
| 109 | 127 | ||
| 110 | - | ||
| 111 | - | ||
| 112 | - | ||
| 128 | + | ```text | |
| 129 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget | |
| 130 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/* | |
| 131 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl | |
| 132 | + | ``` | |
| 113 | 133 | ||
| 114 | 134 | Замените их специальными путями для других платформ. Например, для linux и кросс-компилированной win32: | |
| 115 | 135 | ||
| 116 | - | ||
| 117 | - | ||
| 118 | - | ||
| 119 | - | ||
| 120 | - | ||
| 121 | - | ||
| 122 | - | ||
| 123 | - | ||
| 124 | - | ||
| 125 | - | ||
| 126 | - | ||
| 127 | - | ||
| 136 | + | ```text | |
| 137 | + | #IFDEF win32 | |
| 138 | + | -Fu~/cross_fpc/lib/fpc/$fpcversion/cross/units/i386-win32/ | |
| 139 | + | -Fu~/cross_fpc/lib/fpc/$fpcversion/cross/units/i386-win32/* | |
| 140 | + | -Fu~/cross_fpc/lib/fpc/$fpcversion/cross/units/i386-win32/rtl | |
| 141 | + | -XPi686-mingw32- | |
| 142 | + | -FD~/cross_fpc/cross/bin | |
| 143 | + | #ELSE linux | |
| 144 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget | |
| 145 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/* | |
| 146 | + | -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl | |
| 147 | + | #-Fu~/fpc/packages/*;~/fpc/rtl/linux | |
| 148 | + | #ENDIF | |
| 149 | + | ``` | |
| 128 | 150 | ||
| 129 | 151 | Выполните: тестирование и устранение неполадок. | |
| 130 | 152 | ||
| 131 | 153 | ### Кросс-компиляция LCL и компонентов lazarus | |
| 132 | 154 | ||
| 133 | 155 | В коммандной строке: | |
| 134 | 156 | ||
| 135 | - | ||
| 136 | - | ||
| 157 | + | ```text | |
| 158 | + | cd lazarus; make clean all OS_TARGET=win32 | |
| 159 | + | cd lazarus/lcl; make clean all | |
| 160 | + | ``` | |
| 137 | 161 | ||
| 138 | 162 | Таким образом всё скомпилируется для win32 (включая IDE, что необязательно, но это сокращает объём манипуляций). | |
| 139 | 163 | ||
| 140 | 164 | Или в IDE Сервис-\>Параметры сборки: отметим LCL, Synedit, Codetools, Регистрация пакетов и Интерфейс IDE как Очистить+Собрать, установми в поле Библиотека виджетов LCL значение win32/win64, а Целевая ОС - win32. Затем нажмём 'Собрать'. Ваши файлы .ppu/.o скомпилированные для linux не будут перезаписаны и вам не нужно будет перекомпилировать их каждый раз, т.к. в рабочей папке будут созданы специальные директории для других целевых систем. | |
| 141 | 165 | ||
| 142 | 166 | ### Коросс-компиляция проекта | |
| 143 | 167 | ||
| 144 | 168 | Выберите Проект-\>Параметры проекта-\>Параметры компилятора-\>Генерация кода Целевая ОС='win32' и Проект-\>Параметры проекта-\>Параметры компилятора-\>Пути Библиотека виджетов LCL='win32'. Вот и всё. При следующей компиляции будет создан исполняемый файл win32. IDE произведёт поиск утилит win32, поэтому компилятор будет работать с rtl для win32 вместо rtl для linux. Когда вы откроете другой проект или закроете текущий и откроете его вновь IDE автоматически установит настройки. | |
| 145 | 169 | ||
| 146 | 170 | ### Подсказки по кросс-компиляции и Lazarus | |
| 147 | 171 | ||
| 148 | 172 | Если вы создаете приложение/пакет для различных целевых ОС, вам необходимо действовать следующим образом: устранить баги, скомпилировать и протестировать приложение под linux, затем скомпилировать и протестировать его под win32, .. . Потому что обычно вы перезаписываете ваши .ppu файлы, и вам придётся перекомпилировать всё, каждый раз когда вы переключаете захотите изменить целевую ОС. Но это не обязательно. Lazarus поддреживает макросы. | |
| 149 | 173 | ||
| 150 | 174 | Пример 1: Кросс-компиляция проекта для linux и win32. | |
| 151 | 175 | ||
| 152 | 176 | Установите значение Проект-\> Параметры компилятора-\>Пути-\>Каталог вывода модулей = \$(TargetOS). Этот макрос будет заменён названием целевой ОС в нижнем регистре (например 'linux' для Linux, 'win32' для Win32). Каталог вывода модулей находится в директории вашего проекта (директории где расположен файл .lpi). Создайте директории с именами 'linux' и 'win32' в директории вашего проекта. Когда вы кликните на кнопке 'Показать параметры' в самом низу окна Параметры проекта, вы увидите -FElinux/ или -FEwin32/. Эта опция сообщает компилятору куда записать создаваемые файлы (файлы .ppu/.o). | |
| 153 | 177 | ||
| 154 | 178 | Пример 2: Кросс-компиляция проекта для различных платформ и наборов виджетов. | |
| 155 | 179 | ||
| 156 | 180 | Укажите Каталог вывода модулей следующим образом \$(TargetCPU)/\$(TargetOS)/\$(LCLWidgetType) и создайте поддиректории для всех целей. Этот путь также используется LCL. | |
| 157 | 181 | ||
| 158 | 182 | То же самое можно проделать и для пакетов. | |
| 159 | 183 | ||
| 160 | 184 | ### Кросс-компиляция и пакеты Lazarus | |
| 161 | 185 | ||
| 162 | 186 | Пакеты Lazarus не ограничены библиотеками. Они могут быть использованы для компиляции практически чего угодно. И IDE автоматически перекомпилирует их при необходимости. Пакеты могут наследовать опции компилятора. Например: проект, использующий пакет, наследует каталог вывода пакета. Другими словами: каталог вывода пакета добавляется в пути поиска модулей проекта. Посмотрите в IDE: Проект-\>Параметры проекта-\>Параметры компилятора-\>Унаследованные. | |
| 163 | 187 | ||
| 164 | 188 | Наследование срабатывает единажды. Но существуют исключения: Целевая платформа (ОС и CPU) проекта переопределяет цель для всех используемых пакетов. Это значит, если вы укажете Целевую ОС в проекте = 'win32' и скомпилируете проект, IDE выполнит проверку на предмет необходимости перекомпиляции пакетов для Целевой ОС. | |
| 165 | 189 | ||
| 166 | 190 | Пример: | |
| 167 | 191 | ||
| 168 | 192 | Пакет А имеет директорию вывода: lib/\$(TargetOS) Проект использует А. | |
| 169 | 193 | ||
| 170 | 194 | 1. Проект собирается для linux. IDE компилирует А для linux в \<PackageDirOfA\>/lib/linux/, затем компилирует проект для linux. | |
| 171 | 195 | 2. Проект собирается для win32. IDE компилирует А для win32 в \<PackageDirOfA\>/lib/win32/, затем компилирует проект для win32. | |
| 172 | 196 | 3. Проект снова собирается для linux. IDE проверяет, существует ли А для linux. Затем компилирует проект для linux. | |
| 173 | 197 | ||
| 174 | 198 | Таким образом, использование макросов экономит много времени. | |
| 175 | 199 | ||
| 176 | 200 | ## Для Unix (в общих чертах) | |
| 177 | 201 | ||
| 178 | 202 | Опция -XLA используется для изменения зависимостей библиотек определённых в модулях. Формат -XLAold=new изменяет link-опцию ld -l\<old\> на -l\<new\>. | |
| 179 | 203 | ||
| 180 | 204 | Опция -XR\<sysroot\> (recent trunk) может быть использована для указания корня Целевой ОС. Она используется для: | |
| 181 | 205 | ||
| 182 | 206 | - добавления префикса к указанным по-умолчанию путям библиотек, в прошлом вы использовали -Xd и эти пути вручную. Например для i386-linux | |
| 183 | 207 | ||
| 184 | 208 | вместо следования в /lib, /usr/lib, и /usr/X11R6/lib к ld, будет следовать в \<sysroot\>/lib, \<sysroot\>/usr/lib, и \<sysroot\>/usr/X11R6/lib к ld. | |
| 185 | 209 | ||
| 186 | 210 | - определение местоположения библиотек С (linux-версий): glibc или uclibc. Например для uclibc будет принята попытка поиска по пути '\<sysroot\>/lib/ld-uClibc.so.0' | |
| 187 | 211 | ||
| 188 | 212 | ## Для Linux под Win32 | |
| 189 | 213 | ||
| 190 | 214 | Это просто, есть некоторая информация в [[buildfaq]] | |
| 191 | 215 | ||
| 192 | 216 | ## FreeBSD для sparc | |
| 193 | 217 | ||
| 194 | 218 | Я пытался кросс-компилировать из х86 для Sparc Solaris 9. Несмотря на то что результат не работал должным образом привожу мою командную строку: | |
| 195 | 219 | ||
| 196 | 220 | в компилятор / выполнить: | |
| 197 | 221 | ||
| 198 | - | ||
| 222 | + | ```text | |
| 223 | + | gmake cycle CPU_TARGET=sparc OS_TARGET=solaris CROSSBINUTILPREFIX=solaris-sparc- CROSSOPT='-Xd -Fl~/src/sollib' | |
| 224 | + | ``` | |
| 199 | 225 | ||
| 200 | 226 | ~/src/sollib директория которая содержит: | |
| 201 | 227 | ||
| 202 | 228 | - набор файлов .o из /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 | |
| 203 | 229 | - libgcc.a из /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 | |
| 204 | 230 | - набор файлов lib*.so из /usr/lib: libaio.so libmd5.so libc.so libelf.so librt.so libdl.so libm.so | |
| 205 | 231 | ||
| 206 | 232 | Иллюстрация проблемы при компиляции: | |
| 207 | 233 | ||
| 208 | - | ||
| 209 | - | ||
| 210 | - | ||
| 211 | - | ||
| 212 | - | ||
| 234 | + | ``` pascal | |
| 235 | + | Free Pascal Compiler version 2.1.1 [2006/03/17] for sparc | |
| 236 | + | Copyright (c) 1993-2005 by Florian Klaempfl | |
| 237 | + | Target OS: Solaris for SPARC | |
| 238 | + | Compiling system.pp | |
| 239 | + | system.pp(15,1) Fatal: Syntax error, "BEGIN" expected but "identifier UNIT" found | |
| 240 | + | ``` | |
| 213 | 241 | ||
| 214 | 242 | Я подозреваю что ошибся с выбранными .o файлами. | |
| 215 | 243 | ||
| 216 | 244 | ## Для Mac OS X | |
| 217 | 245 | ||
| 218 | 246 | Посмотрите этот [пост](http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&p=7222#7222). | |
| 219 | 247 | ||
| 220 | 248 | ## Авторы | |
| 221 | 249 | ||
| 222 | 250 | Эта страница была конвертирована из epikwiki [version](http://lazarus-ccr.sourceforge.net/index.php?wiki=CrossCompilingForWin32UnderLinux). | |
| 223 | 251 | ||
| 224 | 252 | --- | |
| 225 | 253 | *From the Free Pascal wiki, page "Cross compiling for Win32 under Linux/ru", as it stood on 2021-07-20 after a change by Dbannon, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 226 | 254 | Category: Cross compilation/ru | |
| 227 | 255 | Category: FPC/ru | |
| 228 | 256 | Category: Lazarus/ru | |
| 229 | 257 | Category: Russian |
