makefile 完美教程

简介

Makefile 是和 make 命令一起配合使用的,很多大型项目的编译都是通过 Makefile 来组织的,。
我建立工程的方法有以下三点:
1.makefile:
优点:使用非常广泛,通用性强,可跨平台。
缺点:语法比较蛋疼。要写出一个通用,便于管理,且兼容性强的makefile比较困难。

2.cmake:
优点:简单易用,使用较广泛,方便管理,可跨平台。
缺点:自动生成的makefile太臃肿。

3.sh脚本:
优点:自由,高度定制。简单易用,可操作性强。方便维护。(甚至还可以生成makefile)
缺点:sh建的工程太少了(估计没人这么搞吧)

但我考虑到方便移植和管理其他人的工程还是选择了第一种,以makefile建立管理工程。(其实我的内心是比较向往第三种sh脚本建工程的)。下面来介绍下makefile的规则以及语法

PS:我本意是想写短一点的,只是想写点常用的东西,方便大家查阅。精炼了这么久,可还有这么多内容(15000字)。所以,大家还是耐心的学习吧,想学好linux这是必不可少的一步。


规则

说明

<target1 > <target2>.... : <prerequisites1> <prerequisites2>...
[TAB] <command1>
[TAB] <command2>
...

target可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。对于标签这种特性,在后续的“伪目标”章节中会有叙述。

<prerequisites>就是,要生成那个target所需要的文件或是目标。

<command>也就是make需要执行的命令。(任意的shell命令)

这是一个文件的依赖关系,也就是说,<target>这一个或多个的目标文件依赖于<prerequisites>中的文件,其生成规则定义在 <command>中。说白一点就是说,<prerequisites>中如果有一个以上的文件比<target>文件要新的话,<command>所定义的命令就会被执行。这就是makefile的规则。也就是makefile中最核心的内容。

经典示例

原始版本

objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.oedit : $(objects)cc -o edit $(objects)
main.o : main.c defs.hcc -c main.c
kbd.o : kbd.c defs.h command.hcc -c kbd.c
command.o : command.c defs.h command.hcc -c command.c
display.o : display.c defs.h buffer.hcc -c display.c
insert.o : insert.c defs.h buffer.hcc -c insert.c
search.o : search.c defs.h buffer.hcc -c search.c
files.o : files.c defs.h buffer.h command.hcc -c files.c
utils.o : utils.c defs.hcc -c utils.c
clean :rm edit $(objects)

自动推导版本

objects = main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ = gccedit : $(objects)cc -o edit $(objects)main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h.PHONY : clean
clean :rm edit $(objects)

理解

1.内容展开

list_a = 1.a 2.a
list_b = 1.b 2.b 3.b#list_a中的元素每次单个展开连接list_b中的所有元素
#结果如下
test:list_a
%.a:list_b	#展开:1.a:1.b 2.b 3.b		#此时&@=1.a  $<=1.b 2.b 3.b2.a:1.b 2.b 3.b		#此时&@=2.a  $<=1.b 2.b 3.b#内容还可以继续展开
%.b:%.x		#自动推导展开1.b:1.x2.b:2.x3.b:3.x

2.include 相当于将内容复制展开,export可以共享全局变量。

3.用make遍历子目录makefile时相当于,用新进程开启make。因此export不能共享全局变量。

注意

1.注意空格与TAB(有些编辑器会自动将TAB转换成4个空格,难以发现)

2.注意 = 与 := 的区别
包括export 在内的所有变量都不能共享
如果使用cd &&make进行遍历。那么最好转换成绝对路径

3.如果使用cd &&make进行遍历。那么最好转换成绝对路径


语法

1.符号

1) 命令前缀

[不用前缀 ]输出执行的命令以及命令执行的结果, 出错的话停止执行
[前缀 @]只输出命令执行的结果, 出错的话停止执行
[前缀 -]命令执行有错的话, 忽略错误, 继续执行

2) 通配符

*表示任意一个或多个字符
? 表示任意一个字符
[...] [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字

3) 自动变量

在下文的 自动变量

4) 赋值

= :=

相同点:都是给内容赋值;
区别:与Verilog的=和<=类似。
其中 = 和 := 的区别在于 :

= 只能使用前面定义好的变量,
= 可以使用后面定义的变量

赋值符号 [=]

= 最后再赋值

# Makefile内容
OBJS2 = $(OBJS1) programC.o
OBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执行 make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使用
$ make
programA.o programB.o programC.o

赋值符号 [:=]

:= 立即赋值

# Makefile内容
OBJS2 := $(OBJS1) programC.o
OBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执行 make, 可以看出 OBJS2 中的 $(OBJS1) 为空
$ make
programC.o

赋值符号 [+=]

+= 变量追加值

# Makefile内容
SRCS := programA.c programB.c programC.c
SRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运行make
$ make
SRCS:  programA.c programB.c programC.c programD.c

5) 伪目标

.PHONY

.PHONY : clean
clean :-rm edit $(objects)

2. 隐含规则

1) 自动推倒命名:

编译C时,*.o 的目标会自动推导为 *.c

2) 隐含变量

[RM] rm -f
[AR] ar
[CC] cc
[CXX] g++
[ARFLAGS] AR命令的参数
[CFLAGS] 语言编译器的参数
[CXXFLAGS] C++语言编译器的参数

3) 自动变量

[$@] 目标集合
[$%] 当目标是函数库文件时, 表示其中的目标文件名
[$<] 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
[$?] 比目标新的依赖目标的集合
[$^] 所有依赖目标的集合, 会去除重复的依赖目标
[$+] 所有依赖目标的集合, 不会去除重复的依赖目标
[$*] 这个是GNU make特有的, 其它的make不一定支持

1.o: 1.c@echo $@ : $< # bash中执行 make:
1.o : 1.c

3.定义

不限于makefile还有部分shell指令

1) 查看依赖关系

gcc -MM

$ gcc -MM kvm_main.c 
kvm_main.o: kvm_main.c iodev.h coalesced_mmio.hasync_pf.h  

#这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系

2) 定义命令包

define <command-name>
command
...
endef

# Makefile 内容
define run-hello-makefile
@echo -n "Hello"
@echo " Makefile!"
@echo "这里可以执行多条 Shell 命令!"
endefall:$(run-hello-makefile)# bash 中运行make
$ make
Hello Makefile!
这里可以执行多条 Shell 命令!

3) 条件判断

# Makefile 内容
all:
ifeq ("aa", "bb")@echo "equal"
else@echo "not equal"
endif# bash 中执行 make
$ make
not equal

4) 自定义函数

$(call <expression>,<parm1>,<parm2>,<parm3>...)

# Makefile 内容
hello = "hello " $(1) " world"all:@echo $(call hello,"我是参数1")# bash 中执行 make
$ make
hello 我是参数1 world

5) 执行shell指令

$(shell <shell command>) 与 `<shell command>`
作用:执行一个shell命令, 并将shell命令的结果作为返回.
注意:` 是反引号(英文状态下,键盘的ESC下面那个键)

4.函数

不限于makefile还有部分shell指令

1) 传参(同一个进程)

export

export EX_VAR = value
export EX_VAR := value
export EX_VAR += value
#=  :=  +=  与上面的描述基本相同

注意:是同一个进程下的make才有用。当多级遍历make时是无法全局的。

2) 字符串处理

(1) 字符串替换函数

$( subst<source>,<new>,<text>)

功能: 把字符串<text> 中的<source> 替换为<new>
返回: 替换过的字符串

# Makefile 内容
all:@echo $(subst t,e,maktfilt)  <-- 将t替换为e# bash 中执行 make
$ make
makefile

(2) 字符串中每个元素替换函数

$( patsubst <source>,<new>,<text>)

功能: 把字符串 <text> 中的的每个元素 <source> 替换为<new>
返回: 替换过的字符串

# Makefile 内容
all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执行 make
$ make
programA.o programB.o

(3) 去空格函数

$(strip <text>)

功能: 去掉 <string> 字符串中开头和结尾的空字符
返回: 被去掉空格的字符串值

# Makefile 内容
VAL := "       aa  bb  cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执行 make
$ make
去除空格前:         aa  bb  cc 
去除空格后:   aa bb cc

(4) 判断字符串内是否存在特定字符串

$(findstring<text>,<elem>)

功能: 在字符串 <text> 中查找 <elem> 字符串是否存在
返回: 如果找到, 返回 <elem> 字符串, 否则返回空字符串

# Makefile 内容
VAL := "       aa  bb  cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执行 make
$ make
aa

3) 文件元素相关

(1) 取文件函数

保留符合条件的元素

$(filter <elem1 elem2...>,<text>)

# Makefile 内容
all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执行 make
$ make
program.o program.a
program.c
去掉符合条件的元素

$(filter-out <elem1 elem2...>,<text>)

# Makefile 内容
all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执行 make
$ make
program.c
获取该目录下所有文件

获取该目录下所有.x文件
$(wildcard *.x)

# Makefile 内容
all:@echo $(wildcard *.c)# bash 中执行 make
$ make
a.x b.x c.x

(2) 路径函数

去掉路径

$(notdir <elem elem...>)

功能: 去掉序列的路径
返回: 文件名序列 <elem> 中的非目录部分

# Makefile 内容
all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执行 make
$ make
a.c bb.c c.c d.c
取路径

$(dir <elem1 elem2...>)

功能: 从文件名序列 <elem> 中取出目录部分
返回: 文件名序列 <elem> 中的目录部分

# Makefile 内容
all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执行 make
$ make
/home/ ./ ../ ./

(3) 取前后缀

取后缀函数

$(suffix <elem1 elem2...>)

功能: 从文件名序列 <elem> 中取出各个文件名的后缀
返回: 文件名序列 <elem> 中各个文件名的后缀, 没有后缀则返回空字符串

# Makefile 内容
all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执行 make
$ make
.c .o .a
取前缀函数

$(basename <elem1 elem2...>)

功能: 从文件名序列 <elem> 中取出各个文件名的前缀
返回: 文件名序列 <elem> 中各个文件名的前缀, 没有前缀则返回空字符串

# Makefile 内容
all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执行 make
$ make
/home/a ./b ../c /home/

(3) 增添前后缀

增添后缀函数

$(addsuffix <suffix>,<elem1 elem2...>)

功能: 把后缀 <suffix> 加到 <elem> 中的每个单词后面
返回: 加过后缀的文件名序列

# Makefile 内容
all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执行 make
$ make
/home/a.c b.c ./c.o.c ../d.c.c
增添前缀函数

$(addprefix <prefix>, <elem1 elem2...>)

功能: 把前缀 <prefix> 加到 <elem> 中的每个单词前面
返回: 加过前缀的文件名序列

# Makefile 内容
all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执行 make
$ make
test_/home/a.c test_b.c test_./d.c

我写的管理大型项目的makefile

以下内容为基础版本。可以混编C和C++。
但没有加入平台兼容性验证等功能。
在ubuntu16.04下测试通过。

tree
.
── app
   ── app1
      ── main.c
      └── makefile
   └── makefile
── make_conf.mk
── makefile
── make_fun.mk
── module
   ── makefile
   └── test
       ── drive
          ── cpp_test.cpp
          ── cpp_test.h
          ── test.c
          └── test.h
       ── hal
          ── test_hal.c
          └── test_hal.h
       └── makefile
└── output── bin   ── app1.bin   └── app2.bin── lib   └── libobj.a└── obj── app   ── app1      └── main.o   └── app2       └── main.o└── module└── test── drive   ── cpp_test.o   └── test.o└── hal└── test_hal.o17 directories, 22 files

顶层 makefile

# -------------------------------------------
# FileName      :makefile
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# Top makefile.
#
# ------------------------------------------- # 设置当前路径
DIR_ROOT:=.# 设置递归子目录
DIR_LIST_SUB :=module appinclude $(DIR_ROOT)/make_conf.mk
all:make_root
clean:make_clean
include $(DIR_ROOT)/make_fun.mk

中间遍历层 makefile

# -------------------------------------------
# FileName      :xx/makefile
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# Level1 makefile.
#
# ------------------------------------------- # 设置当前路径
DIR_ROOT:=..# 添加递归子目录
DIR_LIST_SUB :=\
app1\
app2\# 添加源文件
FILE_LIST_C +=\FILE_LIST_CPP +=\FILE_LIST_S +=\# 添加头文件路径
DIR_LIST_INCLUDE+=\include $(DIR_ROOT)/make_conf.mk 
all:make_show make_subdir
clean:make_clean
include $(DIR_ROOT)/make_fun.mk

app的makefile

# -------------------------------------------
# FileName      :xx/xx/makefile
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# Level2 makefile.
#
# ------------------------------------------- # 设置当前路径
DIR_ROOT:=../..# 添加递归子目录
DIR_LIST_SUB :=\# 添加源文件
FILE_LIST_C +=\
main.c\FILE_LIST_CPP +=\FILE_LIST_S +=\# 添加头文件路径
DIR_LIST_INCLUDE+=\
$(DIR_ROOT)/module/test/hal\
$(DIR_ROOT)/module/test/drive\include $(DIR_ROOT)/make_conf.mk 
all:make_show make_app
clean:make_clean
include $(DIR_ROOT)/make_fun.mk

drive的makefile

# -------------------------------------------
# FileName      :xx/xx/makefile
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# Level2 makefile.
#
# ------------------------------------------- # 设置当前路径
DIR_ROOT:=../..# 添加递归子目录
DIR_LIST_SUB :=\# 添加源文件
FILE_LIST_C +=\
drive/test.c\
hal/test_hal.c\FILE_LIST_CPP +=\
drive/cpp_test.cpp\FILE_LIST_S +=\# 添加头文件路径
DIR_LIST_INCLUDE+=\
hal\
drive\include $(DIR_ROOT)/make_conf.mk 
all:make_show make_lib_a
clean:make_clean
include $(DIR_ROOT)/make_fun.mk

配置文件 make_conf.mk

# -------------------------------------------
# FileName      :make_set.inc
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# 工程相关设置。
#
# -------------------------------------------# 设置常用指令
# -------------------------------------------
RM = rm -f
MV = mv -f
MKDIR = mkdir -p
RMDIR = rm -rf   # 颜色输出
# -------------------------------------------
ECHO_END:=\033[0m"
ECHO_GREEN:=echo "\033[32m
ECHO_RED:=echo "\033[31m
ECHO_YELLOW:=echo "\033[33m
ECHO_BLUE:=echo "\033[34m
ECHO_GREEN_YELLOW:=echo "\033[42;30m# 编译缺省设置
# -------------------------------------------# 默认编译
CXX:=g++#编译选项
COMPILE_C ?= $(CXX)
COMPILE_CXX ?= $(CXX)
COMPILE_ASM ?= $(CXX)
COMPILE_AR ?= ar# 设置优化等级
OPT ?=0# 设置警告开关
COMPILE_WARN ?= -Wall  # 设置静态编译
COMPILE_STATIC ?= -s# 在环境基础下添加设置
CFLAGS+= $(DIR_LIST_INCLUDE_I) $(COMPILE_WARN) -O$(OPT) $(COMPILE_STATIC)
CXXFLAGS+= $(DIR_LIST_INCLUDE_I) $(COMPILE_WARN) -O$(OPT) $(COMPILE_STATIC)
ASFLAGS+= -Wa,-adhlns=$(<:.S=.lst),-gstabs $(DIR_LIST_INCLUDE_I)# 编译设置汇总 
COMPILE_CFLAGS = $(CFLAGS)
COMPILE_CXXFLAGS = $(CXXFLAGS)
COMPILE_ASFLAGS = $(ASFLAGS)#链接选项
LDFLAGS+= -lstdc++#编译C++
LDFLAGS+= -lpthread#使用了线程
LDFLAGS+= -fPIC#编译为位置独立的代码
LDFLAGS+= -ldl#引用动态库
LDFLAGS+= $(DIR_LIST_INCLUDE_I)#引用其他静态库
FILE_LIST_LIB_A+=\

功能文件 make_fun.mk

# -------------------------------------------
# FileName      :make_fun.mk
# Author        :wind 
# Date          :2018-1-16
# Description 
#
# 实际编译过程。
#s
# ------------------------------------------- # 路径关系
# -------------------------------------------
DIR_ROOT_REAL=$(realpath $(DIR_ROOT))
NAME_MODULE := $(notdir $(CURDIR))#所在的文件夹名称
DIR_OUTPUT:=$(DIR_ROOT)/output
DIR_BIN:=$(DIR_OUTPUT)/bin
DIR_OBJ:=$(DIR_OUTPUT)/obj
DIR_LIB:=$(DIR_OUTPUT)/lib# 路径处理成可用参数
# -------------------------------------------
DIR_LIST_INCLUDE_I:=$(addprefix -I,$(DIR_LIST_INCLUDE))#添加编译选项-I
DIR_LIST_SUB:=$(addprefix  $(CURDIR)/,$(DIR_LIST_SUB))#转换成绝对路径
DIR_CURDIR:=$(subst $(DIR_ROOT_REAL),,$(CURDIR))#相对路径
DIR_OBJ_OUT:=$(DIR_OBJ)$(DIR_CURDIR)#文件处理
FILE_LIST_OBJ:=$(FILE_LIST_C:%.c=%.o)
FILE_LIST_OBJ+=$(FILE_LIST_CPP:%.cpp=%.o)
FILE_LIST_OBJ+=$(FILE_LIST_S:%.s=%.o)FILE_LIST_OBJ:=$(addprefix  $(DIR_OBJ_OUT)/,$(FILE_LIST_OBJ))#转换成带绝对路径的中间文件
FILE_LIB_A:=$(DIR_LIB)/libobj.a
FILE_LIST_LIB_APP:=$(DIR_BIN)/$(NAME_MODULE).bin# 函数库
# ------------------------------------------- 
make_root:make_start make_subdir make_end# 工程开始
make_start:@$(ECHO_BLUE)\t-----------------------------$(ECHO_END)@$(ECHO_BLUE)\t-\t [编译开始]  \t    -$(ECHO_END)@$(ECHO_BLUE)\t-----------------------------$(ECHO_END)@$(ECHO_BLUE)[COMPILE_C]$(COMPILE_C) 	 	[COMPILE_CFLAGS]$(COMPILE_CFLAGS)$(ECHO_END)@$(ECHO_BLUE)[COMPILE_CXX]$(COMPILE_CXX) 	[COMPILE_CXXFLAGS]$(COMPILE_CXXFLAGS)$(ECHO_END)@$(ECHO_BLUE)[COMPILE_ASM]$(COMPILE_ASM) 	[COMPILE_ASFLAGS]$(COMPILE_ASFLAGS)$(ECHO_END)@$(ECHO_BLUE)[COMPILE_AR]$(COMPILE_AR)   	[LDFLAGS]$(LDFLAGS)$(ECHO_END)@$(ECHO_BLUE)[OPT]$(OPT)  $(ECHO_END)@$(ECHO_BLUE)[COMPILE_STATIC]$(COMPILE_STATIC)  $(ECHO_END)@$(ECHO_BLUE)[FILE_LIST_LIB_A]$(FILE_LIST_LIB_A)  $(ECHO_END)# 工程完成
make_end: @$(ECHO_BLUE)[编译完成]$(ECHO_END)         # 递归子目录
make_subdir:@for list in $(DIR_LIST_SUB);\do\cd $$list && make all|| exit 1;\done# 生成可执行文件
make_app:make_lib_a make_bin# 生成静态链接库
make_lib_a:make_obj@$(MKDIR) `dirname $(FILE_LIB_A)`@$(ECHO_YELLOW)[$(COMPILE_AR)]-rcs $(FILE_LIB_A) $(FILE_LIST_OBJ)$(ECHO_END)$(COMPILE_AR) -rcs $(FILE_LIB_A) $(FILE_LIST_OBJ)# 链接
make_bin:$(FILE_LIST_LIB_APP)# 编译
make_obj:$(FILE_LIST_OBJ)# 清除
make_clean:$(RMDIR) $(DIR_OUTPUT)# 显示参数,方便调试
make_show:@$(ECHO_GREEN_YELLOW)[DIR_CURDIR] $(DIR_CURDIR) $(ECHO_END)@$(ECHO_GREEN)[FILE_LIST_C] $(FILE_LIST_C) $(ECHO_END)@$(ECHO_GREEN)[DIR_LIST_INCLUDE] $(subst $(DIR_ROOT)/,[DIR_ROOT]/,$(DIR_LIST_INCLUDE)) $(ECHO_END)# 文件操作过程
# ------------------------------------------- # 编译过程成中间文件
$(DIR_OBJ_OUT)/%.o: %.c@$(MKDIR) `dirname $@`@$(ECHO_YELLOW)[$(COMPILE_C)]$< -o $@ $(ECHO_END)$(COMPILE_C) -c $(COMPILE_CFLAGS) $< -o $@$(DIR_OBJ_OUT)/%.o: %.cpp@$(MKDIR) `dirname $@`@$(ECHO_YELLOW)[$(COMPILE_CXX)]$< -o $@ $(ECHO_END)$(COMPILE_CXX) -c $(COMPILE_CXXFLAGS) $< -o $@$(DIR_OBJ_OUT)/%.o: %.s@$(MKDIR) `dirname $@`@$(ECHO_YELLOW)[$(COMPILE_C)]$< -o $@ $(ECHO_END)$(COMPILE_ASM) -c $(COMPILE_ASFLAGS) $< -o $@# 链接成二进制文件
$(FILE_LIST_LIB_APP): $(FILE_LIB_A)@$(MKDIR) `dirname $@`@$(ECHO_YELLOW)[$(COMPILE_C)]$< -o $@ $(ECHO_END)$(COMPILE_C) $(LDFLAGS) -L$(DIR_LIB) -lobj $< $(FILE_LIST_LIB_A) -o $@

内容推荐

跟我一起写Makefile
Makefile 使用总结
项目实用makefile
Makefile之大型工程项目子目录Makefile的一种通用写法

引用本地址

https://www.cnblogs.com/wittxie/p/9836097.html

转载于:https://www.cnblogs.com/wittxie/p/9836097.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——顺序栈和链式栈的简单实现和解析(C语言版)

摘自&#xff1a;数据结构学习——顺序栈和链式栈的简单实现和解析&#xff08;C语言版&#xff09; 作者&#xff1a;正弦定理 发布时间&#xff1a;2020-11-26 21:26:49 网址&#xff1a;https://blog.csdn.net/chinesekobe/article/details/110205257 数据结构——栈的简单解…

c语言位运算负数的实例_0基础学习C语言第三章:位运算

C语言提供了六种位运算符&#xff1a;& 按位与| 按位或^ 按位异或~ 取反<< 左移&#xff0c;相当与*2>> 右移&#xff0c;正数高位补0&#xff0c;负数由计算机决定循环左移k次 (x<<k) | (x >> (32-k)),循环右移k次 (x>>k) | (x << (3…

phpMyAdmin 安装错误解决方法

为什么80%的码农都做不了架构师&#xff1f;>>> phpMyAdmin - Error Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly. Also ensure that cookies are ena…

Harbo1.5.2离线搭建

环境说明 操作系统版本&#xff1a;Centos7.5 docker版本&#xff1a;docker-ce 17.03.2 harbor版本&#xff1a;v1.5.2 docker-compose: 1.22.0 基础环境搭建 系统优化 CentOS关闭selinux sudo sed -i s/SELINUXenforcing/SELINUXdisabled/g /etc/selinux/configsetenforce 0…

数据结构——二叉链表创建二叉树(C语言版)

摘自&#xff1a;数据结构——二叉链表创建二叉树&#xff08;C语言版&#xff09; 作者&#xff1a;正弦定理 发布时间&#xff1a;2020-12-08 15:36:21 网址&#xff1a;https://blog.csdn.net/chinesekobe/article/details/110873792 数据结构——二叉链表创建二叉树 一、思…

pca图解读_干货!手把手一步一步解读PCA分析,逃学博士尽力了!

01 引言之前发了几篇文章关于矩阵中 特征向量和PCA主元分析的文章&#xff0c;大家反响不错。当时并没有涉及到数学运算&#xff0c;只是大概讲了讲原理。这篇文章我们一起来一步一步解读PCA的计算过程如何用Python实现PCA分析准备就绪02 第一步&#xff1a;数据获取第一步&…

中南月赛 1313: ZZY的宠物

1313: ZZY的宠物 Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 114 Solved: 59[Submit][Status][Web Board]Description ZZY领养了一对刚刚出生的不知名小宠物..巨萌巨可爱!!...小宠物的生命为5个单位时间并且不会在中间出意外翘辫子(如: 从0出生能活到5但活不到6)..小宠物…

查询大于2分钟的数据

查询大于2分钟的数据select * from dt_appsdk_users where datediff(mi,update_time,getdate()) > 2转载于:https://www.cnblogs.com/sntetwt/p/9838012.html

数据结构——二叉树根节点到特定节点路径(C语言版)

摘自&#xff1a;数据结构——二叉树根节点到特定节点路径&#xff08;C语言版&#xff09; 作者&#xff1a;正弦定理 发布时间&#xff1a;2020-12-10 21:09:43 网址&#xff1a;https://blog.csdn.net/chinesekobe/article/details/110991771 二叉树——根节点到特定节点路径…

实用插件_精选 10 个非常实用的 VS Code 插件

来源&#xff1a;Daan原文&#xff1a;https://medium.com/better-programming/10-extremely-helpful-visual-studio-code-plugins-for-programmers-c8520a3dc4b8无论你是经验丰富的开发人员还是刚刚开始第一份工作的初级开发人员&#xff0c;你都会想让自己的开发工作尽可能轻…

nginx笔记.

安装&#xff1a; 依赖的软件包&#xff1a; gcc gcc-c autoconf automake zlib zlib-devel openssl opensll-devel pcre pcre-devel 到官方网站上下载nginx包&#xff1a; 解压: tar -zxf nginx-x.x.tar.gz 安装三步走&#xff1a;./configure------- make------make install …

English trip -- VC(情景课)10 C I like to watch TV. 我爱看电视

Grammar focus 语法点&#xff1a; like to do you do they What does he like to do? does she Practice 练习 What do they like to do&#xff1f; They like to play basketball. What does she like to do&#xff1f; She likes to swim. What does he…

数据结构——计算节点个数和二叉树高度(C语言版)

摘自&#xff1a;数据结构——计算节点个数和二叉树高度&#xff08;C语言版&#xff09; 作者&#xff1a;正弦定理 发布时间&#xff1a;2020-12-12 23:27:09 网址&#xff1a;https://blog.csdn.net/chinesekobe/article/details/111086664 数据结构——计算节点个数、二叉树…

写入接口c语言_PYNQ: 使用CFFI嵌入C语言

未经私信同意禁止转载&#xff01;前言CFFI是连接Python与c的桥梁&#xff0c;可实现在Python中调用c文件。CFFI为c语言的外部接口&#xff0c;在Python中使用该接口可以实现在Python中使用外部c文件的数据结构及函数。Python运行比较低&#xff0c;尤其是操作字节流的时候&…

cp命令的编写——浅谈系统调用

摘要&#xff1a;linux中cp命令的实现&#xff0c;通过这个程序&#xff0c;我们需要了解系统调用耗费时间的方面&#xff0c;同时学会系统调用的错误处理机制。 本文来源&#xff1a;http://blog.csdn.net/trochiluses/article/details/11103523 #include<stdio.h> #inc…

Unity 协程原理探究与实现

目录 一、介绍二、迭代器三、原理四、总结一、介绍 协程Coroutine在Unity中一直扮演者重要的角色。可以实现简单的计时器、将耗时的操作拆分成几个步骤分散在每一帧去运行等等&#xff0c;用起来很是方便。 但是&#xff0c;在使用的过程中有没有思考过协程是怎么实现的&#x…

数据结构—无向图创建邻接矩阵、深度优先遍历和广度优先遍历(C语言版)

摘自&#xff1a;数据结构—无向图创建邻接矩阵、深度优先遍历和广度优先遍历&#xff08;C语言版&#xff09; 作者&#xff1a;正弦定理 发布时间&#xff1a;2020-12-19 17:25:49 网址&#xff1a;https://blog.csdn.net/zhuguanlin121/article/details/118436142 无向图创建…

android 图片识别白色区域进行裁剪_【研途技能贴】| 4款好用的图片处理软件推荐...

要考研啦4款好用的图片处理软件推荐01入门级作图神器——图怪兽一款会打字就能用的在线编辑器&#xff0c;80万模板任君挑选~无论是基础的旋转裁剪&#xff0c;还是难度进阶的抠图拼图&#xff0c;在这款软件里&#xff0c;你可以分分钟做出高大上的好图&#xff01;Use tips①…

Android 开发(一)项目概况

2019独角兽企业重金招聘Python工程师标准>>> 开始写博客&#xff0c;自己是边学习边做开发&#xff0c;将自己开发的过程记录下来&#xff0c;能够对学习的知识进行梳理&#xff0c;也可以对学习做个总结。 首先是对项目的介绍&#xff1a; 做一个功能全面的软件&am…

github和dockerhub制作k8s镜像

一、前言&#xff1a; 对于初学者来说&#xff0c;k8s的镜像问题往往会将他们拦在学习门外&#xff0c;今天就白话一下k8s众多镜像的获取方式&#xff0c;前提只有一个&#xff1a;你能上百度。 二、github和dockerhub账号准备&#xff0c;这个没任何门槛&#xff0c;只要知道这…