溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Redis中如何深入了解Makefile文件

發(fā)布時(shí)間:2022-01-27 10:37:44 來(lái)源:億速云 閱讀:178 作者:柒染 欄目:關(guān)系型數(shù)據(jù)庫(kù)

這篇文章的內(nèi)容主要圍繞Redis中如何深入了解Makefile文件進(jìn)行講述,文章內(nèi)容清晰易懂,條理清晰,非常適合新手學(xué)習(xí),值得大家去閱讀。感興趣的朋友可以跟隨小編一起閱讀吧。希望大家通過(guò)這篇文章有所收獲!

Makefile文件詳解

源代碼根目錄的Makefile文件內(nèi)容如下:

default: all

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

install:
	cd src && $(MAKE) $@

.PHONY: install

從代碼中可以看出以下幾點(diǎn)信息:

  • 該文件的第一個(gè)目標(biāo)是default,該目標(biāo)沒有實(shí)際作用,依賴于all目標(biāo)

  • 代碼中并沒有所謂的all目標(biāo),所以當(dāng)我們直接使用make時(shí),首先會(huì)調(diào)用default目標(biāo),然后調(diào)用all目標(biāo),由于all目標(biāo)不存在,所以會(huì)調(diào)用.DEFAULT目標(biāo)來(lái)替代,在Makefile的執(zhí)行語(yǔ)句中,$@代表的就是目標(biāo)的意思,$(MAKE)代表的就是make,所以展開之后的代碼如下,讀者可以自行編譯一下,看看第一條輸出語(yǔ)句是否與我們分析的相同

cd src && make all
  • install目標(biāo)和前面的類似,最終也是進(jìn)去src/目錄,然后調(diào)用該目錄下的Makefile文件,區(qū)別只在于此時(shí)調(diào)用的目標(biāo)變成了install而已,展開后的代碼如下:

cd src && make install
  • 當(dāng)傳入?yún)?shù)是其他是,調(diào)用的都會(huì)轉(zhuǎn)到.DEFAULT去,然后去調(diào)用子目錄下的Makefile的對(duì)應(yīng)的目標(biāo),以clean為例,代碼如下:

cd src && make clean

src/Makefile文件詳解

該文件是真正起編譯作用的文件,內(nèi)容比較多,比較雜,而且為了兼容多種編譯器里面有不少分支選擇語(yǔ)法,我們這里只以Linux下的gcc編譯器為例去講解,其余的沒區(qū)別,就是通過(guò)判斷語(yǔ)句去改變某些編譯參數(shù)而已

1、Makefile.dep目標(biāo)

Makefile在執(zhí)行對(duì)應(yīng)的目標(biāo)之前,會(huì)先把非目標(biāo)的指令給執(zhí)行了,比如變量賦值、Shell語(yǔ)句等等,所以我們會(huì)發(fā)現(xiàn),Makefile文件并不會(huì)完全按照順序去執(zhí)行的
相關(guān)代碼如下:

NODEPS:=clean distclean

# FINAL_CFLAGS里的各個(gè)變量原型
STD=-pedantic -DREDIS_STATIC=''
WARN=-Wall -W -Wno-missing-field-initializers
OPTIMIZATION?=-O2
OPT=$(OPTIMIZATION)
DEBUG=-g -ggdb
#CFLAGS 根據(jù)條件選擇的,不重要的參數(shù),忽略
#REDIS_CFLAGS 根據(jù)條件選擇的,不重要的參數(shù),忽略

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 || true

ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
-include Makefile.dep
endif

首先先補(bǔ)充以下幾點(diǎn)Makefile的基礎(chǔ)

  • Makefilefindstring函數(shù)的使用格式為$(findstring FIND, IN),表示在IN中查找FIND,如果查找到了就返回FIND,找不到就返回空

  • Makefilewords函數(shù)表示統(tǒng)計(jì)單詞數(shù)目,例如$(words, foo bar)的返回值為"2"

  • MakefileMAKECMDGOALS變量表示傳入的參數(shù)(全部)

  • MakefileCC默認(rèn)值是cc

  • Makefile-MM是輸出一個(gè)用于make的規(guī)則,該規(guī)則描述了源文件的依賴關(guān)系,但是不包含系統(tǒng)頭文件

