uboot版本信息

VERSION = 2006 主版本号

PATCHLEVEL = 03 补丁版本号

SUBLEVEL = 次此版本号
EXTRAVERSION =  附加版本
NAME 
 
 
 

MAKEFLAGS变量

$(MAKE) -C subdir $(MAKE)就是调用“make”命令,-C 指定子目录
export VARIABLE …… //导出变量给子 make 。
unexport VARIABLE…… //不导出变量给子 make。
MAKEFLAGS += -rR --include-dir=$(CURDIR) 上述代码使用“+=”来给变量 MAKEFLAGS 追加了一些值,“-rR”表示禁止使用内置的隐含规则和变量定义,“--include-dir”指明搜索路径,”$(CURDIR)”表示当前目录。
 
 
命令输出
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif
 
ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif
 
 
V=1 的话:
KBUILD_VERBOSE=1
quiet= 空 。
Q= 空。
V=0 或者命令行不定义 V 的话:
KBUILD_VERBOSE=0
quiet= quiet_。
Q= @。
 
make V=1  变量V=1
 
静默输出
 
ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
  ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
    quiet=silent_
  endif
else # make-3.8x
  ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  quiet=silent_
endif
 
export quiet Q KBUILD_VERBOSE
 
make -s  选项中的第一个单词
 
 
设置编译结果输出目录
 make O=out 生成的文件和源文件分开, 否则生成的文件在源文件的目录
 
 
代码检查
使用命令“make C=1”使能代码检查,检查那些需要重新编译的文
件。“make C=2”用于检查所有的源码文件
 
 
模块编译
使用命令“make M=dir”即可,旧语法“make
SUBDIRS=dir”也是支持的
 
ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif
 
ifeq ($(KBUILD_SRC),)
# building in the source tree
  srctree := .
else
  ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))
    # building in a subdirectory of the source tree
    srctree := ..
  else
    srctree := $(KBUILD_SRC)
  endif
endif
objtree := .
src := $(srctree)
obj := $(objtree)
 
VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
export srctree objtree VPATH
 
 
获取主机架构和系统
 
HOSTARCH := $(shell uname -m | \
  sed -e s/i.86/x86/ \
    -e s/sun4u/sparc64/ \
    -e s/arm.*/arm/ \
    -e s/sa110/arm/ \
    -e s/ppc64/powerpc/ \
    -e s/ppc/powerpc/ \
    -e s/macppc/powerpc/\
    -e s/sh.*/sh/)
 
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
  sed -e 's/\(cygwin\).*/cygwin/')
 
export HOSTARCH HOSTOS
 
设置目标架构、交叉编译器和配置文件 
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
  CROSS_COMPILE ?=
endif
 
KCONFIG_CONFIG ?= .config
export KCONFIG_CONFIG
 
调用 scripts/Kbuild.include
scripts/Kbuild.include: ;
include scripts/Kbuild.include
 
交叉编译工具变量设置
# Make variables (CC, etc...)
AS  = $(CROSS_COMPILE)as
# Always use GNU ld
ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
  LD = $(CROSS_COMPILE)ld.bfd
else
  LD= $(CROSS_COMPILE)ld
endif
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
 
 
导出其他变量
export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
export MAKE AWK PERL PYTHON
export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGS
 
export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS KBUILD_AFLAGS
 
 
config.mk 配置了ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR等
 
make xxx_defconfig 过程

version_h := include/generated/version_autogenerated.h
timestamp_h := include/generated/timestamp_autogenerated.h
 
no-dot-config-targets := clean clobber mrproper distclean \
  help %docs check% coccicheck \
  ubootversion backup
 
config-targets := 0
mixed-targets := 0
dot-config := 1
 
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
  ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
    dot-config := 0
  endif
endif
 
ifeq ($(KBUILD_EXTMOD),)
  ifneq ($(filter config %config,$(MAKECMDGOALS)),)
    config-targets := 1
    ifneq ($(words $(MAKECMDGOALS)),1)
      mixed-targets := 1
    endif
  endif
endif 
 
%config: scripts_basic outputmakefile FORCE
  $(Q)$(MAKE) $(build)=scripts/kconfig $@
 
 
 
