1、安装CLion
2、下载源码
下载源码到本地~/CLionProjects目录下:
cd ~/CLionProjects
git clone https://github.com/antirez/redis.git
稍等片刻源码即可下载完成。
3、添加CMakeLists.txt文件
- 前提:mac需要安装CMake。
brew install cmake
- 根目录redis/CMakeLists.txt
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
src/crc16.c
src/dict.c
src/siphash.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
)
- redis/deps/CMakeLists.txt
add_subdirectory(hiredis)
add_subdirectory(linenoise)
add_subdirectory(lua)
- redis/deps/hiredis/CMakeLists.txt
add_library(hiredis STATIC
hiredis.c
net.c
dict.c
sds.c
async.c
read.c
)
- redis/deps/linenoise/CMakeLists.txt
add_library(linenoise linenoise.c)
- redis/deps/lua/CMakeLists.txt
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})
- redis/src/modules/CMakeLists.txt
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")
4、cmake
添加完CMakeLists.txt文件之后,进入代码根目录下执行下面命令
cmake .
make
5、ae_kqueue.h
执行make命令的时候,会出现下面的错误:
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:41:24: error: unknown type name 'aeEventLoop'
static int aeApiCreate(aeEventLoop *eventLoop) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/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));
^
/Users/yuanqixiang/CLionProjects/redis-5.0/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/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:47:9: warning: implicit declaration of function 'zfree' is invalid in C99
[-Wimplicit-function-declaration]
zfree(state);
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:52:9: warning: implicit declaration of function 'zfree' is invalid in C99
[-Wimplicit-function-declaration]
zfree(state->events);
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:60:24: error: unknown type name 'aeEventLoop'
static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:63:21: warning: implicit declaration of function 'zrealloc' is invalid in C99
[-Wimplicit-function-declaration]
state->events = zrealloc(state->events, sizeof(struct kevent)*setsize);
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:63:19: warning: incompatible integer to pointer conversion assigning to
'struct kevent *' from 'int' [-Wint-conversion]
state->events = zrealloc(state->events, sizeof(struct kevent)*setsize);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:67:23: error: unknown type name 'aeEventLoop'
static void aeApiFree(aeEventLoop *eventLoop) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:70:5: warning: implicit declaration of function 'close' is invalid in C99
[-Wimplicit-function-declaration]
close(state->kqfd);
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:71:5: warning: implicit declaration of function 'zfree' is invalid in C99
[-Wimplicit-function-declaration]
zfree(state->events);
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:75:26: error: unknown type name 'aeEventLoop'
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:79:16: error: use of undeclared identifier 'AE_READABLE'
if (mask & AE_READABLE) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:83:16: error: use of undeclared identifier 'AE_WRITABLE'
if (mask & AE_WRITABLE) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:90:27: error: unknown type name 'aeEventLoop'
static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:94:16: error: use of undeclared identifier 'AE_READABLE'
if (mask & AE_READABLE) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:98:16: error: use of undeclared identifier 'AE_WRITABLE'
if (mask & AE_WRITABLE) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:104:22: error: unknown type name 'aeEventLoop'
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:127:51: error: use of undeclared identifier 'AE_READABLE'
if (e->filter == EVFILT_READ) mask |= AE_READABLE;
^
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/ae_kqueue.c:128:52: error: use of undeclared identifier 'AE_WRITABLE'
if (e->filter == EVFILT_WRITE) mask |= AE_WRITABLE;
只需要在ae_kqueue.c
文件中添加下面两行即可。
#include "ae.h"
#include "zmalloc.h"
6、sh mkreleasehdr.sh
再次执行make
命令,会报错
/Users/yuanqixiang/CLionProjects/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
只需要执行sh src/mkreleasehdr.sh
即可。
7、CLion打开project
打开Clion,选择new CMake project from Sources...
,找到Redis目录,打开即可,CLion的run configurations
会出现下面的可执行按钮。
运行
redis-server
,出现下面说明运行成功:
/Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/redis-server
51644:C 29 Jul 2019 07:37:42.183 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
51644:C 29 Jul 2019 07:37:42.183 # Redis version=5.0.5, bits=64, commit=388efbf8, modified=1, pid=51644, just started
51644:C 29 Jul 2019 07:37:42.183 # Warning: no config file specified, using the default config. In order to specify a config file use /Users/yuanqixiang/CLionProjects/redis-5.0/redis/src/redis-server /path/to/redis.conf
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.5 (388efbf8/1) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 51644
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
51644:M 29 Jul 2019 07:37:42.233 # Server initialized
51644:M 29 Jul 2019 07:37:42.234 * DB loaded from disk: 0.001 seconds
51644:M 29 Jul 2019 07:37:42.234 * Ready to accept connections
接下来就可以愉快的对代码调试了。