imx6ull-系統移植篇17——linux頂層 Makefile(上)

目錄

前言

頂層 Makefile

源碼簡析

版本號

MAKEFLAGS 變量

命令輸出

靜默輸出

設置編譯結果輸出目錄

代碼檢查

模塊編譯

設置目標架構和交叉編譯器

調用 scripts/Kbuild.include 文件

交叉編譯工具變量設置

頭文件路徑變量

導出變量

make xxx_defconfig 過程

Makefile.build 腳本分析

scripts_basic 目標對應的命令

%config 目標對應的命令


前言

在移植linux內核之前,我們先來學習一下 Linux 內核的頂層 Makefile 文件,因為頂層 Makefile 控制著 Linux 內核的編譯流程。

頂層 Makefile

Linux 的頂層 Makefile 和 uboot 的頂層 Makefile 非常相似,感興趣的可以看下:U-Boot 頂層 Makefile 簡析。

源碼簡析

版本號

頂層 Makefile 一開始就是 Linux 內核的版本號,如下所示:

VERSION = 4
PATCHLEVEL = 1
SUBLEVEL = 15
EXTRAVERSION =

可以看出, Linux 內核版本號為 4.1.15。

MAKEFLAGS 變量

MAKEFLAGS 變量設置如下所示:

MAKEFLAGS += -rR --include-dir=$(CURDIR)

選項

作用

-r

??禁用內置規則??:取消Make預定義的隱式規則(如.c.o的自動編譯規則)

-R

??禁用內置變量??:忽略Make預定義的隱含變量(如CC,?CFLAGS等)

--include-dir=$(CURDIR)

??指定頭文件搜索路徑??:將當前目錄加入頭文件搜索路徑

命令輸出

Linux 編譯的時候也可以通過“V=1”來輸出完整的命令,這個和 uboot 一樣,相關代碼如下所示:

# 檢查變量V是否來自命令行參數
ifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)  # 如果通過make V=1調用,則繼承該值
endif# 設置默認詳細級別(未指定時默認為0)
ifndef KBUILD_VERBOSEKBUILD_VERBOSE = 0      # 默認關閉詳細輸出模式
endif# 根據詳細級別設置編譯行為
ifeq ($(KBUILD_VERBOSE),1)quiet =                 # 空值表示顯示完整命令Q =                     # 空值取消命令隱藏
elsequiet = quiet_          # 前綴用于生成簡潔日志Q = @                   # @符號隱藏命令回顯
endif

靜默輸出

Linux 編譯的時候使用“make -s”就可實現靜默編譯,編譯的時候就不會打印任何的信息,同 uboot 一樣,相關代碼如下:

# 檢測Make版本是否為4.x系列
ifneq ($(filter 4.%,$(MAKE_VERSION)),)  # make-4.x版本處理邏輯# 檢查MAKEFLAGS是否包含-s選項(靜默模式)ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)quiet=silent_  # 啟用靜默模式輸出前綴endif
else  # make-3.8x版本處理邏輯# 兼容舊版本make的-s選項檢測ifneq ($(filter s% -s%,$(MAKEFLAGS)),)quiet=silent_  # 啟用靜默模式輸出前綴endif
endif# 導出關鍵變量到子make進程
export quiet Q KBUILD_VERBOSE

設置編譯結果輸出目錄

Linux 編譯的時候使用“O=xxx”即可將編譯產生的過程文件輸出到指定的目錄中,相關代碼如下:

# 檢查是否在源碼目錄內構建(KBUILD_SRC為空表示是)
ifeq ($(KBUILD_SRC),)# 當前直接在內核源碼目錄執行make# 檢測是否通過命令行參數O指定輸出目錄ifeq ("$(origin O)", "command line")KBUILD_OUTPUT := $(O)  # 使用用戶指定的輸出目錄路徑endif
endif

代碼檢查

