redis 源码 编译

2020-08-07

最近,想一个问题,redis 到底有几个线程,百思不得其解,为寻究竟,看源码,静态看源码后,有了大概结论,想证实一下,编译源码,debug,修改,测试

准备

工具

mac

redis 5.0

Clion

编译

记录下源码编译步骤

  1. 先下载 源码,我这边下载的是5.0 git clone https://github.com/redis/redis.git,切到 5.0 分支

  2. 安装 cmake,brew install cmake, 这个步骤,我执行了蛮久,中间出现的warning,不用管,最后安装好就行

  3. 添加 CMakeLists.txt

    1. deps/hiredis根目录下面添加CMakeLists.txt文件,内容如下:

      1
      2
      3
      4
      5
      6
      7
      8
      add_library(hiredis STATIC
      hiredis.c
      net.c
      dict.c
      sds.c
      async.c
      read.c
      )
    2. deps/linenoise根目录下面添加CMakeLists.txt文件,内容如下:

      1
      add_library(linenoise linenoise.c)
    3. deps/lua根目录下面添加CMakeLists.txt文件,内容如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      set(LUA_SRC
      src/lapi.c src/lcode.c src/ldebug.c src/ldo.c src/ldump.c src/lfunc.c
      src/lgc.c src/llex.c src/lmem.c
      src/lobject.c src/lopcodes.c src/lparser.c src/lstate.c src/lstring.c
      src/ltable.c src/ltm.c
      src/lundump.c src/lvm.c src/lzio.c src/strbuf.c src/fpconv.c
      src/lauxlib.c src/lbaselib.c src/ldblib.c src/liolib.c src/lmathlib.c
      src/loslib.c src/ltablib.c
      src/lstrlib.c src/loadlib.c src/linit.c src/lua_cjson.c
      src/lua_struct.c
      src/lua_cmsgpack.c
      src/lua_bit.c
      )

      add_library(lua STATIC ${LUA_SRC})
    4. deps根目录下面添加CMakeLists.txt文件,内容如下:

      1
      2
      3
      add_subdirectory(hiredis)
      add_subdirectory(linenoise)
      add_subdirectory(lua)
    5. src/modules根目录下面添加CMakeLists.txt文件,内容如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      cmake_minimum_required(VERSION 3.9)
      set(CMAKE_BUILD_TYPE "Debug")
      add_library(helloworld SHARED helloworld.c)
      set_target_properties(helloworld PROPERTIES PREFIX "" SUFFIX ".so")


      add_library(hellotype SHARED hellotype.c)
      set_target_properties(hellotype PROPERTIES PREFIX "" SUFFIX ".so")


      add_library(helloblock SHARED helloblock.c)
      set_target_properties(helloblock PROPERTIES PREFIX "" SUFFIX ".so")


      add_library(testmodule SHARED testmodule.c)
      set_target_properties(testmodule PROPERTIES PREFIX "" SUFFIX ".so")
    6. redis

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
      project(redis VERSION 4.0)
      set(CMAKE_BUILD_TYPE "Debug")

      get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)

      add_subdirectory(deps)
      add_subdirectory(src/modules)

      set(SRC_SERVER_TMP
      src/adlist.c
      src/ae.c
      src/anet.c
      src/ae_kqueue.c
      src/dict.c
      src/sds.c
      src/zmalloc.c
      src/lzf_c.c
      src/lzf_d.c
      src/pqsort.c
      src/zipmap.c
      src/sha1.c
      src/ziplist.c
      src/release.c
      src/networking.c
      src/util.c
      src/object.c
      src/db.c
      src/replication.c
      src/rdb.c
      src/t_string.c
      src/t_list.c
      src/t_set.c
      src/t_zset.c
      src/evict.c
      src/defrag.c
      src/module.c
      src/quicklist.c
      src/expire.c
      src/childinfo.c
      src/redis-check-aof.c
      src/redis-check-rdb.c
      src/lazyfree.c
      src/geohash.c
      src/rax.c
      src/geohash_helper.c
      src/siphash.c
      src/geo.c
      src/t_hash.c
      src/config.c
      src/aof.c
      src/pubsub.c
      src/multi.c
      src/debug.c
      src/sort.c
      src/intset.c
      src/syncio.c
      src/cluster.c
      src/crc16.c
      src/endianconv.c
      src/slowlog.c
      src/scripting.c
      src/bio.c
      src/rio.c
      src/rand.c
      src/memtest.c
      src/crc64.c
      src/bitops.c
      src/sentinel.c
      src/notify.c
      src/setproctitle.c
      src/blocked.c
      src/hyperloglog.c
      src/latency.c
      src/sparkline.c
      src/t_stream.c
      src/lolwut.c
      src/lolwut5.c
      src/listpack.c
      src/localtime.c
      )
      set(SRC_SERVER src/server.c ${SRC_SERVER_TMP})

      set(SRC_CLI
      src/anet.c
      src/sds.c
      src/adlist.c
      src/redis-cli.c
      src/zmalloc.c
      src/release.c
      src/anet.c
      src/ae.c
      src/crc64.c
      )


      set(EXECUTABLE_OUTPUT_PATH src)
      link_directories(deps/linenoise/ deps/lua/src deps/hiredis)

      add_executable(redis-server ${SRC_SERVER})
      target_include_directories(redis-server
      PRIVATE ${REDIS_ROOT}/deps/linenoise
      PRIVATE ${REDIS_ROOT}/deps/hiredis
      PRIVATE ${REDIS_ROOT}/deps/lua/src)
      target_link_libraries(redis-server
      PRIVATE pthread
      PRIVATE m
      PRIVATE lua
      PRIVATE linenoise
      PRIVATE hiredis)


      add_executable(redis-cli ${SRC_CLI})
      target_include_directories(redis-cli
      PRIVATE ${REDIS_ROOT}/deps/linenoise
      PRIVATE ${REDIS_ROOT}/deps/hiredis
      PRIVATE ${REDIS_ROOT}/deps/lua/src)

      target_link_libraries(redis-cli
      PRIVATE pthread
      PRIVATE m
      PRIVATE linenoise
      PRIVATE hiredis
      )