則可以總結(jié)出以下幾點(diǎn)信息:

  • 里面的all目標(biāo)正是我們前一節(jié)說(shuō)到的那個(gè)默認(rèn)的編譯目標(biāo),但是我們可以自己試著去編譯一下,會(huì)發(fā)現(xiàn)先生成的是Makefile.dep文件,因?yàn)樗葓?zhí)行了最下面那個(gè)判斷語(yǔ)句,里面調(diào)用了Makefile.dep目標(biāo)

  • 由于此時(shí)MAKECMDGOALS的值為all,不在NODEPS范圍里,所以上面那個(gè)ifeq語(yǔ)句成立,會(huì)調(diào)用Makefile.dep目標(biāo)

  • REDIS_CC的值由三個(gè)變量組成,QUIET_CC是打印調(diào)試信息的,讀者可以自己去源碼看相關(guān)內(nèi)容,這部分不重要,我們忽略,CC的值代表的是編譯器,FINAL_CFLAGS里面的值則是編譯的一些參數(shù),這些值在上面的代碼中都已經(jīng)摘錄出來(lái)了

  • 綜上所述Makefile.dep目標(biāo)的作用就是生成當(dāng)前目錄下所有以.c結(jié)尾的文件的依賴關(guān)系,并寫入Makefile.dep文件中,編譯之后生成的文件內(nèi)容如下所示,看起來(lái)挺亂,但是里面的內(nèi)容其實(shí)將每個(gè)源文件最終生成的目標(biāo)文件給列出來(lái),并且將它需要的依賴列出來(lái)而已

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

2、通用的生成目標(biāo)文件的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 $<

以下是對(duì)這部分代碼的解析:

  • 這部分是通用的根據(jù)源文件生成目標(biāo)文件的targetMakefile%表示通配符,所以只要符合格式要求的都可以借助這段代碼來(lái)生成對(duì)應(yīng)的目標(biāo)文件

  • .make-prerequisites沒啥用忽略,而REDIS_CC的值在上一小節(jié)有說(shuō)明了,是用于編譯文件的指令

  • gcc-MMD參數(shù)與前面說(shuō)的那個(gè)-MM是基本一致的,只不過(guò)這個(gè)會(huì)將輸出內(nèi)容導(dǎo)入到對(duì)應(yīng)的%.d文件中

  • Makefile$@表示目標(biāo),$<表示第一個(gè)依賴,$^表示全部依賴

  • 綜上,這個(gè)target的作用是依賴于一個(gè)源文件,然后根據(jù)這個(gè)源文件生成對(duì)應(yīng)的目標(biāo)文件,并且將依賴關(guān)系導(dǎo)入到對(duì)應(yīng)的%.d文件中

下面是一個(gè)簡(jiǎn)單的例子:

# 假設(shè)生成的目標(biāo)文件為acl.o,則代入可得
acl.o: acl.c .make-prerequisites
	$(REDIS_CC) -MMD -o acl.o -c acl.c

# 執(zhí)行完成后在該目錄下會(huì)生成一個(gè)acl.o文件和acl.d文件

3、all目標(biāo)所依賴的各個(gè)子目標(biāo)的名稱設(shè)置

PROG_SUFFIX的值默認(rèn)為空,可以忽略。這里設(shè)置的六個(gè)目標(biāo)名都是會(huì)被all這個(gè)目標(biāo)引用的,從名字可以看出這六個(gè)目標(biāo)是對(duì)應(yīng)著Redis不同的功能,依次是服務(wù)、哨兵、客戶端、基礎(chǔ)檢測(cè)、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)

