3.交叉编译Erlang / OTP | 3. Cross Compiling Erlang/OTP
目录
Introduction
otp_build Versus configure/make
Cross Configuration
What can be Cross Compiled?
Compatibility
Patches
Build and Install Procedure
Building With configure/make Directly
Building a Bootstrap System
Cross Building the System
Installing
Installing Using Paths Determined by configure
Installing Manually
- [`Building With the otp_build Script`](about:blank#Build-and-Install-Procedure_Building-With-the-otpbuild-Script)
Building and Installing the Documentation
Testing the cross compiled system
Currently Used Configuration Variables
Variables for otp_build Only
Cross Compiler and Other Tools
Dynamic Erlang Driver Linking
Large File Support
Other Tools
- [`Cross System Root Locations`](about:blank#Currently-Used-Configuration-Variables_Cross-System-Root-Locations)
- [`Optional Feature, and Bug Tests`](about:blank#Currently-Used-Configuration-Variables_Optional-Feature-and-Bug-Tests)
3.1引言
本文档介绍了如何交叉编译Erlang/OTP-20。建议您在尝试交叉编译Erlang/OTP之前阅读整个文档。但是,在阅读本文档之前,您应该阅读$ERL_TOP/HOWTO/INSTALL.md
一般描述构建和安装Erlang/OTP 的文档。$ERL_TOP
是源代码树中的顶级目录。
otp_build与配置/制作
建筑Erlang/OTP既可以做,通过使用$ERL_TOP/otp_build
脚本,或通过调用$ERL_TOP/configure
和make
直接。构建使用otp_build
更容易,因为它涉及更少的步骤,但otp_build
构建过程不如configure
/make
build过程那么灵活。请注意,这otp_build configure
将产生一个默认配置,与默认情况下产生的配置不同configure
。例如,除非已经明确传递,否则当前--disable-dynamic-ssl-lib
被添加到configure
命令行参数中--enable-dynamic-ssl-lib
。我们提供的二进制版本是使用内置的otp_build
。所使用的默认值otp_build configure
可能随时更改,恕不另行通知。
交叉配置
$ERL_TOP/xcomp/erl-xcomp.conf.template
文件包含所有可用的交叉配置变量,并且可以在创建交叉编译配置时用作模板。所有内容cross configuration variables
也列在本文末尾。有关工作交叉配置的示例,请参阅$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
文件和$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf
文件。如果变量的默认行为令人满意,则不需要设置该变量。但是,configure
使用默认值时,脚本将发出警告。变量设置完成后,不会发出警告。
可以otp_build configure
使用--xcomp-conf
命令行参数传递交叉配置文件。请注意,configure
不接受这个命令行参数。configure
直接使用脚本时,将配置变量作为参数传递给configure
使用<VARIABLE>=<VALUE>
语法。变量也可以作为环境变量传递给configure
。但是,如果您在环境中传递配置,请确保在调用之前取消设置所有这些环境变量make
; 否则,环境变量可能会在某些应用程序或某些应用程序的某些部分中设置make变量,并且最终可能会生成错误配置的构建版本。
什么可以交叉编译?
除wx
应用程序之外的所有Erlang/OTP应用程序都可以交叉编译。wx
交叉编译时,驱动程序的构建目前会自动禁用。
兼容性
构建系统(包括使用的交叉编译配置变量)可能会受到非向后兼容的更改,恕不另行通知。当交叉编译某些Linux/GNU系统时,目前的交叉编译系统已经过测试,但只是部分测试了更多深奥的平台。VxWorks示例文件高度依赖于我们的环境,并且或多或少只用于内部使用。
Patches
请按照与本系统一致的方式提交任何交叉编译补丁。所有的输入都是值得欢迎的,因为我们有一套非常有限的交叉编译环境来测试。如果需要新的配置变量,请将其添加到$ERL_TOP/xcomp/erl-xcomp.conf.template
中并用于其中configure.in
。其他可能需要更新的文件是:
$ERL_TOP/xcomp/erl-xcomp-vars.sh
$ERL_TOP/erl-build-tool-vars.sh
$ERL_TOP/erts/aclocal.m4
$ERL_TOP/xcomp/README.md
$ERL_TOP/xcomp/erl-xcomp-*.conf
请注意,这可能是一个不完整的需要更新的文件列表。
有关如何提交补丁的一般信息可以在以下网址找到: http://wiki.github.com/erlang/otp/submitting-patches
3.2构建和安装程序
如果您正在Git中构建,那么您需要在继续之前阅读该Building in Git
部分$ERL_TOP/HOWTO/INSTALL.md
。
我们将首先介绍人们可能最熟悉的configure
/ make
构建过程。
用configure/make直接构建
(1)
将目录切换到Erlang/OTP源树的顶层目录。
$ cd $ERL_TOP
为了编译Erlang代码,必须建立一个小的Erlang引导程序系统,或者必须提供与正在构建的相同版本的Erlang/OTP系统$PATH
。目标系统的Erlang/OTP将使用此Erlang系统以及提供的交叉编译工具构建。
如果你想使用兼容的Erlang/OTP系统构建$PATH
,跳转到(3)。
构建Bootstrap系统
(2)
$ ./configure --enable-bootstrap-only
$ make
--enable-bootstrap-only
参数configure
并非绝对必要,反而会加快速度。它只会configure
在引导程序所需的应用程序中运行,并会禁用引导程序系统不需要的许多事情。如果你configure
没有运行,--enable-boostrap-only
你也必须运行make as make bootstrap
; 否则,整个系统将建成。
交叉构建系统
(3)
$ ./configure --host=<HOST> --build=<BUILD> [Other Config Args]
$ make
<HOST>
是您建立的主机/目标系统。它不一定是一个完整的CPU-VENDOR-OS
三元组,但可以。完整的CPU-VENDOR-OS
三元组将通过执行而创建$ERL_TOP/erts/autoconf/config.sub <HOST>
。如果config.sub
失败,你需要更具体。
<BUILD>
应该等于CPU-VENDOR-OS
你建立的系统的三元组。如果你执行$ERL_TOP/erts/autoconf/config.guess
,它会在大多数情况下打印你想要使用的三元组。
将交叉编译变量作为命令行参数传递给configure
使用<VARIABLE>=<VALUE>
语法。
注意
你可以不使用经过一个配置文件--xcomp-conf
的说法,当你调用configure
直接。该--xcomp-conf
参数只能传递给otp_build configure
。
make
将验证构建时使用的Erlang / OTP系统与正在构建的系统具有相同的版本,并且如果不是这种情况将会失败。尽管不推荐使用错误的Erlang / OTP系统,但也可以强制进行交叉编译。这通过调用make
这样的:make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes
。
警告
调用make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes
可能失败,默默地产生次优代码,或者静静地产生错误的代码。
Installing
您可以使用由configure
(4)确定的安装路径进行安装,也可以使用(5)手动进行安装。
使用路径安装由配置确定
(4)
$ make install DESTDIR=<TEMPORARY_PREFIX>
make install
将在指定的位置安装configure
。configure
参数指定在安装应位于例如为:--prefix
,--exec-prefix
,--libdir
,--bindir
,等它默认安装下/usr/local
。您通常不希望/usr/local
在构建机器上安装交叉构建版本。使用DESTDIR
将导致安装路径前缀为$DESTDIR
。这使得可以在安装机器上安装和打包安装,而不必将安装放置在构建机器上的同一个目录中,因为它应该从目标机器上执行。
当make install
完成,将目录切换到$DESTDIR
,打包系统,将其移动到目标机器并将其解压。请注意,安装只能在目标机器上的位置确定configure
。
手动安装
(5)
$ make release RELEASE_ROOT=<RELEASE_DIR>
make release
将复制您为目标机器构建的内容<RELEASE_DIR>
。该Install
脚本将不会运行。内容<RELEASE_DIR>
是默认结果/usr/local/lib/erlang
。
Install
安装Erlang / OTP时使用的脚本需要常用的Unix工具,例如sed
在你的系统中$PATH
。如果你的目标系统没有这样的工具,你需要Install
在构建机器上运行脚本,然后再打包Erlang / OTP。该Install
脚本应该目前援引为在其所在目录(顶级目录)如下:
$ ./Install [-cross] [-minimal|-sasl] <ERL_ROOT>
当:
-minimal
创建启动最少量应用程序的安装,即仅启动kernel
和stdlib
启动。最小系统通常就足够了,而且是make install
用途。-sasl
创建一个也可以启动sasl
应用程序的安装。-cross
用于交叉编译。通知安装脚本它在生成机器上运行。<ERL_ROOT>
- Erlang安装在运行时使用的绝对路径。这通常与当前工作目录相同,但不一定是。它可以通过文件系统的任何其他路径到同一目录。
如果两者都不是-minimal
,也不会-sasl
作为参数传递,您将被提示。
你现在可以做:
(6)
- 确定安装应位于目标机器
Install
上的位置,在构建机器上运行脚本,并打包安装的安装。安装只需要在目标机器的正确位置解压:$ cd <RELEASE_DIR> $ ./Install -cross -minimal | -sasl <ABSOLUTE_INSTALL_DIR_ON_TARGET>
or:
(7)
- 打包安装
<RELEASE_DIR>
,将其放置在目标计算机Install
上的任意位置,然后在目标计算机上运行脚本:$ cd <ABSOLUTE_INSTALL_DIR_ON_TARGET> $ ./Install -minimal | -sasl <ABSOLUTE_INSTALL_DIR_ON_TARGET>
使用otp_build脚本构建
(8)
$ cd $ERL_TOP
(9)
$ ./otp_build configure --xcomp-conf=<FILE> [Other Config Args]
或者:
$ ./otp_build configure --host=<HOST> --build=<BUILD> [Other Config Args]
如果您在文件中使用了交叉编译配置,请使用--xcomp-conf=<FILE>
命令行参数传递它。如果没有,通过--host=<HOST>
,--build=<BUILD>
以及使用所述配置变量<VARIABLE>=<VALUE>
在命令行上的语法(同(3))。请注意,<HOST>
并<BUILD>
必须通过一种方式或其他; 通过使用erl_xcomp_host=<HOST>
和erl_xcomp_build=<BUILD>
在配置文件中,或通过使用--host=<HOST>
和--build=<BUILD>
命令行参数。
otp_build configure
将在生成机器和跨主机系统上为boostrap系统配置。
(10)
$ ./otp_build boot -a
otp_build boot -a
将首先为构建机构建一个引导系统,然后进行系统的交叉构建。
(11)
$ ./otp_build release -a <RELEASE_DIR>
otp_build release -a
将执行与(5)相同的操作,然后您必须通过执行(6)或(7)来执行手动安装。
3.3构建和安装文档
系统交叉构建后,您可以按照与本机构建系统后相同的方式构建和安装文档。有关如何构建文档的信息,请参阅文档中的How to Build the Documentation
部分$ERL_TOP/HOWTO/INSTALL.md
。
3.4测试交叉编译系统
erlang附带的一些测试使用本机代码进行测试。这意味着在交叉编译erlang时,为了在目标主机上运行测试,还必须交叉编译测试套件。要做到这一点,你首先必须照常发布测试。
$ make release_tests
要么
$ ./otp_build tests
测试将发布到$ERL_TOP/release/tests
。发布测试后,您必须在生成机器上安装测试。您提供与./otp_build
(9)中相同的xcomp文件。
$ cd $ERL_TOP/release/tests/test_server/
$ $ERL_TOP/bootstrap/bin/erl -eval 'ts:install([{xcomp,"<FILE>"}])' -s ts compile_testcases -s init stop
在编译测试用例时,你应该得到很多打印输出。一旦完成,您应该将整个$ERL_TOP/release/tests
文件夹复制到跨主机系统。
然后转到跨主机系统,并将(4)或(5)中安装的erlang设置为您的$PATH
。然后转到以前的内容$ERL_TOP/release/tests/test_server
并发出以下命令。
$ erl -s ts install -s ts run all_tests -s init stop
该配置应该跳过,所有的测试应该有希望通过。有关如何使用ts run的更多详细信息erl -s ts help -s init stop
3.5当前使用的配置变量
请注意,您无法在交叉编译配置文件中定义任意变量。只有下面列出的才能保证在所有configure
脚本的整个执行过程中可见。其他变量需要定义为参数configure
或导出到环境中。
仅限otp_build的变量
当使用$ERL_TOP/otp_build configure
。配置Erlang / OTP进行交叉编译时,仅使用本节中的变量。
注意
这些变量目前还没有效果,如果您配置使用configure
直接脚本。
erl_xcomp_build
- 使用的构建系统。该值将作为--build=$erl_xcomp_build
参数传递给configure
脚本。它不一定是一个完整的CPU-VENDOR-OS
三元组,但可以。完整的CPU-VENDOR-OS
三元组将由...创建$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_build
。如果设置为guess
,构建系统将被猜测使用$ERL_TOP/erts/autoconf/config.guess
。erl_xcomp_host
- 跨主机/目标系统建立。该值将作为--host=$erl_xcomp_host
参数传递给configure
脚本。它不一定是一个完整的CPU-VENDOR-OS
三元组,但可以。完整的CPU-VENDOR-OS
三元组将由...创建$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host
。erl_xcomp_configure_flags
- 额外的配置标志传递给configure
脚本。
交叉编译器和其他工具
如果交叉编译工具以<HOST>-
你为前缀,你可能不需要设置这些变量(其中<HOST>
是作为--host=<HOST>
参数传递的参数configure
)。
本地编译时也可以使用本节中的所有变量。
CC
- C编译器。CFLAGS
- C编译器标志。STATIC_CFLAGS
- 静态C编译器标志。CFLAG_RUNTIME_LIBRARY_PATH
- 此标志应为共享库设置运行时库搜索路径。请注意,这实际上是一个链接器标志,但它需要通过编译器传递。CPP
- C预处理器。CPPFLAGS
- C预处理器标志。CXX
- C ++编译器。CXXFLAGS
- C ++编译器标志。LD
- 离开。LDFLAGS
- 链接器标志。LIBS
- 库。
动态Erlang驱动程序链接
注意
要么设置全部DED_LD*
变量,要么全部不设置。
DED_LD
- 用于动态加载Erlang驱动程序的链接器。DED_LDFLAGS
- 使用的链接器标志DED_LD
。DED_LD_FLAG_RUNTIME_LIBRARY_PATH
- 此标志应与链接时设置共享库的运行时库搜索路径DED_LD
。
Large File Support
注意
要么设置全部LFS_*
变量,要么全部不设置。
LFS_CFLAGS
- 大文件支持C编译器标志。LFS_LDFLAGS
- 大文件支持链接器标志。LFS_LIBS
- 大型文件支持库。
其他工具
RANLIB
-ranlib
归档索引工具。AR
-ar
归档工具。GETCONF
-getconf
系统配置检查工具。getconf
目前用于查找要使用的大文件支持标志,以及在Linux系统上查找是否有NPTL线程库。
跨系统根位置
erl_xcomp_sysroot
- 交叉编译环境的系统根的绝对路径。目前,crypto
,odbc
,ssh
和ssl
应用程序需要的系统根目录。如果系统根目录尚未设置,这些应用程序将被跳过。系统根目录也可能用于其他事情。如果是这种情况并且系统根目录尚未设置,configure
将会失败并请求您设置它。erl_xcomp_isysroot
- 包含交叉编译环境的系统根目录的绝对路径。如果未设置,则此值默认为$erl_xcomp_sysroot
,即只有在包含系统根路径与系统根路径不同时才设置此值。
可选功能和Bug测试
这些测试不能(总是)在交叉编译时自动完成。您通常不需要设置这些变量。
警告
设置这些变量错误可能会导致很难检测到运行时错误。如果您需要更改这些值,真正确保值是正确的。
注意
其中一些值将覆盖执行的测试结果configure
,有些将不会被使用,直到configure
确定它无法确定结果。
configure
当使用默认值时,脚本将发出警告。变量设置完成后,不会发出警告。
erl_xcomp_after_morecore_hook
-yes|no
。默认为no
。如果yes
,目标系统必须有__after_morecore_hook
可用于跟踪使用的malloc()
实现核心内存使用情况的工作。这目前仅被不支持的功能使用。erl_xcomp_bigendian
-yes|no
。没有默认值。如果yes
目标系统必须是大端。如果no
,小尾数。这通常可以自动检测到,但并非总是如此。如果不能自动检测到,configure
将会失败,除非设置了这个变量。由于没有使用默认值,因此configure
会自动计算出结果。erl_xcomp_double_middle
-yes|no
。默认为no
。如果yes
,目标系统必须以“中端”格式加倍。如果no
它具有“常规”排序。erl_xcomp_clock_gettime_cpu_time
-yes|no
。默认为no
。如果yes
目标系统必须具有clock_gettime()
可用于检索进程CPU时间的工作实现。erl_xcomp_getaddrinfo
-yes|no
。默认为no
。如果yes
目标系统必须具有getaddrinfo()
可同时处理IPv4和IPv6 的工作实现。erl_xcomp_gethrvtime_procfs_ioctl
-yes|no
。默认为no
。如果yes
,目标系统必须有一个工作gethrvtime()
实现并与procfs一起使用ioctl()
。erl_xcomp_dlsym_brk_wrappers
-yes|no
。默认为no
。如果yes
目标系统必须有一个dlsym(RTLD_NEXT, <S>)
可以使用的工作实现brk
以及正在sbrk
使用的malloc()
实现所使用的符号,并且通过此跟踪malloc()
实现核心内存使用情况。这目前仅被不支持的功能使用。erl_xcomp_kqueue
-yes|no
。默认为no
。如果yes
,目标系统必须有一个工作kqueue()
实现返回一个文件描述符,这个文件描述符可以被使用poll()
和/或select()
。如果no
目标系统还没有epoll()
或者/dev/poll
,内核轮询功能将被禁用。erl_xcomp_linux_clock_gettime_correction
-yes|no
。默认为yes
在Linux上; 否则,no
。如果yes
,clock_gettime(CLOCK_MONOTONIC, _)
在目标系统上必须工作。建议将此变量设置为no
内核版本低于2.6的Linux系统上。erl_xcomp_linux_nptl
-yes|no
。默认为yes
在Linux上; 否则,no
。如果yes
,目标系统必须具有NPTL(本地POSIX线程库)。较老的Linux系统有LinuxThreads而不是NPTL(Linux内核版本通常小于2.6)。erl_xcomp_linux_usable_sigaltstack
-yes|no
。默认为yes
在Linux上; 否则,no
。如果yes
,sigaltstack()
必须在目标系统上可用。sigaltstack()
在小于2.4的Linux内核版本上被破坏。erl_xcomp_linux_usable_sigusrx
-yes|no
。默认为yes
。如果yes
,所述SIGUSR1
和SIGUSR2
信号必须由ERTS可用。旧的LinuxThreads线程库(Linux内核版本通常小于2.2)使用这些信号并使它们无法由ERTS使用。erl_xcomp_poll
-yes|no
。默认为no
在Darwin / MacOSX上; 否则,yes
。如果yes
,目标系统必须有一个poll()
也可以处理设备的工作实现。如果no
,select()
将被用来代替poll()
。erl_xcomp_putenv_copy
-yes|no
。默认为no
。如果yes
,目标系统必须有一个putenv()
存储密钥/值对副本的实现。erl_xcomp_reliable_fpe
-yes|no
。默认为no
。如果yes
目标系统必须具有可靠的浮点异常。erl_xcomp_posix_memalign
-yes|no
。默认为yes
,如果posix_memalign
系统调用存在; 否则no
。如果yes
目标系统必须具有posix_memalign
接受大于页面大小对齐的实现。
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com