分析的OpenWrt源码目录有助于分析OpenWrt的源码
一、原始目录
1.1、scripts
构建期间用到的各类脚本文件。它存放了一些脚本,使用了bash,python,perl等多种脚本语言.编译过程中,用于第三方软件包管理的feeds文件也是在这个目录当中.在编译过程中,使用到的脚本也统一放在这个目录中.
例如patch-kernel.sh封装了patch命令,在编译时,首先将 patches 目录下的所有补丁文件打上,并且判断如果打补丁失败将退出编译过程。
download.pl 为下载源代码的工具脚本,封装下载工具 wget 的选项以及设置从哪里下载。
1.2、tools
在构建过程中使用的各种工具。编译时,主机需要使用一些工具软件,tools 里包含了获取和编译这些工具的命令.软件包里面有Makefile文件,有的还包含了patch.每个Makefile当中都有一句$(eval $(call HostBuild)),这表明编译这个工具是为了在主机上使用的.
1.3、config
菜单设置配置文件。存放着整个系统的配置文件
1.4、 toolchain
构建工具链所需的生成文件和配置。这个文件中存放的就是编译交叉编译链的软件包.包括:binutils,gcc,libc等等.
1.5、target
构建imagebuilder,内核,sdk和工具链所需的生成文件和配置。openwrt的源码可以编译出各个平台适用的二进制文件,各平台在这个目录里定义了firmware和kernel的编译过程。
存放用于编译各类平台使用的二进制文件,定义了各类平台编译固件和内核的具体过程。
是指目标嵌入式设备,针对不同的平台有不同的特性代码。
例如下面的“target/linux”目录是对Linux系统的划分,目录下包括Linux系统针对于各种平台标准内核的不订及特殊配置(如ar7、arm系统)。
1.6、package
用于文件生成和菜单配置的软件包。存放了openwrt系统中适用的软件包,包含针对各个软件包的Makefile。openwrt定义了一套Makefile模板.各软件参照这个模板定义了自己的信息,如软件包的版本、下载地址、编译方式、安装地址等。在二次开发过程中,这个文件夹我们会经常打交道.
事实上,通过./scripts/feed update -a和./scripts/feed install -a的软件包也会存放在这个目录之中.
我们可以根据自己的需求,在这个目录下新建目录(根据软件类型存放在对应的目录下),然后编写程序和Makefile脚本,这样就可以编译生成自己想要的软件了。
1.7、include
文件生成配置文件。openwrt的Makefile都存放在这里。文件名为 *.mk 。这里的文件上是在Makefile里被include的,类似于库文件.这些文件定义了编译过程.
.mk脚本在编译时的作用
在顶层目录下有一个“Makefile”脚本,当我们在编译源码时,输入make命令,“Makefile”脚本被执行,紧接着.mk脚本会被顶级目录下的Makefile调用,然后这些.mk脚本会解析“.config”文件(.config文件下面有介绍),并且根据“.config”文件的内容来编译相关的内容(例如下载、编译安装packages目录下的第三方软件等)。
二、原始目录下的单个文件
2.1、Makefile:
在顶层目录执行make命令的入口文件。进行编译的总体工作。自己开发时,这个Makefile不需要改动。make文件如下:
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2007 OpenWrt.org
TOPDIR:=${CURDIR}
LC_ALL:=C
LANG:=C
TZ:=UTC
export TOPDIR LC_ALL LANG TZ
empty:=
space:= $(empty) $(empty)
$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt directory must not include any spaces))
world:
DISTRO_PKG_CONFIG:=$(shell $(TOPDIR)/scripts/command_all.sh pkg-config | grep '/usr' -m 1)
export ORIG_PATH:=$(if $(ORIG_PATH),$(ORIG_PATH),$(PATH))
export PATH:=$(if $(STAGING_DIR),$(abspath $(STAGING_DIR)/../host/bin),$(TOPDIR)/staging_dir/host/bin):$(PATH)
ifneq ($(OPENWRT_BUILD),1)
_SINGLE=export MAKEFLAGS=$(space);
override OPENWRT_BUILD=1
export OPENWRT_BUILD
GREP_OPTIONS=
export GREP_OPTIONS
CDPATH=
export CDPATH
include $(TOPDIR)/include/debug.mk
include $(TOPDIR)/include/depends.mk
include $(TOPDIR)/include/toplevel.mk
else
include rules.mk
include $(INCLUDE_DIR)/depends.mk
include $(INCLUDE_DIR)/subdir.mk
include target/Makefile
include package/Makefile
include tools/Makefile
include toolchain/Makefile
$(toolchain/stamp-compile): $(tools/stamp-compile) $(if $(CONFIG_BUILDBOT),toolchain_rebuild_check)
$(target/stamp-compile): $(toolchain/stamp-compile) $(tools/stamp-compile) $(BUILD_DIR)/.prepared
$(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
$(package/stamp-install): $(package/stamp-compile)
$(target/stamp-install): $(package/stamp-compile) $(package/stamp-install)
check: $(tools/stamp-check) $(toolchain/stamp-check) $(package/stamp-check)
printdb:
@true
prepare: $(target/stamp-compile)
_clean: FORCE
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(TOPDIR)/staging_dir/packages
clean: _clean
rm -rf $(BUILD_LOG_DIR)
targetclean: _clean
rm -rf $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
dirclean: targetclean clean
rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(BUILD_DIR_BASE)/host
rm -rf $(TMP_DIR)
$(MAKE) -C $(TOPDIR)/scripts/config clean
toolchain_rebuild_check:
$(SCRIPT_DIR)/check-toolchain-clean.sh
cacheclean:
ifneq ($(CONFIG_CCACHE),)
$(STAGING_DIR_HOST)/bin/ccache -C
endif
ifndef DUMP_TARGET_DB
$(BUILD_DIR)/.prepared: Makefile
@mkdir -p $$(dirname $@)
@touch $@
tmp/.prereq_packages: .config
unset ERROR; \
for package in $(sort $(prereq-y) $(prereq-m)); do \
$(_SINGLE)$(NO_TRACE_MAKE) -s -r -C package/$$package prereq || ERROR=1; \
done; \
if [ -n "$$ERROR" ]; then \
echo "Package prerequisite check failed."; \
false; \
fi
touch $@
endif
# check prerequisites before starting to build
prereq: $(target/stamp-prereq) tmp/.prereq_packages
@if [ ! -f "$(INCLUDE_DIR)/site/$(ARCH)" ]; then \
echo 'ERROR: Missing site config for architecture "$(ARCH)" !'; \
echo ' The missing file will cause configure scripts to fail during compilation.'; \
echo ' Please provide a "$(INCLUDE_DIR)/site/$(ARCH)" file and restart the build.'; \
exit 1; \
fi
$(BIN_DIR)/profiles.json: FORCE
$(if $(CONFIG_JSON_OVERVIEW_IMAGE_INFO), \
WORK_DIR=$(BUILD_DIR)/json_info_files \
$(SCRIPT_DIR)/json_overview_image_info.py $@ \
)
json_overview_image_info: $(BIN_DIR)/profiles.json
checksum: FORCE
$(call sha256sums,$(BIN_DIR),$(CONFIG_BUILDBOT))
buildversion: FORCE
$(SCRIPT_DIR)/getver.sh > $(BIN_DIR)/version.buildinfo
feedsversion: FORCE
$(SCRIPT_DIR)/feeds list -fs > $(BIN_DIR)/feeds.buildinfo
diffconfig: FORCE
mkdir -p $(BIN_DIR)
$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.buildinfo
buildinfo: FORCE
$(_SINGLE)$(SUBMAKE) -r diffconfig buildversion feedsversion
prepare: .config $(tools/stamp-compile) $(toolchain/stamp-compile)
$(_SINGLE)$(SUBMAKE) -r buildinfo
world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
$(_SINGLE)$(SUBMAKE) -r package/index
$(_SINGLE)$(SUBMAKE) -r json_overview_image_info
$(_SINGLE)$(SUBMAKE) -r checksum
ifneq ($(CONFIG_CCACHE),)
$(STAGING_DIR_HOST)/bin/ccache -s
endif
.PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean
endif
(1)、执行make时,如果不指定任何目标,因为world目标处于第一位,所以默认执行world。
(2)、在make时不指定OPENWRT_BUILD参数时,进入ifneq语句,如果编译时make OPENWRT_BUILD=1则进入else。ifneq语句主要工作为:
重写OPENWRT_BUILD变量并export导出OPENWRT_BUILD变量。
包含仅顶级目录下include目录下的debug.mk、depends.mk、toplevel.mk。
debug.mk:在编译过程中各类信息的输出 (V=s参数用到)。
depends.m:检查当前系统在编译内核阶段所有需要依赖的包是否安装。
toplevel.mk:解析编译world目标的规则。
(3)、“make clean”:删除编译目录。
(4)、“make dirclean”:除了删除编译目录之外还删除编译工具目录。
(5)、“make printdb”:输出所有的编译变量定义。
2.2 、rules.mk
定义了Makefile中使用的一些通用变量和函数
2.3、 Config.in
在include/toplevel.mk中我们可以看到,这是和make menuconfig相关联的文件.
2.4、 feeds.conf.default
是下载第三方一些软件包时所使用的地址
2.5、 LICENSE & README
即软件许可证和软件基本说明.其中README描述了编译软件的基本过程和依赖文件.
三、生成目录
在我们编译完成后除了下载的源码文件,多出来的部分很明显就是编译过程中新生成的。编译工具链、目标平台的软件包等需要下载的文件都放在dl目录下。目标平台和软件包两部分都需要“build_dir/”作为编译的临时目录,并且会将目录 staging_dir作为编译的临时安装目录,最终的生成文件保存在目录bin下。
3.1、feeds
openwrt的附加软件包管理器的扩展包索引目录.有点绕,简单来说就是下载管理软件包的.默认的feeds下载有packages、management、luci、routing、telephony。如要下载其他的软件包,需打开源码根目录下面的feeds.conf.default文件,去掉相应软件包前面的#号,然后更新源。
在OpenWrt固件中,几乎所有东西都是软件包(package),可以编译为以“.ipk”结尾的安装包,这样就可以很方便地安装、升级和卸载了。注意,扩展软件包不是在主分支中维护的,但是可以使用软件包编译扩展机制(feeds)来进行扩展安装。这些包能够扩展基本系统的功能,只需要将它们链接进入主干。之后,这些软件包将会显示在编译配置菜单中。
目录feeds用于保存扩展软件包,可以使用软件包编译扩展机制来进行扩展安装。这些包能够扩展基本系统的功能,只需要将它们链接进入编译主目录的package目录下。 之后,这些软件包将会显示在配置菜单中。
./sripts/feeds install -a时,feeds目录就产生了,安装的软件就存放在这个目录下了。
./scripts/feeds update -a
安装下载好的包:
./scripts/feeds install -a
3.2、build_dir
在前面的原始目录中,我们提到了host工具,toolchain工具还有目标文件.openwrt将在这个目录中展开各个软件包,进行编译.所以这个文件夹中包含3个子文件夹:
“build_dir/host”是一个临时目录,用来储存不依赖于目标平台的工具。tools目录中各类工具编译的结果存放在host中,因此可以看到这些目录的名称与tools下的工具名称相同。
“build_dir/toolchain-*”目录,用来储存依赖于指定平台的编译工具链。tools-chain目录交叉编译工具最终编译的结果文件。
“build_dir/”目录:目标平台和软件包两部分都需要“build_dir/”作为编译的临时目录。
3.2.1、 host
在该文件夹中编译主机使用的工具软件
3.2.2 、toolchain-XXX
在该文件夹中编译交叉工具链
3.2.3、 target-XXX
在此编译目标平台的目标文件,包括各个软件包和内核文件.
3.3、bin
保存编译完成后的二进制文件,包括:完整的bin文件,所有的ipk文件.
3.4、.dl
在编译过程中使用的很多软件,刚开始下载源码并没有包含,而是在编译过程中从其他服务器下载的,这里是统一的保存目录。
编译工具链、目标平台的软件包等需要下载的文件都放在dl目录下。
在编译过程中,各类需要下载的包都保存在这个目录下 (编译过程中用的工具)。
当编译的过程中,如果出错,出错的原因是某个软件包下载错误或丢失,可以手动下载对应的软件包(压缩文件形式),并放在这个目录下,之后重新编译。
dl目录与feeds目录的区别:dl中存放的是编译过程中需要用到的工具,而feeds中存放的是系统编译好之后在系统中需要用的软件。
3.5、 staging_dir
用于保存在build_dir目录中编译完成的软件.所以这里也和build_dir有同样的子目录结构.
比如,在target-XXX文件夹中保存了目标平台编译好的头文件,库文件.在我们开发自己的ipk文件时,编译过程中,预处理头文件,链接动态库,静态库都是到这个子文件夹中.
staging_dir作为编译的临时安装目录,其中staging_dir/toolchain-*”目录:是编译工具链的最终安装位置。通常我们不需要改动编译链目录下的任何东西,除非要更新编译工具版本等。
tools、toolchain、build_dir、staging_dir四者的关系
tools、toolchain目录中的编译中间文件存放在buidl_dir目录下。例如生成的.o 文件等。
buidl_dir目录存放的软件编译文件,最终安装在staging_dir目录下,因此staging_dir目录为编译安装目录,文件安装到staging_dir目录,并由staging_dir目录的文件生成最终的编译成果。
所以:流程是:tools、toolchain==>编译到build_dir中==>安装到staging_dir中。
3.6、tmp
从名字来看,是临时文件夹.在编译过程中,有大量中间临时文件需要保存,都是在这里.文章来源:https://www.toymoban.com/news/detail-669707.html
3.7、.logs
这个文件夹,有时可以看到,有时没有.这是因为这个文件夹保存的是,编译过程中出错的信息,只有当编译出错了才会出现.我们可以从这里获取信息,从而分析我们的软件编译为什么没有完成.文章来源地址https://www.toymoban.com/news/detail-669707.html
到了这里,关于OpenWrt源码目录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!