Análisis del código fuente de Skynet

Análisis del código fuente de Skynet

prefacio

La versión de este artículo es skynet v1.4.0. Lo inevitable para compilar skynet es hacer.

Este artículo analizará específicamente la implementación de make.

Acerca de la marca, puede consultar el blog de Ruan Yifeng .

Además, este artículo solo involucra el Makefile de nivel superior y no analiza el Makefile en el subdirectorio.

El apéndice es algunos parámetros de GCC.

texto

Cuando ejecutamos en el directorio skynet, make linuxen realidad estamos ejecutando Makefilelos comandos en él. En la primera línea del archivo hay esta declaración:

include platform.mk

plataforma.mk

La lógica es más o menos la siguiente:

  1. Determine si se pasa la plataforma correcta en linux freebsd macosx. Si no, salga con un mensaje de error:

    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'
    

    Si se pasa la plataforma incorrecta, habrá una impresión similar:

    wyw@DESKTOP-GJ20UDC:~/skynet$ make l
    make: *** No rule to make target 'l'.  Stop.
    
  2. Se establecen diferentes variables según las diferentes plataformas, y las variables establecidas aquí se utilizarán en el Makefile. ej make linux. La ejecución hasta el último comando es la siguiente:

    # 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

Volviendo a Makefile, algunos valores relacionados con la plataforma se establecen después de incluir. Y se ejecuta make all.

La lógica es más o menos la siguiente:

  1. generar jemalloc
  2. Generar partes relacionadas con skynet

jemalloc

Jemalloc es un asignador de memoria. Comparado con otros asignadores de memoria, su mayor ventaja radica en su alto rendimiento en situaciones de subprocesos múltiples y la reducción de la fragmentación de la memoria.

Lea el README.md en el proyecto skynet. Hay una oración como esta:

Para Linux, instale autoconf primero para jemalloc

La razón se revelará más adelante, primero analicemos el Makefile.

Declaración de inicio:

# 定义变量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

Hay más contenido en esta parte, primero la definición de algunas 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

Luego está la entrada all:

Primero analice la primera oración en total:

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)

  

A continuación, mira la segunda oración en total:

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

La tercera frase en total corresponde a la biblioteca tripartita de 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 $@ 

apéndice

parámetros relacionados con gcc:

opciones explicar
-gramo Generar información de depuración. El depurador GNU puede usar esta información.
-O o -O1 Optimizar el código generado.
-O2 optimización avanzada.
-Muro Genera todos los mensajes de advertencia.
-I ( i mayúscula ) Especifique la ruta del archivo de encabezado (ruta relativa o ruta fiel, se recomienda la ruta relativa)
-Wl, opción Esta opción pasa la opción al enlazador; si hay una coma en la opción, la opción se divide en varias opciones y luego se pasa al enlazador.
-MI Solo ejecute el precompilador C.
-lpthread Vincule la biblioteca de subprocesos, que puede ser una biblioteca compilada por usted mismo
-lm Al compilar, vincular la biblioteca de matemáticas
-ldl Vincular una biblioteca de funciones dinámicas que carga explícitamente una biblioteca dinámica
-lrt Enlace biblioteca en tiempo real (tiempo real)
-l (L minúscula) Especifique el nombre de la biblioteca a vincular (enlace libc.a: -lc enlace biblioteca dinámica: libc.so: -lc Nota: agregue el nombre de la biblioteca "lib" y ".so" o ".a" directamente después de -l )
-o Especifique el nombre de destino. De forma predeterminada, el archivo compilado por gcc es a.out

Supongo que te gusta

Origin blog.csdn.net/sayWhat_sayHello/article/details/119046183
Recomendado
Clasificación