Linux 也支持代碼檢查:

  • 使用命令“make C=1”使能代碼檢查,檢查那些需要重新編譯的文件。
  • make C=2”用于檢查所有的源碼文件。

頂層 Makefile 中的代碼如下:

# 檢查變量C是否來自命令行參數(如 make C=1)
ifeq ("$(origin C)", "command line")KBUILD_CHECKSRC = $(C)  # 繼承用戶指定的值
endif# 設置默認源碼檢查級別(未指定時默認為0)
ifndef KBUILD_CHECKSRCKBUILD_CHECKSRC = 0      # 默認關閉源碼檢查
endif

模塊編譯

Linux 允許單獨編譯某個模塊,使用命令“make M=dir”即可,舊語法“make SUBDIRS=dir”也是支持的。

頂層 Makefile 中的代碼如下:

# 處理外部模塊構建目錄指定方式(兩種兼容語法)
# 1. 老式語法:make ... SUBDIRS=$PWD
# 2. 新式語法:make M=dir
# 環境變量 KBUILD_EXTMOD 優先級最高
ifdef SUBDIRSKBUILD_EXTMOD ?= $(SUBDIRS)  # 兼容舊版SUBDIRS參數
endif# 檢查命令行是否指定M參數
ifeq ("$(origin M)", "command line")KBUILD_EXTMOD := $(M)  # 使用新式M參數指定模塊目錄
endif# 根據是否構建外部模塊設置默認構建目標
# 內部構建:依賴all目標
# 外部模塊構建:依賴modules目標
PHONY += all
ifeq ($(KBUILD_EXTMOD),)_all: all       # 常規內核構建
else_all: modules   # 外部模塊構建
endif# 設置源碼樹路徑
ifeq ($(KBUILD_SRC),)# 在源碼目錄內構建srctree := .    # 源碼樹設為當前目錄
elseifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))# 在源碼樹的子目錄構建srctree := ..  # 源碼樹設為上級目錄else# 完全外部構建srctree := $(KBUILD_SRC)  # 使用指定的源碼樹路徑endif
endif# 設置對象樹路徑(總是當前目錄)
objtree := .
src := $(srctree)    # 源碼路徑別名
obj := $(objtree)    # 構建路徑別名# 設置VPATH(Makefile搜索路徑)
# 包含源碼樹和外部模塊目錄(如果指定)
VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))# 導出關鍵路徑變量
export srctree objtree VPATH

外部模塊編譯過程和 uboot 也一樣,最終導出 srctree、 objtree 和 VPATH 這三個變量的值,其中 srctree=.,也就是當前目錄, objtree 同樣為“.”。

設置目標架構和交叉編譯器

同 uboot 一樣, Linux 編譯的時候需要設置目標板架構ARCH 和交叉編譯器 CROSS_COMPILE,在頂層 Makefile 中代碼如下:

ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)

為了方便,一般直接修改頂層 Makefile 中的 ARCH 和 CROSS_COMPILE,直接將其設置為對應的架構和編譯器,比如本教程將 ARCH 設置為為 arm, CROSS_COMPILE 設置為 armlinux-gnueabihf-,如下所示:

ARCH ?= arm
CROSS_COMPILE ?= arm-linux-gnueabihf-

設置好以后我們就可以使用如下命令編譯 Linux 了:

make xxx_defconfig //使用默認配置文件配置 Linux
make menuconfig //啟動圖形化配置界面
make -j16 //編譯 Linux

調用 scripts/Kbuild.include 文件

同 uboot 一樣, Linux 頂層 Makefile 也會調用文件 scripts/Kbuild.include,

頂層 Makefile 相應代碼如下:

# We need some generic definitions (do not try to remake the file).
scripts/Kbuild.include: ;
include scripts/Kbuild.include

交叉編譯工具變量設置

頂層 Makefile 中其他和交叉編譯器有關的變量設置如下:

# 匯編器 (Assembler)
AS = $(CROSS_COMPILE)as      # 用于將匯編代碼編譯為目標文件# 鏈接器 (Linker)
LD = $(CROSS_COMPILE)ld      # 負責目標文件的鏈接和重定位# C編譯器 (C Compiler)
CC = $(CROSS_COMPILE)gcc     # 主編譯工具,處理C語言源文件# 預處理器 (C Preprocessor)
CPP = $(CC) -E               # 只進行預處理不編譯(-E選項)# 靜態庫工具 (Archiver)
AR = $(CROSS_COMPILE)ar      # 創建和管理靜態庫(.a文件)# 符號表查看器 (Symbol Lister)
NM = $(CROSS_COMPILE)nm      # 列出目標文件的符號表# 二進制精簡工具 (Binary Stripper)
STRIP = $(CROSS_COMPILE)strip # 去除調試符號減小文件體積# 二進制轉換工具 (Object Copier)
OBJCOPY = $(CROSS_COMPILE)objcopy # 轉換目標文件格式# 反匯編工具 (Object Dumper)
OBJDUMP = $(CROSS_COMPILE)objdump # 反匯編和調試信息提取

LA、 LD、 CC 等這些都是交叉編譯器所使用的工具。

頭文件路徑變量

頂層 Makefile 定義了兩個變量保存頭文件路徑: USERINCLUDE LINUXINCLUDE

相關代碼如下:

# 用戶空間頭文件包含路徑(UAPI接口)
USERINCLUDE := \-I$(srctree)/arch/$(hdr-arch)/include/uapi \        # 架構特定UAPI頭文件-Iarch/$(hdr-arch)/include/generated/uapi \        # 生成的架構UAPI頭文件-I$(srctree)/include/uapi \                        # 通用UAPI頭文件-Iinclude/generated/uapi \                         # 生成的通用UAPI頭文件-include $(srctree)/include/linux/kconfig.h        # 強制包含kconfig頭文件# 內核空間頭文件包含路徑(兼容O=外部構建選項)
LINUXINCLUDE := \-I$(srctree)/arch/$(hdr-arch)/include \            # 架構特定內核頭文件-Iarch/$(hdr-arch)/include/generated/uapi \        # 生成的架構UAPI頭文件(重復)-Iarch/$(hdr-arch)/include/generated \            # 生成的架構私有頭文件$(if $(KBUILD_SRC), -I$(srctree)/include) \       # 外部構建時包含源碼樹頭文件-Iinclude \                                       # 當前構建目錄頭文件$(USERINCLUDE)                                    # 包含用戶空間路徑

LINUXINCLUDE變量,其中srctree=., hdr-arch=arm, KBUILD_SRC 為空,因此,將 USERINCLUDE 和 LINUXINCLUDE 展開以后為:

USERINCLUDE := \
-I./arch/arm/include/uapi \
-Iarch/arm/include/generated/uapi \
-I./include/uapi \
-Iinclude/generated/uapi \
-include ./include/linux/kconfig.hLINUXINCLUDE := \
-I./arch/arm/include \
-Iarch/arm/include/generated/uapi \
-Iarch/arm/include/generated \
-Iinclude \
-I./arch/arm/include/uapi \
-Iarch/arm/include/generated/uapi \
-I./include/uapi \
-Iinclude/generated/uapi \
-include ./include/linux/kconfig.h

導出變量

頂層 Makefile 會導出很多變量給子 Makefile 使用,導出的這些變量如下:

