草庐IT

UBOOT编译--- include/config.h、 include/autoconf.mk、include/autoconf.mk.dep、u-boot.cfg(三)

BSP-路人甲 2023-03-28 原文

1. 前言

 UBOOT版本:uboot2018.03,开发板myimx8mmek240。

2. 概述

本节主要接上一节解析 :include/config.h、 include/autoconf.mk、include/autoconf.mk.dep、spl/include/autoconf.mk、u-boot.cfg、spl/u-boot.cfg。

3 语句 $ (Q) $(MAKE) -f $(srctree)/scripts/Makefile.autoconf

由于未指定目标,采用默认目标__all

#note:scripts/Makefile.autoconf
__all: include/autoconf.mk include/autoconf.mk.dep

ifeq ($(shell grep -q '^CONFIG_SPL=y' include/config/auto.conf 2>/dev/null && echo y),y) //本人单板该条件成立
__all: spl/include/autoconf.mk

endif


include/autoconf.mk.dep: include/config.h FORCE
	$(call cmd,autoconf_dep)
	
spl/include/autoconf.mk: spl/u-boot.cfg
	$(Q)mkdir -p $(dir $@)
	$(call cmd,autoconf)
	
	
u-boot.cfg: include/config.h FORCE
	$(call cmd,u_boot_cfg)

spl/u-boot.cfg: include/config.h FORCE
	$(Q)mkdir -p $(dir $@)
	$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD)
	
	
include/config.h: scripts/Makefile.autoconf create_symlink FORCE
	$(call filechk,config_h)

3.1 依赖include/autoconf.mk

include/autoconf.mk: u-boot.cfg
	$(call cmd,autoconf)
u-boot.cfg: include/config.h FORCE
	$(call cmd,u_boot_cfg)

3.1.1 include/config.h的规则

include/config.h: scripts/Makefile.autoconf create_symlink FORCE
	$(call filechk,config_h)
3.1.1.1 FORCE

参见UBOOT编译--- make xxx_deconfig过程详解(一)4.3小节。

为mach相关的头文件在arch/arm/include/asm/arch创建软连接。

#note:scripts/Makefile.autoconf
# symbolic links
# If arch/$(ARCH)/mach-$(SOC)/include/mach exists,
# make a symbolic link to that directory.
# Otherwise, create a symbolic link to arch/$(ARCH)/include/asm/arch-$(SOC).
PHONY += create_symlink
create_symlink:
ifdef CONFIG_CREATE_ARCH_SYMLINK
ifneq ($(KBUILD_SRC),)
	$(Q)mkdir -p include/asm
	$(Q)if [ -d $(KBUILD_SRC)/arch/$(ARCH)/mach-$(SOC)/include/mach ]; then	\
		dest=arch/$(ARCH)/mach-$(SOC)/include/mach;			\
	else									\
		dest=arch/$(ARCH)/include/asm/arch-$(if $(SOC),$(SOC),$(CPU));	\
	fi;									\
	ln -fsn $(KBUILD_SRC)/$$dest include/asm/arch
else
	$(Q)if [ -d arch/$(ARCH)/mach-$(SOC)/include/mach ]; then	\
		dest=../../mach-$(SOC)/include/mach;			\
	else								\
		dest=arch-$(if $(SOC),$(SOC),$(CPU));			\
	fi;								\
	ln -fsn $$dest arch/$(ARCH)/include/asm/arch
endif
endif

如果采用直接在源目录编译的方式时KBUILD_SRC为空,走else分支。对于我调试的单板ARCH=arm,SOC=imx8m,因此执行else语句展开为:

if [ -d arch/arm/mach-imx8m/include/mach ]; then        \
        dest=../../mach-imx8m/include/mach;                     \
else                                                            \
        dest=arch-imx8m;                        \
fi;                                                             \
ln -fsn $dest arch/arm/include/asm/arch

由于我使用的单板设备商提供的源码中没有arch/arm/mach-imx8m/include/mach 和arch-imx8m目录(而是直接在arch/arm/include/asm/arch目录下提供必要的头文件,当然一般不建议这么做)。执行该句相当于未执行。

3.1.1.3 scripts/Makefile.autoconf

指定的依赖文件。

