当前位置: 首页 > news >正文

Linux strip 命令 | 详解及在 Linaro 交叉编译工具链中的使用

注:本文为 “Linux strip” 相关合辑。
略作重排,未整理去重。
如有内容异常,请看原文。


一、strip 命令基础概述

1.1 命令用途

strip是 UNIX / Linux 环境下的文件精简工具,作用为去除 XCOFF(扩展公共对象文件格式)对象文件、可执行文件、库文件中的调试信息、冗余标识符与辅助段信息,在不影响文件正常运行的前提下,缩减文件存储体积。

该命令与compress等压缩工具存在功能差异:strip执行永久精简操作,处理后的文件不可恢复原始状态,无需解压即可直接运行;压缩工具处理后的文件必须完成解压操作后才可使用。strip仅适用于已完成调试、测试定稿的程序模块与发布版本文件。

1.2 工作原理

strip命令可对目标文件的冗余信息进行选择性剔除,默认清理范围包含行号信息、重定位信息、调试段、typchk段、注释段、文件头及部分符号表。

针对不同文件类型的处理规则:

  • 对象模块:根据指定参数精准剔除对应冗余信息。
  • 归档 / 库文件:直接清除归档内的全局符号表,可通过ar -s命令恢复归档文件的符号表。

1.3 GCC 编译关联特性

GCC 编译流程可实现与strip等效的精简效果,各项对应规则如下:

编译方式等价操作说明
编译去除-g参数--strip-debug仅剔除调试信息
直接执行strip命令--strip-debug+--strip-all剔除调试信息与全部符号信息,文件精简幅度更大
GCC 编译添加-s参数strip命令功能完全一致,可直接生成精简后的可执行文件

功能限制规则:静态库.a文件仅支持--strip-debug精简模式,无法完整剥离符号表;经过静态编译的程序不建议执行strip操作,该操作易引发链接异常。

二、strip 命令语法与参数详解

2.1 标准语法

strip [ -V ] [ -r [ -l ] | -x [ -l ] | -t | -H | -e | -E ] [ -X { 32 | 64 | 32_64 } ] [ -- ] File ...

2.2 完整参数说明

参数功能描述
-e在对象文件可选头中设置F_LOADONLY标志。若文件存入归档,该标志会告知ld绑定程序,链接时忽略该文件的符号信息。
-E复位关闭对象文件可选头中的F_LOADONLY位,抵消-e参数的设置效果。
-H剔除对象文件头、所有可选头及段头部分,保留符号表信息。
-l(小写 L)单独剔除对象文件中的源代码行号调试信息。
-r剔除绝大部分符号表信息,仅保留外部符号与静态符号条目;同时清除调试段、typchk段,保留重定位信息。处理后的文件仍可作为ld链接编辑器的输入文件。
-t剔除大部分符号表冗余信息,保留函数符号与行号信息。
-V打印strip命令的版本号信息。
-x剔除全部符号表信息,保留静态、外部符号标识;同步清除重定位信息,处理后的文件无法再次链接。
-X mode指定处理的对象文件位数类型,支持三种模式:32:仅处理 32 位对象文件(默认);64:仅处理 64 位对象文件;32_64:同时处理 32 位、64 位对象文件。可通过OBJECT_MODE环境变量默认配置,-X参数优先级高于环境变量。
--将后续所有参数解析为文件名,支持处理名称以连字符开头的特殊文件。

2.3 退出状态值

状态值执行结果
0命令执行成功
> 0命令执行出错

2.4 命令路径

不同系统与编译环境下,strip工具默认路径存在差异:AIX 系统默认路径为/usr/ccs/bin/strip;主流 Linux 系统(Ubuntu、CentOS)GNU 工具集默认路径为/usr/bin/strip;ARM 交叉编译链strip工具路径随工具链安装目录变动,位于工具链bin目录下。

三、strip 命令实操示例

3.1 基础精简可执行文件

剔除a.out默认可执行文件的符号表、行号及冗余调试信息:

strip a.out

3.2 剔除文件头部信息

移除a.out的对象文件头、可选头及段头信息:

strip-Ha.out

3.3 批量处理 32 / 64 位库文件

精简静态库lib.a中所有 32 位、64 位冗余符号信息:

strip-X32_64 lib.a

3.4 实际瘦身效果对比