解决报错

顺利的话可以看到这个界面

image-20200807181004333

此时有可能会报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:41:24: error: unknown type name 'aeEventLoop'
static int aeApiCreate(aeEventLoop *eventLoop) {
^
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:42:25: warning: implicit declaration of function 'zmalloc' is invalid in C99 [-Wimplicit-function-declaration]
aeApiState *state = zmalloc(sizeof(aeApiState));
^
[ 44%] Building C object CMakeFiles/redis-server.dir/src/dict.c.o
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:42:17: warning: incompatible integer to pointer conversion initializing 'aeApiState *' (aka 'struct aeApiState *') with an expression of type 'int' [-Wint-conversion]
aeApiState *state = zmalloc(sizeof(aeApiState));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:47:9: warning: implicit declaration of function 'zfree' is invalid in C99 [-Wimplicit-function-declaration]
zfree(state);
^
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:52:9: warning: implicit declaration of function 'zfree' is invalid in C99 [-Wimplicit-function-declaration]
zfree(state->events);
^
/Users/didi/Desktop/temp/redis/src/ae_kqueue.c:60:24: error: unknown type name 'aeEventLoop'

这个时候只需要点击进入ae_kqueue.c文件中,添加下面两个头文件:

1
2
#include "ae.h"
#include "zmalloc.h"

此时重新点击运行(调试)按钮,继续报错:

1
2
3
4
5
6
7
8
/Users/didi/Desktop/temp/redis/src/release.c:36:10: fatal error: 'release.h' file not found
#include "release.h"
^~~~~~~~~~~
1 error generated.
make[3]: *** [CMakeFiles/redis-server.dir/src/release.c.o] Error 1
make[3]: *** Waiting for unfinished jobs....
[ 48%] Building C object CMakeFiles/redis-server.dir/src/networking.c.o
make[2]: *** [CMakeFiles/redis-server.dir/all] Error 2

找不到release.h头文件,此时只需要切换到src目录下执行mkreleasehdr.sh脚本即可

运行 redis-server

image-20200807181132188

这样就成功了

打个断点试试,入口函数在server.c

image-20200807181219576

👌

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章