찾다
데이터 베이스RedisRedis 클래식 기술에 대한 자세한 설명: Makefile

이 기사에서는 Redis에 대한 관련 지식을 제공합니다. 여기서는 Makefile 파일, src/Makefile 파일, 모든 대상 콘텐츠 및 기타가 의존하는 다양한 하위 목표를 포함하여 Redis 소스 코드 컴파일의 Makefile 파일과 관련된 문제를 주로 소개합니다. 관련 내용이 모든 분들께 도움이 되었으면 좋겠습니다.

Redis 클래식 기술에 대한 자세한 설명: Makefile

추천 학습: Redis Tutorial

1. 머리말

이 글을 배우려면 Redis 소스 코드가 필요하며 관련 컴파일을 설정하는 것이 가장 좋습니다. Makefile파일의 실행 과정을 직관적으로 볼 수 있도록 환경을 제공합니다. 이 문서 "C++ Encapsulation Redis Operation Function"에는 Redis를 컴파일하고 설치하는 방법이 포함되어 있습니다. 독자는 이 문서를 먼저 읽어보세요. 여기에 사용된 소스 코드 버전은 redis-6.2.1입니다. Redis源码,且最好搭建起相关的编译环境,这样才能直观地看到Makefile文件的执行过程。这篇文章《C++封装Redis操作函数》里有编译安装Redis的方法,读者可以先看一下这篇文章。这里使用的源码版本是redis-6.2.1的。

2、Makefile文件详解

源代码根目录的Makefile文件内容如下:

default: all

.DEFAULT:	cd src && $(MAKE) $@install:	cd src && $(MAKE) $@.PHONY: install

从代码中可以看出以下几点信息:

  • 该文件的第一个目标是default,该目标没有实际作用,依赖于all目标
  • 代码中并没有所谓的all目标,所以当我们直接使用make时,首先会调用default目标,然后调用all目标,由于all目标不存在,所以会调用.DEFAULT目标来替代,在Makefile的执行语句中,$@代表的就是目标的意思,$(MAKE)代表的就是make,所以展开之后的代码如下,读者可以自行编译一下,看看第一条输出语句是否与我们分析的相同
cd src && make all
  • install目标和前面的类似,最终也是进去src/目录,然后调用该目录下的Makefile文件,区别只在于此时调用的目标变成了install而已,展开后的代码如下:
cd src && make install
  • 当传入参数是其他是,调用的都会转到.DEFAULT去,然后去调用子目录下的Makefile的对应的目标,以clean为例,代码如下:
cd src && make clean

3、src/Makefile文件详解

该文件是真正起编译作用的文件,内容比较多,比较杂,而且为了兼容多种编译器里面有不少分支选择语法,我们这里只以Linux下的gcc编译器为例去讲解,其余的没区别,就是通过判断语句去改变某些编译参数而已

3.1、Makefile.dep目标

Makefile在执行对应的目标之前,会先把非目标的指令给执行了,比如变量赋值、Shell语句等等,所以我们会发现,Makefile文件并不会完全按照顺序去执行的
相关代码如下:

NODEPS:=clean distclean# FINAL_CFLAGS里的各个变量原型STD=-pedantic -DREDIS_STATIC=''WARN=-Wall -W -Wno-missing-field-initializers
OPTIMIZATION?=-O2
OPT=$(OPTIMIZATION)DEBUG=-g -ggdb#CFLAGS 根据条件选择的,不重要的参数,忽略#REDIS_CFLAGS 根据条件选择的,不重要的参数,忽略FINAL_CFLAGS=$(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS) $(REDIS_CFLAGS)REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS)all: $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME)
	@echo ""
	@echo "Hint: It's a good idea to run 'make test' ;)"
	@echo ""Makefile.dep:
	-$(REDIS_CC) -MM *.c > Makefile.dep 2> /dev/null || trueifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))-include Makefile.dep
endif