3.1.1.4 规则 $(call filechk,config_h)
#note:scripts/Kbuild.include
###
# filechk is used to check if the content of a generated file is updated.
# Sample usage:
# define filechk_sample
#	echo $KERNELRELEASE
# endef
# version.h : Makefile
#	$(call filechk,sample)
# The rule defined shall write to stdout the content of the new file.
# The existing file will be compared with the new one.
# - If no file exist it is created
# - If the content differ the new file is used
# - If they are equal no change, and no timestamp update
# - stdin is piped in from the first prerequisite ($<) so one has
#   to specify a valid file as first prerequisite (often the kbuild file)
define filechk
	$(Q)set -e;				\
	$(kecho) '  CHK     $@';		\
	mkdir -p $(dir $@);			\
	$(filechk_$(1)) < $< > $@.tmp;		\
	if [ -r $@ ] && cmp -s $@ $@.tmp; then	\
		rm -f $@.tmp;			\
	else					\
		$(kecho) '  UPD     $@';	\
		mv -f $@.tmp $@;		\
	fi
endef

上述代码中$@为3.2.1小节的目标:‘include/config.h’,‘ $ (1)’为第一个参数config_h,‘$<’ 为第一个依赖scripts/Makefile.autoconf展开为:

	$(Q)set -e;				\
	$(kecho) '  CHK     include/config.h';		\
	mkdir -p $(dir $@);			\
	$(filechk_config_h) < scripts/Makefile.autoconf > include/config.h.tmp;		\
	if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp; then	\
		rm -f include/config.h.tmp;			\
	else					\
		$(kecho) '  UPD     include/config.h';	\
		mv -f include/config.h.tmp include/config.h;		\
	fi

filechk_config_h定义在scripts/Makefile.autoconf中