# 內核版本信息導出(用于版本標識)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION# 基礎構建配置導出
export ARCH SRCARCH CONFIG_SHELL  # 架構和shell配置
export HOSTCC HOSTCFLAGS          # 主機工具鏈(用于構建host程序)
export CROSS_COMPILE              # 交叉編譯前綴(如arm-linux-gnueabi-)
export AS LD CC                   # 核心工具鏈(匯編器、鏈接器、編譯器)# 二進制工具集導出
export CPP AR NM STRIP OBJCOPY OBJDUMP  # 預處理器、靜態庫、符號表等工具# 腳本解釋器和工具
export MAKE AWK GENKSYMS INSTALLKERNEL  # make/awk/符號生成工具/內核安裝腳本
export PERL PYTHON                     # 腳本解釋器
export UTS_MACHINE                     # 機器標識符# 主機C++工具鏈(用于需要C++的構建步驟)
export HOSTCXX HOSTCXXFLAGS# 模塊構建專用參數
export LDFLAGS_MODULE  # 模塊鏈接參數# 代碼檢查工具
export CHECK CHECKFLAGS  # 靜態分析工具(如sparse)# 預處理和包含路徑
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE  # 預處理標志和頭文件路徑# 二進制工具參數
export OBJCOPYFLAGS LDFLAGS  # objcopy和鏈接器參數# C編譯器標志集
export KBUILD_CFLAGS          # 全局C標志
export CFLAGS_KERNEL         # 內核核心編譯標志
export CFLAGS_MODULE         # 模塊編譯標志
export CFLAGS_GCOV           # GCOV覆蓋率測試標志
export CFLAGS_KASAN          # KASAN內存檢測標志# 匯編器標志集
export KBUILD_AFLAGS         # 全局匯編標志
export AFLAGS_KERNEL         # 內核核心匯編標志
export AFLAGS_MODULE         # 模塊匯編標志# 模塊構建專用標志
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE# 內核核心構建專用標志
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL# 靜態庫工具參數
export KBUILD_ARFLAGS  # ar命令參數

make xxx_defconfig 過程

第一次編譯 Linux 之前都要使用“make xxx_defconfig”先配置 Linux 內核,在頂層 Makefile中有“%config”這個目標,如下所示:

# 初始化構建模式標志
config-targets := 0    # 是否為配置目標(如menuconfig)
mixed-targets := 0     # 是否混合了配置和編譯目標
dot-config := 1        # 是否需要讀取.config文件# 檢查是否需要忽略.config(針對clean/mrproper等目標)
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)dot-config := 0  # 當只有clean類目標時禁用.config依賴endif
endif# 檢測配置類目標(僅在內核構建時檢查)
ifeq ($(KBUILD_EXTMOD),)ifneq ($(filter config %config,$(MAKECMDGOALS)),)config-targets := 1  # 標記為配置目標ifneq ($(words $(MAKECMDGOALS)),1)mixed-targets := 1  # 多個目標混合時標記endifendif
endif# 混合目標處理(如 make menuconfig all)
ifeq ($(mixed-targets),1)PHONY += $(MAKECMDGOALS) __build_one_by_one# 將目標重定向到順序執行$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one@:  # 空命令# 逐個目標執行__build_one_by_one:$(Q)set -e; \for i in $(MAKECMDGOALS); do \$(MAKE) -f $(srctree)/Makefile $$i; \done# 純配置目標處理(如 make menuconfig)
else ifeq ($(config-targets),1)# 包含架構相關配置include arch/$(SRCARCH)/Makefileexport KBUILD_DEFCONFIG KBUILD_KCONFIG# 處理config類目標config: scripts_basic outputmakefile FORCE$(Q)$(MAKE) $(build)=scripts/kconfig $@%config: scripts_basic outputmakefile FORCE$(Q)$(MAKE) $(build)=scripts/kconfig $@# 常規構建目標處理
else# [常規構建流程...]
endif

這段代碼里,最開始是設置定義變量 config-targets、 mixed-targets 和 dot-config的值,最終這三個變量的值為:

config-targets= 1
mixed-targets= 0
dot-config= 1

因此會引用 arch/arm/Makefile 這個文件,這個文件很重要,因為 zImage、 uImage 等這些文件就是由 arch/arm/Makefile 來生成的。

“make xxx_defconfig”與目標“%config”匹配,因此執行。

%config: scripts_basic outputmakefile FORCE$(Q)$(MAKE) $(build)=scripts/kconfig $@