首先先补充以下几点Makefile的基础

  • Makefilefindstring函数的使用格式为$(findstring FIND, IN),表示在IN中查找FIND,如果查找到了就返回FIND,找不到就返回空
  • Makefilewords函数表示统计单词数目,例如$(words, foo bar)的返回值为"2"
  • MakefileMAKECMDGOALS变量表示传入的参数(全部)
  • MakefileCC默认值是cc
  • Makefile-MM是输出一个用于make
  • 2. Makefile에 대한 자세한 설명
소스코드 루트 디렉터리에 있는 Makefile 파일의 내용은 다음과 같습니다.

acl.o: acl.c server.h fmacros.h config.h solarisfixes.h rio.h sds.h \
 connection.h atomicvar.h ../deps/lua/src/lua.h ../deps/lua/src/luaconf.h \
 ae.h monotonic.h dict.h mt19937-64.h adlist.h zmalloc.h anet.h ziplist.h \
 intset.h version.h util.h latency.h sparkline.h quicklist.h rax.h \
 redismodule.h zipmap.h sha1.h endianconv.h crc64.h stream.h listpack.h \
 rdb.h sha256.h
adlist.o: adlist.c adlist.h zmalloc.h
ae.o: ae.c ae.h monotonic.h fmacros.h anet.h zmalloc.h config.h \
 ae_epoll.c
ae_epoll.o: ae_epoll.c...

