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

Linux build:头文件安装

文章目录

  • 1. 前言
  • 2. 安装头文件

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. 安装头文件

Linux通过下面的命令

$makeARCH=arm headers_install

导出头文件给用户空间,通常是给glibc这样的库使用,但用户空间程序也可以直接使用。

先看linux/Makefile

...PHONY+=__headers __headers:$(version_h)scripts_basic uapi-asm-generic archheaders archscripts $(Q)$(MAKE)$(build)=scripts build_unifdef...PHONY+=headers_install headers_install:__headers $(if$(wildcard $(srctree)/arch/$(hdr-arch)/include/uapi/asm/Kbuild),,\ $(error Headers not exportableforthe $(SRCARCH)architecture))$(Q)$(MAKE)$(hdr-inst)=include/uapi dst=include $(Q)$(MAKE)$(hdr-inst)=arch/$(hdr-arch)/include/uapi $(hdr-dst)

具体的安装操作见./scripts/Makefile.headersinst

#SPDX-License-Identifier:GPL-2.0#==========================================================================#Installing headers##All headers under include/uapi,include/generated/uapi,#arch/<arch>/include/uapi and arch/<arch>/include/generated/uapi are#exported.#They are preprocessed to remove __KERNEL__ section of the file.# #==========================================================================PHONY:=__headers __headers:include scripts/Kbuild.include srcdir:=$(srctree)/$(obj)#When make is run under a fakechroot environment,the function# $(wildcard $(srcdir)/*/.) doesn't only return directories, but also regular # files. So, we are using a combination of sort/dir/wildcard which works # with fakechroot. subdirs := $(patsubst $(srcdir)/%/,%,\ $(filter-out $(srcdir)/,\ $(sort $(dir $(wildcard $(srcdir)/*/)))))#Recursion__headers:$(subdirs).PHONY:$(subdirs)$(subdirs):$(Q)$(MAKE)$(hdr-inst)=$(obj)/$@ dst=$(dst)/$@#Skip header install/checkforinclude/uapi and arch/$(hdr-arch)/include/uapi.#We have only sub-directories there.skip-inst:=$(if$(filter%/uapi,$(obj)),1)ifeq($(skip-inst),)#Kbuild file is optionalkbuild-file:=$(srctree)/$(obj)/Kbuild-include $(kbuild-file)installdir:=$(INSTALL_HDR_PATH)/$(dst)gendir:=$(objtree)/$(subst include/,include/generated/,$(obj))header-files:=$(notdir $(wildcard $(srcdir)/*.h)) header-files += $(notdir $(wildcard $(srcdir)/*.agh)) header-files := $(filter-out $(no-export-headers), $(header-files)) genhdr-files := $(notdir $(wildcard $(gendir)/*.h)) genhdr-files := $(filter-out $(header-files), $(genhdr-files)) # files used to track state of install/check install-file := $(installdir)/.install check-file := $(installdir)/.check # all headers files for this dir all-files := $(header-files) $(genhdr-files) output-files := $(addprefix $(installdir)/, $(all-files)) ifneq ($(mandatory-y),) missing := $(filter-out $(all-files),$(mandatory-y)) ifneq ($(missing),) $(error Some mandatory headers ($(missing)) are missing in $(obj)) endif endif # Work out what needs to be removed oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h)) unwanted := $(filter-out $(all-files),$(oldheaders)) # Prefix unwanted with full paths to $(INSTALL_HDR_PATH) unwanted-file := $(addprefix $(installdir)/, $(unwanted)) printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@)) quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\ file$(if $(word 2, $(all-files)),s)) cmd_install = \ $(CONFIG_SHELL) $< $(installdir) $(srcdir) $(header-files); \ $(CONFIG_SHELL) $< $(installdir) $(gendir) $(genhdr-files); \ touch $@ quiet_cmd_remove = REMOVE $(unwanted) cmd_remove = rm -f $(unwanted-file) quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files) # Headers list can be pretty long, xargs helps to avoid # the "Argument list too long" error. cmd_check = for f in $(all-files); do \ echo "$(installdir)/$${f}"; done \ | xargs \ $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \ touch $@ ifndef HDRCHECK # Rules for installing headers __headers: $(install-file) @: targets += $(install-file) $(install-file): scripts/headers_install.sh \ $(addprefix $(srcdir)/,$(header-files)) \ $(addprefix $(gendir)/,$(genhdr-files)) FORCE $(if $(unwanted),$(call cmd,remove),) $(if $(wildcard $(dir $@)),,$(shell mkdir -p $(dir $@))) $(call if_changed,install) else __headers: $(check-file) @: targets += $(check-file) $(check-file): scripts/headers_check.pl $(output-files) FORCE $(call if_changed,check) endif targets := $(wildcard $(sort $(targets))) cmd_files := $(wildcard \ $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) ifneq ($(cmd_files),) include $(cmd_files) endif endif # skip-inst .PHONY: $(PHONY) PHONY += FORCE FORCE: ;

