Cross Compile libdnet and Python for Montavista/PowerPC

本文详细介绍了如何在Montavista/PowerPC环境下交叉编译libdnet和Python。作者首先遇到Python交叉编译的问题,转而尝试编译libdnet,并成功通过调整配置选项和解决编译错误。在解决libdnet的编译问题后,作者对Python的交叉编译进行了尝试,通过修改`./configure`脚本使其适用于交叉编译环境。最终,作者成功编译出适用于PowerPC的Python可执行文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cross Compile libdnet and Python for Montavista/PowerPC

Peter Jiangsy

一开始我是想把Python 2.5.1 交叉编译,以运行在Montavista/PowerPC上,但是一直不成功。于是我想到了先编译一些相对比较小的程序,因为我原本是希望利用自己以前使用Python+Libdnet的经验,在Montavista/PowerPC上做一些开发,所以我就拿了Libdnet开刀。

一开始经过了很多的失败,在网上寻找“Cross Compile Python”和“Cross Compile PowerPC”也没有找到什么好的参考。不过后来不知道搜什么后,我在网上看到了Cross Compile libcurl的文章,这也是在PPC上交叉编译,很简短,摘录如下。

 

CROSS COMPILE libcurl

CROSS COMPILE
=============
 
   (This section was graciously brought to us by Jim Duey, with additions by
   Dan Fandrich)
 
   Download and unpack the cURL package.  Version should be 7.9.1 or later.
 
   'cd' to the new directory. (e.g. cd curl-7.12.3)
 
   Set environment variables to point to the cross-compile toolchain and call
   configure with any options you need.  Be sure and specify the '--host' and
   '--build' parameters at configuration time.  The following script is an
   example of cross-compiling for the IBM 405GP PowerPC processor using the
   toolchain from MonteVista for Hardhat Linux.
 
   (begin script)
 
#!  /bin/sh
 
   export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
   export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
   export AR=ppc_405-ar
   export AS=ppc_405-as
   export LD=ppc_405-ld
   export RANLIB=ppc_405-ranlib
   export CC=ppc_405-gcc
   export NM=ppc_405-nm
 
   ./configure --target=powerpc-hardhat-linux

               --host=powerpc-hardhat-linux

               --build=i586-pc-linux-gnu

               --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local

               --exec-prefix=/usr/local
 
   (end script)
 
   You may also need to provide a parameter like '--with-random=/dev/urandom'
   to configure as it cannot detect the presence of a random number
   generating device for a target system.  The '--prefix' parameter
   specifies where cURL will be installed.  If 'configure' completes
   successfully, do 'make' and 'make install' as usual.
 
   In some cases, you may be able to simplify the above commands to as
   little as:
 
       ./configure --host=ARCH-OS
 
   There are a number of configure options that can be used to reduce the
   size of libcurl for embedded applications where binary size is an
   important factor.  First, be sure to set the CFLAGS environment variable
   when configuring with any compiler optimization flags to reduce the
   size of the binary.  For gcc, this would mean at minimum:
 
      env CFLAGS='-Os' ./configure ...
 
   Be sure to specify as many --disable- and --without- flags on the configure
   command-line as you can to disable all the libcurl features that you
   know your application is not going to need.  Besides specifying the
   --disable-PROTOCOL flags for all the types of URLs your application
   will not use, here are some other flags that can reduce the size of the
   library:
 
     --disable-ares (disables support for the ARES DNS library)
     --disable-cookies (disables support for HTTP cookies)
     --disable-crypto-auth (disables HTTP cryptographic authentication)
     --disable-ipv6 (disables support for IPv6)
     --disable-verbose (eliminates debugging strings and error code strings)
     --without-libidn (disables support for the libidn DNS library)
     --without-ssl (disables support for SSL/TLS)
     --without-zlib (disables support for on-the-fly decompression)
 
   You may find that statically linking libcurl to your application will
   result in a lower total size.
 
 
PORTS
=====
   This is a probably incomplete list of known hardware and operating systems
   that curl has been compiled for. If you know a system curl compiles and
   runs on, that isn't listed, please let us know!
 
        - Alpha DEC OSF 4
        - Alpha Digital UNIX v3.2
        - Alpha FreeBSD 4.1, 4.5
        - Alpha Linux 2.2, 2.4
        - Alpha NetBSD 1.5.2
        - Alpha OpenBSD 3.0
        - Alpha OpenVMS V7.1-1H2
        - Alpha Tru64 v5.0 5.1
        - HP-PA HP-UX 9.X 10.X 11.X
        - HP-PA Linux
        - HP3000 MPE/iX
        - MIPS IRIX 6.2, 6.5
        - MIPS Linux
        - Pocket PC/Win CE 3.0
        - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
        - PowerPC Darwin 1.0
        - PowerPC Linux
        - PowerPC Mac OS 9
        - PowerPC Mac OS X
        - SINIX-Z v5
        - Sparc Linux
        - Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
        - Sparc SunOS 4.1.X
        - StrongARM (and other ARM) RISC OS 3.1, 4.02
        - StrongARM/ARM7/ARM9 Linux 2.4, 2.6
        - StrongARM NetBSD 1.4.1
        - Ultrix 4.3a
        - i386 BeOS
        - i386 DOS
        - i386 Esix 4.1
        - i386 FreeBSD
        - i386 HURD
        - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
        - i386 NetBSD
        - i386 Novell NetWare
        - i386 OS/2
        - i386 OpenBSD
        - i386 SCO unix
        - i386 Solaris 2.7
        - i386 Windows 95, 98, ME, NT, 2000, XP, 2003
        - i386 QNX 6
        - i486 ncr-sysv4.3.03 (NCR MP-RAS)
        - ia64 Linux 2.3.99
        - m68k AmigaOS 3
        - m68k Linux
        - m68k OpenBSD
        - m88k dg-dgux5.4R3.00
        - s390 Linux
        - XScale/PXA250 Linux 2.4

 

