当前位置 博文首页 > 想要去旅行:OpenWrt uboot 编译时间戳问题

    想要去旅行:OpenWrt uboot 编译时间戳问题

    作者:[db:作者] 时间:2021-08-31 15:54

    OpenWrt uboot 编译时间戳问题

    背景

    在uboot 启动过程中会有如下打印:

    U-Boot SPL 2017.11 (Aug 16 2018 - 07:51:15)
    DRAM: 128 MiB
    Trying to boot from MMC1

    U-Boot 2017.11 (Aug 16 2018 - 07:51:15 +0000) Allwinner Technology

    通常我们需要通过编译时间来区分uboot 版本。在使用OpenWrt 编译时uboot 时发现上面的时间戳并不会变。造成版本不易区分问题。

    要解决这问题需要清楚:

    • 编译时间戳是如何生成的?

    uboot 编译时间戳是如何生成的?

    在uboot 的Makefile 中有如下定义

    # The SOURCE_DATE_EPOCH mechanism requires a date that behaves like GNU date.
    # The BSD date on the other hand behaves different and would produce errors
    # with the misused '-d' switch.  Respect that and search a working date with
    # well known pre- and suffixes for the GNU variant of date.
    define filechk_timestamp.h
            (if test -n "$${SOURCE_DATE_EPOCH}"; then \
                    SOURCE_DATE="@$${SOURCE_DATE_EPOCH}"; \
                    DATE=""; \
                    for date in gdate date.gnu date; do \
                            $${date} -u -d "$${SOURCE_DATE}" >/dev/null 2>&1 && DATE="$${date}"; \
                    done; \
                    if test -n "$${DATE}"; then \
                            LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DATE "%b %d %C%y"'; \
                            LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TIME "%T"'; \
                            LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \
                            LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
                            LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
                    else \
                            return 42; \
                    fi; \
            else \
                    LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
                    LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
                    LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \
                    LC_ALL=C date +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
                    LC_ALL=C date +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
            fi)
    endef
    

    这上面首先判断在环境变量中是否定义了 SOURCE_DATE_EPOCH ,有则使用 SOURCE_DATE_EPOCH 生成时间戳,没有则使用当前时间。

    在OpenWrt 的编译环境中,是会定义 SOURCE_DATE_EPOCH 的,位于openwrt/include/toplevel.mk

    ifeq ($(SDK),1)
      include $(TOPDIR)/include/version.mk
    else
      REVISION:=$(shell $(TOPDIR)/scripts/getver.sh)
      SOURCE_DATE_EPOCH:=$(shell $(TOPDIR)/scripts/get_source_date_epoch.sh)
    endif
    

    其使用 $(TOPDIR)/scripts/get_source_date_epoch.sh 来获取时间戳,scripts/get_source_date_epoch.sh 内容如下:

    #!/usr/bin/env bash
    export LANG=C
    export LC_ALL=C
    [ -n "$TOPDIR" ] && cd $TOPDIR
    
    try_version() {
            [ -f version.date ] || return 1
            SOURCE_DATE_EPOCH="$(cat version.date)"
            [ -n "$SOURCE_DATE_EPOCH" ]
    }
    
    try_git() {
            [ -e .git ] || return 1
            SOURCE_DATE_EPOCH="$(git log -1 --format=format:%ct)"
            [ -n "$SOURCE_DATE_EPOCH" ]
    }
    
    try_hg() {
            [ -d .hg ] || return 1
            SOURCE_DATE_EPOCH="$(hg log --template '{date}' -l 1 | cut -d. -f1)"
            [ -n "$SOURCE_DATE_EPOCH" ]
    }
    
    try_mtime() {
            perl -e 'print((stat $ARGV[0])[9])' "$0"
            [ -n "$SOURCE_DATE_EPOCH" ]
    }
    
    try_version || try_git || try_hg || try_mtime || SOURCE_DATE_EPOCH=""
    echo "$SOURCE_DATE_EPOCH"
    

    其首先从 version.date 文件中读取时间戳,失败的话尝试使用git ,hg ,mtime 时间戳。

    而我当前环境是存在 version.date 文件的

    openwrt$ cat version.date
    1534405875

    这就难怪每次编译uboot 时间戳都是一样的了( Aug 16 2018 - 07:51:15)。

    解决:

    #!/usr/bin/env bash
    export LANG=C
    export LC_ALL=C
    [ -n "$TOPDIR" ] && cd $TOPDIR
    
    
    try_date_now(){
            SOURCE_DATE_EPOCH="$(date +%s)"
    }
    ...
    
    try_date_now ||try_version || try_git || try_hg || try_mtime || SOURCE_DATE_EPOCH=""
    echo "$SOURCE_DATE_EPOCH"
    
    cs
    下一篇:没有了