交叉编译的三个参数:sysroot和DESTDIR、prefix

本文深入探讨了在交叉编译环境中,DESTDIR和sysroot的作用及用法,解释了它们如何帮助解决编译时路径与运行时路径不一致的问题,为开发者提供了实用的解决方案。

       软件编译过程中用到指定路径的头文件、链接指定路径的库,软件运行过程中需要在该指定路径下寻找相应资源。如gcc指定在/usr/include目录查找头文件,binutils中提供的ld命令从/lib、/usr/lib、LD_LIBRARY_PATH、/etc/ld.so.conf等指定路径进行共享库和静态库连接。交叉编译时需要在本地系统进行编译,而编译出的软件在目标系统运行,这就存在编译时指定的路径和运行时的路径不一致的矛盾。DESTDIR和sysroot配合用于解决这个问题。

       1、sysroot用于交叉编译工具的制作

       sysroot仅在交叉编译工具链用到的工具中使用,如binutils、gcc。


       2、DESTDIR、prefix用于目标系统软件的安装

       DESTDIR添加在prefix前,指定软件的安装位置。


       3、关于prefix在交叉编译工具制作中的说明

       交叉编译工具制作中,在配置时应用的prefix选项是指定生成的交叉编译工具安装在本机的路径,于后序使用交叉编译工具编辑目标系统的软件的安装路径无关。


       本文在阅读clfs、孙海勇《手把手教你制作自己的Linux系统》以及网络上相关文献的基础上写出。未完,待完善。

