makefile基础及常用规则

2023-10-27

      什么是makefile?或许很多Windows的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。特别在Unix下的软件编译,你就不能不自己写makefile了。
      我们用一个示例来说明Makefile的书写规则。在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:
     1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
     2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
     3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
      只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成

(1)Makefile的规则。还是让我们先来粗略地看一看Makefile的规则。
    target ... : prerequisites ...
            command
       target也就是一个目标文件,可以是Object File,也可以是执行文件,还可以是一个标签(Label)。 prerequisites就是要生成那个target所需要的文件或是目标。command也就是make需要执行的命令。这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

        Linux中对Makefile的使用,内核的Makefile分为5个组成部分: 

A,Makefile     最顶层的Makefile 
B,.config        内核的当前配置文档,由Kconfig在menu config时生成,编译时成为顶层Makefile的一部分
C,arch/$(ARCH)/Makefile    和体系结构相关的Makefile 
D,scripts/Makefile.xxx     一些特定Makefile的规则
E,kbuild级别Makefile      各级目录下的大概约500个文档,编译时根据上层Makefile传下来的宏定义和其他编译规则,将源代码编译成模块或编入内核。顶层的Makefile文档读取.config文档的内容,并总体上负责build内核和模块。Arch Makefile则提供补充体系结构相关的信息。
(2)示例:

    edit : main.o kbd.o command.o display.o /
           insert.o search.o files.o utils.o
            cc -o edit main.o kbd.o command.o display.o /
                       insert.o search.o files.o utils.o
    main.o : main.c defs.h
            cc -c main.c
    kbd.o : kbd.c defs.h command.h
            cc -c kbd.c
    command.o : command.c defs.h command.h
            cc -c command.c
    display.o : display.c defs.h buffer.h
            cc -c display.c
    insert.o : insert.c defs.h buffer.h
            cc -c insert.c
    search.o : search.c defs.h buffer.h
            cc -c search.c
    files.o : files.c defs.h buffer.h command.h
            cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
            rm edit main.o kbd.o command.o display.o /
               insert.o search.o files.o utils.o

        在该目录下直接输入命令“make”就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以了。在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个.o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。
       这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

 (3) 现就最常接触到的就是linux各层目录下基于kbuild架构的kbuild Makefile文件规则做下说明和使用,核心内容主要包括:

 A,目标定义。

        就是用来定义哪些内容要做为模块编译,哪些要编译链接进内核。例如:obj-y += foo.o,表示要由foo.c或者foo.s文件编译得到foo.o并链接进内核,而obj-m则表示该文件要作为模块编译成ko,可以手动insmod加进去。而更常见的做法是根据.config文件的CONFIG_ 变量($变量标识变量的值)来决定文件的编译方式,如:
obj-$(CONFIG_ISDN)             += isdn.o
 除了obj-形式的目标以外,还有lib-y library库,hostprogs-y 主机程序等目标,但是基本都应用在特定的目录和场合下。

B,多文件模块的定义。

        最简单的kbuild Makefile如上一节一句话的形式就够了,如果一个模块由多个文件组成,那么稍微复杂一些,采用模块名加 –objs后缀或者–y后缀的形式来定义模块的组成文件。如以下例子:
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
模块的名字为ext2,由balloc.o和bitmap.o两个目标文件最终链接生成ext2.o,是否包括xattr.o取决于内核配置文件的配置情况。

C,目录层次的迭代。
      如:obj-$(CONFIG_EXT2_FS) += ext2/
如果CONFIG_EXT2_FS 的值为y或m,kbuild将会将ext2目录列入向下迭代的目标中,但是其作用也仅限于此,具体ext2目录下的文件是要作为模块编译还是链入内核,还是由ext2目录下的Makefile文件的内容来决定的。

(4)关于出现编译错误:makefile:1:   ***   遗漏分隔符(或者*** missing separator. Stop)

        简单的说,Makefile中的语句主要有2类,“规则”和“动作”,动作命令前需要有一个TAB字符,不能顶格,也不能多空格! 另外,make 的时候出现错误:commands   commence   before   first   target ,也是由于这个原因。另一个出错的原因是用\做换行符时,后面不能跟任何字符包括空格。