zipmap.o: zipmap.c zmalloc.h endianconv.h config.h
zmalloc.o: zmalloc.c config.h zmalloc.h atomicvar.h
코드에서 확인할 수 있는 정보는 다음과 같습니다. 🎜
  • 파일 첫 번째 목표는 default이며 실제 효과는 없으며 all 목표에 의존합니다🎜
  • 소위 all은 없습니다. 목표를 코드에 포함하므로 make를 직접 사용하면 default 대상이 먼저 호출된 다음 all 대상이 호출됩니다. all 대상이 존재하지 않으므로 Makefile의 실행 문에서 .DEFAULT 대상이 대신 호출됩니다. /code>는 대상의 의미를 나타내고, $(MAKE)make를 나타내므로 확장된 코드는 다음과 같이 독자가 직접 컴파일하여 첫 번째 출력이 나오는지 확인할 수 있습니다. 명령문은 우리가 분석한 것과 동일합니다🎜🎜
    .make-prerequisites:
    	@touch $@ifneq ($(strip $(PREV_FINAL_CFLAGS)), $(strip $(FINAL_CFLAGS))).make-prerequisites: persist-settings
    endif
    
    ifneq ($(strip $(PREV_FINAL_LDFLAGS)), $(strip $(FINAL_LDFLAGS))).make-prerequisites: persist-settings
    endif
    
    %.o: %.c .make-prerequisites	$(REDIS_CC) -MMD -o $@ -c $
    • 설치 대상은 이전 대상과 유사합니다. 결국 src/ 디렉터리로 이동한 다음 Makefile을 호출합니다. 파일을 해당 디렉터리에 저장하세요. 유일한 차이점은 이제 호출되는 대상이 install이 되고 확장된 코드는 다음과 같습니다. 🎜🎜
      # 假设生成的目标文件为acl.o,则代入可得acl.o: acl.c .make-prerequisites	$(REDIS_CC) -MMD -o acl.o -c acl.c
      # 执行完成后在该目录下会生成一个acl.o文件和acl.d文件
      • 수신 매개변수가 other인 경우 , 호출은 .DEFAULT로 이동한 다음 하위 디렉터리에 있는 Makefile의 해당 대상을 호출합니다. 예를 들어 clean을 사용하면 코드는 다음과 같습니다. 🎜🎜
        REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
        REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX)
        REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX)
        REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX)
        REDIS_CHECK_RDB_NAME=redis-check-rdb$(PROG_SUFFIX)
        REDIS_CHECK_AOF_NAME=redis-check-aof$(PROG_SUFFIX)
        🎜3. src/Makefile 파일에 대한 자세한 설명🎜🎜이 파일은 실제 파일입니다. 컴파일에 사용되는 파일은 내용이 많고 복잡합니다. 많은 분기 선택 구문이 있습니다. 여기서는 Linux에서 gcc만 사용합니다. 컴파일러는 설명하기 위해 예로 사용되었습니다. 판단문을 통한 특정 컴파일 매개변수🎜🎜3.1. Makefile.dep target🎜🎜Makefile은 변수 할당, Shell과 같은 비대상 명령이 실행되기 전에 먼저 해당 대상을 실행합니다. 문 등으로 인해 Makefile 파일이 순서대로 완전히 실행되지 않는 것을 알 수 있습니다.
        관련 코드는 다음과 같습니다. 🎜
        REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o gopher.o tracking.o connection.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o
        REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o
        REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o
        
        DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ:%.o=%.d)-include $(DEP)INSTALL=install
        REDIS_INSTALL=$(QUIET_INSTALL)$(INSTALL)# redis-server$(REDIS_SERVER_NAME): $(REDIS_SERVER_OBJ)
        	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a $(FINAL_LIBS)# redis-sentinel$(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)
        	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME)# redis-check-rdb$(REDIS_CHECK_RDB_NAME): $(REDIS_SERVER_NAME)
        	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_RDB_NAME)# redis-check-aof$(REDIS_CHECK_AOF_NAME): $(REDIS_SERVER_NAME)
        	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_AOF_NAME)# redis-cli$(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)
        	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o $(FINAL_LIBS)# redis-benchmark$(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ)
        	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/hdr_histogram/hdr_histogram.o $(FINAL_LIBS)
        🎜우선 add Makefile🎜
        • Makefilefindstring 코드> 함수의 사용 형식은 다음과 같습니다. <code>$(findstring FIND, IN), 이는 IN에서 FIND를 검색하고, 발견되면 FIND를 반환함을 의미합니다. >, 찾을 수 없으면 비어 있음을 반환합니다🎜
        • Makefilewords 함수는 $(words)와 같이 단어 수를 세는 것을 의미합니다. , foo bar )의 반환 값은 "2"🎜
        • MakefileMAKECMDGOALS 변수는 전달된 매개 변수를 나타냅니다. in (all)🎜
        • Makefile에 대한 CC의 기본값은 cc
        • 🎜
        • -MMMakefile /code>는 make에 대한 규칙을 출력합니다. 이 규칙은 소스 파일의 종속성을 설명하지만 시스템 헤더 파일은 포함하지 않습니다. 🎜🎜🎜🎜다음 정보를 요약할 수 있습니다. : 🎜
          • 里面的all目标正是我们前一节说到的那个默认的编译目标,但是我们可以自己试着去编译一下,会发现先生成的是Makefile.dep文件,因为他先执行了最下面那个判断语句,里面调用了Makefile.dep目标
          • 由于此时MAKECMDGOALS的值为all,不在NODEPS范围里,所以上面那个ifeq语句成立,会调用Makefile.dep目标
          • REDIS_CC的值由三个变量组成,QUIET_CC是打印调试信息的,读者可以自己去源码看相关内容,这部分不重要,我们忽略,CC的值代表的是编译器,FINAL_CFLAGS里面的值则是编译的一些参数,这些值在上面的代码中都已经摘录出来了
          • 综上所述Makefile.dep目标的作用就是生成当前目录下所有以.c结尾的文件的依赖关系,并写入Makefile.dep文件中,编译之后生成的文件内容如下所示,看起来挺乱,但是里面的内容其实将每个源文件最终生成的目标文件给列出来,并且将它需要的依赖列出来而已
          acl.o: acl.c server.h fmacros.h config.h solarisfixes.h rio.h sds.h \
           connection.h atomicvar.h ../deps/lua/src/lua.h ../deps/lua/src/luaconf.h \
           ae.h monotonic.h dict.h mt19937-64.h adlist.h zmalloc.h anet.h ziplist.h \
           intset.h version.h util.h latency.h sparkline.h quicklist.h rax.h \
           redismodule.h zipmap.h sha1.h endianconv.h crc64.h stream.h listpack.h \
           rdb.h sha256.h
          adlist.o: adlist.c adlist.h zmalloc.h
          ae.o: ae.c ae.h monotonic.h fmacros.h anet.h zmalloc.h config.h \
           ae_epoll.c
          ae_epoll.o: ae_epoll.c...
          
          zipmap.o: zipmap.c zmalloc.h endianconv.h config.h
          zmalloc.o: zmalloc.c config.h zmalloc.h atomicvar.h

          3.2、通用的生成目标文件的target

          代码如下:

          .make-prerequisites:
          	@touch $@ifneq ($(strip $(PREV_FINAL_CFLAGS)), $(strip $(FINAL_CFLAGS))).make-prerequisites: persist-settings
          endif
          
          ifneq ($(strip $(PREV_FINAL_LDFLAGS)), $(strip $(FINAL_LDFLAGS))).make-prerequisites: persist-settings
          endif
          
          %.o: %.c .make-prerequisites	$(REDIS_CC) -MMD -o $@ -c $<p>以下是对这部分代码的解析:</p>
          • 这部分是通用的根据源文件生成目标文件的targetMakefile%表示通配符,所以只要符合格式要求的都可以借助这段代码来生成对应的目标文件
          • .make-prerequisites没啥用忽略,而REDIS_CC的值在上一小节有说明了,是用于编译文件的指令
          • gcc-MMD参数与前面说的那个-MM是基本一致的,只不过这个会将输出内容导入到对应的%.d文件中
          • Makefile$@表示目标,$表示第一个依赖,<code>$^表示全部依赖
          • 综上,这个target的作用是依赖于一个源文件,然后根据这个源文件生成对应的目标文件,并且将依赖关系导入到对应的%.d文件中

          下面是一个简单的例子:

          # 假设生成的目标文件为acl.o,则代入可得acl.o: acl.c .make-prerequisites	$(REDIS_CC) -MMD -o acl.o -c acl.c
          # 执行完成后在该目录下会生成一个acl.o文件和acl.d文件

          3.3、all目标所依赖的各个子目标的名称设置

          PROG_SUFFIX的值默认为空,可以忽略。这里设置的六个目标名都是会被all这个目标引用的,从名字可以看出这六个目标是对应着Redis不同的功能,依次是服务、哨兵、客户端、基础检测、rdf持久化以及aof持久化。
          代码如下:

          REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
          REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX)
          REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX)
          REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX)
          REDIS_CHECK_RDB_NAME=redis-check-rdb$(PROG_SUFFIX)
          REDIS_CHECK_AOF_NAME=redis-check-aof$(PROG_SUFFIX)

          3.4、all目标所依赖的各个子目标的内容

          • REDIS_LD也是一个编译指令,和前面那个REDIS_CC有点像,只不过这个指定了另外的一些编译参数,比如设置了某些依赖的动态库、静态库的路径,读者有兴趣的话可以去看一下代码,看看REDIS_LD的详细内容
          • FINAL_LIBS是一系列动态库链接参数,读者有兴趣可以自行去Makefile里面查看该变量的内容,限于篇幅原因这里就不展开讲了
          • QUIET_INSTALL忽略(这个是自定义打印编译信息的),可以看出REDIS_INSTALL的值其实就是installLinux下的install命令是用于安装或升级软件或备份数据的,这个命令与cp类似,但是install允许你控制目标文件的属性,这里不作深入分析了,有兴趣的读者可以自行查阅相关的介绍install命令的文章。基本用法为:install src des,表示将src文件复制到des文件去
            代码如下:
          REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o gopher.o tracking.o connection.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o
          REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o
          REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o
          
          DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ:%.o=%.d)-include $(DEP)INSTALL=install
          REDIS_INSTALL=$(QUIET_INSTALL)$(INSTALL)# redis-server$(REDIS_SERVER_NAME): $(REDIS_SERVER_OBJ)
          	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/lua/src/liblua.a $(FINAL_LIBS)# redis-sentinel$(REDIS_SENTINEL_NAME): $(REDIS_SERVER_NAME)
          	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME)# redis-check-rdb$(REDIS_CHECK_RDB_NAME): $(REDIS_SERVER_NAME)
          	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_RDB_NAME)# redis-check-aof$(REDIS_CHECK_AOF_NAME): $(REDIS_SERVER_NAME)
          	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(REDIS_CHECK_AOF_NAME)# redis-cli$(REDIS_CLI_NAME): $(REDIS_CLI_OBJ)
          	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o $(FINAL_LIBS)# redis-benchmark$(REDIS_BENCHMARK_NAME): $(REDIS_BENCHMARK_OBJ)
          	$(REDIS_LD) -o $@ $^ ../deps/hiredis/libhiredis.a ../deps/hdr_histogram/hdr_histogram.o $(FINAL_LIBS)

          3.4.1、REDIS_SERVER_NAME目标

          该目标依赖于REDIS_SERVER_OBJ,而REDIS_SERVER_OBJ的内容都是一些目标文件(上面代码有给出),这些目标文件最终都会通过3.2小节介绍的那个target来生成。可以看到REDIS_SERVER_NAME这个target需要使用REDIS_SERVER_OBJ…/deps/hiredis/libhiredis.a…/deps/lua/src/liblua.a以及FINAL_LIBS这些来编译链接生成最终的目标文件,即redis-server

          3.4.2、REDIS_SENTINEL_NAME目标

          可以看到REDIS_SENTINEL_NAME目标很简单,只是简单地使用install命令复制了REDIS_SERVER_NAME目标生成的那个文件,即redis-server,从这里可以知道哨兵服务redis-sentinelRedis服务使用的是同一套代码

          3.4.3、REDIS_CHECK_RDB_NAME目标

          和前面的如出一辙,也是简单复制了redis-server文件到redis-check-rdb文件去

          3.4.4、REDIS_CHECK_AOF_NAME目标

          和前面的如出一辙,也是简单复制了redis-server文件到redis-check-aof文件去

          3.4.5、REDIS_CLI_NAME目标

          这个就不是简单复制了,而是使用和REDIS_SERVER_NAME目标相同的方法进行直接编译的,唯一的区别是REDIS_SERVER_NAME链接了…/deps/lua/src/liblua.a,而REDIS_CLI_NAME链接的是…/deps/linenoise/linenoise.o

          3.4.6、REDIS_BENCHMARK_NAME目标

          这个也是使用和REDIS_SERVER_NAME目标相同的方法进行直接编译的,唯一的区别是REDIS_SERVER_NAME链接了…/deps/lua/src/liblua.a,而REDIS_BENCHMARK_NAME链接的是…/deps/hdr_histogram/hdr_histogram.o

          3.5、all目标

          经过前面的介绍,all目标的作用也就一目了然了,最终会生成六个可执行文件,以及输出相应的调试信息
          代码如下:

          all: $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME)
          	@echo ""
          	@echo "Hint: It's a good idea to run 'make test' ;)"
          	@echo ""

          3.6、安装和卸载Redis的目标

          3.6.1、安装Redis的目标

          这里逻辑很简单,先创建一个用于存放Redis可执行文件的文件夹(默认是/usr/local/bin),然后将REDIS_SERVER_NAMEREDIS_BENCHMARK_NAMEREDIS_CLI_NAME对应的可执行文件复制到/usr/local/bin中去,这里可以看到前面那几个照葫芦画瓢的文件并没有复制过去,而是直接通过创建软连接的方式去生成对应的可执行文件(内容相同,复制过去浪费空间)
          代码如下:

          PREFIX?=/usr/local
          INSTALL_BIN=$(PREFIX)/bin
          
          install: all
          	@mkdir -p $(INSTALL_BIN)
          	$(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(INSTALL_BIN)
          	$(REDIS_INSTALL) $(REDIS_BENCHMARK_NAME) $(INSTALL_BIN)
          	$(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN)
          	@ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
          	@ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
          	@ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)

          3.6.2、卸载Redis的目标

          这里就是删除前面复制的那些文件了,比较简单,就不细讲了
          代码如下:

          uninstall:
          	rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME)}

          3.7、clean和distclean目标

          所有Makefileclean或者distclean目标的作用都是大致相同的,就是删除编译过程中产生的那些中间文件,以及最终编译生成的动态库、静态库、可执行文件等等内容,代码比较简单,就不作过多的分析了
          代码如下:

          clean:	rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep dict-benchmark	rm -f $(DEP).PHONY: clean
          
          distclean: clean
          	-(cd ../deps && $(MAKE) distclean)
          	-(rm -f .make-*).PHONY: distclean

          3.8、test目标

          执行完Redis编译之后,会有一段提示文字我们可以运行make test测试功能是否正常,从代码中我们可以看出其实不止一个test目标,还有另一个test-sentinel目标,这个是测试哨兵服务的。这两个目标分别运行了根目录的runtestruntest-sentinel文件,这两个是脚本文件,里面会继续调用其他脚本来完成整个功能的测试,并输出测试信息到控制台。具体怎么测试的就不分析了,大家有兴趣的可以去看一下。
          代码如下:

          test: $(REDIS_SERVER_NAME) $(REDIS_CHECK_AOF_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME)
          	@(cd ..; ./runtest)test-sentinel: $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME)
          	@(cd ..; ./runtest-sentinel)

          4、总结

          本文详细地分析了与Redis编译相关的Makefile文件,通过学习Makefile文件里的内容,我们可以更为全面地了解Redis的编译过程,因为Makefile文件中将很多编译命令用@给取消显示了,转而使用它自己特制的编译信息输出给我们看,代码如下:

          ifndef V
          QUIET_CC = @printf '    %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR) 1>&2;
          QUIET_LINK = @printf '    %b %b\n' $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2;
          QUIET_INSTALL = @printf '    %b %b\n' $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2;
          endif

          所以我们直接去编译的话很多细节会看不到,可以自己尝试修改Makefile文件,在前面这段代码之前定义V变量,这样就可以看到完整的编译信息了。修改如下:

          V = 'good'
          
          ifndef V
          QUIET_CC = @printf '    %b %b\n' $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR) 1>&2;
          QUIET_LINK = @printf '    %b %b\n' $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2;
          QUIET_INSTALL = @printf '    %b %b\n' $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1>&2;
          endif

          本人之前也写过Nginx编译相关的文章,下面总结两者的几点区别:

          • NginxShell 관련 기술을 많이 사용하는 반면, Redis는 이러한 Nginx使用了大量的Shell相关的技术,而Redis则很少使用这些
          • Nginx跨平台的相关参数是通过配置脚本进行配置的,而Redis则是直接在Makefile文件中将这件事给做了,这两者没有什么优劣之分,Nginx主要是为了可扩展性强才使用那么多配置脚本的,而Redis基本不用考虑这些,所以简单一点实现就行了
          • 由于Redis将其一些逻辑都放在了Makefile文件中了,所以看起来Nginx最终生成的Makefile文件要比Redis简单易懂很多(Nginx复杂逻辑在那些配置脚本里)
          • Nginx生成的配置文件足有1000多行,代码量比Redis的400多行要大很多,因为Nginx把全部依赖的生成方式全部列举了出来,而Redis借助了Makefile.dep、各种%.d文件来将依赖信息分散到中间文件中去,极大地减少了Makefile
          • Nginx 크로스 플랫폼을 거의 사용하지 않습니다. 관련 매개변수는 구성 스크립트를 통해 구성되는 반면 RedisMakefile 파일에서 직접 수행합니다. 단점 측면에서 Nginx는 강력한 확장성을 위해 많은 구성 스크립트를 주로 사용하는 반면, <code>Redis는 기본적으로 이러한 사항을 고려할 필요가 없어 간단하게 구현할 수 있습니다

          Redis가 일부를 배치하기 때문에 해당 논리는 Makefile 파일에 있으므로 Nginx가 최종적으로 Makefile를 생성하는 것 같습니다. 파일은 보다 훨씬 간단하고 이해하기 쉽습니다. Redis(Nginx에는 해당 구성 스크립트에 복잡한 논리가 있음) Nginx는 1,000개 이상의 구성 파일 라인을 생성했으며 코드의 양은 Nginx는 모든 종속성의 모든 생성 방법을 나열하고 RedisMakefile의 도움으로 400줄 이상의 <code>Redis를 포함합니다. dep 및 다양한 %.d 파일의 경우 종속성 정보가 중간 파일로 분산되어 Makefile 코드 양이 크게 줄어듭니다.

          🎜🎜 추천 학습: 🎜 Redis 학습 튜토리얼🎜🎜