MAKECMDGOALS 是 make 的一个环境变量,这个变量会保存你所指定的终极目标列表,比如执行“make mx6ull_alientek_emmc_defconfig”
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)    保留$(MAKECMDGOALS)符合$(no-dot-config-targets)的部分,
这里得到了空,ifneq不成立, dot-config := 1保持不变

 
不单独编译模块则$(KBUILD_EXTMOD)为空, 所以ifeq ($(KBUILD_EXTMOD),)成立
ifneq ($(filter config %config,$(MAKECMDGOALS)),)的%config匹配了make mx6ull_alientek_emmc_defconfig
所以config-targets := 1
 
ifneq ($(words $(MAKECMDGOALS)),1) 多个目标, 这里不成立
 
因此最后有
config-targets = 1
mixed-targets = 0
dot-config = 1
 
make mx6ull_alientek_emmc_defconfig 匹配了目标 %config
%config: scripts_basic outputmakefile FORCE
  $(Q)$(MAKE) $(build)=scripts/kconfig $@
 
其中FORCE没有规则和依赖, 因此FORCE总是新的, 因此$(Q)$(MAKE) $(build)=scripts/kconfig $@总是被执行
PHONY += scripts_basic
PHONY += FORCE  
FORCE:
 
PHONY += scripts_basic
scripts_basic:
  $(Q)$(MAKE) $(build)=scripts/basic
  $(Q)rm -f .tmp_quiet_recordmcount
 
scripts/basic/%: scripts_basic ;
 
变量 build 是在 scripts/Kbuild.include 文件中有定义,定义如下:
build := -f $(srctree)/scripts/Makefile.build obj
即build=-f ./scripts/Makefile.build obj
scripts_basic 展开以后如下
scripts_basic:
  @make -f ./scripts/Makefile.build obj=scripts/basic //也可以没有@,视配置而定
  @rm -f . tmp_quiet_recordmcount //也可以没有@
 
同样 %config展开有
%config: scripts_basic outputmakefile FORCE    
  $(Q)$(MAKE) $(build)=scripts/kconfig $@   =>  @make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
 
PHONY += outputmakefile
outputmakefile:
ifneq ($(KBUILD_SRC),)
  $(Q)ln -fsn $(srctree) source
  $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif
 
 这里$(KBUILD_SRC)为空, ifneq ($(KBUILD_SRC),)不成立
 
最终
scripts_basic 目标对应的命令 @make -f ./scripts/Makefile.build obj=scripts/basic

%config 目标对应的命令 @make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
其中 %config依赖scripts_basic,另外两个outputmakefile, FORCE没有构建命令
 
Makefile.build 脚本分析
 
scripts_basic 目标对应的命令
 
# Modified for U-Boot
prefix := tpl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := spl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := .
endif
endif
 
对于@make -f ./scripts/Makefile.build obj=scripts/basic
有src := $(patsubst $(prefix)/%,%,$(obj)) = $(patsubst tpl/%,%, scripts/basic), 其中scripts/basic不符合tpl/%, 没有东西被替换
所以src := scripts/basic    prefix  := .
 

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
 
将 kbuild-dir 展开后为 
$(if $(filter /%, scripts/basic), scripts/basic, ./scripts/basic),
以$(filter /%, scripts/basic)的结果为空, 所以kbuild-dir=./scripts/basic
 
将 kbuild-file 展开后为
$(if $(wildcard ./scripts/basic/Kbuild), ./scripts/basic/Kbuild, ./scripts/basic/Makefile)
因为 scrpts/basic 目录中没有 Kbuild 这个文件,所以 kbuild-file= ./scripts/basic/Makefile
 
最后为 include ./scripts/basic/Makefile
 
 
 
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
  @:
 
__build 是默认目标,因为命令“@make -f ./scripts/Makefile.build obj=scripts/basic”没有指定目标,所以会使用到默认目标:__build
在顶层 Makefile 中,KBUILD_BUILTIN 为 1,KBUILD_MODULES 为 0,因此展开后目标__build 为:
__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)
  @:
 
只有 always 有效,因此__build 最终为 __build: scripts/basic/fixdep
scripts_basic 目标的作用就是编译出 scripts/basic/fixdep 这个软件
 
%config 目标对应的命令
@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
src= scripts/kconfig
kbuild-dir = ./scripts/kconfig
kbuild-file = ./scripts/kconfig/Makefile
include ./scripts/kconfig/Makefile
可以看出,Makefilke.build 会读取 scripts/kconfig/Makefile 中的内容,此文件有如下所示内容
%_defconfig: $(obj)/conf
  $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
 
 # Added for U-Boot (backward compatibility)
%_config: %_defconfig
  @:
 
$(obj)/conf 为编译出来的主机工具
$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)最终是@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig
 
最后make xxx_defconfig 执行流程总结
make xxx_defconfig -> 顶层Makefile中的%config
依赖  
  scripts_basic
    make -f ./scripts/Makefile.build obj=scripts/basic  -> 生成 script/basic/fixdep
  outputmakefile
  FORCE
 
命令 make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig 生成  scripts/kconfig/conf 
命令 scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig 生成 .config
 
 

make 过程
PHONY := _all
_all:
 
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
_all: modules
endif
 
在主 Makefile 中 all 目标规则如下
all: $(ALL-y)
ifneq ($(CONFIG_SYS_GENERIC_BOARD),y)
  @echo "===================== WARNING ======================"
  @echo "Please convert this board to generic board."
  @echo "Otherwise it will be removed by the end of 2014."
  @echo "See doc/README.generic-board for further information"
  @echo "===================================================="
endif
ifeq ($(CONFIG_DM_I2C_COMPAT),y)
  @echo "===================== WARNING ======================"
  @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
  @echo "(possibly in a subsequent patch in your series)"
  @echo "before sending patches to the mailing list."
  @echo "===================================================="
endif
 
all 目标依赖$(ALL-y),而在顶层 Makefile 中,ALL-y 如下
# Always append ALL so that arch config.mk's can add custom ones
ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
 
ifeq ($(CONFIG_SPL_FSL_PBL),y)
  ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin
else
  ifneq ($(CONFIG_SECURE_BOOT), y)
     # For Secure Boot The Image needs to be signed and Header must also
    # be included. So The image has to be built explicitly
    ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl
  endif
endif
 
ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin
ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb
ifeq ($(CONFIG_SPL_FRAMEWORK),y)
  ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img
endif
ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb
ifneq ($(CONFIG_SPL_TARGET),)
  ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
endif
ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
 
ifneq ($(BUILD_ROM),)
  ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
endif
 
# enable combined SPL/u-boot/dtb rules for tegra
ifeq ($(CONFIG_TEGRA)$(CONFIG_SPL),yy)
  ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin
  ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
endif
 
# Add optional build target if defined in board/cpu/soc headers
ifneq ($(CONFIG_BUILD_TARGET),)
  ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
endif
 
ALL-y 包含 u-boot.srec、u-boot.bin、u-boot.sym、System.map、u-boot.cfg 和 binary_size_check 这几个文件。
根据 uboot 的配置情况也可能包含其他的文件,比如:ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
 
 
ALL-y 里面有个 u-boot.bin,这个就是我们最终需要的 uboot 二进制可执行文件,所作的所有工作就是为了它。在顶层 Makefile 中找到 u-boot.bin 目标对应的规则
ifeq ($(CONFIG_OF_SEPARATE),y)
u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE
  $(call if_changed,cat)
 
u-boot.bin: u-boot-dtb.bin FORCE
  $(call if_changed,copy)
else
u-boot.bin: u-boot-nodtb.bin FORCE
  $(call if_changed,copy)
endif
 
if_changed 是 一 个 函 数 , 这 个 函 数 在scripts/Kbuild.include 中有定义,而顶层 Makefile 中会包含 scripts/Kbuild.include 文件
ifneq ($(KBUILD_NOCMDDEP),1)
  arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) $(filter-out $(cmd_$@), $(cmd_$(1))) )
else  
  arg-check = $(if $(strip $(cmd_$@)),,1)
endif
 
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
 
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \

  @set -e;  \

  $(echo-cmd) $(cmd_$(1));  \
  printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
 
if_change引用变量太多, 只要知道它从 u-boot-nodtb.bin 生成 u-boot.bin 就行了
 
 
目标 u-boot 依赖于 u-boot_init、u-boot-main 和 u-boot.lds
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
 
head-y := arch/arm/cpu/$(CPU)/start.o
=> head-y := arch/arm/cpu/armv7/start.o

=> u-boot-init= arch/arm/cpu/armv7/start.o
 