(5)交叉编译器的路径

        由于makefile不是shell脚本,所以交叉编译器不能设置成带变量的路径。例如设置成:CROSS_COMPILE  = $HOME/gcc/arm-eabi-4.4.3/bin/arm-eabi-,那么在调用时会以$来约束变量H,而不是把它当作一个整体路径。所以得用CROSS_COMPILE  = /home/zxtcukk/gcc/arm-eabi-4.4.3/bin/arm-eabi-等绝对路径。

(6)编译错误:make: Nothing to be done for 

         原因是Makefile书写格式非常严格,大概如下:
all:
<TAB缩进>make -C $(KDIR) M=$(PWD) $(EXTRA_CFLAGS) modules
default:
<TAB缩进>make -C $(KDIR) M=$(PWD) $(EXTRA_CFLAGS) modules
clean:
<TAB缩进>make -C $(KDIR) M=$(PWD) clean
         在拷贝网络代码的过程中,很可能原有的TAB被若干空格键所替代,就会出现Nothing to be done for...的错误了。

(7)常用语法和函数:

        “ifeq strip”:ifeq 用来判断参数是否相等,如果相同则(条件为真)将“TEXT-IF-TRUE”作为make要执行的一部分,否则将“TEXT-IF-FALSE”作为make要执行的一部分。由于参数值可能是通过引用变量或者函数得到的,因而在展开过程中可能造成参数值中包含空字符(空格等)。一般在这种情况时我们使用“strip”函数来对它变量的值进行处理,去掉其中的空字符。格式为: 
 ifeq ($(strip $(foo)),yes)
TEXT-IF-EMPTY
endif

如果以不等于作为判断条件,用ifneq

          过滤函数:filter,以模式过滤字符串中的单词,保留符合模式的单词。

GSL_TOUCH_ID := $(if $(filter gslX680,$(CUSTOM_KERNEL_TOUCHPANEL)),yes,no)
ifeq ($(GSL_TOUCH_ID),yes)
........
endif

filter还可以做逻辑或,因为在makefile中不可能用||来实现逻辑或,如下例,filter 的功能是将MAINLCD_SIZE分別和320X480及480X800比较,如果一样就满足

ifeq ($(strip $(MAINLCD_SIZE)), $(filter $(MAINLCD_SIZE), 240X400 320X480))
...执行前往 
endif

         call函数:call函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。其语法是:
    $(call
,,,...)
当make执行这个函数时,参数中的变量,如$(1),$(2),$(3)等,会被参数,,依次取代。返回值就是call函数的返回值。例如:
    reverse =  $(1) $(2)
    foo = $(call reverse,a,b)
那么,foo的值就是“a b”。当然,参数的次序是可以自定义的,不一定是顺序的,如:
    reverse = $(2) $(1)
    foo = $(call reverse,a,b)

(8)关于o_shipped的说明,如何在kernel模块中使用已经编译好的obj文件

         在Document/kbuild/modules.txt中看到这么一段:--- 3.3 Binary Blobs,Some external modules need to include an object file as a blob.kbuild has support for this, but requires the blob file to be named <filename>_shipped. When the kbuild rules kick in, a copy of <filename>_shipped is created with _shipped stripped off,giving us <filename>. This shortened filename can be used in the assignment to the module.

        A,最开始使用 gcc -c ex_obj.c -o ex_obj.o_shipped 来做的,结果链接后不能正常工作。原来是一定要放在编译kernel的环境中编译这个obj。编译文件成功后,将这个.o拷贝到需要链接的模块目录。记住要添加_shipped后缀

        B,然后在需要这个obj的模块中添加scull-y := main.o pipe.o access.o ex_obj.o,然后在源代码中调用相应的函数,ok,可以了。作用就是可以用来加密某些文件。

        C,也就是,没有源码的二进制.o文件必须以原文件名加_shipped结尾,例如8123_bin.o_shipped,KBuild会把8123_bin.o_shipped复制为8123_bin.o,然后一起编译。

(9)关于.PHONY的用法

先看一个样例:

main1.c内容:

#include<stdio.h>
int main(void)
{
    printf("main1\n");
}