위 내용은 Redis 클래식 기술에 대한 자세한 설명: Makefile의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 CSDN에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
Redis : 기능과 기능을 탐색합니다Redis : 기능과 기능을 탐색합니다Apr 19, 2025 am 12:04 AM

Redis는 고속, 다양성 및 풍부한 데이터 구조로 인해 두드러집니다. 1) Redis는 문자열, 목록, 컬렉션, 해시 및 주문 컬렉션과 같은 데이터 구조를 지원합니다. 2) 메모리를 통해 데이터를 저장하고 RDB 및 AOF 지속성을 지원합니다. 3) Redis 6.0에서 시작하여 멀티 스레드 I/O 작업이 도입되어 동시 동시성 시나리오에서 성능이 향상되었습니다.

Redis는 SQL 또는 NOSQL 데이터베이스입니까? 대답이 설명되었습니다Redis는 SQL 또는 NOSQL 데이터베이스입니까? 대답이 설명되었습니다Apr 18, 2025 am 12:11 AM

redisisclassifiedasanoSqldatabaseBecauseItuseSakey-valuedatamodelinsteadofThraditionalRelationalDatabasemodel.Itoffersspeedandflexibility, makingIdealforreal-timeApplicationsandcaching, butitmaynotbesuitableforscenariosrequiringstrictaintetaintetaintetaintetaintetaintetaintegry