通过编写基础测试程序,可直观验证strip对文件体积的精简效果:

#include<stdio.h>main(){printf("hello, world\n");}

使用cc编译源码后,原始文件大小为 46176 字节。执行strip处理后,文件体积缩减至 30648 字节,体积缩减比例超过1 / 3 1 / 31/3,处理后的程序可正常运行。

四、COFF 文件结构与 strip 作用区段

COFF(通用对象文件格式)是目标文件(.o)与可执行文件的通用存储格式。strip命令的精简操作可作用于 COFF 文件的指定区段,文件完整组成结构及对应区段属性如下:

区段名称功能说明
文件头(File header)存储文件基础通用信息,所有 COFF 文件默认包含,可通过strip部分参数剔除
扩展头(Optional header)仅存在于可执行文件,存储可执行程序专属信息,支持strip精简
区段头(Section header)记录所有文件区段的属性信息,每个区段对应一个独立区段头
原始数据区(Raw data sections)存储机器指令、初始化变量等业务数据,strip不会剔除该区域内容
重定位信息(Relocation information)存储跨模块符号引用信息,仅存在于目标文件,部分strip参数可剔除该信息
行号信息(Line number information)源码行号调试信息,编译带-g参数时生成,是strip主要精简对象
符号表(Symbol table)存储文件所有符号信息,未被strip处理的可执行文件默认保留
字符串表(String table)存储长度超过 8 字节的长符号名

五、strip 开发使用规范与注意事项

5.1 使用场景规范

  • 适用场景:已调试完成、功能稳定的可执行文件、发布版动态库,用于缩减程序体积、节省设备存储(嵌入式开发高频使用)。
  • 禁用场景:开发调试阶段文件、静态库文件、需要后续链接的目标文件。

5.2 开发最佳实践

为同时满足程序调试与版本发布的使用需求,可采用双文件保留方案:

  1. 保留未strip原始文件:用于线上问题定位、addr2line源码溯源、程序调试。
  2. 使用strip精简后文件:用于设备部署、版本发布,减小存储占用。

5.3 常见问题说明

  • 执行strip后文件体积无变化,表明当前文件已完成精简,不存在可剔除的冗余信息。
  • 经过strip处理的文件会移除全部调试符号,无法使用dbxaddr2line等工具完成程序调试与溯源工作。
  • strip默认操作会清除文件的.symbol符号段与.debug调试段,未完成定型测试的程序不建议执行该操作。

六、ARM 交叉编译工具链及配套工具使用

6.1 交叉编译概述

交叉编译用于适配编译环境与程序运行环境不匹配的开发场景,典型场景为在 x86 架构设备上完成程序编译,生成可在 ARM 架构硬件设备上运行的可执行文件,是嵌入式开发的常用编译方式。

6.2 交叉编译链安装配置

6.2.1 工具链下载地址
  • ARM 官方工具链 - Arm GNU Toolchain
    https://developer.arm.com/Tools and Software/GNU Toolchain
  • https://developer.arm.com/open-source/gnu-toolchain
  • Linaro 历史版本:Download Linaro Forge
    https://www.linaroforge.com/release-history
    https://www.linaroforge.com/download-forge-old-version
6.2.2 解压与环境变量配置

解压工具链至系统目录:

sudotar-xvfgcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz-C/opt

编辑环境变量文件,追加工具链路径:

vim~/.bashrc

文件末尾追加:

exportPATH=$PATH:/opt/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin

生效环境变量:

source~/.bashrc
6.2.3 依赖兼容处理

32 位工具链在 64 位系统运行时,需安装兼容依赖:

sudoapt-getinstallia32-libssudoapt-getinstalllibc6:i386sudoapt-getinstalllib32z1
6.2.4 工具链校验
arm-none-linux-gnueabihf-gcc-v

6.3 交叉编译工具集使用

嵌入式 ARM 开发常用工具集包含gccreadelfobjdumpsizenmaddr2lineobjcopystringsstrip,各工具的标准实操方式如下。

测试用例源码

#include<stdlib.h>#include<stdio.h>intg_val=12;intg_uninit;constchar*str="who am I?";staticchars_uninit;intmain(){printf("hello world!\n");int*p=malloc(sizeof(int));staticints_tmp=0;free(p);return0;}
6.3.1 gcc 编译工具