620 libs-y += lib/
621 libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
622 libs-$(CONFIG_OF_EMBED) += dts/
623 libs-y += fs/
624 libs-y += net/
625 libs-y += disk/
626 libs-y += drivers/
627 libs-y += drivers/dma/
628 libs-y += drivers/gpio/
629 libs-y += drivers/i2c/
......
660 libs-y += cmd/
661 libs-y += common/
662 libs-$(CONFIG_API) += api/
663 libs-$(CONFIG_HAS_POST) += post/
664 libs-y += test/
665 libs-y += test/dm/
666 libs-$(CONFIG_UT_ENV) += test/env/
667
668 libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
669
670 libs-y := $(sort $(libs-y))
671
672 u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools
examples
673
674 u-boot-alldirs := $(sort $(u-boot-dirs)
$(patsubst %/,%,$(filter %/, $(libs-))))
675
676 libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
 
u-boot.lds: $(LDSCRIPT) prepare FORCE
  $(call if_changed_dep,cpp_lds)
 
built-in.o 是怎么生成的,以 drivers/gpio/built-in.o 为例
在drivers/gpio/目录下会有个名为.built-in.o.cmd 的文件
cmd_drivers/gpio/built-in.o := arm-linux-gnueabihf-ld.bfd -r -o drivers/gpio/built-in.o drivers/gpio/mxc_gpio.o
 -r =>  -r –relocateable: 产生可重定向的输出,比如,产生一个输出文件它可再次作为‘ld’的输入,这经常被叫做“部分链接”,当我们需要将几个小的.o 文件链接成为一个.o 文件的时候,需要使用此选项

 
 
最终
arm-linux-gnueabihf-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x87800000 \
-o u-boot -T u-boot.lds \
arch/arm/cpu/armv7/start.o \
--start-group arch/arm/cpu/built-in.o \
arch/arm/cpu/armv7/built-in.o \
arch/arm/imx-common/built-in.o \
arch/arm/lib/built-in.o \
board/freescale/common/built-in.o \
board/freescale/mx6ull_alientek_emmc/built-in.o \
cmd/built-in.o \
common/built-in.o \
disk/built-in.o \
drivers/built-in.o \
drivers/dma/built-in.o \
drivers/gpio/built-in.o \
……
drivers/spi/built-in.o \
drivers/usb/dwc3/built-in.o \
drivers/usb/emul/built-in.o \
drivers/usb/eth/built-in.o \
drivers/usb/gadget/built-in.o \
drivers/usb/gadget/udc/built-in.o \
drivers/usb/host/built-in.o \
drivers/usb/musb-new/built-in.o \
drivers/usb/musb/built-in.o \
drivers/usb/phy/built-in.o \
drivers/usb/ulpi/built-in.o \
fs/built-in.o \
lib/built-in.o \
net/built-in.o \
test/built-in.o \
test/dm/built-in.o \
--end-group arch/arm/lib/eabi_compat.o \
-L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux
gnueabihf/4.9.4 -lgcc -Map u-boot.map
 
arm-linux-gnueabihf-ld.bfd 命令将 arch/arm/cpu/armv7/start.o 和其他众多的 built_in.o 链接在一起,形成 u-boot
 
 
最后的总结
make xxx_defconfig:用于配置 uboot,这个命令最主要的目的就是生成.config 文件
make:用于编译 uboot,这个命令的主要工作就是生成二进制的 u-boot.bin 文件和其他的一些与 uboot 有关的文件,比如 u-boot.imx 等等。
 

