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

From Lazarus wiki
Jump to navigationJump to search
(Allow for a name change on another page)
 
(7 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{Cross compiling for Win32 under Linux}}
+
{{Cross compiling for Windows under Linux}}
  
 
== 概述 ==
 
== 概述 ==
Line 5: Line 5:
 
=== 介绍 - 了解你在做什么 ===
 
=== 介绍 - 了解你在做什么 ===
  
'''注意 :''' If your FPC has come from your Linux Distribution Repository, it is likely it won't have everything needed to be turned into a cross compiler. Please see [[Installing_the_Free_Pascal_Compiler#Linux|Installing the Free Pascal Compiler - Linux]].
+
'''注意 :''' 如果你的FPC来自你的Linux发行版存储库,那么它很可能不会有转换成交叉编译器的东西。请查看[[Installing_the_Free_Pascal_Compiler#Linux|安装Free Pascal编译器 - Linux]]
  
 
这是针对新手的一份简短介绍。下面的部分将解释如何设置一个Linux系统来交叉编译,创建Win32可执行文件(或者为FreeBSD或者为Darwin/macOS,或者为...)。为什么交叉编译?Free Pascal是一个编译器,,基本上就是将源文件转换为二进制文件(机器语言)。这些二进制文件也包含操作系统应该如何启动可执行文件的信息。所以,这些二 进制文件是特定于平台的。  
 
这是针对新手的一份简短介绍。下面的部分将解释如何设置一个Linux系统来交叉编译,创建Win32可执行文件(或者为FreeBSD或者为Darwin/macOS,或者为...)。为什么交叉编译?Free Pascal是一个编译器,,基本上就是将源文件转换为二进制文件(机器语言)。这些二进制文件也包含操作系统应该如何启动可执行文件的信息。所以,这些二 进制文件是特定于平台的。  
Line 84: Line 84:
 
[[File:002-paths-win32.png]]  
 
[[File:002-paths-win32.png]]  
  
- Create builds and edit build names 在"构建模式: [BuildName]" 窗口中(单击上面的[...]按钮来打开它),创建构建模式和编辑构建模式。
+
- 在"构建模式: [BuildName]" 窗口中(单击上面的[...]按钮来打开它),创建构建模式和编辑构建模式。
 
[[File:001-build-modes.png]]
 
[[File:001-build-modes.png]]
  
Line 108: Line 108:
 
=== 交叉编译一个工程 ===
 
=== 交叉编译一个工程 ===
  
In Project->Compiler Options->Code, set the Target OS to 'win32' and in "Additions and Overrides" click  Set LCL WidgetType and select win32. That's all. The next time you build, you will create a win32 executable.
+
按 Ctrl+Shift+F11,或导航到 工程->工程选项,在弹出的"工程选项"对话框的右侧列表中找到 编译器选项路径->配置和目标,在右侧的 目标平台 中,设置 目标操作系统 为 'win32' ,在右侧的 目标-具体选项 中,勾选 Win32图形界面应用程序(-WG,忽略)。这就是全部。你下次构建时,你将创建一个win32可执行文件。
  
Lazarus IDE将重新扫描win32单元,so that 'Find declaration' and code completion features will now work with the win32 rtl instead of the linux rtl.
+
Lazarus IDE将重新扫描win32单元,因此现在 '查找声明' 和代码补全特色将使用win32 rtl工作,而不再是使用linux rtl工作。当你打开另一个工程或重新打开这个工程时,lazarus IDE将自动切换。
When you open another project or reopen this project the IDE will automatically switch.
 
  
=== 交叉编译和 Lazarus的提示 ===
+
=== 交叉编译和Lazarus的提示 ===
如果你为多个目标创建一个应用程序/软件包,你通常将执行下面的动作:在Linux下编译和测试它,接 下来在win32下编译和测试它, .. .因为你每次切换目标时,你通常会重写你的.ppu文件,你必须重新编译所有的东西。这是没有必要的,因为Lazarus IDE支持宏命令。  
+
如果你为多个目标创建一个应用程序/软件包,你通常将执行下面的动作:在Linux下编译和测试它,接 下来在win32下编译和测试它,因为你每次切换目标时,你通常会重写你的.ppu文件,你必须重新编译所有的东西。这是没有必要的,因为Lazarus IDE支持宏命令。  
  
Example 1: Cross compiling a project for linux and win32.
+
示例1:为Linux和win32交叉编译一个工程。
  
Set Project -> 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).
+
导航到 工程->工程选项,在弹出的"工程选项"对话框的右侧列 表中找到"编译器选项"。在右侧的  路径 中设置 '单元输出目录'为 $(TargetOS)。这个宏将替换Code -> TargetOS中值为小写值 (例如,针对Linux的 "linux"和针对Win32的"win32")。输出目录是相对于你的工程目录的(你的.lpi文件所在位置的目录)。 在你的工程目录中会创建一个linux和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).
+
当你单击编译器选项底部的"显示选项"时,你将看到一个-FElinux/-FEwin32/。这个选项将告诉 编译器在何处写入输出文件(例如,ppu/.o 文件)
  
  
Example 2: Cross compiling a project for various platforms and widget sets.
+
示例2:为各种平台和widget集交叉编译工程。
  