这个文章给了我很大的启发,于是我参考它,在下载并解压libdnet 1.11之后,写了如下的脚本以编译libdnet

 

[jiangsy@MontaVista libdnet-1.11]$ ./configure CC=ppc_85xx-gcc RANLIB=ppc_85xx-ranlib CPP=ppc_85xx-cpp AR=ppc_85xx-ar AS=ppc_85xx-as STRIP=ppc_85xx-strip LD=ppc_85xx-ld CXX=ppc_85xx-c++ GXX=ppc_85xx-g++ --prefix=/opt/montavista/pro/devkit/ppc/85xx/target/usr/local/ --host= ppc_85xx

configure: WARNING: If you wanted to set the --build type, don't use --host.

    If a cross compiler is detected then cross compile mode will be used.

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking for gawk... gawk

checking whether make sets $(MAKE)... yes

checking for powerpc-ppc85xx-linux 2.4.20 -strip... ppc_85xx-strip

checking whether to enable maintainer-specific portions of Makefiles... no

checking build system type... i686-pc-linux-gnu

checking host system type... powerpc-ppc85xx-linux-gnu 2.4.20

checking for powerpc-ppc85xx-linux 2.4.20 -gcc... ppc_85xx-gcc

checking for C compiler default output file name... configure: error: C compiler cannot create executables

See `config.log' for more details.

[jiangsy@MontaVista libdnet-1.11]$

 

这个脚本中的好几个地方是学来的,例如“--prefix”这个选项,我知道应该设定为交叉编译toolchain工具链中的“/target/usr/local”目录,这里就是“/opt/montavista/pro/devkit/ppc/85xx/target/usr/local/”。

从脚本运行的Warning提示我们可以看出,Autoconf支持了cross-compile概念,通过“--build”,“--host”以及“--target”等选项帮助cross compile

值得一提的是一开始学习搬用“--target”和“--host”这两个选项的时候,之前我一直不知道该怎么写,于是我自作主张,使用“ppc_85xx-gcc”的前缀“ppc_85xx”作为值,因为我发现“STRIP”这个工具需要使用“--host”的值作为前缀。结果出现了“machine `ppc_85xx' not recognized”错误。于是我又参考上文,将“--host”设定为“powerpc-ppc85xx-linux 2.4.20 ”,我只是生搬硬套,同时将linux版本号改成我们的ICM 3G 使用的2.4.20而已。解决了这个问题,而且,“./configure”之后,编译系统得出了“powerpc-ppc85xx-linux-gnu2. 4.20 这个信息,我很奇怪它怎么得到的

 

export PATH=$PATH:/opt/montavista/pro/devkit/ppc/85xx/bin/

export CPPFLAGS="/opt/montavista/pro/devkit/ppc/85xx/include/"

export AR=ppc_85xx-ar

export AS=ppc_85xx-as

export LD=ppc_85xx-ld

export RANLIB=ppc_85xx-ranlib

export CC=ppc_85xx-gcc

export NM=ppc_85xx-nm

export CPP=ppc_85xx-cpp

export CXX=ppc_85xx-c++

export GXX=ppc_85xx-g++

export STRIP=ppc_85xx-strip

 

./configure --target=powerpc-ppc85xx-linux2.4.20 /

            --host=powerpc-ppc85xx-linux 2.4.20 /

            --build=i686-pc-linux-gnu /

            --prefix=/opt/montavista/pro/devkit/ppc/85xx/target/usr/local/ /

            --exec-prefix=/usr/local

 

这里我换了一种写法,把“export”语句独立出来了,具体的参考文档已经无处寻觅了。

另外,对于“STRIP”的问题,系统自动使用“--host”的值去试图使用“powerpc-ppc85xx-linux 2.4.20 -strip”,虽然不会中断“./configure”进程,但是会出现“no”的提示。如果设定了“STRIP=ppc_85xx-strip”,就可以解决问题。这里“--target”选项删除了,也不会影响编译。

这个脚本的执行结果出现了错误“checking for C compiler default output file name... configure: error: C compiler cannot create executables”。通过查看“config.log”,发现了如下的语句:

 

configure:2337: checking for C compiler default output file name

configure:2340: ppc_85xx-gcc  /opt/montavista/pro/devkit/ppc/85xx/include/  conftest.c  >&5

/opt/montavista/pro/devkit/ppc/85xx/include/: file not recognized: Is a directory

collect2: ld returned 1 exit status

configure:2343: $? = 1

configure: failed program was:

| /* confdefs.h.  */

|

| #define PACKAGE_NAME ""

| #define PACKAGE_TARNAME ""

| #define PACKAGE_VERSION ""

| #define PACKAGE_STRING ""

| #define PACKAGE_BUGREPORT ""

| #define PACKAGE "libdnet"

| #define VERSION "1.11"

| /* end confdefs.h.  */

|

| int

| main ()

| {

|

|   ;

|   return 0;

| }

configure:2382: error: C compiler cannot create executables

