clion使用cmake导入redis源码3.0和6.0版本

redis源码导入clion

背景

学习redis,看看源码,但是发现redis是直接使用make构建的,makefile晦涩难懂,本文在前人的基础之上使用cmake重构一下,导入到自己的ide里面。直接对面源进行debug.

环境

redis是可以跨平台的,但是目前工作没见过windows的redis,所以直接在linux系统下面操作,开发工具clion(idea的亲兄弟,java开发者最爱)

deepinv20+clion

redis3.0

redis3.0不直接采用github的源码,因为目前有人做好了笔记可以直接拿来学习

gitee地址

本项目是注释版的 Redis 3.0 源码, 原始代码来自: https://github.com/antirez/redis 。

这份注释是我在创作新版《Redis 设计与实现》期间, 为了了解 Redis 的内部实现而制作的, 所有在书中有介绍的内容, 在源码中都进行了相应的注释。

在注释的过程中, 除了少量空格和空行方面的调整外, 没有对原始代码进行任何其他改动, 最大程度地保证了代码的“原汁原味”。

希望这份注释源码能给大家学习和了解 Redis 带来一点帮助。

另外, 新版《Redis 设计与实现》正在各大网店发售中, 希望大家可以多多支持这本书。

Have fun!

黄健宏(huangz)

2014 年 6 月 28 日

redis-3.0源码目录结构

文件作用
adlist.cadlist.h双端链表数据结构的实现。
ae.cae.hae_epoll.cae_evport.cae_kqueue.cae_select.c事件处理器,以及各个具体实现。
anet.canet.hRedis 的异步网络框架,内容主要为对 socket 库的包装。
aof.cAOF 功能的实现。
asciilogo.h保存了 Redis 的 ASCII LOGO 。
bio.cbio.hRedis 的后台 I/O 程序,用于将 I/O 操作放到子线程里面执行, 减少 I/O 操作对主线程的阻塞。
bitops.c二进制位操作命令的实现文件。
blocked.c用于实现 BLPOP 命令和 WAIT 命令的阻塞效果。
cluster.ccluster.hRedis 的集群实现。
config.cconfig.hRedis 的配置管理实现,负责读取并分析配置文件, 然后根据这些配置修改 Redis 服务器的各个选项。
crc16.ccrc64.ccrc64.h计算 CRC 校验和。
db.c数据库实现。
debug.c调试实现。
dict.cdict.h字典数据结构的实现。
endianconv.cendianconv.h二进制的大端、小端转换函数。
fmacros.h一些移植性方面的宏。
help.hutils/generate-command-help.rb 程序自动生成的命令帮助信息。
hyperloglog.cHyperLogLog 数据结构的实现。
intset.cintset.h整数集合数据结构的实现,用于优化 SET 类型。
lzf_c.clzf_d.clzf.hlzfP.hRedis 对字符串和 RDB 文件进行压缩时使用的 LZF 压缩算法的实现。
MakefileMakefile.dep构建文件。
memtest.c内存测试。
mkreleasehdr.sh用于生成释出信息的脚本。
multi.cRedis 的事务实现。
networking.cRedis 的客户端网络操作库, 用于实现命令请求接收、发送命令回复等工作, 文件中的函数大多为 write 、 read 、 close 等函数的包装, 以及各种协议的分析和构建函数。
notify.cRedis 的数据库通知实现。
object.cRedis 的对象系统实现。
pqsort.cpqsort.h快速排序(QuickSort)算法的实现。
pubsub.c发布与订阅功能的实现。
rand.crand.h伪随机数生成器。
rdb.crdb.hRDB 持久化功能的实现。
redisassert.hRedis 自建的断言系统。
redis-benchmark.cRedis 的性能测试程序。
redis.c负责服务器的启动、维护和关闭等事项。
redis-check-aof.credis-check-dump.cRDB 文件和 AOF 文件的合法性检查程序。
redis-cli.cRedis 客户端的实现。
redis.hRedis 的主要头文件,记录了 Redis 中的大部分数据结构, 包括服务器状态和客户端状态。
redis-trib.rbRedis 集群的管理程序。
release.crelease.h记录和生成 Redis 的释出版本信息。
replication.c复制功能的实现。
rio.crio.hRedis 对文件 I/O 函数的包装, 在普通 I/O 函数的基础上增加了显式缓存、以及计算校验和等功能。
scripting.c脚本功能的实现。
sds.csds.hSDS 数据结构的实现,SDS 为 Redis 的默认字符串表示。
sentinel.cRedis Sentinel 的实现。
setproctitle.c进程环境设置函数。
sha1.csha1.hSHA1 校验和计算函数。
slowlog.cslowlog.h慢查询功能的实现。
solarisfixes.h针对 Solaris 系统的补丁。
sort.cSORT 命令的实现。
syncio.c同步 I/O 操作。
testhelp.h测试辅助宏。
t_hash.ct_list.ct_set.ct_string.ct_zset.c定义了 Redis 的各种数据类型,以及这些数据类型的命令。
util.cutil.h各种辅助函数。
valgrind.supvalgrind 的suppression文件。
version.h记录了 Redis 的版本号。
ziplist.cziplist.hZIPLIST 数据结构的实现,用于优化 LIST 类型。
zipmap.czipmap.hZIPMAP 数据结构的实现,在 Redis 2.6 以前用与优化 HASH 类型, Redis 2.6 开始已经废弃。
zmalloc.czmalloc.h内存管理程序。

