OperWrt 环境搭建

首次编译

  1. openwrt源代码下载(lede为例说明)

    #Lean 大佬的源码仓库 需要访问github 可能速度不行 
    git clone https://github.com/coolsnowwolf/lede
    
    # 或者 使用下面的国内镜像源 下载比较快
    git clone https://gitee.com/robot-open-source/lede.git
    
  2. 修改部分代理 否则编译的时候有肯能会报错

    参见https://github.com/goproxy/goproxy.cn/blob/master/README.zh-CN.md 説明

    export GO111MODULE=on
    export GOPROXY=https://goproxy.cn
    

    或者全局生效

    echo "export GO111MODULE=on" >> ~/.profile
    echo "export GOPROXY=https://goproxy.cn" >> ~/.profile
    source ~/.profile
    
  3. 添加部分软件源

    cd lede
    vim eeds.conf.default
    #最后行添加下面两句
    src-git kenzo https://github.com/kenzok8/openwrt-packages
    src-git small https://github.com/kenzok8/small
    

    修改后如下:

  4. 安装编译依赖

    sudo apt update -y
    sudo apt full-upgrade -y
    sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
    bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \
    git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libglib2.0-dev libgmp3-dev libltdl-dev \
    libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz \
    mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pip libpython3-dev qemu-utils \
    rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev
    
  5. 更新feeds,feeds是扩展的软件包,独立于 Open­Wrt 源码之外,所以需要单独进行拉取和更新

    ./scripts/feeds update -a     # 更新
    ./scripts/feeds install -a    # 安装
    
  6. 配置

    #使用默认配置
    make defconfig
    #或者使用自己的配置
    make menuconfig
    
  7. 下载dl库

    make download -j8
    

    注意:此时有可能下载文件有问题,使用下面的命令看看下载的文件有没有小于1kb的

    # 列出dl目录下 大小小于1kb的文件
    find dl -size -1024c -exec ls -l {} \;
    
    #如果有小于1kb的文件请执行下面的命令,把下载不完全的文件删除掉,然后重新下载
    find dl -size -1024c -exec rm -f {} \;
    make download
    
    #直到dl目录下没有小于1kb的文件即可,否则请重复执行该步骤,如果重复了很多次还是不行,请放弃吧,你被墙的太狠了
    

    注意:在编译时需要连接互联网,因为OpenWrt采用补丁包方式来管理代码,第三方的代码不放在它自己的代码库中,仅在编译前从第三方服务器下载(编译时首先从Internet 上下载软件模块代码,因为OpenWrt 仅有编译及配置指令,各种依赖的代码包在上游网站及代码仓库里面。 OpenWrt 网站也有第三方的代码包镜像,在上游网站不可用时将使用 OpenWrt 自己的服 务器地址,下载地址为: http://downloads.openwrt.org/sources/

  8. 编译

    # 第一次的时候请使用 -j1  否则可能出错
    make V=s -j1
    
  9. 编译完成后查看生成的文件

    ls bin/targets/x86/64
    

    結果如下:

  10. todo

第二次编译

如果第一次已經编译通过,现在想同步源代码,并重新编译的时候,请执行下面的操作,此时应该比首次的时候要快很多

cd lede
git pull
./scripts/feeds update -a
./scripts/feeds install -a
make defconfig
make download -j8
make V=s -j$(nproc)

重新配置

如果第一次已经编译通过,不使用默认配置,自己根据需求配置的话,请执行下面的操作

rm -rf ./tmp && rm -rf .config
make menuconfig
make V=s -j$(nproc)

知识点

  1. 单独编译模块

    • make package/tcpdump/clean:清除编译生成的文件,包含安装包及编译过程生成的 临时文件

    • make package/tcpdump/prepare:进行编译准备,包含下载软件代码包、并解压缩和 打补丁

    • make package/tcpdump/configure:根据设置选项进行配置并生成 Makefile

    • make package/tcpdump/compile:根据生成的 Makefile 进行编译

    • make package/tcpdump/install:生成安装包

    注意:上面是一個軟件包单独编译的步骤,且均可以使用-j -V参数

  2. 其他全局编译命令

    • make download:下载所有已选择的软件代码压缩包

    • make clean:清理bin目录下生成的烧录镜像文件

      clean: FORCE
        rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages
      
    • make dirclean:make clean+清除交叉编译工具及工具链目录

      dirclean:clean                  
        rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
        rm -rf $(TMP_DIR)
      
    • make distclean: 清除所有相关的东西,包括下载的软件包,配置文件,feed内容等,一夜回到解放前

    • git clean -xdf:还原 Open­Wrt 源码到初始状态

      如果把源码改坏了,想恢复为最初下载的样子

    • make printdb:输出所有的编译变量定义

    • make kernel_menuconfig:内核配置

    • make -C build_dir/target-*/u-boot-*/ menuconfig :u-boot配置

    • 总结

  3. todo

Openwrt的feeds机制

feeds update命令执行的过程

  1. 执行feeds update命令,会根据feeds.conf.default或者feeds.conf文件,下载依赖包到feeds文件夹

  2. 此时还没有放到和feeds目录同级的 $(TOPDIR)/package文件夹里

  3. 第一次feeds install会先扫描package目录,然后再把 feeds文件夹里的依赖包,通过软连接方式放进$(TOPDIR)/ package/feeds/目录

  4. 所以原先已经在 package目录里的软件包,第一次会报缺少一些依赖包,之后再运行就不会报了,因为 feeds文件夹已经软链接放在 package目录里了。

feeds用法

  • list

    • 说明:从创建的索引文件feed.index中读取列表并显示。只有进行更新之后才能查看列表

    • 命令格式

      ./scripts/feeds list 选项
      
    • 选项

      -n : 列出库名称
      -s : 列出库名称和他们的URL
      -r <库名称>: 列出指定的库
      -d <分隔符>: 使用特定的分隔符来区分每一行(默认:空格)
      
  • install

    • 说明:安装软件包以及它所依赖的软件包,从feeds目录安装到package目录,即在package/feeds目录创建软件包的软链接。只有安装之后,在后面执行make menuconfig时,才可以对相关软件包是否编译进行选择

    • 命令格式

      ./scripts/feeds install 选项
      
    • 选项

      -a : 安装所有的软件包
      -p <库名>: 单独安装软件包
      -d <y|m|n>: 设置新安装的软件默认状态.
      -f : 强制安装软件,如果存在则覆盖
      
  • search

    • 说明:按照给定的字符串来查找软件包,需要传入一个字符串参数

    • 命令格式

      ./scripts/feeds search 选项
      
    • 选项

      -r <库名>: 仅搜索这个库
      
  • uninstall

    • 说明:卸载软件包,但它没有处理依赖关系,仅仅删除本软件包的软链接。

    • 命令格式

      ./scripts/feeds uninstall -a # 卸载所有软件包
      ./scripts/feeds uninstall 软件包名称  # 卸载指定的软件包,这里是具体的软件包名字,比如一个仓库可能有很多软件包,这里不能是仓库名字,必须是软件包得名字
      
  • clean

    删除update命令下载和生成的索引文件,但不会删除install创建的链接。

  • update

    • 说明升级软件包.conf中指定的库

    • 命令格式

      ./scripts/feeds update  -a         					#升级.conf中所有的库列表 并创建index
      ./scripts/feeds update  软件包名称  		#升级指软件包
      
      ./scripts/feeds update  -i 							#重建索引文件,不会拉代码
      

feeds代码处理过程是这样的:这个命令首先读取并解析feeds.conf或者feeds.conf.default配置文件,然后执行相应的命令,例如install时,将安装feeds.conf或者feeds.conf.default里面所指示的应用程序包和直接或间接依赖的所有软件包。安装时将创建一个符号链接,package/feeds/$package_name指向feeds/$package_name, 这样在make menuconfig时,feeds的软件包就可以被处理到,就可以选择编译了。

feeds.conf

我们可以修改该文件使编译时从自己指定的位置进行下载。主要支持feed方法的类型有以下3种:

  • src-cpy:通过从数据源path拷贝数据

  • src-git:通过使用Git从代码仓库地址下载代码数据。

  • src-svn:通过使用SVN从代码仓库地址下载代码数据。

  • src-bzr:通过使用bzr从数据源的path/URL下载数据

  • src-darcs:通过使用darcs从数据源path/URL下载数据

  • src-hg:通过使用hg从数据源path/URL下载数据

  • src-link:创建一个数据源path的symlink,例如本地链接src-link qca_hk ../qca/feeds/qca_hk

常用命令

全部更新安装

./scripts/feeds update -a  #根据配置下载所有软件包或者依赖到feeds/目录下,并更新feed.index文件
./scripts/feeds install -a #创建 package/feeds/软件包 的软链接指向 feeds/软件包

单独更新安装软件包

./scripts/feeds update luci #从仓库把luci代码根据feed.conf拉到 feeds/目录下
./scripts/feeds install -a -p luci  # 安装luci目录下的所有软件包,软连接到 package/feeds/目录下

feed机制实际操作

一个仓库下可能存在一个或者多个软件包,如下:wifi6仓库下的wim_apps文件夹下面存在很多软件包

├── doc
│   ├── 00.测试固件备份
│   ├── 01.qsdk环境搭建
│   ├── 02.chenqiao_driver文档
│   └── 02.cq driver文档
├── media
└── wim_apps
    ├── luci-app-network-service     # 软件包1
    ├── luci-app-roam							# 软件包2
    ├── luci-app-wim							 # 软件包3
    ├── web_modify								# 软件包……
    ├── wim-alpm
    ├── wim-app
    ├── wim-hostap
    ├── wim-lib
    ├── wim-luci-app-qos
    ├── wim-neighborlist
    ├── wim-qca-wifi
    ├── wim-qos-scripts
    ├── wim-relearning
    ├── wim-roam
    ├── wim-snmp-lib
    ├── wim-snmp-subagent
    ├── wim-wdt
    ├── wim-wpa
    └── wim-wpa-supplicant

我们应该如何把wifi6仓库通过feeds机制添加到OpenWrt的编译机制中?

  1. 修改 feeds.conf 文件,新增下面的内容

    # src-git   																							:使用git方式     
    # wifi6 																								:下载后存放在feeds目录下的文件夹名字,不是仓库名字
    #  ssh://xiong@192.168.2.222:29418/wifi6.git				  : 仓库git地址
    
    src-git   wifi6     ssh://xiong@192.168.2.222:29418/wifi6.git
    
  2. 执行./scripts/feeds update wifi6

    该步骤是脚本会从仓库把代码下载到feeds/wifi6目录下,并在feeds下创建索引,如下:

    • feeds/wifi6目录下存放的git仓库的所有内容,

    • wifi6.index存放的是带有目录下带有OpenWrt能认识的软件包信息,内容大致如下:

      Source-Makefile: feeds/wifi6/wim_apps/wim-relearning/Makefile
      Package: wim-relearning
      Version: 1.0
      Depends: +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread +libstdcpp +libuv +libuci
      Conflicts: 
      Menu-Depends: 
      Provides: 
      Section: net
      Category: Network
      Title: wim-relearning utility
      Maintainer: 
      Source: 
      Type: ipkg
      Description: 	This is wifi6 wim-relearning Project.
      
      @@
      
      
      Source-Makefile: feeds/wifi6/wim_apps/wim-roam/Makefile
      Package: wim-roam
      Version: 1.0
      Depends: +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread +libstdcpp +qca-cfg80211 +qca-cfg80211tool +libuv +libuci +libjson-c
      Conflicts: 
      Menu-Depends: 
      Provides: 
      Section: net
      Category: Network
      Title: wim-roam utility
      Maintainer: 
      Source: 
      Type: ipkg
      Description: 	This is wifi6 wim-roam Project.
      
      @@
      
    • 和wifi6.targetindex 暂时先不管

    • 总结:该步骤仅仅是把代码下载到feeds/wifi6目录下,此时make menuconfig 还是看不到的

  3. 安装feeds/wifi6/目录下的软件包到package/feeds目录下

    OpenWrt的机制,带有Makefile的软件包 只有放到package目录下,才能被编译机制看到,故而,该步骤仅仅是以软连接的形式,把feeds/wifi6/目录下的软件包,连接到package/feeds目录下。

    两种情况:

    • 安装feeds/wifi6目录下的所有软件包,命令如下:

      ./scripts/feeds install -a -p wifi6
      

      此时就是执行的

      # 循环遍历 feeds/wifi6/所有软件包,
      ln -sf   feeds/wifi6/wim_apps/包名     package/feeds/wifi6/包名
      
      #也就是为每个包到创建了一个软连接到package/feeds/wifi6/目录下,这样编译就能看到了
      

      效果如下:

      **注意:**这里不能是下面的命令

      ./scripts/feeds install  wifi6
      
    • 安装feeds/wifi6目录下的一个具体软件包,比如wim-roam

      ./scripts/feeds install wim-roam
      
      #同理该命令仅仅是创建一个软连接,注意这里在package/feeds/wifi6/已经省略了wim_apps目录
      ln -sf   feeds/wifi6/wim_apps/wim-roam     package/feeds/wifi6/wim-roam 
      
  4. 卸载

    • 卸载所有

      由于feed机制的限制,我们无法使用命令全部卸载package/feeds/wifi6/目录下的所有软件

      只有一个方法。要不使用./scripts/feeds uninstall -a 卸载所有的,除了wifi6的,谨慎使用

      要不,使用单个卸载,一个一个卸载,

      无法执行下面的命令,下面都是错误的

      ./scripts/feeds uninstall wifi6
      ./scripts/feeds uninstall -a wifi6
      ./scripts/feeds uninstall -a -p wifi6
      ./scripts/feeds uninstall -p wifi6
      
    • 卸载一个

      ./scripts/feeds uninstall wim-roam
      

      注意该命令仅仅是删了package/feeds/wifi6/wim-roam软连接,feeds/wifi6/wim_apps/wim-roam 还在

  5. 注意事项

    如果安装的时候提示:

    WARNING: No feed for package 'libnetsnmpagent' found, maybe it's already part of the standard packages?

    或者package/feeds/目录下并没有安装成功,

    可以在安装的时候加上-f 选项,如下:

    ./scripts/feeds install -a -p wifi6 -f
    
    #或者单独的包的时候
    ./scripts/feeds install wim-roam -f
    
    
    
    

    这是因为在tmp/info目录下存在认为已经安装的索引,feeds脚本认为安装过了,所以使用-f选项或者把tmp/info对应这些索引删除掉也行。

    ll tmp/info
    
    -rw-rw-r-- 1 book book  12495 3   1 15:53 .packageinfo-feeds_wifi6_luci-app-network-service
    -rw-rw-r-- 1 book book    422 3   1 15:53 .packageinfo-feeds_wifi6_luci-app-roam
    -rw-rw-r-- 1 book book    414 3   1 15:53 .packageinfo-feeds_wifi6_luci-app-wim
    -rw-rw-r-- 1 book book    362 3   1 15:53 .packageinfo-feeds_wifi6_web_modify
    -rw-rw-r-- 1 book book    352 3   1 15:53 .packageinfo-feeds_wifi6_wim-alpm
    -rw-rw-r-- 1 book book    387 3   1 15:53 .packageinfo-feeds_wifi6_wim-app
    -rw-rw-r-- 1 book book    348 3   1 15:53 .packageinfo-feeds_wifi6_wim-lib
    -rw-rw-r-- 1 book book  11920 3   1 15:53 .packageinfo-feeds_wifi6_wim-luci-app-qos
    -rw-rw-r-- 1 book book    401 3   1 15:53 .packageinfo-feeds_wifi6_wim-neighborlist
    -rw-rw-r-- 1 book book    358 3   1 15:53 .packageinfo-feeds_wifi6_wim-qca-wifi
    -rw-rw-r-- 1 book book    656 3   1 15:53 .packageinfo-feeds_wifi6_wim-qos-scripts
    -rw-rw-r-- 1 book book    400 3   1 15:53 .packageinfo-feeds_wifi6_wim-relearning
    -rw-rw-r-- 1 book book    419 3   1 15:47 .packageinfo-feeds_wifi6_wim-roam
    -rw-rw-r-- 1 book book   3994 3   1 15:53 .packageinfo-feeds_wifi6_wim-snmp-lib
    -rw-rw-r-- 1 book book    552 3   1 15:53 .packageinfo-feeds_wifi6_wim-snmp-subagent
    -rw-rw-r-- 1 book book    357 3   1 15:53 .packageinfo-feeds_wifi6_wim-wdt
    -rw-rw-r-- 1 book book    398 3   1 15:53 .packageinfo-feeds_wifi6_wim-wpa
    -rw-rw-r-- 1 book book    382 3   1 15:53 .packageinfo-feeds_wifi6_wim-wpa-supplicant
    -rw-rw-r-- 1 book book   4473 3   1 15:53 .packageinfo-feeds_wifi6_wim-wpa-supplicant_files