See `config.log' for more details.

我看了之后,把“export CPPFLAGS="/opt/montavista/pro/devkit/ppc/85xx/include/"”修改成“export CPPFLAGS=”,空的,就解决了。而且最后编译成功了。

所以最后的可用的最小命令集合就是:

 

export PATH=$PATH:/opt/montavista/pro/devkit/ppc/85xx/bin/

export CPPFLAGS=

export AR=ppc_85xx-ar

export AS=ppc_85xx-as

export LD=ppc_85xx-ld

export RANLIB=ppc_85xx-ranlib

export CC=ppc_85xx-gcc

export NM=ppc_85xx-nm

export CPP=ppc_85xx-cpp

export CXX=ppc_85xx-c++

export GXX=ppc_85xx-g++

export STRIP=ppc_85xx-strip

 

./configure --host=powerpc-ppc85xx-linux2.4.20 /

            --build=i686-pc-linux-gnu /

            --prefix=/opt/montavista/pro/devkit/ppc/85xx/target/usr/local/ /

            --exec-prefix=/usr/local

这些其实就是交叉编译比普通linux上编译的多余的步骤。我这里姑且称他们为“PPC交叉编译前奏”。

 

最后的输出,虽然比较多,但是也摘录下来,可以做参考。如下:

 

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking for gawk... gawk

checking whether make sets $(MAKE)... yes

checking for powerpc-ppc85xx-linux 2.4.20 -strip... ppc_85xx-strip

checking whether to enable maintainer-specific portions of Makefiles... no

checking build system type... i686-pc-linux-gnu

checking host system type... powerpc-ppc85xx-linux-gnu 2.4.20

checking for powerpc-ppc85xx-linux 2.4.20 -gcc... ppc_85xx-gcc

checking for C compiler default output file name... a.out

checking whether the C compiler works... yes

checking whether we are cross compiling... yes

checking for suffix of executables...

checking for suffix of object files... o

checking whether we are using the GNU C compiler... yes

checking whether ppc_85xx-gcc accepts -g... yes

checking for ppc_85xx-gcc option to accept ANSI C... none needed

checking for style of include used by make... GNU

checking dependency style of ppc_85xx-gcc... none

checking for a BSD-compatible install... /usr/bin/install -c

checking for a sed that does not truncate output... /bin/sed

checking for egrep... grep -E

checking for ld used by ppc_85xx-gcc... ppc_85xx-ld

checking if the linker (ppc_85xx-ld) is GNU ld... yes

checking for ppc_85xx-ld option to reload object files... -r

checking for BSD-compatible nm... ppc_85xx-nm

checking whether ln -s works... yes

checking how to recognise dependent libraries... pass_all

checking how to run the C preprocessor... ppc_85xx-cpp

checking for ANSI C header files... yes

checking for sys/types.h... yes

checking for sys/stat.h... yes

checking for stdlib.h... yes

checking for string.h... yes

checking for memory.h... yes

checking for strings.h... yes

checking for inttypes.h... yes

checking for stdint.h... yes

checking for unistd.h... yes

checking dlfcn.h usability... yes

checking dlfcn.h presence... yes

checking for dlfcn.h... yes

checking for powerpc-ppc85xx-linux 2.4.20 -ppc_85xx-g++... ppc_85xx-c++

checking whether we are using the GNU C++ compiler... no

checking whether ppc_85xx-c++ accepts -g... no

checking dependency style of ppc_85xx-c++... none

checking how to run the C++ preprocessor... /lib/cpp

checking for powerpc-ppc85xx-linux 2.4.20 -g77... no

checking for powerpc-ppc85xx-linux 2.4.20 -f77... no

checking for powerpc-ppc85xx-linux 2.4.20 -xlf... no

checking for powerpc-ppc85xx-linux 2.4.20 -frt... no

checking for powerpc-ppc85xx-linux 2.4.20 -pgf77... no

checking for powerpc-ppc85xx-linux 2.4.20 -fort77... no

checking for powerpc-ppc85xx-linux 2.4.20 -fl32... no

checking for powerpc-ppc85xx-linux 2.4.20 -af77... no

checking for powerpc-ppc85xx-linux 2.4.20 -f90... no

checking for powerpc-ppc85xx-linux 2.4.20 -xlf90... no

checking for powerpc-ppc85xx-linux 2.4.20 -pgf90... no

checking for powerpc-ppc85xx-linux 2.4.20 -epcf90... no

checking for powerpc-ppc85xx-linux 2.4.20 -f95... no

checking for powerpc-ppc85xx-linux 2.4.20 -fort... no

checking for powerpc-ppc85xx-linux 2.4.20 -xlf95... no

checking for powerpc-ppc85xx-linux 2.4.20 -ifc... no

checking for powerpc-ppc85xx-linux 2.4.20 -efc... no

checking for powerpc-ppc85xx-linux 2.4.20 -pgf95... no

checking for powerpc-ppc85xx-linux 2.4.20 -lf95... no

checking for powerpc-ppc85xx-linux 2.4.20 -gfortran... no

checking for g77... g77

checking whether we are using the GNU Fortran 77 compiler... yes

checking whether g77 accepts -g... yes

checking the maximum length of command line arguments... 32768

checking command to parse ppc_85xx-nm output from ppc_85xx-gcc object... ok

checking for objdir... .libs

checking for powerpc-ppc85xx-linux 2.4.20 -ar... ppc_85xx-ar

checking for powerpc-ppc85xx-linux 2.4.20 -ranlib... ppc_85xx-ranlib

checking for powerpc-ppc85xx-linux 2.4.20 -strip... (cached) ppc_85xx-strip

checking if ppc_85xx-gcc static flag  works... yes

checking if ppc_85xx-gcc supports -fno-rtti -fno-exceptions... no

checking for ppc_85xx-gcc option to produce PIC... -fPIC

checking if ppc_85xx-gcc PIC flag -fPIC works... yes

checking if ppc_85xx-gcc supports -c -o file.o... yes

checking whether the ppc_85xx-gcc linker (ppc_85xx-ld) supports shared libraries... yes

checking how to hardcode library paths into programs... immediate

checking whether stripping libraries is possible... yes

checking dynamic linker characteristics... GNU/Linux ld.so

checking for shl_load... no

checking for shl_load in -ldld... no

checking for dlopen... no

checking for dlopen in -ldl... yes

checking whether a program can dlopen itself... cross

checking if libtool supports shared libraries... yes

checking whether to build shared libraries... yes

checking whether to build static libraries... yes

configure: creating libtool

appending configuration tag "CXX" to libtool

checking whether the ppc_85xx-c++ linker (ppc_85xx-ld) supports shared libraries... yes

libtool.m4: error: problem compiling CXX test program

checking for ppc_85xx-c++ option to produce PIC...

checking if ppc_85xx-c++ supports -c -o file.o... no

checking whether the ppc_85xx-c++ linker (ppc_85xx-ld) supports shared libraries... yes

checking how to hardcode library paths into programs... immediate

checking whether stripping libraries is possible... yes

checking dynamic linker characteristics... GNU/Linux ld.so

checking for shl_load... (cached) no

checking for shl_load in -ldld... (cached) no

checking for dlopen... (cached) no

checking for dlopen in -ldl... (cached) yes

checking whether a program can dlopen itself... (cached) cross

appending configuration tag "F77" to libtool

checking if libtool supports shared libraries... yes

checking whether to build shared libraries... yes

checking whether to build static libraries... yes

checking for g77 option to produce PIC... -fPIC

checking if g77 PIC flag -fPIC works... yes

checking if g77 supports -c -o file.o... yes

checking whether the g77 linker (ppc_85xx-ld) supports shared libraries... yes

checking how to hardcode library paths into programs... immediate

checking whether stripping libraries is possible... yes

checking dynamic linker characteristics... GNU/Linux ld.so

checking for Python... checking for gethostbyname... yes

checking for socket... yes

checking for putmsg in -lstr... no

checking for open_mib in -lnm... no

checking for Check... no

checking for ANSI C header files... (cached) yes

checking fcntl.h usability... yes

checking fcntl.h presence... yes

checking for fcntl.h... yes

checking for unistd.h... (cached) yes

checking sys/bufmod.h usability... no

checking sys/bufmod.h presence... no

checking for sys/bufmod.h... no

checking sys/dlpi.h usability... no

checking sys/dlpi.h presence... no

checking for sys/dlpi.h... no

checking sys/dlpihdr.h usability... no

checking sys/dlpihdr.h presence... no

checking for sys/dlpihdr.h... no

checking sys/dlpi_ext.h usability... no

checking sys/dlpi_ext.h presence... no

checking for sys/dlpi_ext.h... no

checking sys/ioctl.h usability... yes

checking sys/ioctl.h presence... yes

checking for sys/ioctl.h... yes

checking sys/mib.h usability... no

checking sys/mib.h presence... no

checking for sys/mib.h... no

checking sys/ndd_var.h usability... no

checking sys/ndd_var.h presence... no

checking for sys/ndd_var.h... no

checking sys/socket.h usability... yes

checking sys/socket.h presence... yes

checking for sys/socket.h... yes

checking sys/sockio.h usability... no

checking sys/sockio.h presence... no

checking for sys/sockio.h... no

checking sys/sysctl.h usability... yes

checking sys/sysctl.h presence... yes

checking for sys/sysctl.h... yes

checking sys/time.h usability... yes

checking sys/time.h presence... yes

checking for sys/time.h... yes

checking net/bpf.h usability... yes

checking net/bpf.h presence... yes

checking for net/bpf.h... yes

checking net/if.h usability... yes

checking net/if.h presence... yes

checking for net/if.h... yes

checking net/if_var.h usability... no

checking net/if_var.h presence... no

checking for net/if_var.h... no

checking net/if_arp.h usability... yes

checking net/if_arp.h presence... yes

checking for net/if_arp.h... yes

checking net/if_dl.h usability... no

checking net/if_dl.h presence... no

checking for net/if_dl.h... no

checking net/pfilt.h usability... no

checking net/pfilt.h presence... no

checking for net/pfilt.h... no

checking net/pfvar.h usability... no

checking net/pfvar.h presence... no

checking for net/pfvar.h... no

checking net/radix.h usability... no

checking net/radix.h presence... no

checking for net/radix.h... no

checking net/raw.h usability... no

checking net/raw.h presence... no

checking for net/raw.h... no

checking net/route.h usability... yes

checking net/route.h presence... yes

checking for net/route.h... yes

checking netinet/in_var.h usability... no

checking netinet/in_var.h presence... no

checking for netinet/in_var.h... no

checking net/if_tun.h usability... no

checking net/if_tun.h presence... no

checking for net/if_tun.h... no

checking linux/if_tun.h usability... yes

checking linux/if_tun.h presence... yes

checking for linux/if_tun.h... yes

checking netinet/ip_fw.h usability... no

checking netinet/ip_fw.h presence... no

checking for netinet/ip_fw.h... no

checking linux/ip_fw.h usability... no

checking linux/ip_fw.h presence... no

checking for linux/ip_fw.h... no

checking linux/ip_fwchains.h usability... no

checking linux/ip_fwchains.h presence... no

checking for linux/ip_fwchains.h... no

checking linux/netfilter_ipv4/ipchains_core.h usability... no

checking linux/netfilter_ipv4/ipchains_core.h presence... yes

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h: present but cannot be compiled

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h:     check for missing prerequisite headers?

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h: see the Autoconf documentation

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h:     section "Present But Cannot Be Compiled"

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h: proceeding with the preprocessor's result

configure: WARNING: linux/netfilter_ipv4/ipchains_core.h: in the future, the compiler will take precedence

configure: WARNING:     ## ------------------------------------------ ##

configure: WARNING:     ## Report this to the AC_PACKAGE_NAME lists.  ##

configure: WARNING:     ## ------------------------------------------ ##

checking for linux/netfilter_ipv4/ipchains_core.h... yes

checking ip_fil_compat.h usability... no

checking ip_fil_compat.h presence... no

checking for ip_fil_compat.h... no

checking netinet/ip_fil_compat.h usability... no

checking netinet/ip_fil_compat.h presence... no

checking for netinet/ip_fil_compat.h... no

checking ip_compat.h usability... no

checking ip_compat.h presence... no

checking for ip_compat.h... no

checking netinet/ip_compat.h usability... no

checking netinet/ip_compat.h presence... no

checking for netinet/ip_compat.h... no

checking ip_fil.h usability... no

checking ip_fil.h presence... no

checking for ip_fil.h... no

checking netinet/ip_fil.h usability... no

checking netinet/ip_fil.h presence... no

checking for netinet/ip_fil.h... no

checking hpsecurity.h usability... no

checking hpsecurity.h presence... no

checking for hpsecurity.h... no

checking stropts.h usability... yes

checking stropts.h presence... yes

checking for stropts.h... yes

checking for an ANSI C-conforming const... yes

checking for inline... inline

checking for pid_t... yes

checking for size_t... yes

checking for sockaddr_in6 struct in <netinet/in.h>... yes

checking for sa_len in sockaddr struct... no

checking for arp_dev in arpreq struct... yes

checking for rt_msghdr struct in <net/route.h>... no

checking whether ppc_85xx-gcc needs -traditional... no

checking for working memcmp... no

checking for err... yes

checking for strlcat... no

checking for strlcpy... no

checking for strsep... yes

checking for Berkeley Packet Filter... no

checking for Linux proc filesystem... yes

checking for Linux PF_PACKET sockets... yes

checking for SNMP MIB2 STREAMS... no

checking for route(7) STREAMS... no

checking for arp(7) ioctls... yes

checking for raw IP sockets ip_{len,off} host byte ordering... no

checking for cooked raw IP sockets... no

configure: creating ./config.status

config.status: creating Makefile

config.status: creating dnet-config

config.status: creating include/Makefile

config.status: creating include/dnet/Makefile

config.status: creating man/Makefile

config.status: creating src/Makefile

config.status: creating python/Makefile

config.status: creating python/setup.py

config.status: creating test/Makefile

config.status: creating test/check/Makefile

config.status: creating test/dnet/Makefile

config.status: creating include/config.h

config.status: include/config.h is unchanged

config.status: executing depfiles commands

config.status: executing default commands

[root@MontaVista libdnet-1.11]#

 

然后再通过“make –s”,得到了最终的dnet库。输出如下:

 

[root@MontaVista libdnet-1.11]# make -s

Making all in include

Making all in dnet

Making all in man

Making all in src

mkdir .libs

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c addr-util.c  -fPIC -DPIC -o .libs/addr-util.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c addr-util.c -o addr-util.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c addr.c  -fPIC -DPIC -o .libs/addr.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c addr.c -o addr.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c blob.c  -fPIC -DPIC -o .libs/blob.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c blob.c -o blob.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip-util.c  -fPIC -DPIC -o .libs/ip-util.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip-util.c -o ip-util.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip6.c  -fPIC -DPIC -o .libs/ip6.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip6.c -o ip6.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c rand.c  -fPIC -DPIC -o .libs/rand.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c rand.c -o rand.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c memcmp.c  -fPIC -DPIC -o .libs/memcmp.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c memcmp.c -o memcmp.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c strlcat.c  -fPIC -DPIC -o .libs/strlcat.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c strlcat.c -o strlcat.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c strlcpy.c  -fPIC -DPIC -o .libs/strlcpy.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c strlcpy.c -o strlcpy.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c arp-ioctl.c  -fPIC -DPIC -o .libs/arp-ioctl.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c arp-ioctl.c -o arp-ioctl.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c eth-linux.c  -fPIC -DPIC -o .libs/eth-linux.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c eth-linux.c -o eth-linux.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c fw-ipchains.c  -fPIC -DPIC -o .libs/fw-ipchains.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c fw-ipchains.c -o fw-ipchains.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c intf.c  -fPIC -DPIC -o .libs/intf.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c intf.c -o intf.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip.c  -fPIC -DPIC -o .libs/ip.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c ip.c -o ip.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c route-linux.c  -fPIC -DPIC -o .libs/route-linux.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c route-linux.c -o route-linux.o >/dev/null 2>&1

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c tun-linux.c  -fPIC -DPIC -o .libs/tun-linux.o

 ppc_85xx-gcc -DHAVE_CONFIG_H -I. - I. -I../include -I../include -g -O2 -Wall -c tun-linux.c -o tun-linux.o >/dev/null 2>&1

ppc_85xx-gcc -shared  .libs/addr-util.o .libs/addr.o .libs/blob.o .libs/ip-util.o .libs/ip6.o .libs/rand.o .libs/memcmp.o .libs/strlcat.o .libs/strlcpy.o .libs/arp-ioctl.o .libs/eth-linux.o .libs/fw-ipchains.o .libs/intf.o .libs/ip.o .libs/route-linux.o .libs/tun-linux.o  -lc  -Wl,-soname -Wl,libdnet.1 -o .libs/libdnet. 1.0.1

(cd .libs && rm -f libdnet.1 && ln -s libdnet. 1.0.1 libdnet.1)

(cd .libs && rm -f libdnet && ln -s libdnet. 1.0.1 libdnet)

ppc_85xx-ar cru .libs/libdnet.a  addr-util.o addr.o blob.o ip-util.o ip6.o rand.o memcmp.o strlcat.o strlcpy.o arp-ioctl.o eth-linux.o fw-ipchains.o intf.o ip.o route-linux.o tun-linux.o

ppc_85xx-ranlib .libs/libdnet.a

creating libdnet.la

(cd .libs && rm -f libdnet.la && ln -s ../libdnet.la libdnet.la)

Making all in python

Making all in test

Making all in check

Making all in dnet

mkdir .libs

ppc_85xx-gcc -g -O2 -Wall -o .libs/dnet addr.o arp.o aton.o dnet.o eth.o fw.o hex.o icmp.o intf.o ip.o rand.o route.o send.o tcp.o udp.o  ../../src/.libs/libdnet -Wl,--rpath -Wl,/usr/local/lib

creating dnet

[root@MontaVista libdnet-1.11]#

 

可以通过“make distclean”清除所有的最终文件和中间文件。

最后的输出就是:

 

[root@MontaVista libdnet-1.11]# ll /home1/jiangsy/libdnet-1.11/src/.libs/libdnet.a

-rw-r--r--    1 root     root       170628 Sep 27 18:52 /home1/jiangsy/libdnet-1.11/src/.libs/libdnet.a

 

通过“ppc_85xx-objdump -d”导出的符号表可以看出具体的指令是属于PowerPC指令集的。如果我们直接采用x86-linuxgccmake进行编译,具体的“./configure”以及“make –s”的不同可以通过输出进行比较,参见pc.configure.txtppc.configure.txt。最终得到的libdnet.a为:

 

[root@MontaVista libdnet-1.11]# ll /home1/jiangsy/libdnet-1.11/src/.libs/libdnet.a

-rw-r--r--    1 root     root       519550 Sep 27 19:02 /home1/jiangsy/libdnet-1.11/src/.libs/libdnet.a

 

-rw-r--r--    1 root     root       309100 Sep 27 19:04 libdnet.sym.pc

-rw-r--r--    1 root     root       240750 Sep 27 19:04 libdnet.sym.ppc

 

X86-PCPowerPC不同的“./configure”输出记录:

 

符号表我就不嵌入进来了。不过应该都是完整的,因为我在两个符号表中都查找到了其中的一个函数。

 

两个libdnet.a的文件大小差别很大,到底会不会是交叉编译失败了呢?具体的回答,只能在以后使用的时候做解答了。不过两者的符号表大小相差不大。

我这些是通过“su”到“root”用户执行的。

 

编译libdnet成功之后,我有信心重新去交叉编译(cross compilepython 2.5.1 了。我使用跟上面一样的命令集合,结果还是出现了下面的错误:

 

checking for %zd printf() format support... configure: error: cannot run test program while cross compiling

See `config.log' for more details.