“%config”依賴scripts_basic、 outputmakefile 和 FORCE,“%config”真正有意義的依賴就只有 scripts_basic。

?scripts_basic 的規則如下:

scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount

其中,build 定義在文件 scripts/Kbuild.include 中,值為:

build := -f $(srctree)/scripts/Makefile.build obj

因此?scripts_basic展開為:

scripts_basic:
@make -f ./scripts/Makefile.build obj=scripts/basic //也可以沒有@,視配置而定
@rm -f . tmp_quiet_recordmcount //也可以沒有@

所以目標“%config”代入scripts_basic的值,展開為:

@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

Makefile.build 腳本分析

我們現在已經知道:“ make xxx_defconfig“配置 Linux 的時候如下兩行命令會執行腳本scripts/Makefile.build:

@make -f ./scripts/Makefile.build obj=scripts/basic
@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

scripts_basic 目標對應的命令

打開文件 scripts/Makefile.build,有如下代碼:

# Kbuild文件優先級高于Makefile
# 確定子目錄路徑(支持絕對路徑和相對路徑)
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))# 確定構建規則文件名(優先查找Kbuild,不存在則用Makefile)
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)# 包含找到的構建規則文件
include $(kbuild-file)

其中:將 kbuild-dir、kbuild-file都展開代入:

kbuild-dir =./scripts/basic
kbuild-file = ./scripts/basic/Makefile
include ./scripts/basic/Makefile

繼續分析 scripts/Makefile.build,如下代碼:

# 默認構建目標(通過__build偽目標實現)
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \$(subdir-ym) $(always)@:  # 空命令(實際工作由依賴項完成)

__build 是默認目標,在頂層 Makefile 中, KBUILD_BUILTIN 為 1, KBUILD_MODULES 為空,因此展開后目標__build 為:

__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)@:

可以看出目標__build 有 5 個依賴: builtin-target、 lib-target、 extra-y、 subdir-ym 和 always。這 5 個依賴的具體內容如下:

builtin-target =
lib-target =
extra-y =
subdir-ym =
always = scripts/basic/fixdep scripts/basic/bin2c

只有 always 有效,因此__build 最終為:

__build: scripts/basic/fixdep scripts/basic/bin2c@:

__build 依賴于 scripts/basic/fixdep 和 scripts/basic/bin2c,所以要先將 scripts/basic/fixdep 和scripts/basic/bin2c.c 這兩個文件編譯成 fixdep 和 bin2c。

@make -f ./scripts/Makefile.build obj=scripts/basic

綜上所述, scripts_basic 目標的作用就是編譯出 scripts/basic/fixdep scripts/basic/bin2c 這兩個軟件。

%config 目標對應的命令

%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

可以看出, Makefile.build 會讀取 scripts/kconfig/Makefile 中的內容,

此文件有如下所示內容:

 %_defconfig: $(obj)/conf$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@
$(Kconfig)

目標%_defconfig 與 xxx_defconfig 匹配,所以會執行這條規則,將其展開就是:

%_defconfig: scripts/kconfig/conf
@ scripts/kconfig/conf --defconfig=arch/arm/configs/%_defconfig Kconfig

_defconfig依賴scripts/kconfig/conf,所以會編譯scripts/kconfig/conf.c生成conf 這個軟件。

此軟件就會將%_defconfig 中的配置輸出到.config 文件中,最終生成 Linux kernel 根目錄下的.config 文件。

我們下一講內容再來說明make 過程、built-in.o 文件編譯生成過程、make zImage 過程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90200.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90200.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90200.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV 官翻6 - Computational Photography

文章目錄圖像去噪目標理論OpenCV中的圖像去噪1、cv.fastNlMeansDenoisingColored()2、cv.fastNlMeansDenoisingMulti()附加資源圖像修復目標基礎概念代碼補充資源練習高動態范圍成像&#xff08;HDR&#xff09;目標理論基礎曝光序列HDR1、將曝光圖像加載到列表中2、將曝光序列…