交叉编译 Nginx 是指在一个平台上(如 x86_64 的 Linux)编译出能在另一个平台(如 ARM 架构的嵌入式设备)上运行的 Nginx 可执行文件。这在嵌入式系统开发中非常常见,比如为路由器、IoT 设备等构建 Nginx。 以下是详细步骤示例代码来交叉编译 Nginx: --- ### ✅ 一、准备工作 #### 1. 安装依赖工具 确保主机系统已安装以下工具: - `build-essential`(或对应开发包) - `autoconf`, `automake`, `libtool` - 交叉编译工具链(例如针对 ARM) ```bash # Ubuntu/Debian 示例 sudo apt update sudo apt install build-essential autoconf automake libtool ``` #### 2. 下载 Nginx 源码 ```bash wget http://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 ``` #### 3. 获取交叉编译工具链(以 ARM 为例) 假设你使用的是 GNU 的 ARM 工具链: ```bash # 安装 ARM 交叉编译器(适用于大多数 ARMv7 设备) sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf ``` 验证是否可用: ```bash arm-linux-gnueabihf-gcc --version ``` --- ### ✅ 二、配置并交叉编译 Nginx Nginx 使用 `auto` 脚本系统进行构建,不支持标准的 `./configure --host=...` 方式,因此需要手动修改其 `Makefile` 生成逻辑。 #### 编辑 `auto/cc/name` 文件(防止编译器检测失败) 编辑 `auto/cc/name`,注释掉输出编译器名称的部分,避免 configure 报错: ```bash vim auto/cc/name ``` 将内容改为: ```bash # echo $0 > $NGX_OBJS/ngx_auto_cc_log ``` #### 运行 configure 并指定交叉编译环境变量 ```bash CC=arm-linux-gnueabihf-gcc \ CXX=arm-linux-gnueabihf-g++ \ AR=arm-linux-gnueabihf-ar \ RANLIB=arm-linux-gnueabihf-ranlib \ ./configure \ --crossbuild=Linux::aarch64::unknown \ --prefix=/opt/nginx-arm \ --with-cc=arm-linux-gnueabihf-gcc \ --with-cpp=arm-linux-gnueabihf-cpp \ --with-cc-opt="-march=armv7-a" \ --without-http_rewrite_module \ --without-http_gzip_module \ --without-pcre \ --without-http_ssl_module \ --without-http_proxy_module \ --without-http_fastcgi_module \ --without-http_uwsgi_module \ --without-http_scgi_module \ --without-http_memcached_module \ --without-http_empty_gif_module \ --without-http_browser_module \ --without-http_geo_module \ --without-http_map_module \ --without-http_split_clients_module \ --without-http_referer_module \ --without-http_limit_conn_module \ --without-http_limit_req_module \ --without-http_auth_basic_module \ --without-http_access_module \ --without-http_realip_module \ --without-http_addition_module \ --without-http_degradation_module \ --without-http_flv_module \ --without-http_mp4_module \ --without-http_sub_module \ --without-http_slice_module \ --without-mail_pop3_module \ --without-mail_imap_module \ --without-mail_smtp_module \ --without-http_upstream_ip_hash_module \ --without-http_upstream_least_conn_module \ --without-http_upstream_keepalive_module \ --without-http_upstream_zone_module \ --without-threads \ --without-select_module \ --without-poll_module \ --without-kqueue_module \ --without-eventport_module \ --without-file_aio \ --without-http_dav_module \ --without-http_ssi_module ``` > 💡 **说明**: > - `--crossbuild` 告诉 Nginx 构建系统这是跨平台编译。 > - `--with-cc` 指定使用的交叉编译器。 > - 禁用大量模块是为了减少依赖(如 PCRE、OpenSSL),简化交叉编译过程。 > - 如果你需要 HTTPS 支持,需交叉编译 OpenSSL PCRE 库,并链接它们。 #### 手动修复 Makefile(关键步骤) 由于 Nginx 的 auto 系统不会自动处理交叉编译时的目标架构判断,生成的 `Makefile` 中可能仍包含 `$(CC)` 直接调用本地编译器。 打开生成的 `objs/Makefile`,搜索并替换所有 `gcc` 为 `arm-linux-gnueabihf-gcc`,或者更安全地确保所有 `$(CC)` 都正确指向交叉编译器。 也可以通过 patching `auto/tools/gcc` 来固化 CC 设置。 --- ### ✅ 三、开始编译 ```bash make -j$(nproc) ``` 如果成功,会在 `objs/` 目录下生成 `nginx` 可执行文件。 检查是否为 ARM 架构: ```bash file objs/nginx ``` 输出应类似: ``` objs/nginx: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, ... ``` 表示是 ARM 架构程序。 --- ### ✅ 四、部署到目标设备 将整个 `objs` 或安装目录打包: ```bash make DESTDIR=/tmp/nginx-arm-root install ``` 然后将 `/tmp/nginx-arm-root/opt/nginx-arm` 复制到 ARM 设备上运行即可。 --- ### ✅ 补充:静态编译(可选,避免依赖问题) 若想生成静态链接版本(避免目标机缺少 libc 等库),可在 configure 时加上: ```bash --with-cc-opt="-static" --with-ld-opt="-static" ``` 但注意某些模块无法静态编译,建议最小化功能。 --- ### ✅ 注意事项 1. **第三方模块**:如果有第三方模块(如 Lua 模块),也需要交叉编译对应的库。 2. **依赖库**:PCRE、zlib、OpenSSL 都需要先交叉编译,并通过 `--with-pcre=...` 指定路径。 3. **目标系统头文件**:有时需要为目标平台提供 sysroot(即完整的 rootfs 包含 `/usr/include` 等)。 --- ### 示例完整命令汇总 ```bash # 设置环境变量 export CC=arm-linux-gnueabihf-gcc export CXX=arm-linux-gnueabihf-g++ export AR=arm-linux-gnueabihf-ar export RANLIB=arm-linux-gnueabihf-ranlib # 修改 auto/cc/name 防止报错 sed -i 's|echo \$0 > $NGX_OBJS/ngx_auto_cc_log|#echo \$0 > $NGX_OBJS/ngx_auto_cc_log|' auto/cc/name # 配置 ./configure \ --prefix=/opt/nginx-arm \ --with-cc=$CC \ --with-cpp=arm-linux-gnueabihf-cpp \ --without-http_rewrite_module \ --without-http_gzip_module \ --without-pcre \ --without-http_ssl_module \ --crossbuild=Linux::x86_64::unknown # 编辑 objs/Makefile,确认所有 gcc 替换为 arm-linux-gnueabihf-gcc # 编译 make -j8 ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值