[root@MontaVista Python- 2.5.1 ]#

 

我开始寻找原因。在“./configure”文件中我发现如下代码段:

 

if test "$cross_compiling" = yes; then

  { { echo "$as_me:$LINENO: error: catttnnot run test program while cross compiling

See /`config.log' for more details." >&5

echo "$as_me: error: cannot run test program while cross compiling

See /`config.log' for more details." >&2;}

   { (exit 1); exit 1; }; }

else

 

这一段代码段的意思很明显,就是如果“$cross_compiling”=yes”,就要执行“exit 1”。也就是说对于交叉编译,肯定是做不下去了。这是怎么回事呢?

我想来想去,觉得先把这段代码删除试试。于是就变成这样:

 

echo "$as_me:$LINENO: checking for %zd printf() format support" >&5

echo $ECHO_N "checking for %zd printf() format support... $ECHO_C" >&6

if test "$cross_compiling" = yes; then

  { { echo "$as_me:$LINENO: error: catttnnot run test program while cross compiling

See /`config.log' for more details." >&5

echo "$as_me: error: cannot run test program while cross compiling

See /`config.log' for more details." >&2;}

   }

就是直接把“(exit 1); exit 1; };”删除了。注意这里的“;”都不要留下来。

 

然后重新执行ppc的交叉编译前奏,跳过了那一步之后,竟然通过了!于是,我又开始执行“make –s”,中间出现了很多warning,部分摘录如下:

 

./Modules/_codecsmodule.c:555: warning: dereferencing type-punned pointer will break strict-aliasing rules

./Modules/zipimport.c: In function `initzipimport':

./Modules/zipimport.c:1181: warning: dereferencing type-punned pointer will break strict-aliasing rules

./Modules/xxsubtype.c: In function `initxxsubtype':

./Modules/xxsubtype.c:292: warning: dereferencing type-punned pointer will break strict-aliasing rules

./Modules/xxsubtype.c:297: warning: dereferencing type-punned pointer will break strict-aliasing rules

libpython2.5.a(posixmodule.o)(.text+0x51e4): In function `posix_tmpnam':

./Modules/posixmodule.c:6850: warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'

libpython2.5.a(posixmodule.o)(.text+0x 50f 4): In function `posix_tempnam':

./Modules/posixmodule.c:6805: warning: the use of `tempnam' is dangerous, better use `mkstemp'

 

不过一直都没有中断,直到最后,出现了“./python: cannot execute binary file”,退出了编译。

 

/bin/sh: line 1: ./python: cannot execute binary file

make: *** [sharedmods] Error 126

[root@MontaVista Python- 2.5.1 ]# ll

 

一开始我以为“真的”出错了,但是立刻我就想起来,我们编译出来的最终python可执行程序是在PowerPC/linux上才能跑的,现在在x86/linux上,当然不能跑!于是我认为已经成功了!只要输出就好了!于是赶紧“ll”以下当前目录,果然,看到了“python”和“libpython2.5.a”(就这两个输出是同一个时间的)两个最新的文件!!!:

 

[jiangsy@MontaVista Python- 2.5.1 ]$ ll *python*

-rw-r--r--    1 root     root      4814512 Sep 27 19:20 libpython2.5.a

-rwxr-xr-x    1 root     root      3014140 Sep 27 19:20 python

 

我把着两个文件TFTP bin模式上传到ICM 3G 上面,使用“bash -2.05a # chmod a+x python”修改了属性,然后尝试运行。天哪!成功了!!!!!!

 

bash -2.05a # ./python

Could not find platform independent libraries <prefix>

Could not find platform dependent libraries <exec_prefix>

Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]

