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

猜你喜欢

转载自blog.csdn.net/weixin_43328357/article/details/120259464