#note:scripts/Makefile.autoconf
# Prior to Kconfig, it was generated by mkconfig. Now it is created here.
define filechk_config_h
	(echo "/* Automatically generated - do not edit */";		\
	for i in $$(echo $(CONFIG_SYS_EXTRA_OPTIONS) | sed 's/,/ /g'); do \
		echo \#define CONFIG_$$i				\
		| sed '/=/ {s/=/	/;q; } ; { s/$$/	1/; }'; \
	done;								\
	echo \#define CONFIG_BOARDDIR board/$(if $(VENDOR),$(VENDOR)/)$(BOARD);\
	echo \#include \<config_defaults.h\>;				\
	echo \#include \<config_uncmd_spl.h\>;				\
	echo \#include \<configs/$(CONFIG_SYS_CONFIG_NAME).h\>;		\
	echo \#include \<asm/config.h\>;				\
	echo \#include \<linux/kconfig.h\>;				\
	echo \#include \<config_fallbacks.h\>;)
endef

其中CONFIG_SYS_EXTRA_OPTIONS为xxx_deconfig中定义:CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,SPL_TEXT_BASE=0x7E1000"。具体编译命令如下:

set -e; : '  CHK     include/config.h'; mkdir -p include/;      (echo "/* Automatically generated - do not edit */"; for i in $(echo "IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,SPL_TEXT_BASE=0x7E1000" | sed 's/,/ /g'); do echo \#define CONFIG_$i | sed '/=/ {s/=/   /;q; } ; { s/$/ 1/; }'; done; echo \#define CONFIG_BOARDDIR board/myzr/myimx8mm; echo \#include \<config_defaults.h\>; echo \#include \<config_uncmd_spl.h\>; echo \#include \<configs/"myimx8mmek240".h\>; echo \#include \<asm/config.h\>; echo \#include \<linux/kconfig.h\>; echo \#include \<config_fallbacks.h\>;) < scripts/Makefile.autoconf > include/config.h.tmp; if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp; then rm -f include/config.h.tmp; else : '  UPD     include/config.h'; mv -f include/config.h.tmp include/config.h; fi

include/config.h内容如下:


3.1.2 u-boot.cfg的规则 $(call cmd,u_boot_cfg)

#note:scripts/Makefile.autoconf
# echo command.
# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
echo-cmd = $(if $($(quiet)cmd_$(1)),\
	echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)

# printing commands
cmd = @$(echo-cmd) $(cmd_$(1))

quiet定义在顶层Makefile,默认值(空),escsq的作用是转义在回显语句中使用的单引号。为了方便理解,这里把静默编译功能关掉,即quiet=quiet_。

quiet_cmd_u_boot_cfg = CFG     $@     //编译时经常看的就是这句打印
      cmd_u_boot_cfg = \
	$(CPP) $(c_flags) $2 -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && { \
		grep 'define CONFIG_' $@.tmp > $@;			\
		rm $@.tmp;						\
	} || {								\
		rm $@.tmp; false;					\
	}

上诉命展开如下:

  /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -fshort-wchar -O2 -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time  -D__KERNEL__ -D__UBOOT__   -D__ARM__           -fno-pic  -mstrict-align  -ffunction-sections -fdata-sections -fno-common -ffixed-r9    -fno-common -ffixed-x18 -pipe -Iinclude  -I./arch/arm/include -include ./include/linux/kconfig.h  -nostdinc -isystem /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.3.1/include  -DDO_DEPS_ONLY -dM ./include/common.h > u-boot.cfg.tmp && { grep 'define CONFIG_' u-boot.cfg.tmp > u-boot.cfg; rm u-boot.cfg.tmp; } || { rm u-boot.cfg.tmp; false; }

$2为空,编译选项“-dM”的作用是输出include/common.h中定义的所有宏。根据上面的规则,编译器提取include/common.h中(include/common.h文件包含了include/config.h文件,而include/config.h文件又包含了其它头文件,这里面的内容都会得到解析。 )定义的宏,然后输出给u-boot.cfg.tmp,然后查找和处理以“CONFIG_”开头的宏定义的功能并输出给u-boot.cfg。

3.1.3 include/autoconf.mk的规则 $(call cmd,autoconf)

# We are migrating from board headers to Kconfig little by little.
# In the interim, we use both of
#  - include/config/auto.conf (generated by Kconfig)
#  - include/autoconf.mk      (used in the U-Boot conventional configuration)
# The following rule creates autoconf.mk
# include/config/auto.conf is grepped in order to avoid duplication of the
# same CONFIG macros
quiet_cmd_autoconf = GEN     $@     //编译时经常看的就是这句打印
      cmd_autoconf = \
		sed -n -f $(srctree)/tools/scripts/define2mk.sed $< |			\
		while read line; do							\
			if [ -n "${KCONFIG_IGNORE_DUPLICATES}" ] ||			\
			   ! grep -q "$${line%=*}=" include/config/auto.conf; then	\
				echo "$$line";						\
			fi								\
		done > $@

上诉命展开如下:

sed -n -f ./tools/scripts/define2mk.sed u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"; fi done > include/autoconf.mk

上面语句就是寻找u-boot.cfg 中有但是include/config/auto.conf没有的行,并把摘到的内容输出到include/autoconf.mk中

3.2 include/autoconf.mk.dep

include/autoconf.mk.dep: include/config.h FORCE
	$(call cmd,autoconf_dep)
#note:scripts/Makefile.autoconf
# echo command.
# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
echo-cmd = $(if $($(quiet)cmd_$(1)),\
	echo '  $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)

# printing commands
cmd = @$(echo-cmd) $(cmd_$(1))

quiet定义在顶层Makefile,默认值(空),escsq的作用是转义在回显语句中使用的单引号。为了方便理解,这里把静默编译功能关掉,即quiet=quiet_。

quiet_cmd_autoconf_dep = GEN     $@
      cmd_autoconf_dep = $(CC) -x c -DDO_DEPS_ONLY -M -MP $(c_flags) \
	-MQ include/config/auto.conf $(srctree)/include/common.h > $@ || {	\
		rm $@; false;							\
	}

上诉命展开如下:

   /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -x c -DDO_DEPS_ONLY -M -MP -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -fshort-wchar -O2 -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time  -D__KERNEL__ -D__UBOOT__   -D__ARM__           -fno-pic  -mstrict-align  -ffunction-sections -fdata-sections -fno-common -ffixed-r9    -fno-common -ffixed-x18 -pipe -Iinclude  -I./arch/arm/include -include ./include/linux/kconfig.h  -nostdinc -isystem /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.3.1/include -MQ include/config/auto.conf ./include/common.h > include/autoconf.mk.dep || { rm include/autoconf.mk.dep; false; }

分析:include/autoconf.mk.dep依赖 include/config.h,其中include/config.h为动态创建。
(1)-M 生成目标依赖关系,其中目标的格式为源文件去路径文件名+.o后缀。生成文件的依赖关系,同时也把一些标准库的头文件包含了进来。本质是告诉预处理器输出一个适合 make 的规则,用于描述各目标文件的依赖关系。对于每个源文件,预处理器输出 一个 make 规则,该规则的目标项 (target) 是源文件对应的目标文件名,依赖项 (dependency) 是源文件中 “#include” 引用的所有文件,生成的规则可以是单行,但如果太长,就用’'换行符续成多行。规则显示在标准输出,不产生预处理过的 C 程序。
-M 处理后的格式如下:

(2)-MP生成的依赖文件里面,依赖规则中的所有 .h 依赖项都会在该文件中生成一个伪目标,其不依赖任何其他依赖项。该伪规则将避免删除了对应的头文件而没有更新 “Makefile” 去匹配新的依赖关系而导致 make 出错的情况出现。
-MP 处理后的格式如下:

(3)-MQ相当于-MT,覆盖默认的源文件去路径文件名+.o后缀的目标生成格式,采用指定的字符串,这里对应include/config/auto.conf;
-MQ 处理后的格式如下:

(4)$@为自动变量,代表依赖关系中的目标,这里对应include/autoconf.mk.dep;
(5)-x c,指定源文件使用C语言语法;

总体来说:该依赖关系用来生成include/autoconf.mk.dep,生成的方法是生成 include/common.h的依赖关系

3.3 spl/u-boot.cfg

spl/u-boot.cfg: include/config.h FORCE
	$(Q)mkdir -p $(dir $@)
	$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD)

cmd的定义在本篇前面已经讲过,这里略过,直接展开$(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD):

```c
quiet_cmd_u_boot_cfg = CFG     $@     //编译时经常看的就是这句打印
      cmd_u_boot_cfg = \
	$(CPP) $(c_flags) $2 -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && { \
		grep 'define CONFIG_' $@.tmp > $@;			\
		rm $@.tmp;						\
	} || {								\
		rm $@.tmp; false;					\
	}

上诉命展开如下:

 /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -fshort-wchar -O2 -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time  -D__KERNEL__ -D__UBOOT__   -D__ARM__           -fno-pic  -mstrict-align  -ffunction-sections -fdata-sections -fno-common -ffixed-r9    -fno-common -ffixed-x18 -pipe -Iinclude  -I./arch/arm/include -include ./include/linux/kconfig.h  -nostdinc -isystem /home/h/my-work/03_toolchain/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.3.1/include -DCONFIG_SPL_BUILD -DDO_DEPS_ONLY -dM ./include/common.h > spl/u-boot.cfg.tmp && { grep 'define CONFIG_' spl/u-boot.cfg.tmp > spl/u-boot.cfg; rm spl/u-boot.cfg.tmp; } || { rm spl/u-boot.cfg.tmp; false; }

$2为-DCONFIG_SPL_BUILD(新增宏定义CONFIG_SPL_BUILD ),编译选项“-dM”的作用是输出include/common.h中定义的所有宏。根据上面的规则,编译器提取include/common.h中(include/common.h文件包含了include/config.h文件,而include/config.h文件又包含了其它头文件,这里面的内容都会得到解析。 )定义的宏,然后输出给spl/u-boot.cfg.tmp,然后查找和处理以“CONFIG_”开头的宏定义的功能并输出给spl/u-boot.cfg。

spl/u-boot.cfg和u-boot.cfg的区别主要是根据是否定义CONFIG_SPL_BUILD宏,代码会有不同的分支

3.4 spl/include/autoconf.mk

spl/include/autoconf.mk: spl/u-boot.cfg
	$(Q)mkdir -p $(dir $@)
	$(call cmd,autoconf)
# We are migrating from board headers to Kconfig little by little.
# In the interim, we use both of
#  - include/config/auto.conf (generated by Kconfig)
#  - include/autoconf.mk      (used in the U-Boot conventional configuration)
# The following rule creates autoconf.mk
# include/config/auto.conf is grepped in order to avoid duplication of the
# same CONFIG macros
quiet_cmd_autoconf = GEN     $@     //编译时经常看的就是这句打印
      cmd_autoconf = \
		sed -n -f $(srctree)/tools/scripts/define2mk.sed $< |			\
		while read line; do							\
			if [ -n "${KCONFIG_IGNORE_DUPLICATES}" ] ||			\
			   ! grep -q "$${line%=*}=" include/config/auto.conf; then	\
				echo "$$line";						\
			fi								\
		done > $@

上诉命展开如下:

sed -n -f ./tools/scripts/define2mk.sed spl/u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"; fi done > spl/include/autoconf.mk

上面语句就是寻找spl/u-boot.cfg中有但是include/config/auto.conf没有的行,并把摘到的内容输出到spl/include/autoconf.mk中

4. 总结(包含上一篇文章)

#顶层Makefile
|--- include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd //KCONFIG_CONFIG = .config
    |
    |--- $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
    |    |--- #顶层Makefile
    |    |--- %config: scripts_basic outputmakefile FORCE
    |         |--- $(Q)$(MAKE) $(build)=scripts/kconfig $@
    |         |    |--- #scripts/kconfig/Makefile
    |         |    |--- silentoldconfig: $(obj)/conf
    |                  |--- $(Q)mkdir -p include/config include/generated
    |                  |--- $(Q)test -e include/generated/autoksyms.h || touch   include/generated/autoksyms.h
    |                  |--- $< $(silent) --$@ $(Kconfig) //等价于 scripts/kconfig/conf -s --myimx8mmek240-8mm-2g_defconfig .config
    |
    |--- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf //未指定目标,采用默认目标__all
    |    |--- #scripts/Makefile.autoconf
    |    |--- __all: include/autoconf.mk include/autoconf.mk.dep
    |    |    |--- include/autoconf.mk: u-boot.cfg
    |    |    |    |--- $(call cmd,autoconf_dep)//通过编译选项"-M"、"-MP"、"-MQ"生成 include/common.h的依赖关系
    |    |
    |    |---__all: spl/include/autoconf.mk
    |         |--- spl/include/autoconf.mk: spl/u-boot.cfg 
    |    |    |    |--- $(Q)mkdir -p $(dir $@)
    |    |    |    |--- $(call cmd,autoconf)//寻找spl/u-boot.cfg中有但是include/config/auto.conf没有的行,并把摘到的内容输出到spl/include/autoconf.mk中 

include/config.h: scripts/Makefile.autoconf create_symlink FORCE
    $(call filechk,config_h) //生成include/config.h文件

u-boot.cfg: include/config.h FORCE
    $(call cmd,u_boot_cfg) //通过编译选项"-dM"输出include/common.h中定义的所有宏

spl/u-boot.cfg: include/config.h FORCE
    $(Q)mkdir -p $(dir $@)
    $(call cmd,u_boot_cfg,-DCONFIG_SPL_BUILD)//通过宏 CONFIG_SPL_BUILD 和编译选项"-dM"输出include/common.h中定义的所有宏_SPL_BUILD)//通过宏 CONFIG_SPL_BUILD 和编译选项"-dM"输出include/common.h中定义的所有宏                                    

5. 参考

(1)Linux Makefile 生成 *.d 依赖文件以及 gcc -M -MF -MP 等相关选项说明
(2)gcc -M -MM -MQ -MF -MT -MD(示例代码)
(3)gcc 选项 -M -MQ

有关UBOOT编译--- include/config.h、 include/autoconf.mk、include/autoconf.mk.dep、u-boot.cfg(三)的更多相关文章

  1. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  2. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  5. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  6. .net - 是否有 Ruby .NET 编译器? - 2

    是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/

  7. python - 使用 Python、Ruby 和 Perl 重新编译 MacPort 版本的 MacVim - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭10年前。ImprovethisquestionLinux专家正在转向Mac(10.8)。因为我懒...我使用MacPorts安装MacVim。它似乎安装没有错误。我只需要mvim中的python、ruby和perl支持。$/opt/local/bin/mvim--version|egrep'patches|python|ruby|perl'Includedpatches:1-244,246-646+multi_lang-mzscheme+

  8. ruby - 为什么 `middleman serve` 有效,但是 `middleman build` 编译这个 Sass 失败? - 2

    当我刚刚运行middleman时服务,all.css编译得很好,只包含对+box-shadow(none)的调用:/*line1,/home/yang/asdf/source/stylesheets/content.css.sass*/div{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}但是当我构建网站时,我得到了这个Sass/Compass错误:$middlemanbuildSlim::EmbeddedEngineisdeprecated,itiscalledSlim::EmbeddedinSlim2.0

  9. ruby-on-rails - rails 生成 rspec :install config/environments/development. rb:1:in `<top (required)>': 未定义方法 `configure' - 2

    首先,这是我的版本:Greg-Nowickis-MacBook-Pro:sample_appGreg_Nowicki$ruby-vruby2.0.0p451(2014-02-24revision45167)[x86_64-darwin13.1.0]Greg-Nowickis-MacBook-Pro:sample_appGreg_Nowicki$rails-vRails4.0.4我正在学习HartlRails教程并安装rspec进行测试。我已将gem'rspec-rails'添加到我的gemfile中,当我运行railsgeneraterspec:install时,这就是我得到的:Gre

  10. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

随机推荐