APT32F1732RBT8愛普特微電子 32位MCU國產芯片 智能家居/工業控制 首選

APT32F1732RBT8 愛普特微電子&#xff0c;32位MCU國產芯片一、產品簡介APT32F1732RBT8 是愛普特微電子&#xff08;APT&#xff09;推出的高性能32位ARM Cortex-M0內核MCU&#xff0c;主頻高達48MHz&#xff0c;內置64KB Flash8KB RAM&#xff0c;專為智能家居、工業控制、消費…

Smart Tomcat

本篇博客的內容是教你借助idea中的插件,把tomcat集成到idea中安裝 Smart Tomcat 插件搜索下載 ,如果一直處于加載界面,就嘗試一下科學上網配置 Smart Tomcat 插件 點擊右上角的 "Add Configuration"選擇左側的 "Smart Tomcat" 在 Name 這一欄填寫一個名字(…

Linux_shell編寫

title: Linux_4 shell編寫 shell pwd (/root/A/2025_7/19/myshell) 首先需要設計命令行提示 &#xff08;MakeCommandLine()&#xff09; 首先獲取相關信息 getenv(“name”) // 獲取用戶名 const char* GetUserName() {const char* name getenv("USER");if (name …

【數據結構】棧的深入解析--用C語言實現

文章目錄1.棧的概念2.棧的底層結構3.棧的功能4.棧的實現4.1.棧結構的定義4.2.棧的初始化4.3.棧的銷毀4.4.入棧4.5.出棧4.6.取棧頂元素4.7.獲取棧中有效元素個數5.完整代碼Stack.hStack.cmain.c運行結果1.棧的概念 是一種特殊的線性表&#xff0c;只允許數據在固定的一段進行插…

Git倉庫核心概念與工作流程詳解:從入門到精通

Git倉庫的基本概念版本庫&#xff08;Repository&#xff09;是Git的核心概念&#xff0c;你可以簡單理解為一個被Git管理的目錄。這個目錄里的所有文件都能被Git跟蹤&#xff0c;記錄每次修改和刪除&#xff0c;讓你可以隨時追溯歷史或在未來某個時刻"還原"文件。Gi…

Web開發 05

1 React庫&#xff08;人話詳解版&#xff09;別慌&#xff0c;React 剛接觸時是會有點懵&#xff0c;咱們用 “人話 類比” 一步步拆&#xff1a;核心概念先抓牢組件&#xff08;Component&#xff09;把它想成 “樂高積木”&#xff0c;比如做個社交 App&#xff0c;頂部導航…

RustDesk 自建中繼服務器教程(Mac mini)

&#x1f4d6; 教程目標 在家里的 Mac mini 上部署 RustDesk 中繼服務器 (hbbs hbbr)&#xff0c;讓你從辦公室、筆電或手機 低延遲、安全 地遠程控制家里的 Windows 和 Mac mini。 ? 不依賴第三方服務器 ? 支持 P2P 和中繼雙模式 ? 全流量可控、跨平臺 &#x1f3d7;? 架…

數據庫—修改某字段默認值

前言有時候&#xff0c;數據庫的字段默認值沒有正確設置&#xff0c;這時候需要改默認值。以下是我做的改默認值的記錄&#xff0c;希望對網友有所幫助。1.SQL SERVER下面的示例假設你要修改名為 YourColumnName 的字段&#xff0c;并為其設置一個新的默認值 NewDefaultValue。…

Spring快速整合Mybatis

MyBatis是一個優秀的持久層框架&#xff0c;Spring則是廣泛使用的Java應用框架。可以將兩者整合可以充分發揮各自的優勢。 1、Spring整合MyBatis的基本配置 添加依賴&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spri…

基于深度學習的語音識別:從音頻信號到文本轉錄

前言 語音識別&#xff08;Automatic Speech Recognition, ASR&#xff09;是人工智能領域中一個極具挑戰性和應用前景的研究方向。它通過將語音信號轉換為文本&#xff0c;為人們提供了更加自然和便捷的人機交互方式。近年來&#xff0c;深度學習技術在語音識別領域取得了顯著…

本地部署Nacos開源服務平臺,并簡單操作實現外部訪問,Windows 版本

Nacos 是一款阿里開源的動態服務發現、配置、管理平臺&#xff0c;擁有易于集成、高可用與可擴展等特點。它提供了動態服務注冊和發現能力&#xff0c;使得服務自動注冊到服務器并且消費真能夠發現提供者。本文將詳細介紹如何在本地安裝 Nacos &#xff0c;以及結合nat123端口映…

數據結構:反轉字符串(Reversing a String)

目錄 方法一&#xff1a;雙指針法 方法二&#xff1a;輔助數組 方法對比總結&#xff1a; 問題定義 給定一個字符串&#xff0c;例如&#xff1a; char str[] "hello";我們的目標是把它反轉成&#xff1a; "olleh"&#x1f4cc; 輸入特點&#xff…

Redis Copy-on-Write機制:

Copy-on-Write機制&#xff1a; 父子進程共享內存頁 當父進程修改數據時&#xff0c;內核會復制被修改的頁 這可能導致內存使用量暫時增加 通俗的話描述一下可以用一個生活中的例子來通俗解釋 Copy-on-Write&#xff08;寫時復制&#xff09; 機制&#xff1a;&#x1f4d6; 比…

iOS加固工具有哪些?從零源碼到深度混淆的全景解讀

在iOS安全加固領域&#xff0c;不同項目類型對保護需求有著本質差異&#xff1a;“我有源碼”與“我只有IPA”兩條路徑決定了你該用什么工具。本文將從 無需源碼處理整個IPA包 到 源碼級編譯期混淆&#xff0c;分層探討主流工具如何發揮價值&#xff0c;并附上適配方案建議。工…

Composer 可以通過指定 PHP 版本運行

是的&#xff0c;Composer 可以通過指定 PHP 版本運行&#xff0c;尤其是在服務器上有多個 PHP 版本時&#xff08;如 PHP 7.x 和 PHP 8.x&#xff09;。以下是幾種常見方法&#xff1a;方法 1&#xff1a;使用 php 命令指定版本 Composer 依賴系統中的 php 命令&#xff0c;因…

vscode文件顏色,只顯示自己更改的文件顏色

這個主要是因為你github git下來以后&#xff0c;用vscode打開會默認顯示更改了&#xff0c;你只要在這里先手動取消更改就行了&#xff0c;注意不要把你自己更改的取消了

記錄我coding印象比較深刻的BUG

4778&#xff1a;我的BUG噩夢問題描述&#xff1a;DAB播放中關ACC掉電后開ACC&#xff0c;手動切到FM/AM(有時第一次切換出現問題/有時第二次切換出現問題)&#xff0c;FM/AM不記憶關ACC前電臺或者FM/AM關ACC掉電后開ACC&#xff0c;手動切到DAB再回到FM/AM&#xff0c;FM/AM不…

Kubernetes集群中Istio mTLS握手失敗問題排查與解決方案

Kubernetes集群中Istio mTLS握手失敗問題排查與解決方案 在微服務架構中&#xff0c;Istio 提供了基于 Envoy 的服務網格能力&#xff0c;其中 mTLS&#xff08;雙向 TLS&#xff09;是確保服務間通信安全的重要機制。但在生產環境中&#xff0c;開發者常常會遇到 mTLS 握手失敗…

antd+react+可輸入的下拉選擇組件

該組件是一個可輸入的下拉選擇組件&#xff0c;支持從預設選項中選擇或手動輸入自定義值。組件基于 React 和 Ant Design 實現&#xff0c;具有良好的交互體驗和靈活的配置選項。 &#x1f9e0; 核心邏輯分析 1. 狀態管理 const [isInput, setIsInput] useState(false); con…