'import site' failed; use -v for traceback

Python 2.5.1 (r251:54863, Sep 27 2007, 19:20:03)

[GCC 3.4.1 (MontaVista 3.4.1-2.0.16.0501116 2005-07-21 )] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> a=2

>>> a

2

>>> a=3

>>> a

3

>>>

>>>

>>>  

 

此时此刻,我能说什么呢?我太激动了。程序员的要求,原来就是如此而已啊!如果编译失败,今晚肯定很难睡着觉了。可是现在,竟然成功了,可是我还是很难睡着觉吧?这几天一直失眠,这是一个原因;另一个原因,我太激动了!我还能睡得着吗?后面还会有多少问题呢?而且,我为之奋斗了一个下午,加上黄昏到现在,我总算有个成果了。想想工作近七年,有多少天是面对失败而失眠!

19:33

 
<think>我们正在讨论的是在编译U-Boot时使用的`make`命令中的`CROSS_COMPILE`参数。根据用户的问题,他想要理解`CROSS_COMPILE`参数的作用及其在交叉编译中的意义,特别是针对`aarch64-linux-gnu-`工具链。 参考引用: - 引用[1]详细解释了`export CROSS_COMPILE=aarch64-none-linux-gnu-`的作用:设置交叉编译工具链的前缀,使得构建系统能够找到正确的工具(如编译器、链接器等)。 - 引用[2]和[3]提供了实际使用`CROSS_COMPILE`的例子,包括在ATF(ARM Trusted Firmware)和FFmpeg的交叉编译中。 ### 1. `CROSS_COMPILE`参数的作用 `CROSS_COMPILE`是`make`命令的一个环境变量(或直接作为参数传递给`make`),用于指定交叉编译工具链的前缀。它的主要作用是告诉构建系统,在编译过程中使用的工具(如`gcc`、`ld`、`objcopy`等)都是针对目标平台(例如ARM64)的交叉编译工具,而不是本机(例如x86_64)的工具。 #### 工作方式 - 当设置`CROSS_COMPILE=aarch64-linux-gnu-`时,构建系统会: - 将`gcc`替换为`aarch64-linux-gnu-gcc` - 将`ld`替换为`aarch64-linux-gnu-ld` - 将`objcopy`替换为`aarch64-linux-gnu-objcopy` - 其他工具类似。 这样,编译出的二进制文件就是目标架构(这里是ARM64)的可执行文件,而不是主机架构(如x86_64)的文件。 ### 2. 为什么需要交叉编译? 在嵌入式开发中,目标设备(如路由器、手机)通常使用ARM、MIPS等架构的处理器,而开发主机通常是x86架构。因此,我们需要在x86主机上编译出能在ARM等架构上运行的代码,这就是交叉编译。 ### 3. 如何设置`CROSS_COMPILE`? 有两种常见方式: 1. **通过环境变量设置**(在运行`make`之前): ```bash export CROSS_COMPILE=aarch64-linux-gnu- make ``` 2. **直接作为`make`参数传递**(如用户示例): ```bash make CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- ``` 注意:这里传递的路径前缀(如`/usr/bin/`)必须包含交叉编译工具链的可执行文件。实际上,如果工具链已经在`PATH`中,通常只需要提供前缀(如`aarch64-linux-gnu-`)即可,因为构建系统会自动在`PATH`中查找。但如果工具链不在`PATH`中,或者有多个版本,可以指定完整路径(如引用[3]和[5]所示)。 ### 4. 工具链的安装 在Ubuntu系统中,可以通过包管理器安装`aarch64-linux-gnu`工具链: ```bash sudo apt update sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu ``` 安装后,工具链的可执行文件通常位于`/usr/bin/`目录下,文件名为`aarch64-linux-gnu-gcc`、`aarch64-linux-gnu-ld`等。因此,设置`CROSS_COMPILE=aarch64-linux-gnu-`即可。 ### 5. 在U-Boot编译中的具体应用 用户提供的命令: ```bash cd uboot-mtk-20240807/ make mt7981_spim_nand_rfb_defconfig make CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- ``` - 第一行:进入U-Boot源代码目录。 - 第二行:应用针对MT7981芯片(SPI-NAND闪存)的默认配置。 - 第三行:使用交叉编译工具链编译U-Boot,其中`CROSS_COMPILE`指定了工具链的前缀为`/usr/bin/aarch64-linux-gnu-`(注意:这里指定了完整路径前缀,但通常只需要前缀`aarch64-linux-gnu-`,因为`/usr/bin`已经在`PATH`中)。 ### 6. 注意事项 - **路径分隔符**:在指定`CROSS_COMPILE`时,如果使用完整路径,需要确保路径以`/`结尾(如`/path/to/toolchain/bin/aarch64-linux-gnu-`),因为构建系统会直接拼接工具名(如`gcc`)到后面。 - **环境变量优先级**:如果同时设置了环境变量`CROSS_COMPILE`和命令行参数,命令行参数优先级更高。 - **工具链版本**:确保安装的工具链版本与目标平台兼容。 ### 7. 示例:工具链路径解析 假设交叉编译工具链安装在`/opt/toolchain/bin/`目录下,工具链前缀为`aarch64-linux-gnu-`,则: ```bash make CROSS_COMPILE=/opt/toolchain/bin/aarch64-linux-gnu- ``` 构建系统会调用: - 编译器:`/opt/toolchain/bin/aarch64-linux-gnu-gcc` - 链接器:`/opt/toolchain/bin/aarch64-linux-gnu-ld` ### 总结 `CROSS_COMPILE`参数在交叉编译中至关重要,它指定了目标平台工具链的前缀,使得构建系统能够使用正确的工具编译出目标平台的二进制文件。对于ARM64架构,常用的工具链前缀是`aarch64-linux-gnu-`。 --- §§ 相关问题 §§ 1. 如何验证交叉编译生成的U-Boot二进制文件是否针对ARM64架构? 2. 交叉编译工具链中的`aarch64-linux-gnu-gcc`和`gcc`有何区别? 3. 在哪些情况下需要指定完整的工具链路径而不仅仅是前缀? 4. 如何为不同的目标架构(如ARM32、MIPS)选择正确的交叉编译工具链? > 参考文献: > [^1]: `CROSS_COMPILE` 环境变量详解 > [^2]: ATF 编译中 `CROSS_COMPILE` 的使用示例 > [^3]: FFmpeg 交叉编译中指定工具链路径的示例</think>### `CROSS_COMPILE` 参数在交叉编译中的作用解析 `CROSS_COMPILE` 是 `make` 命令的关键参数,用于指定交叉编译工具链的前缀。它在嵌入式开发和跨平台编译中至关重要,特别是在为 ARM64 架构(如 `aarch64-linux-gnu-`)编译时。以下是详细解析: --- #### 一、核心作用:**指定目标平台工具链** 1. **交叉编译的本质** 在主机(如 x86 PC)上编译目标平台(如 ARM64 设备)的代码时,需要使用目标平台的专用工具链。 `CROSS_COMPILE` 定义了工具链的可执行文件前缀,使构建系统自动组合完整命令: $$ \text{实际调用命令} = \text{CROSS\_COMPILE} + \text{工具名} $$ 2. **示例解析** ```bash make CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- ``` - 编译器调用:`aarch64-linux-gnu-gcc` - 链接器调用:`aarch64-linux-gnu-ld` - 二进制处理:`aarch64-linux-gnu-objcopy` > 构建系统自动将前缀与工具名拼接[^1][^2]。 --- #### 二、参数格式详解 | 格式类型 | 示例 | 适用场景 | |---------|------|---------| | **仅前缀** | `aarch64-linux-gnu-` | 工具链已加入 `PATH` 环境变量 | | **完整路径+前缀** | `/opt/toolchain/bin/aarch64-linux-gnu-` | 工具链在自定义目录[^3][^5] | | **环境变量形式** | `export CROSS_COMPILE=...` | 需在多个 `make` 命令间共享配置[^1][^2] | > **关键规则**:路径必须以 `/` 结尾(如 `/usr/bin/`),前缀必须以 `-` 结尾(如 `aarch64-linux-gnu-`)。 --- #### 三、`aarch64-linux-gnu-` 工具链的意义 1. **目标架构标识** - `aarch64`:ARMv8 64 位架构(如 Cortex-A53/A72) - `linux-gnu`:目标系统为 Linux + GNU C 库(glibc) 2. **工具链组件** ```mermaid graph LR A[aarch64-linux-gnu-gcc] -->|编译器| B[C代码→ARM64机器码] A[aarch64-linux-gnu-gcc] -->|调用| C[aarch64-linux-gnu-ld] D[aarch64-linux-gnu-objcopy] -->|生成二进制文件| E[.bin/.hex] ``` 3. **安装方法** Ubuntu/Debian 系统: ```bash sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu ``` 安装后工具链路径通常为 `/usr/bin/aarch64-linux-gnu-*`[^4]。 --- #### 四、实际应用场景 1. **U-Boot 编译(用户案例)** ```bash # 配置 make mt7981_spim_nand_rfb_defconfig # 编译(指定 ARM64 工具链) make CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- ``` - 生成 ARM64 架构的 `u-boot.bin`,可在 MT7981 路由器芯片运行 2. **FFmpeg 交叉编译** ```bash ./configure \ --cross-prefix=/opt/toolchain/bin/aarch64-linux-gnu- \ --cc=aarch64-linux-gnu-gcc \ --arch=arm64 ``` 生成 ARM64 平台的 FFmpeg 可执行文件[^3][^5] --- #### 五、常见错误处理 1. **工具链未找到** ```bash make: aarch64-linux-gnu-gcc: Command not found ``` **解决**: - 检查路径是否正确:`ls /usr/bin/aarch64-linux-gnu-gcc` - 确认工具链已安装:`apt list --installed | grep gcc-aarch64` 2. **前缀格式错误** ```bash make: /usr/bin/aarch64-linux-gnu-gcc: invalid option ``` **解决**:确保参数格式为: ```bash make CROSS_COMPILE=/usr/bin/aarch64-linux-gnu- # 结尾有短横线 ``` --- ### 总结 `CROSS_COMPILE` 通过定义工具链前缀实现了: 1. **平台隔离**:在 x86 主机上生成 ARM64 二进制 2. **构建自动化**:自动拼接工具命令(`${CROSS_COMPILE}gcc`) 3. **灵活配置**:支持自定义工具链路径 > 在嵌入式 Linux 开发中(如 U-Boot、内核、FFmpeg),正确设置 `CROSS_COMPILE` 是跨平台编译的基础[^1][^2][^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值