uboot之顶层Makefile的更多相关文章

  1. UBOOT编译--- UBOOT顶层Makefile中目标_all和all的关系及背景(四)

    @ 目录 1. 前言 2. 概述 3. 老版本UBOOT(背景) 4. 新版本UBOOT 5. 参考 1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 概 ...

  2. uboot 顶层makefile细节分析

    uboot的源文件众多,学习庞然大物首先找到脊椎--顶层的makfile,逐一破解.但是,uboot的makefile同样是一个庞然大物,所以也要找到它的主线.倘若过分专注部分细节,很难做到把握全局, ...

  3. TQ210 —— S5PV210 uboot顶层Makefile分析

    转自:http://blog.csdn.net/wqx521/article/details/52469759 # (C) Copyright 2000-2008 # Wolfgang Denk, D ...

  4. 内核顶层Makefile相关3

    http://www.groad.net/bbs/simple/?f104.html 伪目标 .PHONY是一个特殊工作目标(special target),它用来指定一个假想的工作目标,也就是说它后 ...

  5. 内核顶层Makefile相关4

    http://www.groad.net/bbs/simple/?f104.html make 的递归执行与 MAKEFLAGS 变量 make 的递归调用是指:在 Makefile 中使用 make ...

  6. u-boot顶层Makefile分析

    1.u-boot制作命令 make forlinx_nand_ram256_config: make all; 2.顶层mkconfig分析,参考 U-BOOT顶层目录mkconfig分析 mkcon ...

  7. UBOOT编译--- UBOOT的顶层config.mk(五)

    1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 概述 此文件包含在 ./Makefile 和 spl/Makefile 中. 清理状态以避免添加两次相同 ...

  8. Uboot 2014.07 makefile分析 - 其他Cortex系列

    uboot的官网可以通过谷歌搜索得到,显示结果第一个链接就是. 官网:: http://www.denx.de/wiki/U-Boot ftp下载: ftp://ftp.denx.de/pub/u-b ...

  9. u-boot中的Makefile

    在windos下,pc机上电之后,BIOS会初始化硬件配置,为内核传递参数,引导操作系统启动,并且识别C盘.D盘.等整个操作系统启动起来之后,才可以运行应用程序比如QQ.QQ音影.同理,在嵌入式Lin ...

  10. 内核顶层Makefile相关1

    http://www.groad.net/bbs/simple/?f104.htm $(Q) 变量 内核 Makefile 文件 238 行到 259 行的注释中知道,$(Q) 变量的作用是决定是否在 ...

随机推荐

  1. vcenter异常死机无法重启

    esxi主机异常掉电重启后,vcenter启动失败 查阅相关资料发现,一般是由于时间同步异常造成, 推荐方法是先确认bios硬件时间已同步,再删除旧的本地服务json文件,重启vcenter的服务. ...

  2. Shell脚本--信号发送与捕捉

    信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相 应的处理函数. 进程可以通过三种方式来响应一个信号: 忽略信号,即对信号不做任何处理,其中有两个信号不能忽 ...

  3. linux系统移植

    1 linux环境搭建 1.1 添加交叉开发工具链 新建如下工程目录: gcc-4.6.4.tar.xz #拷贝 tar -Jxvf gcc-4.6.4.tar.xz #解压 cd ./gcc-4.6 ...

  4. ValueError: Detected newline in header value. This is a potential security problem

    原因 flask框架进行重定向的url中包含 换行符\n或\r 解决方法 使用 strip() 函数去除行首或行尾的换行符(如果你url中间包含这些符号replace函数替换, 但是如果中间包含只能说 ...

  5. 一次MTU问题导致的RDS访问故障

    导语 VPN是一种通过公网连接两个或多个私网站点的专用网络,使得这些站点仿佛是通过专线连接在一起.IPSec是一套协议框架,用于保证数据传输的私密性,完整性,真实性.但是VPN网络经常会带来一些连通性 ...

  6. 你的项目使用Optional了吗?

    1.基本概念 java.util.Optional<T>类本质上就是一个容器,该容器的数值可以是空代表一个值不存在,也可以是非空代表一个值存在. 2.获取对象 2.1 相关方法 2.2 案 ...

  7. 秒级查询之开源分布式SQL查询引擎Presto实操-上

    @ 目录 概述 定义 概念 架构 优缺点 连接器 部署 集群安装 常用配置说明 资源管理安装模式 安装命令行界面 基于Tableau Web 连接器 使用优化 数据存储 查询SQL优化 无缝替换Hiv ...

  8. linux安装influxdb和chronograf

    安装环境: Alibaba Cloud Linux 安装influxdb 1.下载.安装 wget https://dl.influxdata.com/influxdb/releases/influx ...

  9. python注释、变量、数据类型详细

    目录 1.python注释 2.PEP8规范 3.变量与常量 1.python中的变量 2.变量名的命名规范 3.常量的基本使用 1.python注释 什么是注释? 注释是对代码的解释说明,写注释是为 ...

  10. python多进程程序打包成exe的问题

    粘贴一下部分的多进程代码 if __name__ == '__main__': """"流程模拟""" multiprocessi ...