转自:https://www.cnblogs.com/tfanalysis/p/3625430.html

 

参考网站:http://wiki.openwrt.org/doc/howto/buildroot.exigence

需要下载必要的库文件,编译器等。。。

 

1 首先要获得openwrt的源码,参考openwrt.org官方网站的内容 https://dev.openwrt.org/wiki/GetSource

其中trunk为开发版本,最新的稳定版为12.09 branch (Attitude Adjustment)。

使用git获得:git clone git://git.openwrt.org/12.09/openwrt.git

如果要更新源码则运行git pull即可。

使用svn获得:svn co svn://svn.openwrt.org/openwrt/branches/attitude_adjustment

2 下载完源码之后

获取包列表:

./scripts/feeds update -a

将包选项加到menuconfig中去:

./scripts/feeds install -a

3 make menuconfig

在此菜单中选择要编译的模块并生成依赖

3.1

我们打开openwrt根目录下的Makefile文件,发现并没有找到menuconfig这个目标,这个目标是在

include $(TOPDIR)/include/toplevel.mk

所指的toplevel.mk中定义的,如下图:

【转】openwrt make menuconfig过程(提取menuconfig)

它的依赖是scripts/config/mconf和prepare-tmpinfo FORCE

  • scripts/config/mconf是一个已经存在的可执行文件;
  • prepare-tmpinfo是本文件中的一个目标,等会再阐述;
  • FORCE尚还不清楚它的作用和来源;

我们先看看menuconfig中的命令

    if [ \! -e .config -a -e $(HOME)/.openwrt/defconfig ]; then \
        cp $(HOME)/.openwrt/defconfig .config; \
    fi
    $< Config.in

这是一句shell脚本,意思是:如果不存在.config而且存在$(HOME)/.openwrt/defconfig,则拷贝$(HOME)/.openwrt/defconfig为.config

 $<是什么?The automatic variable ‘$<’ is just the first prerequisite,即是指scripts/config/mconf。
把这两个字符串连起来看就知道什么意思啦:scripts/config/mconf Config.in

你也可以直接到openwrt目录下去试运行一下这个指令,如下图,正是我们运行make menuconfig时出现的画面(下图我已经关闭了menuconfig):

【转】openwrt make menuconfig过程(提取menuconfig)

3.2

 好!现在我们回头去理prepare-tmpinfo的帐,并且看看能不能把Config.in这个文件搞懂是怎么回事。

【转】openwrt make menuconfig过程(提取menuconfig)
prepare-tmpinfo: FORCE
    mkdir -p tmp/info
    $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_DEPTH=5 SCAN_EXTRA=""
    $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
    for type in package target; do \
        f=tmp/.$${type}info; t=tmp/.config-$${type}.in; \
        [ "$$t" -nt "$$f" ] || ./scripts/metadata.pl $${type}_config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
    done
    ./scripts/metadata.pl package_mk tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; }
    touch $(TOPDIR)/tmp/.build
【转】openwrt make menuconfig过程(提取menuconfig)

3.2.1

两个变量

_SINGLE在顶层Makefile中定义:

_SINGLE=export MAKEFLAGS=$(space);

NO_TRACE_MAKE的-/include/verbose.mk中定义:

ifeq ($(NO_TRACE_MAKE),)
NO_TRACE_MAKE := $(MAKE) V=s$(OPENWRT_VERBOSE)
export NO_TRACE_MAKE
endif

 这里的命令先是去make V=xx -j1 -r -s -f include/scan.mk(分别Verbose,单线程,没有内建规则,指定Makefile文件)。所以我们再打开include/scan.mk文件看看怎么回事。最终目标是:

all: $(TMP_DIR)/.$(SCAN_TARGET)

3.2.2

这时scan.mk先定义了一个叫做PackageDir的“函数”(命令序列,后面将会使用):

【转】openwrt make menuconfig过程(提取menuconfig)
define PackageDir
  $(TMP_DIR)/.$(SCAN_TARGET): $(TMP_DIR)/info/.$(SCAN_TARGET)-$(1)
  $(TMP_DIR)/info/.$(SCAN_TARGET)-$(1): $(SCAN_DIR)/$(2)/Makefile $(SCAN_STAMP) $(foreach DEP,$(DEPS_$(SCAN_DIR)/$(1)/Makefile) $(SCAN_DEPS),$(wildcard $(if $(filter /%,$(DEP)),$(DEP),$(SCAN_DIR)/$(1)/$(DEP))))
    { \
        $$(call progress,Collecting $(SCAN_NAME) info: $(SCAN_DIR)/$(2)) \
        echo Source-Makefile: $(SCAN_DIR)/$(2)/Makefile; \
        $(NO_TRACE_MAKE) --no-print-dir -r DUMP=1 -C $(SCAN_DIR)/$(2) $(SCAN_MAKEOPTS) 2>/dev/null || { \
            mkdir -p "$(TOPDIR)/logs/$(SCAN_DIR)/$(2)"; \
            $(NO_TRACE_MAKE) --no-print-dir -r DUMP=1 -C $(SCAN_DIR)/$(2) $(SCAN_MAKEOPTS) > $(TOPDIR)/logs/$(SCAN_DIR)/$(2)/dump.txt 2>&1; \
            $$(call progress,ERROR: please fix $(SCAN_DIR)/$(2)/Makefile - see logs/$(SCAN_DIR)/$(2)/dump.txt for details\n) \
            rm -f $$@; \
        }; \
        echo; \
    } > $$@ || true