main2.c内容:

#include<stdio.h>
int main(void)
{
    printf("main2\n");
}

makefile的内容:

all:main1 main2
main1: main1.c
	@gcc main1.c -o main1
main2: main2.o
	@gcc main2.o -o main2
main2.o:main2.c
	@gcc -c main2.c

clean:
	@rm -f main2.o	

执行完make all后再去执行make clean,发现main2.o还在,也即clean并没有执行到。什么原因呢?原来这里的目标clean没有任何依赖,make执行时认为这已经到“根上”了,将其忽略。关键字.PHONY可以解决这问题,告诉make该目标是“假的”,这时make为生成这个目标就会将其规则执行一次。.PHONY修饰的目标就是只有规则没有依赖。
改成:

all:main1 main2
main1: main1.c
	@gcc main1.c -o main1
main2: main2.o
	@gcc main2.o -o main2
main2.o:main2.c
	@gcc -c main2.c
.PHONY:clean
clean:
	@rm -f main2.o	

再执行make clean就可以了。

(10)ccflags编译链接选项,类似宏

ifneq ($(CONFIG_MTK_CCCI_DEVICES),y)
ccflags-y  += -D__USING_DUMMY_CCCI_API__
endif

去掉-D,类似定义了__USING_DUMMY_CCCI_API__这个宏,在C代码中,用#ifdef __USING_DUMMY_CCCI_API__来使用。

(11)include -include

         Makefile 中包含其它文件的关键字是“include”,它和 C 语言对头文件的包含方式一致。 “include”指示符告诉 make 暂停读取当前的 Makefile,而转去读取“include”指定的一个或者多个文件,完成以后再继续当前 Makefile 的读取。其形式如下include FILENAMES。切忌不能以 [Tab] 字符开始(如果一行以 [Tab] 字符开始 make 程序将此行作为一个命令行来处理)。
         如果指示符“include”指定的文件不是以斜线开始(绝对路径,如/usr/src/Makefile...),而且当前目录下也不存在此文件;make将根据文件名试图在以下几个目录下查找:首先,查找使用命令行选项“-I”或者“--include-dir”指定的目录,如果找到指定的文件,则使用这个文件;否则继续依此搜索以下几个目录(如果其存在/usr/gnu/include”、“/usr/local/include”和“/usr/include”。当在这些目录下都没有找到“include”指定的文件时,make将会提示一个包含文件未找到的告警提示,但是不会立刻退出。而是继续处理Makefile的后续内容。
         当完成读取整个Makefile后,make将试图使用规则来创建通过指示符“include”指定的但未找到的文件,当不能创建它时(没有创建这个文件的规则),make将提示致命错误并退出。会输出类似如下错误提示:
Makefile:错误的行数:未找到文件名:提示信息(No such file or directory)
Make: *** No rule to make target ‘’. Stop 
        -include FILENAMES...使用这种方式时,当所要包含的文件不存在时不会有错误提示、make也不会退出;除此之外,和第一种方式效果相同。

(12) = := ?= +=这四个符号的差别

= 是最基本的赋值
:= 是覆盖之前的值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是追加等号后面的值

至于makefile中“=”和“:=”的区别到底有什么区别,因为给变量赋值时,两个符号都在使用。举一个例子清晰说明

1、“=”
      make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
            x = foo
            y = $(x) bar
            x = xyz
      在上例中,y的值将会是 xyz bar ,而不是 foo bar 。
 2、“:=”
      “:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
            x := foo
            y := $(x) bar
            x := xyz
      在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。具体可详见http://www.cnblogs.com/wanqieddy/archive/2011/09/21/2184257.html

(13)Makefile中跑shell命令

比如一个拷贝命令

CUR_PATH := device/rockchip/rkpx2/goc
$(shell cp -af $(CUR_PATH)/goc $(ANDROID_PRODUCT_OUT)/system/)

(14)内核的Makefile中加打印,确认编译时编到没有。Android.mk中同样可用

比如$(warning this is log1),就会在编译时显示这句this is log1,以确认编译路径。

也可以输出变量值

$(warning path is $(shell pwd)),编译时提示当前编译到的路径。回显/home/sw01/workspace/atc8317M/out/target/product/ac83xx_evb/obj/KERNEL_OBJ

(15)patsubst 与 subst 区别

格式:$(subst <from>,<to>,<text>),名称:字符串替换函数——subst。功能:把字串<text>中的<from>字符串替换成<to>。返回:函数返回被替换过后的字符串。
    示例:
$(subst a,the,There is a big tree),
把“There is a big tree”中的“a”替换成“the”,返回结果是“There is the big tree”。

而对于patsubst,模式字符 “%”,只会把最末尾的替换。example: 

SRC = a.c b.c m.c.c
all:
echo $(patsubst %.c,%.s,${SRC}) 
echo $(subst .c,.s, ${SRC})
a.s b.s m.c.s

a.s b.s m.s.s

(16)makefile中实现或操作

ifeq ($(strip $(PRODUCT_CUSTOMER)),$(filter $(PRODUCT_CUSTOMER),SEIWA BLAUPUNKT AVT))

可以巧妙地混用filter去达到以上的效果,filter 的功能是将PRODUCT_CUSTOMER分別和SEIWA及BLAUPUNKT或者AVT比较,如果一样就会返回其中的某个值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

makefile基础及常用规则 的相关文章

  • 是否可以使用现有的 Makefile 在 Code::Blocks 中构建项目?

    编辑 我发现项目属性中有一个选项可以设置自定义生成文件 现在项目构建良好 现在 我偶然发现了如何在单击 运行 时指定要运行的目标可执行文件 代码 块 http www codeblocks org is an IDE https en wi
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • 错误:-march= 开关的值错误

    我写了一个Makefile 但无法让它工作 我有一个选项应该选择编译到哪个处理器 然而 当我跑步时make从命令行它说 tandex tandex P 6860FX emulators nintendo sdks 3DS SDK HomeB
  • 使用 MS NMAKE 打印长编译行

    我有一个遗留的 MS NMAKE Makefile 我需要修复其中的一些错误 我希望调试一些非常长的命令行 这些命令行正在使用 NMAKE 技巧执行 内联文件 http msdn microsoft com en us library se
  • 为什么 Visual Studio Code 在编辑 Makefile 和 "editor.insertSpaces": "auto" 时插入空格?

    make 不喜欢 Makefile 中的目标主体有空格 必须是一个标签 我将 editor insertSpaces 更改为 auto 认为这会有所帮助 事实并非如此 我必须将其设置为 false 才能使代码正常工作 现在可以通过语言特定设
  • ubuntu 中的 echo -e 选项不起作用

    我的同事使用Ubuntu 我使用openSUSE 我们使用相同的makefile编译相同的源代码 我的环境运行良好 但我的同事不能 总是输出无法识别 e选项 我们检查makefile 只发现echo命令使用 e option Ubuntu的
  • 使用 Object.create(null) 创建空对象的影响和好处

    首先 我做了一个快速的 jsperf 测试用例来展示显而易见的内容 Object create null 比使用创建对象慢得多 syntax http jsperf com js object creation null proto htt
  • 如何通过仅调用一个命令来构建多个目标?

    我得到了一个像下面这样的 Makefile PHONY all all aaa 2 bbb 2 aaa 2 aaa 1 common 1 create 2 bbb 2 bbb 1 common 1 create 2 程序 create 2
  • 使用变量“name”不适用于 JS 对象

    该行为可以在这个小片段中看到 将其作为全局脚本执行 var name name FirstName Tom alert name FirstName 警报产生undefined在 Chrome 中 但在 IE 和 Firefox 中工作 当
  • Excel 对象库文件在哪里

    我正在寻找 Excel 对象库文件以将其导入 LabVIEW 我安装了 MS Office 2013 可以找到 MSACC olb MSOUTL olb MSPPT olb 和 MSWORD olb 但无法确定要导入哪个文件 olb 或 d
  • 找出对象列表中是否包含具有指定字段值的内容?

    我有一个从数据库收到的 DTO 列表 它们有一个 ID 我想确保我的列表包含具有指定 ID 的对象 显然 在这种情况下创建具有预期字段的对象不会有帮助 因为 contains 调用 Object equals 并且它们不会相等 我想出了这样
  • 从 GNU Makefile 调用 `command -v find`

    我使用 shell bash 但我需要可移植性 和 GNU Makefile 我有这个代码 check commands command v find gt dev null command v asdf gt dev null 正如假设的
  • Typescript 继承:扩展基类对象属性

    当扩展一个类时 我可以轻松地向它添加一些新属性 但是 如果当我扩展基类时 我想向基类的对象 简单对象的属性 添加新属性怎么办 这是一个带有一些代码的示例 基类 type HumanOptions alive boolean age numb
  • 面向对象设计的良好参考[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 链接器失败:存档中的成员不是对象

    我正在尝试在 Windows 7 上使用 64 位 mingw 构建 Open CASCADE 6 7 1 库 我正在使用x86 64 4 9 1 release posix seh rt v3 rev1 from mingw w64 项目
  • 当我尝试在 PHP 中访问类变量时,类变量为 null

    好吧 这是我的主要代码 require checkpassword php require mysqllogininfo php Validate password if validatePassword GET password retu
  • 如何处理GNU make中的子make错误?

    我在 Makefile GNU 中使用子 make 但每当子 make 失败时 主 make 都会继续成功运行 我希望每当我的子 make 失败时我的主 Makefile 都会失败 我怎么做 all pushd STA DIR make c
  • 用于编译和运行 C++ 的 bash 脚本

    我正在尝试进入 C 但必须使用冗长的命令通过命令行运行东西很烦人 所以我想制作一个 bash 脚本来简化过程并运行这些命令 bin bash if 1 start then cd CCPP cd HelloWorld g Wall W We
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 使用 Makefile 项目在 Visual Studio 中自定义调试命令

    我在 Visual Studio 2010 中有一个由 Makefile 支持的项目 实际上使用 NAnt 但这不是重点 构建过程的输出是一个 elf 文件 我有一个单独的非 VStudio 调试器 可以在该 elf 文件上运行来调试它 构

随机推荐

  • Python一行代码过滤标点符号等特殊字符

    本文首发于公众号 AntDream 欢迎微信搜索 AntDream 或扫描文章底部二维码关注 和我一起每天进步一点点 很多时候我们需要过滤掉标点符号等特殊字符 网上虽然有一堆的方法 但是都没有找到一个非常满意的 有些过滤不了中文的标点符号
  • CICD详解(十五)——Jenkins插件安装失败解决

    今天继续给大家介绍Linux运维相关知识 本文主要内容是Jenkins插件安装失败解决 一 背景 今天 在做Jenkins上安装Git和Gitlab插件时 插件的安装出现了问题 结果如下所示 经过我的研究和实验 对Jenkins插件安装失败
  • 【算法】Java 中栈的使用

    栈是一种重要的数据结构 满足后进先出 是面试中会重点考察的内容 下面通过例题来学习栈的使用 1 力扣20 有效的括号 1 给定一个只包括 的字符串 s 判断字符串是否有效 有效字符串需满足 左括号必须用相同类型的右括号闭合 左括号必须以正确
  • 软件中常用的反义词组

    软件中常用的反义词组 add remove begin end create destroy insert delete first last g et release increment decrement put get add del
  • 软件项目中的成本构成及估算方法

    随着知识经济 信息时代的来临 计算机软件业迅猛发展 商品化 资本化 资产化的计算机软件的价值 评估的社会需求也日益增多 而且有越来越多的趋势 由于系统软件通常是一些规模大 复杂程度高的人一 机系统 因此 系统软件的开发 使用 维护 管理的过
  • linux安装.AppImage后缀安装包

    假设有个安装包名称为 myinstall AppImage 添加权限后直接可以运行 chmod a x myinstall AppImage myinstall AppImage
  • ubuntu18 新增配置用户删除用户

    进入root用户 sudo su 输入密码 新安装的ubuntu修改root用户密码 sudo passwd 输入密码 useradd 命令格式 命令一 这种命令会在登录界面显示用户名 sudo useradd m ftpuser d ho
  • 安卓手机玩游戏卡顿怎么解决_和平精英:你还在为游戏卡顿掉帧而烦恼吗?5招之内帮你解决...

    相信大家在玩和平精英时必然会遇到游戏卡顿的现象吧 想要解决这些问题吗 赤几现在就来教你哟 在上个游戏版本的时候 不少小伙伴在玩和平精英的时候遇到人会出现画面掉帧很厉害的情况 一般只要卡了就说明附近有人了 但最近的更新中 官方尽可能的优化了这
  • Excel批量创建带超链接的工作表目录

    工作中总会遇到包含多个工作表的工作簿 很多人都在想这时候如果能有一个目录 不但能显示出所有的工作表名称 还能够链接跳转到指定的工作表 该有多好呀 于是 一些勤奋的人们就开始行动了 他们手动创建超链接指向各个工作表 但当工作表数量很多时 手动
  • 2023华为od机试 Python【拔河比赛】

    前言 本题使用Python解答 如果需要Java代码 请参考以下链接 点我 题目 我们需要为拔河比赛挑选人选 挑选规则如下 1首先按身高排序 然后按体重排序 2 选出10个最合适的人选 输入是一个数组 数组存储的是所有人员的身高 体重信息
  • vue项目的简体繁体切换

    vue项目的简体繁体切换 在项目中有这样的一个需求 需要对APP内的字体进行简体和繁体的切换 一开始在项目中下载引入了vue i18n的语言包 但是有个缺点就是i18n语言包不能对接口返回的字体进行转换 还有的就是只能实现部分字体的转换 工
  • AcWing 826. 单链表

    题目 实现一个单链表 链表初始为空 支持三种操作 1 向链表头插入一个数 2 删除第k个插入的数后面的数 3 在第k个插入的数后插入一个数 现在要对该链表进行M次操作 进行完所有操作后 从头到尾输出整个链表 注意 题目中第k个插入的数并不是
  • Spring中@component的使用

    Spring中 component的使用 component是spring中的一个注解 它的作用就是实现bean的注入 在探究 component前先了解一下注解 何为注解 注解本质上就是一个类 开发中我们可以使用注解 取代 xml配置文件
  • [项目管理-14]:大规模组织的项目管理办公室PMO

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 什么是PMO 1 1 PMO定义 1 2 PMO的由来 1 3 PMP的职责 第2章 PMO的组织架构 1 1 架构 1 2
  • Python 之 元组小结

    字典是Python中唯一内建的映射类型 字典中的值并没有特殊的顺序 键可以是数字 字符串甚至是元组 dic 1 a 2 b 3 c dict 创建字典 gt gt gt dic 1 a 2 b 3 c gt gt gt dic dict d
  • HAL库函数中的HAL_I2C_Mem_Write /HAL_I2C_Mem_Read中的DevAddress解析

    在HAL库函数中的HAL I2C Mem Write HAL I2C Mem Read两个函数的作用就是玩IIC设备中写入 读取多个直接的数据 函数原型 HAL StatusTypeDef HAL I2C Mem Read I2C Hand
  • java---lambda函数

    背景 lambda 表达式是一个可传递的代码块 可以在以后执行一次或多次 就类似于sort arrs comparator 函数在排列结束之前会不停调用comparator代码块 在java中传递一个代码段并不容易 不能直接传递代码段 Ja
  • LeetCode常见经典算法——KMP算法

    常见经典算法 KMP算法 参考 https www bilibili com video BV1jb411V78H from search seid 6567338116212695926 关键字 有效回溯 最大公共前后缀长度 样本串的ne
  • 西门子200PLC软件的安装和使用

    西门子200PLC软件 v4 0 STEP 7 MicroWIN SP6 的安装和使用 文章目录 目录 文章目录 前言 二 安装时可能会出现的问题 1 无法进行安装并出现英文提示 2 解决方法 三 通信问题 PC PG设置无PC PPI C
  • makefile基础及常用规则

    什么是makefile 或许很多Windows的程序员都不知道这个东西 因为那些Windows的IDE都为你做了这个工作 但我觉得要作一个好的和professional的程序员 makefile还是要懂 特别在Unix下的软件编译 你就不能