导入之后的目录结构

CMakeLists.txt的编写,在相应目录创建CMakeLists.txt

根目录
#指定cmake最低版本
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

#项目名称
project(redis-3.0 VERSION 3.0)

if (NOT CMAKE_BUILD_TYPE)
    message(STATUS "No build type defined; defaulting to 'Debug'")
    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
            "The type of build. Possible values are: Debug, Release, RelWithDebInfo and MinSizeRel.")
endif()

message(STATUS "Host is: ${CMAKE_HOST_SYSTEM}.  Build target is: ${CMAKE_SYSTEM}")
get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
message(STATUS "Project root directory is: ${REDIS_ROOT}")

# Just for debugging when handling a new platform.
if (false)
    message("C++ compiler supports these language features:")
    foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
        message("  ${i}")
    endforeach()
endif()

message(STATUS "Generating release.h...")

#这个比较重要,会生成release.h到src目录下面
execute_process(
        COMMAND sh -c ./mkreleasehdr.sh
        WORKING_DIRECTORY ${REDIS_ROOT}/src/
)

#子目录的配置
add_subdirectory(deps)

#redis服务的源码文件,网上抄
set(SRC_SERVER
        src/adlist.c src/ae.c src/anet.c src/dict.c src/redis.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
        )

#redistribute-cli客户段的源码,网上抄
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
        )


if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    # better not to work with jemalloc
endif()

# 生成两个可执行文件
add_executable(redis-server ${SRC_SERVER})
add_executable(redis-cli ${SRC_CLI})

#一直设置,直接从网上抄
set_property(TARGET redis-server PROPERTY C_STANDARD 99)
set_property(TARGET redis-server PROPERTY CXX_STANDARD 11)
set_property(TARGET redis-server PROPERTY CXX_STANDARD_REQUIRED ON)

set_property(TARGET redis-cli PROPERTY C_STANDARD 99)
set_property(TARGET redis-cli PROPERTY CXX_STANDARD 11)
set_property(TARGET redis-cli PROPERTY CXX_STANDARD_REQUIRED ON)


## link_directories(deps/hiredis/ deps/linenoise/ diredeps/lua/src)

# 链接动/静态库文件目录
target_include_directories(redis-server
        PRIVATE ${REDIS_ROOT}/deps/hiredis
        PRIVATE ${REDIS_ROOT}/deps/linenoise
        # PRIVATE ${REDIS_ROOT}/deps/jemalloc
        PRIVATE ${REDIS_ROOT}/deps/lua/src
        )