endef
【转】openwrt make menuconfig过程(提取menuconfig)

3.2.3

这个命令系列的用法可以看下面的$(call progress, Colleting....),progress也正是scan.mk文件中定义的一个命令序列:

$(TMP_DIR)/.$(SCAN_TARGET): $(TARGET_STAMP) $(SCAN_STAMP)
    $(call progress,Collecting $(SCAN_NAME) info: merging...)
    -cat $(FILELIST) | awk '{gsub(/\//, "_", $$0);print "$(TMP_DIR)/info/.$(SCAN_TARGET)-" $$0}' | xargs cat > $@ 2>/dev/null
    $(call progress,Collecting $(SCAN_NAME) info: done)
    echo

 具体progress的定义是这样的:

【转】openwrt make menuconfig过程(提取menuconfig)
ifeq ($(IS_TTY),1)
  define progress
    printf "\033[M\r$(1)" >&2;
  endef
else
  define progress
    :;
  endef
endif
【转】openwrt make menuconfig过程(提取menuconfig)

所以,调用它之后会输出“<[M Collecting package info : merging... ”"....info: done"类似这样的信息(重定义到2,标准错误输出),$(1)表示第一个参数的意思

中间则输出awk信息,来研究下这个语句

-cat $(FILELIST) | awk '{gsub(/\//, "_", $$0);print "$(TMP_DIR)/info/.$(SCAN_TARGET)-" $$0}' | xargs cat > $@ 2>/dev/null

 处理过程:

  1. -cat $(FILELIST),-cat最头的-表示如果出错也不提示如意思;
  2. cat得的数据输出通过awk的解析
    awk '{gsub(/\//, "_", $$0);print "$(TMP_DIR)/info/.$(SCAN_TARGET)-" $$0}'
  3. awk得的数据输出通过xargs cat(分小段输出给@,也就是(TMP_DIR)/.$(SCAN_TARGET)自己!),而错误输出的定义到null

看上面的过程,这部分主要问题是要搞清楚$(FILELIST)和awk的用法:

先上$(FILELIST)

$(FILELIST):
    rm -f $(TMP_DIR)/info/.files-$(SCAN_TARGET)-*
    $(call FIND_L, $(SCAN_DIR)) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -HE 'call (Build/DefaultTargets|Build(Package|Target)|.+Package)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq > $@

这儿的FIND_L命令序列实在x/tmp/.host.mk中定义的(该mk文件由x/include/host.mk生成)

FIND_L=/usr/bin/find -L $(1)

因而这个命令就演变成了系统指令find/xarg&grep/sed/uniq的用法了。

1 find查找$(SCAN_DIR)中的叫做Makefile的文件(搜索深度1~5);

2 xargs grep会展开各个Makefile文件,-H为显示时makefile名字,-E为启用后面跟着的正则表达式;

【转】openwrt make menuconfig过程(提取menuconfig)

【转】openwrt make menuconfig过程(提取menuconfig)

这儿call (Build/DefaultTargets|Build(Package|Target)|.+Package)会匹配到call Build/DefaultTargets或者BuildPackage或BuildTarget或者_任意多个字符_Package等三种情况的字符串(以行为结束);

3 sed

4 uniq

最后获得的文件写到了FILELIST := $(TMP_DIR)/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)中;

【转】openwrt make menuconfig过程(提取menuconfig)
spidev_test
hostapd
opkg
fuse
hotplug2
ppp
...
feeds/xwrt/webif-iw-lua-openssl
feeds/xwrt/webif-netsukuku
feeds/xwrt/webif-mesh
feeds/xwrt/webif-fonheartbeat
robocfg
comgt
rssileds
madwifi
grub
libjson-c
odhcp6c
rotary-gpio-custom
ead
rtc-rv5c386a
sierra-directip
button-hotplug
grub2
kexec-tools
linux-atm
util-linux
xfsprogs
pjsip
ltq-tapidemo
owsip
fbtest
gpioctl
uboot-omap4
i2c-gpio-custom
ltq-tapi
ltq-vmmc
uboot-lantiq
swconfig
uhttpd
trelay
iptables
switch
owipcalc
ltq-kpi2udp
【转】openwrt make menuconfig过程(提取menuconfig)

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-14
  • 2021-05-19
  • 2022-01-05
  • 2021-11-22
  • 2021-12-25
猜你喜欢
  • 2022-12-23
  • 2022-01-16
  • 2021-08-19
  • 2021-08-29
  • 2021-04-30
  • 2021-10-23
  • 2021-06-11
相关资源
相似解决方案