REDIS : 응용 프로그램 성능 및 확장 성 향상REDIS : 응용 프로그램 성능 및 확장 성 향상Apr 17, 2025 am 12:16 AM

Redis는 데이터를 캐싱하여 분산 잠금 및 데이터 지속성을 구현하여 응용 프로그램 성능 및 확장 성을 향상시킵니다. 1) 캐시 데이터 : Redis를 사용하여 데이터 액세스 속도를 향상시키기 위해 자주 액세스하는 데이터를 캐시합니다. 2) 분산 잠금 : Redis를 사용하여 분산 된 잠금 장치를 구현하여 분산 환경에서 작동의 보안을 보장합니다. 3) 데이터 지속성 : 데이터 손실을 방지하기위한 RDB 및 AOF 메커니즘을 통한 데이터 보안을 보장합니다.

Redis : 데이터 모델과 구조 탐색Redis : 데이터 모델과 구조 탐색Apr 16, 2025 am 12:09 AM

Redis의 데이터 모델 및 구조에는 5 가지 주요 유형이 포함됩니다. 1. 문자열 : 텍스트 또는 이진 데이터를 저장하는 데 사용되며 원자 연산을 지원합니다. 2. 목록 : 정렬 된 요소 컬렉션, 대기열 및 스택에 적합합니다. 세트 : 세트 작동을 지원하는 비 순차 고유 요소 세트. 4. 순서 세트 (SortedSet) : 순위에 적합한 점수가있는 고유 한 요소 세트. 5. 해시 테이블 (HASH) : 객체를 저장하는 데 적합한 키 값 쌍 모음.