# 链接动/静态
target_include_directories(redis-cli
        PRIVATE ${REDIS_ROOT}/deps/hiredis
        PRIVATE ${REDIS_ROOT}/deps/linenoise
        # PRIVATE ${REDIS_ROOT}/deps/jemalloc
        PRIVATE ${REDIS_ROOT}/deps/lua/src
        )


target_link_libraries(redis-server
        #多线程,系统库
        PRIVATE pthread
        #m不知道啥
        PRIVATE m
        # lua和其他两个都是源码里面有的
        PRIVATE lua
        PRIVATE linenoise
        PRIVATE hiredis
        )

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

deps

#添加自己目录配置
add_subdirectory (hiredis)
add_subdirectory(linenoise)
add_subdirectory(lua)

deps/hiredis

#生成一个静态库
add_library(hiredis STATIC
        hiredis.c
        net.c
        dict.c
        net.c
        sds.c
        async.c
        )

deps/jemalloc

作用位置(像内存分配的,暂时可不管)

deps/linenoise

add_library(linenoise
        linenoise.c
        )

deps/lua

#这个指令是把整个目录的所有文件作为变量,免得一个一个的加
aux_source_directory (${PROJECT_SOURCE_DIR}/deps/lua/src LUA_SRC)
add_library(lua STATIC ${LUA_SRC})

reload项目

在这里插入图片描述

重点在于redis-server和redis-cli

redis6.0

fork源码

redis源码github

2.git clone 切换到6.0分支

3. 导入到clion

4.CMakeLists.txt的编写

根目录

#制定cmake最小版本
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
#项目名称
project(redis VERSION 6.0)

set(CMAKE_BUILD_TYPE "Debug")
get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)

if (NOT CMAKE_BUILD_TYPE)
    message(STATUS "No build type defined; defaulting to 'Debug'")
    set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
            "The type of build. Possible values are: Debug, Release, RelWithDebInfo and MinSizeRel.")
endif()

message(STATUS "Host is: ${CMAKE_HOST_SYSTEM}.  Build target is: ${CMAKE_SYSTEM}")
get_filename_component(REDIS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
message(STATUS "Project root directory is: ${REDIS_ROOT}")

# Just for debugging when handling a new platform.
if (false)
    message("C++ compiler supports these language features:")
    foreach(i ${CMAKE_CXX_COMPILE_FEATURES})
        message("  ${i}")
    endforeach()
endif()

#zai src目录生成release.h 比较重要
message(STATUS "Generating release.h...")
execute_process(
        COMMAND sh -c ./mkreleasehdr.sh
        WORKING_DIRECTORY ${REDIS_ROOT}/src/
)


#子目录构建配置
add_subdirectory(deps)
#这个感觉不是重点先封着
#add_subdirectory(src/modules)

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

# redis客户端源码文件,网上抄
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
        src/crcspeed.c
        src/dict.c
        src/crc16.c
        src/siphash.c
        )

#这个指令不需要,不用自己制定可执行文件的输出位置,clion自己有 cmake-build-debug
#set(EXECUTABLE_OUTPUT_PATH src)
#库所在目录
link_directories(deps/linenoise/ deps/lua/src deps/hiredis)

# redis-server
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
        #这一步,是因为出现dlopen找不到等报错,dlopen,dlclose等是系统调用动态库的函数
        ${CMAKE_DL_LIBS}
        )

# redis-cli
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
        )

deps/hiredis

这里已经有了

add_library(hiredis STATIC
		#这个在master是有的,6.0分支没有了
        #alloc.c
        async.c
        dict.c
        hiredis.c
        net.c
        read.c
        sds.c
        sockcompat.c)

# 注释的源码自带的
#[[CMAKE_MINIMUM_REQUIRED(VERSION 3.4.0)
INCLUDE(GNUInstallDirs)
PROJECT(hiredis)

OPTION(ENABLE_SSL "Build hiredis_ssl for SSL support" OFF)

