唯书籍不朽。——乔特
学习一个软件的实现原理的最好方法就是查看其源码。redis是一套开源的内存数据库,以其快速而强大的功能而让软件人员喜爱。既然开源,那么我们就可以通过细研其内部代码,了解其背后运行的基本实现。本期将在centos6.8操作系统下clion开发环境中,通过配置CMakeLists.txt文件,利用cmake编译运行redis 5.0.5
一、基本软件
开发环境:clion 2016(我自己下载的版本比较老,各位也可以自己下载最新clion.
操作系统:centos 6.8_x86-64
软件:redis-5.0.5 gcc-4.4.7 cmake 3.6.1 gdb 7.11.1
二,配置部署
1,导入redis工程
下载redis源码后(git克隆即可),我们通过 Import Project(新版本可以通过New Cmake Project From Source...)选中redis源码目录导入。
2,配置hiredis组件CMakeLists.txt文件(在deps/hiredis下面新建CMakeLists.txt文件),使其编译通过:
add_library(hiredis STATIC
hiredis.c
net.c
dict.c
net.c
sds.c
async.c
read.c)
3,配置linenoise组件CMakeLists.txt文件(在deps/inenoise下面新建CMakeLists.txt文件),使其编译通过:
add_library(linenoise
linenoise.c)
4,配置lua组件CMakeLists.txt文件(在deps/lua下面新建CMakeLists.txt文件),使其编译通过:
set(LUA_SRC
src/fpconv.c
src/lapi.c
src/lauxlib.c
src/lbaselib.c
src/lcode.c
src/ldblib.c
src/ldebug.c
src/ldo.c
src/ldump.c
src/lfunc.c
src/lgc.c
src/linit.c
src/liolib.c
src/llex.c
src/lmathlib.c
src/lmem.c
src/loadlib.c
src/lobject.c
src/lopcodes.c
src/loslib.c
src/lparser.c
src/lstate.c
src/lstring.c
src/lstrlib.c
src/ltable.c
src/ltablib.c
src/ltm.c
src/lua.c
src/lua_bit.c
src/lua_cjson.c
src/lua_cmsgpack.c
src/lua_struct.c
src/luac.c
src/lundump.c
src/lvm.c
src/lzio.c
src/print.c
src/strbuf.c)
add_library(lua STATIC ${LUA_SRC})
5,在deps下面新建并配置CMakeLists.txt文件:
add_subdirectory(hiredis)
add_subdirectory(linenoise)
add_subdirectory(lua)
6,核心搭建,因redis有多个启动组件,我们此次主要配置核心的redis-server和redis-cli,在redis源码目录下面新建CMakeLists.txt文件。
主要配置如下:
cmake_minimum_required(VERSION 3.6) #cmake版本需求
project(redis_5_0_5) #工程
set(CMAKE_BUILD_TYPE "Debug")
get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE) #设置文件获取路径
包含基本组件(hiredis,linenoise,lua等):
add_subdirectory(deps)
add_subdirectory(src/modules)
c99支持:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -pedantic -DREDIS_STATIC=''")
redis-server和redis-cli运行所需源文件
set(SRC_SERVER
src/t_stream.c
src/lolwut.c
src/localtime.c
src/listpack.c
src/lolwut5.c
src/adlist.c
src/quicklist.c
src/ae.c
src/anet.c
src/dict.c
src/server.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/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/redis-check-rdb.c
src/redis-check-aof.c
src/geo.c
src/lazyfree.c
src/module.c
src/evict.c
src/expire.c
src/geohash.c
src/geohash_helper.c
src/childinfo.c
src/defrag.c
src/siphash.c
src/rax.c)
set(SRC_CLIENT src/siphash.c
src/dict.c
src/crc16.c
src/anet.c
src/adlist.c
src/redis-cli.c
src/zmalloc.c
src/release.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})
add_executable(redis-cli ${SRC_CLIENT})
target_include_directories(redis-server
PRIVATE ${REDIS_ROOT}/deps/linenoise
PRIVATE ${REDIS_ROOT}/deps/hiredis
PRIVATE ${REDIS_ROOT}/deps/lua/src
#PRIVATE ${REDIS_ROOT}/deps/jemalloc
)
target_include_directories(redis-cli
PRIVATE ${REDIS_ROOT}/deps/linenoise
PRIVATE ${REDIS_ROOT}/deps/hiredis
PRIVATE ${REDIS_ROOT}/deps/lua/src
#PRIVATE ${REDIS_ROOT}/deps/jemalloc
)
target_link_libraries(redis-server
PRIVATE pthread
PRIVATE m
PRIVATE dl
PRIVATE lua
PRIVATE linenoise
PRIVATE hiredis)
target_link_libraries(redis-cli
PRIVATE pthread
PRIVATE m
PRIVATE dl
PRIVATE linenoise
PRIVATE hiredis)
7,自此,整个redis cmake编译所需配置就已完成,在编译右上角configuration上,我们可以看到我们配置的redis-server和redis-cli:
本人先在server.c源文件的main函数上设置了断点,再进行debug:
三、运行调试
配置完成后,选择redis-server进行debug,编译没报错,代码直接运行到断点处,可以一步一步运行调试代码了:
redis-cli通用也编译通过,我直接进入clion工程debug后的运行文件,直接运行redis-cli,连接进运行的server,敲入命令测试:
可以看到,redis-cli命令成功连接进入到了服务器,敲入命令也运行成功,直至redis核心源码编译运行成功,后续便可以一步一步调试查看源码了!