REDIS : 데이터베이스 접근 방식을 분류합니다REDIS : 데이터베이스 접근 방식을 분류합니다Apr 15, 2025 am 12:06 AM

Redis의 데이터베이스 방법에는 메모리 인 데이터베이스 및 키 값 저장소가 포함됩니다. 1) Redis는 메모리에 데이터를 저장하고 빠르게 읽고 쓰고 있습니다. 2) 키 값 쌍을 사용하여 데이터를 저장하고 캐시 및 NOSQL 데이터베이스에 적합한 목록, 컬렉션, 해시 테이블 및 주문 컬렉션과 같은 복잡한 데이터 구조를 지원합니다.

왜 Redis를 사용합니까? 혜택과 장점왜 Redis를 사용합니까? 혜택과 장점Apr 14, 2025 am 12:07 AM

Redis는 빠른 성능, 풍부한 데이터 구조, 고 가용성 및 확장 성, 지속성 기능 및 광범위한 생태계 지원을 제공하기 때문에 강력한 데이터베이스 솔루션입니다. 1) 매우 빠른 성능 : Redis의 데이터는 메모리에 저장되며 동시성이 높고 대기 시간이 낮은 응용 프로그램에 적합한 빠른 읽기 및 쓰기 속도를 가지고 있습니다. 2) 풍부한 데이터 구조 : 다양한 시나리오에 적합한 목록, 컬렉션 등과 같은 여러 데이터 유형을 지원합니다. 3) 고 가용성 및 확장 성 : 마스터 슬레이브 복제 및 클러스터 모드를 지원하여 고 가용성 및 수평 확장 성을 달성합니다. 4) 지속성 및 데이터 보안 : 데이터 지속성은 RDB 및 AOF를 통해 달성되어 데이터 무결성 및 신뢰성을 보장합니다. 5) 광범위한 생태계 및 지역 사회 지원 : 거대한 생태계와 활동적인 커뮤니티,

