Difference between revisions of "Cross compiling for Win32 under Linux/hu"

From Lazarus wiki
Jump to navigationJump to search
Line 209: Line 209:
 
Marco vd Voort írt a témáról [http://www.stack.nl/~marcov/crossnotes.txt crossnotes] címmel feljegyzést (angolul). Ha valakinek van ideje hozzáadhatja a wiki oldalhoz.
 
Marco vd Voort írt a témáról [http://www.stack.nl/~marcov/crossnotes.txt crossnotes] címmel feljegyzést (angolul). Ha valakinek van ideje hozzáadhatja a wiki oldalhoz.
  
== FreeBSD to sparc ==
+
== FreeBSD-ről sparc-ra ==
  
I managed to crosscompile from x86 to Sparc Solaris 9. However the result doesn't work very well, but here is my cmdline:
+
Végigcsináltam egy keresztfordítást x86-ról Sparc Solaris 9 rendszerre. Azonban az eredmény nem volt megfelelő. Itt a parancsror amit futtattam:
 
+
<!--in compiler/ execute:-->
in compiler/ execute:
 
  
 
   gmake cycle CPU_TARGET=sparc OS_TARGET=solaris CROSSBINUTILPREFIX=solaris-sparc- CROSSOPT='-Xd -Fl~/src/sollib'
 
   gmake cycle CPU_TARGET=sparc OS_TARGET=solaris CROSSBINUTILPREFIX=solaris-sparc- CROSSOPT='-Xd -Fl~/src/sollib'
  
~/src/sollib is a directory that contains:
+
Az ~/src/sollib egy könyvtár ami a következőket tartalmazta:
* a set of .o's from /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3
+
* több .o fájlt a /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 könytvtárból
* libgcc.a from /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3
+
* a libgcc.a fájlt a /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 könytvtárból
* a set of lib*.so from /usr/lib: libaio.so libmd5.so libc.so libelf.so librt.so libdl.so libm.so         
+
* több lib*.so fájlt a /usr/lib könyvtárból: libaio.so libmd5.so libc.so libelf.so librt.so libdl.so libm.so         
  
Problem is illustrated by the following binary.
+
A problémát a következő példa mutatja meg.
  
 
   Free Pascal Compiler version 2.1.1 [2006/03/17] for sparc
 
   Free Pascal Compiler version 2.1.1 [2006/03/17] for sparc

Revision as of 08:51, 12 July 2009

Template:Translate Keresztfordítás Windows-ra Linux rendszeren


Tippek Win32 binárisok keresztfordításához Linux rendszeren

A 0.9.10 óta létezik egy rpm 'fpc-crosswin32' néven, ami telepíti szükséges binutils eszközöket (assembler, linker), az FPC .ppu fájljait win32-re keresztfordítva és a módosított /etc/fpc.cfg.

A csomag nem tartalmazza a keresztfordított LCL .ppu fájlokat. Neked kell lefordítanod őket az fpc-crosswin32 telepítése után.

A Lazarus és a Free Pascal Compiler

A kersztfordításról - Hogy tudd mit csinálsz

Ez egy rövid bevezetés kezdőknek. A következőkben leírjuk hogyan állítsd be a rendszert keresztfordításhoz, ami azt jelenti, hogy Linux rendszeren dolgozva készíthetsz Win32 alkalmazásokat (és ugyanígy FreeBSD, Darwin, stb.). Amiért jó a keresztfordítás: A FreePascal egy fordító és forráskódból gépi kódodú bináris állományokat készít. Ez a bináris tartalmaz információkat arról is hogy az operációs rendszer milyen módon kezelje az állományt. Mindezek miatt a készített bináris állományok rendszerfüggők. Maga a FreePascal nem igényel sok beállítást. Képes binárisokat készíteni sok rendszerhez, csak kérd meg rá. A fordító azonban csak egy rész. Szükségünk van még assemblerre és a linkerre is. Az FPC rendelkezik beépített assemblerrel és/vagy linkerrel néhány rendszerhez, más rendszereken külső eszközökre van szüksége. Ezek az eszközök általában nem képesek binárisokat létrehozni eltérő rendszerek számára. Ezért van, hogy speciális linkert 'ld' és assemblert 'as' használunk minden célrendszeren. Ezeket nevezzük binutils-nak. Miután létrehoztuk (vagy megszereztük/telepítettük) a keresztfordító eszközöket, szükség lesz még az FPC RTL és további unitokra a választott célrendszerre lefordítva. Például minden célrendszerhez eltérő system.ppu (System unit) fájlra van szükség, stb. Miután az fpc config fájl beállítása megtörtént, a keresztfordítás könnyűvé válik, elfeledkezhetsz az unalmas részletekről. Ugyanezt kell tenni az LCL (lazarus component lybrary) esetén is (ha Lazarus-t használsz). Ezután már fordíthatod is a pascal programokat a win32 rendszerre. Az elkészült binárisok futtathatók a Wine segítségével vagy átmásolhatók egy olyan gépre amin win32 fut és ott kipróbálhatók.

Miért *nix rendszerről windows rendszerre és nem a másik irányba?

A legfőbb ok az, hogy Unix binárisok létrehozása más rendszereken (másik Unix vagy akár Linux is) jóval bonyolultabb.

Szükséged lehet függvénytárakra (library) a célrendszerről (gtk, glib,libc etc), és rengetek finomhangolás elvégzésére van szükség az ld számára (függvénytárak helyei, dynlinker helye, stb.).

Ezek részlegesen megoldottak (a statikus linkelés esetén), de nehéz feladat mert utólagos kézi szerkesztést igényel a linker fájlokban és a parancssorban, és széles ismereteket arról ahogy a Unix binárisok működnek.

Töltsd le az FPC forráskódját

A binárisok letöltése nem elég, szükséged van a teljes FPC forráskódra. Megtalálod az www.freepascal.org címen. Használhatod a CVS-t vagy a napi kódot (snapshot). A következő példák esetében az FPC forráskódja a ~/sources/fpc könvtárba lettek letöltve.

Töltsd le a GNU binutils programokat.

Például a binutils-2.18.tar.gz fájlt töltsd le ide: ~/download/binutils-2.18.tar.gz.

A binutils programok keresztfordítása

Az fpcbuild tárhelyén megtalálható egy szkript amivel létre lehet hozni a binutils programokat minden rendszerre: install/cross/buildcrossbinutils

Töltsd le és telepítsd az fpcbuild csomagot:

 []$ cd ~
 []$ svn co http://svn.freepascal.org/svn/fpcbuild/branches/fixes_2_2/install install

Készíts másolatot a szkriptről:

 []$ cd ~/install/cross/
 []$ cp buildcrossbinutils buildcrossbinutils.sh

Szerkesztd a változókat az új szkript elején.

A BASE változó mutatja meg a fordítás és telepítés könyvtárát. Ezért ez lehetőleg egy üres könyvtár legyen. Például:

 BASE=~/cross_fpc

Most következnek a letöltött binutils programok. Ha a csomagot a ~/download/binutils-2.18.tar.gz néven mentetted akkor a beállítások a következőképpen nézzenek ki:

 BINUTILSPATH=~/download/
 BINUTILSBASE=binutils
 BINUTILSVERSION=2.18
 BINUTILS_GZIP=yes

A szkript automatikusan összeállítja belőlük az eredeti nevet: ~/download/binutils-2.18.tar.gz. A további változók a célrendszert határozzák meg. Alapértelmezés szerint szép csendben több rendszerre is lefordítja a kódot, ezért a fordítás sok időt (lassú gépeken órákat) vehet igénybe. Ha csak windows-ra akarsz keresztfordítani akkor csak ennyi kell:

 TARGETS_WIN="mingw32"
 

a többit pedig megjegyzésbe kell áttenni:

 #BSD="freebsd netbsd openbsd"
 #TARGETS_WIN="cygwin mingw32 msdosdjgpp"
 #TARGETS_I386="${BSD} linux solaris darwin"
 #TARGETS_POWERPC="${BSD} linux darwin"
 #TARGETS_SPARC="${BSD} linux solaris"
 #TARGETS_M68k=


Ezután futtasd a szkriptet:

 []$ sh buildcrossbinutils.sh
 

A szkript létrehozz a 'logs' nevű alkönyvtárat tele naplófájlokkal. Ha valami rosszul megy akkor itt kezdj nyomozni.

Ne felejtsd el, hogy több rendszerhez (Linux, FreeBSD, win32) ezek az eszközök már elérhetők lefordítva is. Lásd: ftp://freepascal.stack.nl/pub/fpc/contrib/cross/

Az FPC keresztfordítása

Az fpcbuld tárhelyén megtalálható egy szkript az FPC napi kód (snapshot) keresztfordításához több rendszerhez: install/cross/buildcrosssnapshot Készíts másolatot a szkriptről:

 []$ cd ~/install/cross/
 []$ cp buildcrosssnapshot buildcrosssnapshot.sh

Szerkesztd a változókat az új szkript elején.

Általában csak a CROSSTOOLSROOT, FPCCVS, DESTDIR, TARGETS_OS és TARGETS_CPU értékeit kell beállítanod. Például:

 CROSSTOOLSROOT=~/cross_fpc/cross
 FPCCVS=~/sources/fpc
 TARGETS_OS="win32"
 TARGETS_CPU="i386"
 DESTDIR=~/cross_fpc/
 

Ezután futtasd a szkriptet:

 []$ sh buildcrosssnapshot.sh

Ezután a megtalálod a keresztfordított unit fájlokat a ~/cross_fpc/ könyvtárban.

Az fpc.cfg beállításai

Rendszergazdaként nyisd meg az /etc/fpc.cfg fájlt vagy készíts másolatot az /etc/fpc.cfg fájlról ~/fpc.cfg néven, majd szerkesztd ezt a fájlt. Keresd meg benne a unit-ok útvonalait meghatározó részt.

Ne felejtsd el, hogy a régebbi FPC változatok a $version és $target változókat használják az $fpcversion és $fpctarget helyett.

-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl

Cseréld le őket az egyes rendszereknek megfelelő útvonalakra. Pélául normál Linux és keresztfordított win32 esetében így:

#IFDEF win32
-Fu~/cross_fpc/lib/fpc/$fpcversion/cross/i386-win32/units/
-Fu~/cross_fpc/lib/fpc/$fpcversion/cross/i386-win32/units/*
-Fu~/cross_fpc/lib/fpc/$fpcversion/cross/i386-win32/units/rtl
-XPi686-mingw32-
-FD~/cross_fpc/cross/bin
#ELSE linux
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl
#-Fu~/fpc/packages/*;~/fpc/rtl/linux
#ENDIF

Tennivaló: Tesztelés és hibaelhárítás

Cross compiling the LCL and lazarus components

At Command line:

cd lazarus; make clean all OS_TARGET=win32
cd lazarus/lcl; make clean all 

This will first cross compile everything for win32 (including the IDE, which is unecessary, but so I have to write less doc).

Or in the IDE: Set LCL, Synedit, Codetools, Package Registration and IDE Interface to Clean+Build, set LCL interface to win32/win64 and set 'Target OS' to win32. Then 'build lazarus'. These four parts have splitted output directories, so your linux .ppu/.o files are *not* overwritten and you don't need to recompile them.

Cross compiling a project

Set in Run->Compiler Options->Code the Target OS to 'win32' and in Paths the 'LCL Widget Type' to win32. That's all. The next time you build, you will create a win32 executable. The IDE will rescan for win32 units, so that 'Find declaration' and code completion features will now work with the win32 rtl instead of the linux rtl. When you open another project or reopen this project the IDE will automatically switch.

Hints for Cross compiling and Lazarus

If you create an application/package for multiple targets, you will often do the following: Fix a bug, compile and test it under linux, then compile and test it under win32, .. . Because normally you overwrite your .ppu files, you have to recompile everything, everytime you switch. This is not necessary. The Lazarus IDE supports macros.

Example 1: Cross compiling a project for linux and win32.

Set Run -> Compiler Options -> Paths -> Unit Output directory to $(TargetOS). This macro will be replaced by the value in Code -> TargetOS in lowercase (i.e. "linux" for Linux and "win32" for Win32). The output directory is relative to your project directory (the directory where your .lpi is). Create a linux and win32 directory in your project directory. When you click on the "Show Options" button at the bottom of the compiler options, you will see a -FElinux/ or -FEwin32/. This option tells the compiler where to write the output (e.g. .ppu/.o files).


Example 2: Cross compiling a project for various platforms and widget sets.

Set the Unit output directory to $(TargetCPU)/$(TargetOS)/$(LCLWidgetType) and create the sub directories for all targets. This path construction is also used by the LCL.


The same can be done for packages.

Cross compiling and Lazarus Packages

Lazarus packages are not limited to libraries. They can be used to compile nearly everything. And the IDE automatically recompiles them if needed. Packages can inherit compiler options. For example: A project that uses a package inherits the output directory of the package. In other words: the output directory of the package is added to unit search path of the project. See in the IDE: Run -> Compiler options -> Inherited. Inheritance normally works only one way. But there are exceptions: The target platform (OS and CPU) of the project overrides the target for all used packages. That means, if you set the Target OS of the project to "win32" and compile the project, the IDE will check if the used packages need to be recompiled for this Target OS.

For example:

Package A has as output directory: lib/$(TargetOS) Project uses A.

  1. The project is built for linux. The IDE compiles A for linux in <PackageDirOfA>/lib/linux/, then it compiles the project for linux.
  2. The project is built for win32. The IDE compiles A for win32 in <PackageDirOfA>/lib/win32/, then it compiles the project for win32.
  3. The project is built again for linux. The IDE checks A for linux and does not recompile it. Then it compiles the project for linux.

So, using the macros saves a lot of time.

For Unix (general)

Option -XLA is used to rename library dependencies specified in pascal units. Format is -XLAold=new, to modify ld link option -l<old> to -l<new>.

Option -XR<sysroot> (recent trunk) that can be used to specify the target system root. It's used for:

  • adding a prefix to the default added library paths; in the past you used to specify -Xd and these paths manually. E.g. for i386-linux instead of passing /lib, /usr/lib, and /usr/X11R6/lib to ld, it will pass <sysroot>/lib, <sysroot>/usr/lib, and <sysroot>/usr/X11R6/lib to ld.
  • detecting the C library (linux specific): glibc or uclibc. E.g. for uclibc detection '<sysroot>/lib/ld-uClibc.so.0' is tried.

Linux rendszerre Win32 alatt

Marco vd Voort írt a témáról crossnotes címmel feljegyzést (angolul). Ha valakinek van ideje hozzáadhatja a wiki oldalhoz.

FreeBSD-ről sparc-ra

Végigcsináltam egy keresztfordítást x86-ról Sparc Solaris 9 rendszerre. Azonban az eredmény nem volt megfelelő. Itt a parancsror amit futtattam:

 gmake cycle CPU_TARGET=sparc OS_TARGET=solaris CROSSBINUTILPREFIX=solaris-sparc- CROSSOPT='-Xd -Fl~/src/sollib'

Az ~/src/sollib egy könyvtár ami a következőket tartalmazta:

  • több .o fájlt a /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 könytvtárból
  • a libgcc.a fájlt a /usr/local/gcc-3.3-32bit/lib/gcc-lib/sparc-sun-solaris/3.3 könytvtárból
  • több lib*.so fájlt a /usr/lib könyvtárból: libaio.so libmd5.so libc.so libelf.so librt.so libdl.so libm.so

A problémát a következő példa mutatja meg.

 Free Pascal Compiler version 2.1.1 [2006/03/17] for sparc
 Copyright (c) 1993-2005 by Florian Klaempfl
 Target OS: Solaris for SPARC
 Compiling system.pp
 system.pp(15,1) Fatal: Syntax error, "BEGIN" expected but "identifier UNIT" found

Azt gyanítom, hogy rossz .o fájlokat kapott.

Mac OS X

Nézd meg ezt a fórum bejegyzést (angol).


Eredeti közreműködők

Ez az oldal az epikwiki változat átalakításával készült.