MACRO(getVersionBit name)
  SET(VERSION_REGEX "^#define ${name} (.+)$")
  FILE(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hiredis.h"
    VERSION_BIT REGEX ${VERSION_REGEX})
  STRING(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}")
ENDMACRO(getVersionBit)

getVersionBit(HIREDIS_MAJOR)
getVersionBit(HIREDIS_MINOR)
getVersionBit(HIREDIS_PATCH)
getVersionBit(HIREDIS_SONAME)
SET(VERSION "${HIREDIS_MAJOR}.${HIREDIS_MINOR}.${HIREDIS_PATCH}")
MESSAGE("Detected version: ${VERSION}")

PROJECT(hiredis VERSION "${VERSION}")

SET(ENABLE_EXAMPLES OFF CACHE BOOL "Enable building hiredis examples")

ADD_LIBRARY(hiredis SHARED
    async.c
    dict.c
    hiredis.c
    net.c
    read.c
    sds.c
    sockcompat.c)

SET_TARGET_PROPERTIES(hiredis
    PROPERTIES
    VERSION "${HIREDIS_SONAME}")
IF(WIN32 OR MINGW)
    TARGET_LINK_LIBRARIES(hiredis PRIVATE ws2_32)
ENDIF()
TARGET_INCLUDE_DIRECTORIES(hiredis PUBLIC .)

CONFIGURE_FILE(hiredis.pc.in hiredis.pc @ONLY)

INSTALL(TARGETS hiredis
    DESTINATION "${CMAKE_INSTALL_LIBDIR}")

INSTALL(FILES hiredis.h read.h sds.h async.h
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
    
INSTALL(DIRECTORY adapters
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
    
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis.pc
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

IF(ENABLE_SSL)
    IF (NOT OPENSSL_ROOT_DIR)
        IF (APPLE)
            SET(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
        ENDIF()
    ENDIF()
    FIND_PACKAGE(OpenSSL REQUIRED)
    ADD_LIBRARY(hiredis_ssl SHARED
        ssl.c)
    TARGET_INCLUDE_DIRECTORIES(hiredis_ssl PRIVATE "${OPENSSL_INCLUDE_DIR}")
    TARGET_LINK_LIBRARIES(hiredis_ssl PRIVATE ${OPENSSL_LIBRARIES})
    CONFIGURE_FILE(hiredis_ssl.pc.in hiredis_ssl.pc @ONLY)

    INSTALL(TARGETS hiredis_ssl
        DESTINATION "${CMAKE_INSTALL_LIBDIR}")

    INSTALL(FILES hiredis_ssl.h
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis)
    
    INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_ssl.pc
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
ENDIF()

IF(NOT (WIN32 OR MINGW))
    ENABLE_TESTING()
    ADD_EXECUTABLE(hiredis-test test.c)
    TARGET_LINK_LIBRARIES(hiredis-test hiredis)
    ADD_TEST(NAME hiredis-test
        COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test.sh)
ENDIF()

# Add examples
IF(ENABLE_EXAMPLES)
  ADD_SUBDIRECTORY(examples)
ENDIF(ENABLE_EXAMPLES)]]

其他目录的配置同3.0

唯一改动的代码是server里面的,里面报错函数找不到,暂时注释(这里有条件编译,可有可无的那种)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qQ1Y50C-1631473138465)(C:\Users\authorZhao\Desktop\note\md\redis源码导入\image-20210913025222612.png)]

启动

在这里插入图片描述

使用

县启动server然后启动cli

在这里插入图片描述

注意点

  • 3.0版本按照网上的基本没问题
  • 6.0的版本需要微调一下,windows和linus还略有不同,重点在于CMakeLists.txt的编写,可以参考网上的其他文章

参考文章:https://blog.csdn.net/Nuan_Feng/article/details/108542440?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-13.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-13.no_search_link

参考视频:https://www.bilibili.com/video/BV1vE411v7cR/?spm_id_from=autoNext

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值