Skynet source code analysis make

Skynet source code analysis make

foreword

The version of this article is skynet v1.4.0. The inevitable thing to compile skynet is make.

This article will specifically look at the implementation of make.

About make, you can refer to Ruan Yifeng's weblog .

In addition, this article only involves the top-level Makefile, and does not analyze the Makefile in the subdirectory.

The appendix is ​​some parameters of GCC.

text

When we execute in the skynet directory, make linuxwe are actually executing Makefilethe commands in it. In the first line of the file there is this statement:

include platform.mk

platform.mk

The logic is roughly as follows:

  1. Determine whether the correct platform is passed in linux freebsd macosx. If not, exit with an error message:

    wyw@DESKTOP-GJ20UDC:~/skynet$ make
    make none
    make[1]: Entering directory '/home/wyw/skynet'
    Please do 'make PLATFORM' where PLATFORM is one of these:
       linux freebsd macosx
    make[1]: Leaving directory '/home/wyw/skynet'
    

    If the wrong platform is passed in, there will be a similar print:

    wyw@DESKTOP-GJ20UDC:~/skynet$ make l
    make: *** No rule to make target 'l'.  Stop.
    
  2. Different variables are set according to different platforms, and the variables set here will be used in the Makefile. eg make linux. Execution to the last command is as follows:

    # make all PLAT=linux SKYNET_LIBS="-lpthread -lm -ldl -lrt" SHARED="-fPIC --shared" EXPORT="-Wl,-E" MALLOC_STATICLIB="" SKYNET_DEFINES=""
    $(MAKE) all PLAT=$@ SKYNET_LIBS="$(SKYNET_LIBS)" SHARED="$(SHARED)" EXPORT="$(EXPORT)" MALLOC_STATICLIB="$(MALLOC_STATICLIB)" SKYNET_DEFINES="$(SKYNET_DEFINES)"
    

Makefile

Returning to Makefile, some platform-related values ​​are set after include. And it is executed make all.

The logic is roughly as follows:

  1. Generate jemalloc
  2. Generate skynet related parts

jemalloc

Jemalloc is a memory allocator. Compared with other memory allocators, its biggest advantage lies in its high performance in multi-threaded situations and the reduction of memory fragmentation.

Read the README.md in the skynet project. There is a sentence like this:

For Linux, install autoconf first for jemalloc

The reason will be revealed later, let's analyze the Makefile first.

Start statement:

# 定义变量MALLOC_STATICLIB
JEMALLOC_STATICLIB := 3rd/jemalloc/lib/libjemalloc_pic.a
MALLOC_STATICLIB := $(JEMALLOC_STATICLIB)

all : jemalloc
# 声明伪目标 jemalloc update3rd
.PHONY : jemalloc update3rd
# 伪目标前提是 $(MALLOC_STATICLIB)
jemalloc : $(MALLOC_STATICLIB)
# 前提是先生成 3rd/jemalloc/Makefile,后执行命令cd 3rd/jemalloc && $(MAKE) CC=$(CC)
# 这一步的make 中需要用到 AUTOCONF := /usr/bin/autoconf
$(JEMALLOC_STATICLIB) : 3rd/jemalloc/Makefile
	cd 3rd/jemalloc && $(MAKE) CC=$(CC) 
# 生成3rd/jemalloc/Makefile  order-only先决条件 从git拉取模块

3rd/jemalloc/Makefile : | 3rd/jemalloc/autogen.sh
	# 执行autogen.sh
	cd 3rd/jemalloc && ./autogen.sh --with-jemalloc-prefix=je_ --enable-prof

3rd/jemalloc/autogen.sh :
	git submodule update --init

skynet

There is more content in this part, first the definition of some variables.

CSERVICE = snlua logger gate harbor
LUA_CLIB = skynet \
  client \
  bson md5 sproto lpeg $(TLS_MODULE)

LUA_CLIB_SKYNET = \
  lua-skynet.c lua-seri.c \
  lua-socket.c \
  lua-mongo.c \
  lua-netpack.c \
  lua-memory.c \
  lua-multicast.c \
  lua-cluster.c \
  lua-crypt.c lsha1.c \
  lua-sharedata.c \
  lua-stm.c \
  lua-debugchannel.c \
  lua-datasheet.c \
  lua-sharetable.c \
  \

SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
  skynet_server.c skynet_start.c skynet_timer.c skynet_error.c \
  skynet_harbor.c skynet_env.c skynet_monitor.c skynet_socket.c socket_server.c \
  malloc_hook.c skynet_daemon.c skynet_log.c

Then there is the entry all:

First analyze the first sentence in all:

all : \
  $(SKYNET_BUILD_PATH)/skynet \
  
LUA_LIB ?= $(LUA_STATICLIB) 