基础编译命令(带调试信息):

arm-none-linux-gnueabihf-gcc-gmain.c-omain

编译后文件状态(未精简):带调试信息、未剥离符号。

filemain

输出:

main: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
6.3.2 readelf 文件信息查看工具

该工具用于读取并展示 ELF 可执行文件的文件头部、区段分布、符号表等底层信息。

查看文件头部信息:

arm-none-linux-gnueabihf-readelf-hmain

查看所有区段头信息:

arm-none-linux-gnueabihf-readelf-Smain

查看文件符号地址:

arm-none-linux-gnueabihf-readelf-smain
6.3.3 objdump 反汇编工具

该工具用于完成文件反汇编操作,查看程序对应的汇编代码,多用于程序异常调试与代码逻辑分析。

arm-none-linux-gnueabihf-objdump-Dmain>main.txt
6.3.4 size 段大小查看工具

该工具用于快速统计可执行文件中textdatabss等区段的存储空间占用大小。

arm-none-linux-gnueabihf-size main
6.3.5 nm 符号查看工具

该工具用于输出文件内所有全局变量、静态变量、自定义函数的符号信息及属性标识。

arm-none-linux-gnueabihf-nm main

符号属性标识规则:小写字母代表局部符号,大写字母代表全局符号;T对应代码段、D对应初始化数据段、B对应未初始化 BSS 段、U对应未定义符号。

6.3.6 addr2line 源码溯源工具

该工具可通过程序内存地址反向匹配对应的源码文件与代码行号,是程序崩溃定位的常用工具。

arm-none-linux-gnueabihf-addr2line-emain-psfC0x10451
6.3.7 objcopy 文件格式转换工具

该工具可实现目标文件格式转换、自定义区段增减、调试信息分离等操作,常用命令如下:

# 转换为二进制裸机文件arm-none-linux-gnueabihf-objcopy-Obinary main main.bin# 分离调试信息arm-none-linux-gnueabihf-objcopy --only-keep-debug main main.debuginfo# 剔除调试信息arm-none-linux-gnueabihf-objcopy --strip-debug main main.stripdebug
6.3.8 strings 字符串查看工具

该工具用于提取可执行文件中所有可打印字符串,可用于查看程序内置的常量文本内容。

arm-none-linux-gnueabihf-strings main
6.3.9 交叉编译环境 strip 工具实操

ARM 交叉编译链内置的strip工具,可对嵌入式可执行文件进行精简处理,降低文件体积,减少设备 Flash 存储空间占用:

# 精简 ARM 可执行文件arm-none-linux-gnueabihf-strip main

文件处理前后体积对比:原始文件大小为 13116 字节,精简后文件大小为 5600 字节,文件体积缩减幅度明显。

6.4 Linaro aarch64 交叉编译工具链专项配置

6.4.1 软硬件环境参数

编译主机环境:x86_64 架构,Ubuntu 20.04 系统;目标运行环境:RK3588 设备,aarch64 架构,Ubuntu 20.04 系统,小端字节序模式。

6.4.2 工具链版本选择

本次适配开发场景选用 Linaro 7.5 稳定版本工具链,该版本兼容性强,适配多数嵌入式 Linux 设备开发场景,无特殊定制需求时,可选用对应系列最新稳定版本。

工具链官方下载主页:https://releases.linaro.org/components/toolchain/binaries/

6.4.3 目标平台版本分类选型

Linaro 工具链针对 aarch64 架构划分多种适配版本,对应不同运行场景,具体分类如下:

版本名称适用场景
aarch64-elf适配裸机嵌入式开发场景,无 Linux 系统依赖
aarch64-linux-gnu适配 aarch64 架构 Linux 系统开发场景,为常规嵌入式 Linux 开发通用版本
aarch64_be-elf大端字节序,适配裸机嵌入式开发场景
aarch64_be-linux-gnu大端字节序,适配 aarch64 架构 Linux 系统开发场景

本次 RK3588 aarch64 小端 Linux 设备开发,选用aarch64-linux-gnu版本工具链。

6.4.4 工具链文件解析与下载

aarch64-linux-gnu目录下包含三类配套文件,各文件功能定义如下:

文件名功能说明
gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz交叉编译工具包,集成 GCC 编译器、汇编器、链接器及各类配套调试、处理工具,用于在 x86_64 主机编译生成 aarch64 架构可执行文件
runtime-gcc-linaro-7.5.0-2019.12-aarch64-linux-gnu.tar.xz运行时依赖库包,包含目标设备运行程序所需的共享库文件
sysroot-glibc-linaro-2.25-2019.12-aarch64-linux-gnu.tar.xz系统根目录库文件包,包含目标平台 Glibc 标准库头文件、静态库与动态库文件,用于编译链接依赖系统库的程序

常规应用开发仅需下载编译工具包,完整下载地址:https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

6.4.5 工具链解压与目录结构

执行解压命令释放工具链文件:

tar-xvfgcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

解压后目录结构如下,bin目录集成全部交叉编译工具,包含aarch64-linux-gnu-strip精简工具:

. ├── aarch64-linux-gnu │ ├── bin │ ├── include │ ├── lib │ ├── lib64 │ └── libc ├── bin │ ├── aarch64-linux-gnu-addr2line │ ├── aarch64-linux-gnu-ar │ ├── aarch64-linux-gnu-as │ ├── aarch64-linux-gnu-g++ │ ├── aarch64-linux-gnu-gcc │ ├── aarch64-linux-gnu-ld │ ├── aarch64-linux-gnu-nm │ ├── aarch64-linux-gnu-objcopy │ ├── aarch64-linux-gnu-objdump │ ├── aarch64-linux-gnu-readelf │ ├── aarch64-linux-gnu-size │ ├── aarch64-linux-gnu-strings │ └── aarch64-linux-gnu-strip ├── include ├── lib ├── libexec └── share
6.4.6 工具链功能测试

编写基础 HelloWorld 测试源码,完成交叉编译验证工具链可用性。x86_64 主机无法直接运行 aarch64 架构可执行文件,可通过file命令校验文件架构信息。

使用nm工具可正常读取编译后可执行文件的符号表信息,输出结果包含程序全局符号、局部符号、未定义库符号等完整数据,证明工具链运行正常。

$ /root/workspace/cross_test/cross_build/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-nm main

输出示例:

U abort@@GLIBC_2.17 0000000000411038 B __bss_end__ 0000000000411038 B _bss_end__ 0000000000411030 B __bss_start 0000000000411030 B __bss_start__ 0000000000400578 t call_weak_fn 0000000000411030 b completed.7806 0000000000411020 D __data_start 0000000000411020 W data_start 0000000000400590 t deregister_tm_clones 00000000004005f8 t __do_global_dtors_aux 0000000000410dd0 t __do_global_dtors_aux_fini_array_entry 0000000000411028 D __dso_handle 0000000000410dd8 d _DYNAMIC 0000000000411030 D _edata 0000000000411038 B __end__ 0000000000411038 B _end 00000000004006dc T _fini 0000000000400628 t frame_dummy 0000000000410dc8 t __frame_dummy_init_array_entry 0000000000400770 r __FRAME_END__ 0000000000410fd8 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__ 0000000000400718 r __GNU_EH_FRAME_HDR 00000000004004b8 T _init 0000000000410dd0 t __init_array_end 0000000000410dc8 t __init_array_start 00000000004006f0 R _IO_stdin_used w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 00000000004006d8 T __libc_csu_fini 0000000000400658 T __libc_csu_init U __libc_start_main@@GLIBC_2.17 000000000040062c T main U puts@@GLIBC_2.17 00000000004005c0 t register_tm_clones 0000000000400530 T _start 0000000000411030 D __TMC_END__
6.4.7 CMake 交叉编译环境配置

基于 CMake 构建项目时,可通过固定参数配置交叉编译环境,指定工具链路径与编译链接参数,适配 aarch64 嵌入式平台开发,基础配置模板如下:

# 设置编译器和链接器路径 set(CMAKE_C_COMPILER "/path/to/embedded-gcc") set(CMAKE_CXX_COMPILER "/path/to/embedded-g++") set(CMAKE_LINKER "/path/to/embedded-ld") # 配置编译与链接标志 set(CMAKE_C_FLAGS "-mcpu=cortex-m3 -mthumb") set(CMAKE_CXX_FLAGS "-mcpu=cortex-m3 -mthumb") set(CMAKE_EXE_LINKER_FLAGS "-T/path/to/linker_script.ld")

七、总结

strip是应用于 Linux 与嵌入式开发的轻量化文件精简工具,功能为在不影响程序运行的前提下,剥离文件内的调试信息、符号信息、重定位信息等冗余数据,缩减文件存储体积。工具使用需区分开发调试场景与版本发布场景,规避调试信息丢失导致的问题无法溯源的情况。

在 ARM 交叉编译开发流程中,strip可与gccreadelfobjdump等工具配合使用。标准化的编译、调试、精简流程,可同时适配程序开发调试需求与设备部署的轻量化需求,是嵌入式产品量产发布的常用操作。


Reference

  • strip 命令的用法_c 语言 strip 函数用法-CSDN 博客
    https://blog.csdn.net/clozxy/article/details/5581452
  • gcc 编译 strip 使用_gcc strip .a-CSDN 博客
    https://blog.csdn.net/hailmy/article/details/26227347
  • 编译中使用 strip 的介绍_编译 strip-CSDN 博客
    https://blog.csdn.net/sevennineeleven/article/details/81218154
  • gcc -strip 编译选项的作用_gcc strip-CSDN 博客
    https://blog.csdn.net/weixin_43839785/article/details/108690150
  • 交叉编译链安装及工具集(gcc、readelf、objdump、objcopy 和 strip 等)使用方法_交叉编译工具-CSDN 博客
    https://blog.csdn.net/sinat_32152141/article/details/124970429
  • linaro 交叉编译工具链下载与使用笔记-CSDN 博客
    https://blog.csdn.net/yjkhtddx/article/details/134676016
http://www.jsqmd.com/news/1100104/

相关文章:

  • 指夹式脉搏血氧仪PCBA整体方案
  • YOLOv8知识蒸馏实战:让小模型获得大模型的精度
  • AI辅助科研工作流:从Idea到论文草稿的DraftPaper_Loop实践
  • 第49期 | 求职策略与渠道——AI时代的前端求职指南
  • 杰理蓝牙芯片功耗优化实战:如何用BLE_TX_POWER_LEVEL和bt_max_pwr_set函数平衡信号与续航
  • 为什么83%的VMware迁移失败源于网卡驱动?20年运维老兵披露迁移前必做的6项Pre-check清单
  • 数据分析入门到精通:Excel、Python、SQL、BI四大核心技能25集免费教程
  • FreeSWITCH mod_callcenter 官方手册
  • RAG = 就是让AI去查资料然后再回答 ?
  • YOLOv8工业级目标检测全流程实战:从训练到边缘部署
  • 终极图片去重解决方案:AntiDupl.NET免费开源工具完全指南
  • RAG 看起来简单,一上线就翻车?逐个排查 5 个环节
  • MySQL零基础入门:从核心概念到实战应用的全链路学习指南
  • DeepSeek V3技术深扒!MoE+MLA如何让AI推理快如闪电?
  • LyricsX:macOS歌词同步终极指南 - 打造完美音乐体验
  • 2026年吉安本地岩板批发门店实力盘点
  • VMware虚拟机组网通信失效?立即执行这6个命令,90%问题3分钟定位
  • 拐点将至——国内企业级AI智能体发展洞察(2026年上半年报告)
  • 10万技术转移人才缺口下为什么交大MTT是全国首个学位点-2026政策与产业背景
  • Claude Code与Kimi Code进阶指南:从代码补全到智能体协作开发
  • YOLOv8知识蒸馏实战:从37%到42% mAP的模型压缩与性能提升
  • 国产大模型的具象交互补全:魔珐星云让 Qwen/DeepSeek Agent 拥有 3D 身体
  • Doris集群Docker部署实战:解决节点注册失败与网络配置难题
  • AI Agent开发实战:从概念到落地,构建自动化工作流
  • 数据分析实战学习路径:从Excel、SQL到Python与BI的完整技能树构建
  • 基于Hermes Agent与Harness Engineering的金融AI问答机器人实战
  • AI智能体记忆层设计:为Codex、OpenCode与Claude构建长效记忆系统
  • 企业级Agentic AI落地指南:从概念到工程实践的五维拆解
  • MySQL从零到一:Windows/Linux环境搭建与核心操作实战指南
  • 做历史解说视频素材太难找?我用花生AI跑通了一套省心的新流程