可以看到,安装下面这4个目录下的头文件:

# 公用 UAPI 头文件include/uapi include/generated/uapi# 编译时生成# 架构 UAPI 头文件arch/$(hdr-arch)/include/uapi# 如 arch/arm/include/uapiarch/<arch>/include/generated/uapi# 编译时生成

./scripts/Makefile.headersinst调用scripts/headers_install.sh进行头文件安装,默认安装在linux/usr目录下,生成一个linux/usr/include文件夹,其中包含所有安装的头文件。

看看4个安装目录下都有哪些头文件:

# 这个有点多,就不用 tree 命令展开了$lsinclude/uapi asm-generic drm linux misc mtd rdma scsi sound video xen $ tree include/generated/uapi/ include/generated/uapi/ └── linux └── version.h1directory,1file$ tree arch/arm/include/uapi arch/arm/include/uapi └── asm ├── auxvec.h ├── byteorder.h ├── fcntl.h ├── hwcap.h ├── ioctls.h ├── Kbuild ├── kvm.h ├── kvm_para.h ├── mman.h ├── perf_regs.h ├── posix_types.h ├── ptrace.h ├── setup.h ├── sigcontext.h ├── signal.h ├── statfs.h ├── stat.h ├── swab.h ├── types.h └── unistd.h1directory,20files asm $ tree arch/arm/include/generated/uapi arch/arm/include/generated/uapi └── asm ├── bitsperlong.h ├── errno.h ├── ioctl.h ├── ipcbuf.h ├── msgbuf.h ├── param.h ├── poll.h ├── resource.h ├── sembuf.h ├── shmbuf.h ├── siginfo.h ├── socket.h ├── sockios.h ├── termbits.h ├── termios.h ├── unistd-common.h ├── unistd-eabi.h └── unistd-oabi.h1directory,18files

看一下安装过程:

$makeARCH=arm headers_installO=output/ make[1]: Entering directory'/home/lxj/Work/qemu-lab/linux-4.14.111'CHK include/generated/uapi/linux/version.h HOSTCC scripts/unifdef INSTALL usr/include/asm-generic/(36files)INSTALL usr/include/drm/(25files)INSTALL usr/include/linux/(485files)INSTALL usr/include/linux/android/(1file)INSTALL usr/include/linux/byteorder/(2files)INSTALL usr/include/linux/caif/(2files)INSTALL usr/include/linux/can/(6files)INSTALL usr/include/linux/cifs/(1file)INSTALL usr/include/linux/dvb/(8files)INSTALL usr/include/linux/genwqe/(1file)INSTALL usr/include/linux/hdlc/(1file)INSTALL usr/include/linux/hsi/(2files)INSTALL usr/include/linux/iio/(2files)INSTALL usr/include/linux/isdn/(1file)INSTALL usr/include/linux/mmc/(1file)INSTALL usr/include/linux/netfilter/(87files)INSTALL usr/include/linux/netfilter/ipset/(4files)INSTALL usr/include/linux/netfilter_arp/(2files)INSTALL usr/include/linux/netfilter_bridge/(17files)INSTALL usr/include/linux/netfilter_ipv4/(9files)INSTALL usr/include/linux/netfilter_ipv6/(12files)INSTALL usr/include/linux/nfsd/(5files)INSTALL usr/include/linux/raid/(2files)INSTALL usr/include/linux/sched/(1file)INSTALL usr/include/linux/spi/(1file)INSTALL usr/include/linux/sunrpc/(1file)INSTALL usr/include/linux/tc_act/(15files)INSTALL usr/include/linux/tc_ematch/(4files)INSTALL usr/include/linux/usb/(12files)INSTALL usr/include/linux/wimax/(1file)INSTALL usr/include/misc/(1file)INSTALL usr/include/mtd/(5files)INSTALL usr/include/rdma/(20files)INSTALL usr/include/rdma/hfi/(2files)INSTALL usr/include/scsi/(4files)INSTALL usr/include/scsi/fc/(4files)INSTALL usr/include/sound/(15files)INSTALL usr/include/video/(3files)INSTALL usr/include/xen/(4files)INSTALL usr/include/asm/(37files)make[1]: Leaving directory'/home/lxj/Work/qemu-lab/linux-4.14.111'