NOSQL 이해 : Redis의 주요 기능NOSQL 이해 : Redis의 주요 기능Apr 13, 2025 am 12:17 AM

Redis의 주요 기능에는 속도, 유연성 및 풍부한 데이터 구조 지원이 포함됩니다. 1) 속도 : Redis는 메모리 내 데이터베이스이며, 읽기 및 쓰기 작업은 거의 순간적이며 캐시 및 세션 관리에 적합합니다. 2) 유연성 : 복잡한 데이터 처리에 적합한 문자열, 목록, 컬렉션 등과 같은 여러 데이터 구조를 지원합니다. 3) 데이터 구조 지원 : 다양한 비즈니스 요구에 적합한 문자열, 목록, 컬렉션, 해시 테이블 등을 제공합니다.

REDIS : 기본 기능을 식별합니다REDIS : 기본 기능을 식별합니다Apr 12, 2025 am 12:01 AM

Redis의 핵심 기능은 고성능 인 메모리 데이터 저장 및 처리 시스템입니다. 1) 고속 데이터 액세스 : Redis는 메모리에 데이터를 저장하고 마이크로 초 수준 읽기 및 쓰기 속도를 제공합니다. 2) 풍부한 데이터 구조 : 문자열, 목록, 컬렉션 등을 지원하며 다양한 응용 프로그램 시나리오에 적응합니다. 3) 지속성 : RDB 및 AOF를 통해 디스크에 데이터를 지속하십시오. 4) 구독 게시 : 메시지 대기열 또는 실시간 통신 시스템에서 사용할 수 있습니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.