Set the Unit output directory to
+
设置 单元输出目录 为 $(TargetCPU)/$(TargetOS)/$(LCLWidgetType) ,并为所有的目录创建子目录。LCL也使用这个路径构造。
$(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.
+
软件包也可以这样做。
  
 
=== 交叉编译和Lazarus软件包 ===
 
=== 交叉编译和Lazarus软件包 ===
 
Lazarus软件包不限于库。它们几乎可以用于编译所有的东西。如果需要,Lazarus IDE 会自动重新编译它们。  
 
Lazarus软件包不限于库。它们几乎可以用于编译所有的东西。如果需要,Lazarus IDE 会自动重新编译它们。  
  
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: Project -> Compiler options -> Inherited.
+
软件包可以继承编译器选项。例如:一个工程使用一个软件包,并继承软件包的输出目录。换句话说:软件包的输出目录 将被添加到工程的单元搜索路径中。在Lazarus IDE中查看:导航到: 工程 -> 工程选项,在弹出的"工程选项"对话框的最下部找到"显示选项",在弹出的"编译器选项"对话框找到 继承的参数 标签页。
  
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.
+
工程的目标平台(OS和CPU)重写(override)所有所使用软件包 的目标。这意味着,如果你设置工程的 目标操作系统为"win32",并编译工程,Lazarus IDE将检查是否需要为这个目标操作系统来重新编译所使用的软件包。
  
 
例如:
 
例如:
Line 144: Line 140:
 
工程使用软件包A,而软件包A有输出目录: lib/$(TargetOS)
 
工程使用软件包A,而软件包A有输出目录: lib/$(TargetOS)
  
# The project is built for linux. The IDE compiles A for linux in <PackageDirOfA>/lib/linux/, then it compiles the project for linux.
+
# 为linux构建工程。Lazarus IDE将在<PackageDirOfA>/lib/linux/中为linux编译A,接下来,它将为linux编译工程。
# The project is built for win32. The IDE compiles A for win32 in <PackageDirOfA>/lib/win32/, then it compiles the project for win32.
+
# 为win32构建工程。Lazarus IDE将在<PackageDirOfA>/lib/win32/中为win32编译A,接下来,它将为win32编译工程。
# 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.
+
# 为linux再次构建工程。Lazarus IDE将针对Linux做一次针对A的检查,但并不会重新编译A,接下来,它将为linux编译工程。
  
So, using the macros saves a lot of time.
+
所以,使用宏命令可以节省很多时间。
  
==See also==
+
==参考==
* [[Cross compiling]]
+
* [[Cross compiling |交叉编译]]
* [http://www.stack.nl/~marcov/crossnotes.txt crossnotes] Notes about cross compiling
+
* [http://www.stack.nl/~marcov/crossnotes.txt crossnotes] 关于交叉编译的注释
* [[buildfaq]]
+
* [[buildfaq |构建指南]]
  
 
[[Category:Cross compilation]]
 
[[Category:Cross compilation]]
 
[[Category:FPC]]
 
[[Category:FPC]]
 
[[Category:Lazarus]]
 
[[Category:Lazarus]]
 +
 +
= 贡献者和更改 =
 +
* 简体中文版本由 [[User:Robsean | robsean]] 于 2021-06-25 创建(2021-07-08完成全部翻译)。

Latest revision as of 13:57, 20 July 2021

English (en) français (fr) magyar (hu) italiano (it) русский (ru) 中文(中国大陆)‎ (zh_CN)

概述

介绍 - 了解你在做什么

注意 : 如果你的FPC来自你的Linux发行版存储库,那么它很可能不会有转换成交叉编译器的东西。请查看安装Free Pascal编译器 - Linux

这是针对新手的一份简短介绍。下面的部分将解释如何设置一个Linux系统来交叉编译,创建Win32可执行文件(或者为FreeBSD或者为Darwin/macOS,或者为...)。为什么交叉编译?Free Pascal是一个编译器,,基本上就是将源文件转换为二进制文件(机器语言)。这些二进制文件也包含操作系统应该如何启动可执行文件的信息。所以,这些二 进制文件是特定于平台的。

Free Pascal本身不需要多少设置。它可以为很多平台创建二进制文件。只需要告诉它来做什么就行。但是编译器只是其中的一部分。

这里也有汇编器和链接器。并且这些工具不能创建交叉平台的代码。这就是为什么我们必须为每一个目标平台创建一个特 殊的链接器'ld'和汇编器'as'。这些都是二进制实用程序。

在创建交叉工具后,所有的FPC的Pascal单元也将被交叉编译。例如,针对每个目标平台都将会有一个目标系统 的.ppu文件。 接下来,你将会设置FPC的配置文件(fpc.cfg),以便交叉编译将变得很容易,这样你可以 忘记所有令人厌倦的细节。同样的事情也会发生在LCL - Lazarus组件库上。并且在这之后,你可以为Win32交叉编译Pascal程序。要么使用wine启动它们,要么将它们复制到一个Windows机 器上,并在其中测试它们。

Free Pascal

为什么是从*nix到Windows,而不是从Windows到*nix

主要原因是,在一个外部平台上(甚至是在另一个Unix或Linux系统上)生成Linux/Unix二进制文件更为复杂。 静态链接已经很复杂了,更不要说动态链接了。

你可能需要使用来自目标平台的库(gtk, glib, libc等等),以及针对ld的很多附加的配置(库路径,动态链接器路径等)。

这样已经部分完成了(针对静态情况),但是它是很难的,因为它需要对链接器文件和链接器命令行进行手动后期编辑, 并且对Unix二进制文件做出深刻的理解。

较新的FPC - 2.1.1及较新的版本

如果你正在编译FPC的一个2.1.1或者较新的版本,你只需要这样做:

$ make all OS_TARGET=win32 CPU_TARGET=i386

然后

$ su -c "make crossinstall OS_TARGET=win32 CPU_TARGET=i386"

Light bulb  Note:
make crossinstall默认情况下在/usr/local/lib/fpc/$fpcversion/units 目录下安装所有的文件,这就是你需要添加一个新的搜索路径到/etc/fpc.cfg file的原因,路径: -Fu/usr/local/lib/fpc/$fpcversion/units/$fpctarget/*.

另外一个选项是,在执行make crossinstall期间使用可选项INSTALL_PREFIX=/usr。在这种情况下,你将不需要更改在/etc/fpc.cfg文件中的任何东西,因为所有的文件都将添加到已经存在的/usr/lib/fpc/$fpcversion/units目录下。
Light bulb  Note:
构建win64的版本的make命令是: make all OS_TARGET=win64 CPU_TARGET=x86_64


之所以这么简单是因为在fpc的这个版本中已经包含了内部链接器。

在Bunsen Labs系统下的一个示例(Debian 8)

- 使用FPC 3.0.0和Lazarus 1.6.2交叉编译到Win32和Win64。

- 打开你的终端并执行下面的命令(为此非常感谢Handoko和Leledumbo,你们真是令人敬畏)。

# Navigate to the fpc source folder.
cd /usr/share/fpcsrc/3.0.0

# Compile the cross-compiler.
make all OS_TARGET=win32 CPU_TARGET=i386

# Install the cross-compiler.
sudo make crossinstall OS_TARGET=win32 CPU_TARGET=i386 INSTALL_PREFIX=/usr

# Link the cross-compiler and place the link where Lazarus can see it.
sudo ln -sf /usr/lib/fpc/3.0.0/ppcross386 /usr/bin/ppcross386

# Do the same using x64 as target
make all OS_TARGET=win64 CPU_TARGET=x86_64
sudo make crossinstall OS_TARGET=win64 CPU_TARGET=x86_64 INSTALL_PREFIX=/usr
sudo ln -sf /usr/lib/fpc/3.0.0/ppcrossx64 /usr/bin/ppcrossx64

- 确保你的交叉编译器是存在的:(注意,链接到交叉编译二进制文件出现在/usr/bin中,而不是仅出现在/usr/lib中,如下图所示)。

000-cross-compilers-compiled.png

- 确保你的交叉编译器已经正确的链接:

000-cross-compilers-linked.png

- 现在,打开Lazarus。

- 按 Ctrl+Shift+F11,或导航到 工程->工程选项->路径菜单。在弹出的"工程选项"对话框的右侧列表中找到"路径"选项。

- 针对每次构建,配置你的路径,以便所有需要的库都是可获取的,并且由Lazarus/FPC生成所有输出文件不需要重写。在"单元输出路径"和"目标文件 名称"中,我选择使用宏命令。

002-paths-win32.png

- 在"构建模式: [BuildName]" 窗口中(单击上面的[...]按钮来打开它),创建构建模式和编辑构建模式。 001-build-modes.png

- 当你完成后,单击ok

- 现在,转到 运行->编译多种模式。按ok。一直等到Lazarus和FPC完成它们的工作。

003-build-many-modes.png

- 转到你的工程文件夹,好好享受!

Write once, compile anywhere.

较老的FPC,早于2.1.1

针对早于2.1.1的FPC版本,请查看历史链接(在2014年08月19日之前的版本)来查看需要的步骤。

Lazarus/LCL

交叉编译LCL和Lazarus组件

当你更改你的工程的目标并构建它时,Lazarus IDE会自动交叉编译所有使用的软件包。.

交叉编译一个工程

按 Ctrl+Shift+F11,或导航到 工程->工程选项,在弹出的"工程选项"对话框的右侧列表中找到 编译器选项路径->配置和目标,在右侧的 目标平台 中,设置 目标操作系统 为 'win32' ,在右侧的 目标-具体选项 中,勾选 Win32图形界面应用程序(-WG,忽略)。这就是全部。你下次构建时,你将创建一个win32可执行文件。

Lazarus IDE将重新扫描win32单元,因此现在 '查找声明' 和代码补全特色将使用win32 rtl工作,而不再是使用linux rtl工作。当你打开另一个工程或重新打开这个工程时,lazarus IDE将自动切换。

交叉编译和Lazarus的提示

如果你为多个目标创建一个应用程序/软件包,你通常将执行下面的动作:在Linux下编译和测试它,接 下来在win32下编译和测试它,因为你每次切换目标时,你通常会重写你的.ppu文件,你必须重新编译所有的东西。这是没有必要的,因为Lazarus IDE支持宏命令。

示例1:为Linux和win32交叉编译一个工程。

导航到 工程->工程选项,在弹出的"工程选项"对话框的右侧列 表中找到"编译器选项"。在右侧的 路径 中设置 '单元输出目录'为 $(TargetOS)。这个宏将替换Code -> TargetOS中值为小写值 (例如,针对Linux的 "linux"和针对Win32的"win32")。输出目录是相对于你的工程目录的(你的.lpi文件所在位置的目录)。 在你的工程目录中会创建一个linux和win32目录。

当你单击编译器选项底部的"显示选项"时,你将看到一个-FElinux/或-FEwin32/。这个选项将告诉 编译器在何处写入输出文件(例如,ppu/.o 文件)。


示例2:为各种平台和widget集交叉编译工程。

设置 单元输出目录 为 $(TargetCPU)/$(TargetOS)/$(LCLWidgetType) ,并为所有的目录创建子目录。LCL也使用这个路径构造。

软件包也可以这样做。

交叉编译和Lazarus软件包

Lazarus软件包不限于库。它们几乎可以用于编译所有的东西。如果需要,Lazarus IDE 会自动重新编译它们。

软件包可以继承编译器选项。例如:一个工程使用一个软件包,并继承软件包的输出目录。换句话说:软件包的输出目录 将被添加到工程的单元搜索路径中。在Lazarus IDE中查看:导航到: 工程 -> 工程选项,在弹出的"工程选项"对话框的最下部找到"显示选项",在弹出的"编译器选项"对话框找到 继承的参数 标签页。

继承通常只起一种作用,但是也有异常: 工程的目标平台(OS和CPU)重写(override)所有所使用软件包 的目标。这意味着,如果你设置工程的 目标操作系统为"win32",并编译工程,Lazarus IDE将检查是否需要为这个目标操作系统来重新编译所使用的软件包。

例如:

工程使用软件包A,而软件包A有输出目录: lib/$(TargetOS)

  1. 为linux构建工程。Lazarus IDE将在<PackageDirOfA>/lib/linux/中为linux编译A,接下来,它将为linux编译工程。
  2. 为win32构建工程。Lazarus IDE将在<PackageDirOfA>/lib/win32/中为win32编译A,接下来,它将为win32编译工程。
  3. 为linux再次构建工程。Lazarus IDE将针对Linux做一次针对A的检查,但并不会重新编译A,接下来,它将为linux编译工程。

所以,使用宏命令可以节省很多时间。

参考

贡献者和更改

  • 简体中文版本由 robsean 于 2021-06-25 创建(2021-07-08完成全部翻译)。