默认在linux/usr目录下,创建linux/usr/include目录,然后安装所有UAPI头文件。为什么只安装uapi目录下头文件?因为 linux uapi 下头文件就是导出给用户使用的,其它的头文件不应该导出,是不对用户开放的黑盒子。

另外,可以通过 INSTALL_HDR_PATH 将头文件安装到指定目录:

$makeARCH=armINSTALL_HDR_PATH=<target-path>headers_install

同样会在<target-path>目录下创建<target-path>/include文件夹安装所有头文件。另外,O=参数也是支持的,如:

$makeARCH=armO=output headers_install

则会在output/usr/include目录下安装所有头文件。当然,也可以同时使用 INSTALL_HDR_PATH= 和O=参数:

$makeARCH=armO=outputINSTALL_HDR_PATH=<target-path>headers_install

最后,还可以通过命令:

$makeheaders_install_all

安装所有架构的头文件。

调试可以加上V=1参数。

http://www.jsqmd.com/news/217452/

相关文章:

  • Soundflower音频路由神器:彻底释放Mac音频系统的无限潜能
  • WE Learn智能学习助手终极指南:5步开启高效学习新时代
  • WE Learn AI学习助手终极指南:5步轻松开启智能学习模式
  • 基于遗传算法和粒子群算法的潮流计算比较(Matlab代码实现)
  • [特殊字符]_内存管理深度解析:如何避免GC导致的性能陷阱[20260108161913]
  • 性价比高的海外代理IP:怎么选不踩坑
  • 汽车焊接工艺参数优化的方法和案例
  • 巴菲特-芒格的神经形态计算投资:类脑计算的未来
  • 【无人机】基于遗传算法混合粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)
  • Docker 基础:怎么配置、怎么拉取运行、怎么构建推送
  • Node.js 用beforeExit优雅关闭应用
  • 谁说思维链越长越好?Yuan3.0 Flash开源:砍掉70%无效token,重构推理范式
  • 欧莱雅集团在CES 2026上发布LED光能面膜
  • 5分钟快速上手gerbv:电子工程师必备的Gerber文件查看终极指南
  • Switch文件传输与RCM注入全攻略:NS-USBLoader深度体验
  • 为什么数据库文件不建议提交:你提交的不是数据,是未来的麻烦
  • linux下使用SHC对Shell脚本进行封装和源码隐藏
  • 当云原生遇见VMware
  • WE Learn智能助手完整指南:5步掌握高效学习新方法
  • 大数据领域数据架构在企业中的应用价值
  • 科沃斯重磅亮相2026年CES,向海外市场展示新一代机器人解决方案 | 美通社头条
  • GEO优化服务商导航与选择:在AI搜索时代构建品牌认知资产
  • 见证历史:智谱敲钟,国产大模型第一股来了
  • 基于Python的纪念币预约自动化工具完全指南
  • 嵌入式定时器计时技巧:用有符号数省略溢出判断的底层逻辑与实践
  • 全渠道 AI 推荐,如何终结创作者的“效率焦虑”?
  • WE Learn网课助手终极指南:3步开启智能学习新时代
  • 中国计算机学会(CCF)推荐学术会议-A(计算机网络):SIGCOMM 2026
  • 汽车涂装工艺参数优化的关键点及企业实践案例
  • NS-USBLoader终极指南:Switch文件传输与RCM注入一键搞定