4、all目標(biāo)所依賴的各個(gè)子目標(biāo)的內(nèi)容

  • REDIS_LD也是一個(gè)編譯指令,和前面那個(gè)REDIS_CC有點(diǎn)像,只不過(guò)這個(gè)指定了另外的一些編譯參數(shù),比如設(shè)置了某些依賴的動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)的路徑,讀者有興趣的話可以去看一下代碼,看看REDIS_LD的詳細(xì)內(nèi)容

  • FINAL_LIBS是一系列動(dòng)態(tài)庫(kù)鏈接參數(shù),讀者有興趣可以自行去Makefile里面查看該變量的內(nèi)容,限于篇幅原因這里就不展開講了

  • QUIET_INSTALL忽略(這個(gè)是自定義打印編譯信息的),可以看出REDIS_INSTALL的值其實(shí)就是install,Linux下的install命令是用于安裝或升級(jí)軟件或備份數(shù)據(jù)的,這個(gè)命令與cp類似,但是install允許你控制目標(biāo)文件的屬性,這里不作深入分析了,有興趣的讀者可以自行查閱相關(guān)的介紹install命令的文章?;居梅椋?code>install src des,表示將src文件復(fù)制到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)

4.1、REDIS_SERVER_NAME目標(biāo)

該目標(biāo)依賴于REDIS_SERVER_OBJ,而REDIS_SERVER_OBJ的內(nèi)容都是一些目標(biāo)文件(上面代碼有給出),這些目標(biāo)文件最終都會(huì)通過(guò)3.2小節(jié)介紹的那個(gè)target來(lái)生成??梢钥吹?code>REDIS_SERVER_NAME這個(gè)target需要使用REDIS_SERVER_OBJ、…/deps/hiredis/libhiredis.a、…/deps/lua/src/liblua.a以及FINAL_LIBS這些來(lái)編譯鏈接生成最終的目標(biāo)文件,即redis-server

4.2、REDIS_SENTINEL_NAME目標(biāo)

可以看到REDIS_SENTINEL_NAME目標(biāo)很簡(jiǎn)單,只是簡(jiǎn)單地使用install命令復(fù)制了REDIS_SERVER_NAME目標(biāo)生成的那個(gè)文件,即redis-server,從這里可以知道哨兵服務(wù)redis-sentinelRedis服務(wù)使用的是同一套代碼

4.3、REDIS_CHECK_RDB_NAME目標(biāo)

和前面的如出一轍,也是簡(jiǎn)單復(fù)制了redis-server文件到redis-check-rdb文件去

4.4、REDIS_CHECK_AOF_NAME目標(biāo)

和前面的如出一轍,也是簡(jiǎn)單復(fù)制了redis-server文件到redis-check-aof文件去

4.5、REDIS_CLI_NAME目標(biāo)

這個(gè)就不是簡(jiǎn)單復(fù)制了,而是使用和REDIS_SERVER_NAME目標(biāo)相同的方法進(jìn)行直接編譯的,唯一的區(qū)別是REDIS_SERVER_NAME鏈接了…/deps/lua/src/liblua.a,而REDIS_CLI_NAME鏈接的是…/deps/linenoise/linenoise.o

4.6、REDIS_BENCHMARK_NAME目標(biāo)

這個(gè)也是使用和REDIS_SERVER_NAME目標(biāo)相同的方法進(jìn)行直接編譯的,唯一的區(qū)別是REDIS_SERVER_NAME鏈接了…/deps/lua/src/liblua.a,而REDIS_BENCHMARK_NAME鏈接的是…/deps/hdr_histogram/hdr_histogram.o

5、all目標(biāo)

經(jīng)過(guò)前面的介紹,all目標(biāo)的作用也就一目了然了,最終會(huì)生成六個(gè)可執(zhí)行文件,以及輸出相應(yīng)的調(diào)試信息
代碼如下:

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 ""

6、安裝和卸載Redis的目標(biāo)

6.1、安裝Redis的目標(biāo)

