共計(jì) 10641 個(gè)字符,預(yù)計(jì)需要花費(fèi) 27 分鐘才能閱讀完成。
這篇文章的內(nèi)容主要圍繞 Redis 中如何深入了解 Makefile 文件進(jìn)行講述,文章內(nèi)容清晰易懂,條理清晰,非常適合新手學(xué)習(xí),值得大家去閱讀。感興趣的朋友可以跟隨丸趣 TV 小編一起閱讀吧。希望大家通過這篇文章有所收獲!
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ū)別,就是通過判斷語(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ǔ)
Makefile 的 findstring 函數(shù)的使用格式為 $(findstring FIND, IN),表示在 IN 中查找 FIND,如果查找到了就返回 FIND,找不到就返回空
Makefile 的 words 函數(shù)表示統(tǒng)計(jì)單詞數(shù)目,例如 $(words, foo bar) 的返回值為 2
Makefile 的 MAKECMDGOALS 變量表示傳入的參數(shù)(全部)
Makefile 的 CC 默認(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 的值代表的是編譯器,F(xiàn)INAL_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)文件的 target,Makefile 中 % 表示通配符,所以只要符合格式要求的都可以借助這段代碼來(lái)生成對(duì)應(yīng)的目標(biāo)文件
.make-prerequisites 沒啥用忽略,而 REDIS_CC 的值在上一小節(jié)有說(shuō)明了,是用于編譯文件的指令
gcc 的 -MMD 參數(shù)與前面說(shuō)的那個(gè) -MM 是基本一致的,只不過這個(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)像,只不過這個(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 命令的文章。基本用法為: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ì)通過 3.2 小節(jié)介紹的那個(gè) target 來(lái)生成。可以看到 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-sentinel 與 Redis 服務(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)過前面的介紹,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_NAME、REDIS_BENCHMARK_NAME、REDIS_CLI_NAME 對(duì)應(yīng)的可執(zhí)行文件復(fù)制到 /usr/local/bin 中去,這里可以看到前面那幾個(gè)照葫蘆畫瓢的文件并沒有復(fù)制過去,而是直接通過創(chuàng)建軟連接的方式去生成對(duì)應(yīng)的可執(zhí)行文件(內(nèi)容相同,復(fù)制過去浪費(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)
所有 Makefile 的 clean 或者 distclean 目標(biāo)的作用都是大致相同的,就是刪除編譯過程中產(chǎn)生的那些中間文件,以及最終編譯生成的動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)、可執(zhí)行文件等等內(nèi)容,代碼比較簡(jiǎn)單,就不作過多的分析了
代碼如下:
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)行了根目錄的 runtest 和 runtest-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 文件,通過學(xué)習(xí) Makefile 文件里的內(nèi)容,我們可以更為全面地了解 Redis 的編譯過程,因?yàn)?Makefile 文件中將很多編譯命令用 @給取消顯示了,轉(zhuǎn)而使用它自己特制的編譯信息輸出給我們看,代碼如下:
ifndef V
QUIET_CC = @printf %b %b\n $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR) 1
QUIET_LINK = @printf %b %b\n $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1
QUIET_INSTALL = @printf %b %b\n $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1
endif
所以我們直接去編譯的話很多細(xì)節(jié)會(huì)看不到,可以自己嘗試修改 Makefile 文件,在前面這段代碼之前定義 V 變量,這樣就可以看到完整的編譯信息了。修改如下:
V = good
ifndef V
QUIET_CC = @printf %b %b\n $(CCCOLOR)CC$(ENDCOLOR) $(SRCCOLOR)$@$(ENDCOLOR) 1
QUIET_LINK = @printf %b %b\n $(LINKCOLOR)LINK$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1
QUIET_INSTALL = @printf %b %b\n $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 1
endif
本人之前也寫過 Nginx 編譯相關(guān)的文章,下面總結(jié)兩者的幾點(diǎn)區(qū)別:
Nginx 使用了大量的 Shell 相關(guān)的技術(shù),而 Redis 則很少使用這些
Nginx 跨平臺(tái)的相關(guān)參數(shù)是通過配置腳本進(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)?Nginx 把全部依賴的生成方式全部列舉了出來(lái),而 Redis 借助了 Makefile.dep、各種 %.d 文件來(lái)將依賴信息分散到中間文件中去,極大地減少了 Makefile 的代碼量
感謝你的閱讀,相信你對(duì)“Redis 中如何深入了解 Makefile 文件”這一問題有一定的了解,快去動(dòng)手實(shí)踐吧,如果想了解更多相關(guān)知識(shí)點(diǎn),可以關(guān)注丸趣 TV 網(wǎng)站!丸趣 TV 小編會(huì)繼續(xù)為大家?guī)?lái)更好的文章!