# 'cc -g -O2 -Wall -I3rd/lua  -o skynet skynet-src/skynet_main.c skynet-src/skynet_handle.c skynet-src/skynet_module.c skynet-src/skynet_mq.c skynet-src/skynet_server.c skynet-src/skynet_start.c skynet-src/skynet_timer.c skynet-src/skynet_error.c skynet-src/skynet_harbor.c skynet-src/skynet_env.c skynet-src/skynet_monitor.c skynet-src/skynet_socket.c skynet-src/socket_server.c skynet-src/malloc_hook.c skynet-src/skynet_daemon.c skynet-src/skynet_log.c 3rd/lua/liblua.a 3rd/jemalloc/lib/libjemalloc_pic.a -Iskynet-src -I3rd/jemalloc/include/jemalloc  -Wl,-E -lpthread -lm -ldl -lrt '
# 先决条件中skynet-src下的文件是已经存在的,$(LUA_LIB) 在下文中定义,$(MALLOC_STATICLIB)在前文中已经定义
$(SKYNET_BUILD_PATH)/skynet : $(foreach v, $(SKYNET_SRC), skynet-src/$(v)) $(LUA_LIB) $(MALLOC_STATICLIB)
	$(CC) $(CFLAGS) -o $@ $^ -Iskynet-src -I$(JEMALLOC_INC) $(LDFLAGS) $(EXPORT) $(SKYNET_LIBS) $(SKYNET_DEFINES)
	
# 执行3rd/lua下的Makefile
$(LUA_STATICLIB) :
	cd 3rd/lua && $(MAKE) CC='$(CC) -std=gnu99' $(PLAT)

  

Next, look at the second sentence in all:

all:   $(foreach v, $(CSERVICE), $(CSERVICE_PATH)/$(v).so) \

$(LUA_CLIB_PATH) :
	mkdir $(LUA_CLIB_PATH)

$(CSERVICE_PATH) :
	mkdir $(CSERVICE_PATH)

# 定义了模板
define CSERVICE_TEMP
  $$(CSERVICE_PATH)/$(1).so : service-src/service_$(1).c | $$(CSERVICE_PATH)
	$$(CC) $$(CFLAGS) $$(SHARED) $$< -o $$@ -Iskynet-src
endef	

# https://www.gnu.org/software/make/manual/make.html#Eval-Function
# such as: cc -g -O2 -Wall -I3rd/lua  -fPIC --shared service-src/service_snlua.c -o cservice/snlua.so -Iskynet-src
$(foreach v, $(CSERVICE), $(eval $(call CSERVICE_TEMP,$(v))))

The third sentence in all corresponds to the tripartite library of lua:

all : $(foreach v, $(LUA_CLIB), $(LUA_CLIB_PATH)/$(v).so) $(LUA_CLIB_PATH)/skynet.so : $(addprefix lualib-src/,$(LUA_CLIB_SKYNET)) | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src$(LUA_CLIB_PATH)/bson.so : lualib-src/lua-bson.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) -Iskynet-src $^ -o $@$(LUA_CLIB_PATH)/md5.so : 3rd/lua-md5/md5.c 3rd/lua-md5/md5lib.c 3rd/lua-md5/compat-5.2.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) -I3rd/lua-md5 $^ -o $@ $(LUA_CLIB_PATH)/client.so : lualib-src/lua-clientsocket.c lualib-src/lua-crypt.c lualib-src/lsha1.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) $^ -o $@ -lpthread$(LUA_CLIB_PATH)/sproto.so : lualib-src/sproto/sproto.c lualib-src/sproto/lsproto.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) -Ilualib-src/sproto $^ -o $@ $(LUA_CLIB_PATH)/ltls.so : lualib-src/ltls.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) -Iskynet-src -L$(TLS_LIB) -I$(TLS_INC) $^ -o $@ -lssl$(LUA_CLIB_PATH)/lpeg.so : 3rd/lpeg/lpcap.c 3rd/lpeg/lpcode.c 3rd/lpeg/lpprint.c 3rd/lpeg/lptree.c 3rd/lpeg/lpvm.c | $(LUA_CLIB_PATH)	$(CC) $(CFLAGS) $(SHARED) -I3rd/lpeg $^ -o $@ 

appendix

gcc related parameters:

options explain
-g Generate debug information. The GNU debugger can use this information.
-O or -O1 Optimize generated code.
-O2 advanced optimization.
-Wall Generate all warning messages.
-I ( uppercase i ) Specify the header file path (relative path or felt path, relative path is recommended)
-Wl,option This option passes option to the linker; if there is a comma in the option, the option is split into multiple options, and then passed to the linker.
-E Only run the C precompiler.
-lpthread Link the thread library, which can be a library compiled by yourself
-lm When compiling, link the math library
-ldl Linking a dynamic function library that explicitly loads a dynamic library
-lrt Link real time library (real time)
-l (lowercase L) Specify the name of the library to be linked (link libc.a: -lc link dynamic library: libc.so: -lc Note: add the library name "lib" and ".so" or ".a" directly after -l)
-o Specify the target name. By default, the file compiled by gcc is a.out

Guess you like

Origin blog.csdn.net/sayWhat_sayHello/article/details/119046183