這里邏輯很簡(jiǎn)單,先創(chuàng)建一個(gè)用于存放Redis可執(zhí)行文件的文件夾(默認(rèn)是/usr/local/bin),然后將REDIS_SERVER_NAMEREDIS_BENCHMARK_NAME、REDIS_CLI_NAME對(duì)應(yīng)的可執(zhí)行文件復(fù)制到/usr/local/bin中去,這里可以看到前面那幾個(gè)照葫蘆畫瓢的文件并沒有復(fù)制過(guò)去,而是直接通過(guò)創(chuàng)建軟連接的方式去生成對(duì)應(yīng)的可執(zhí)行文件(內(nèi)容相同,復(fù)制過(guò)去浪費(fèi)空間)
代碼如下:

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)

6.2、卸載Redis的目標(biāo)

這里就是刪除前面復(fù)制的那些文件了,比較簡(jiǎn)單,就不細(xì)講了
代碼如下:

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)}

7、clean和distclean目標(biāo)

所有Makefileclean或者distclean目標(biāo)的作用都是大致相同的,就是刪除編譯過(guò)程中產(chǎn)生的那些中間文件,以及最終編譯生成的動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)、可執(zhí)行文件等等內(nèi)容,代碼比較簡(jiǎn)單,就不作過(guò)多的分析了
代碼如下:

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

8、test目標(biāo)

執(zhí)行完Redis編譯之后,會(huì)有一段提示文字我們可以運(yùn)行make test測(cè)試功能是否正常,從代碼中我們可以看出其實(shí)不止一個(gè)test目標(biāo),還有另一個(gè)test-sentinel目標(biāo),這個(gè)是測(cè)試哨兵服務(wù)的。這兩個(gè)目標(biāo)分別運(yùn)行了根目錄的runtestruntest-sentinel文件,這兩個(gè)是腳本文件,里面會(huì)繼續(xù)調(diào)用其他腳本來(lái)完成整個(gè)功能的測(cè)試,并輸出測(cè)試信息到控制臺(tái)。具體怎么測(cè)試的就不分析了,大家有興趣的可以去看一下。
代碼如下:

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)

總結(jié)

本文詳細(xì)地分析了與Redis編譯相關(guān)的Makefile文件,通過(guò)學(xué)習(xí)Makefile文件里的內(nèi)容,我們可以更為全面地了解Redis的編譯過(guò)程,因?yàn)?code>Makefile文件中將很多編譯命令用@給取消顯示了,轉(zhuǎn)而使用它自己特制的編譯信息輸出給我們看,代碼如下:

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

所以我們直接去編譯的話很多細(xì)節(jié)會(huì)看不到,可以自己嘗試修改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

本人之前也寫過(guò)Nginx編譯相關(guān)的文章,下面總結(jié)兩者的幾點(diǎn)區(qū)別:

  • Nginx使用了大量的Shell相關(guān)的技術(shù),而Redis則很少使用這些

  • Nginx跨平臺(tái)的相關(guān)參數(shù)是通過(guò)配置腳本進(jìn)行配置的,而Redis則是直接在Makefile文件中將這件事給做了,這兩者沒有什么優(yōu)劣之分,Nginx主要是為了可擴(kuò)展性強(qiáng)才使用那么多配置腳本的,而Redis基本不用考慮這些,所以簡(jiǎn)單一點(diǎn)實(shí)現(xiàn)就行了

  • 由于Redis將其一些邏輯都放在了Makefile文件中了,所以看起來(lái)Nginx最終生成的Makefile文件要比Redis簡(jiǎn)單易懂很多(Nginx復(fù)雜邏輯在那些配置腳本里)

  • Nginx生成的配置文件足有1000多行,代碼量比Redis的400多行要大很多,因?yàn)?code>Nginx把全部依賴的生成方式全部列舉了出來(lái),而Redis借助了Makefile.dep、各種%.d文件來(lái)將依賴信息分散到中間文件中去,極大地減少了Makefile的代碼量

感謝你的閱讀,相信你對(duì)“Redis中如何深入了解Makefile文件”這一問題有一定的了解,快去動(dòng)手實(shí)踐吧,如果想了解更多相關(guān)知識(shí)點(diǎn),可以關(guān)注億速云網(wǎng)站!小編會(huì)繼續(xù)為大家?guī)?lái)更好的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI