背景:
OS:CentOs 7.7
Redis: 6.0.6
- 编译构建报错如下:
```javascript
In file included from server.c:30:0:
server.h:1044:5: error: expected specifier-qualifier-list before ‘_Atomic’
_Atomic unsigned int lruclock; / Clock for LRU eviction /
^
server.c: In function ‘serverLogRaw’:
server.c:1028:31: error: ‘struct redisServer’ has no member named ‘logfile’
int log_to_stdout = server.logfile[0] == '\0';
server.c:1031:23: error: ‘struct redisServer’ has no member named ‘verbosity’^
if (level < server.verbosity) return;
server.c:1033:47: error: ‘struct redisServer’ has no member named ‘logfile’^
fp = log_to_stdout ? stdout : fopen(server.logfile,"a");
server.c:1046:47: error: ‘struct redisServer’ has no member named ‘timezone’^
server.c:1046:63: error: ‘struct redisServer’ has no member named ‘daylight_active’nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active); ^
server.c:1049:19: error: ‘struct redisServer’ has no member named ‘sentinel_mode’nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active); ^
...
server.c:5103:19: error: ‘struct redisServer’ has no member named ‘supervised_mode’
if (server.supervised_mode == SUPERVISED_SYSTEMD) {
^
server.c:5104:24: error: ‘struct redisServer’ has no member named ‘masterhost’
if (!server.masterhost) {
^
server.c:5117:15: error: ‘struct redisServer’ has no member named ‘maxmemory’
if (server.maxmemory > 0 && server.maxmemory < 10241024) {
^
server.c:5117:39: error: ‘struct redisServer’ has no member named ‘maxmemory’
if (server.maxmemory > 0 && server.maxmemory < 10241024) {
^
server.c:5118:176: error: ‘struct redisServer’ has no member named ‘maxmemory’
serverLog(LL_WARNING,"WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want?", server.maxmemory);
^
server.c: In function ‘hasActiveChildProcess’:
server.c:1476:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
server.c: In function ‘allPersistenceDisabled’:
server.c:1482:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
server.c: In function ‘writeCommandsDeniedByDiskError’:
server.c:3747:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
server.c: In function ‘iAmMaster’:
server.c:4914:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
make[1]: [server.o] Error 1
make[1]: Leaving directory `/root/redis-6.0.1/src'
make: [all] Error 2
编译文件报错,查看编译文件
[查看redis6.0 源码的makefile文件](https://github.com/redis/redis/blob/6.0/src/Makefile)
```c
/*Default settings 这里标明了需要用到C11的特性*/
STD=-std=c11 -pedantic -DREDIS_STATIC=''
ifneq (,$(findstring clang,$(CC)))
ifneq (,$(findstring FreeBSD,$(uname_S)))
STD+=-Wno-c11-extensions
endif
endif
WARN=-Wall -W -Wno-missing-field-initializers
OPT=$(OPTIMIZATION)
PREFIX?=/usr/local
INSTALL_BIN=$(PREFIX)/bin
INSTALL=install
PKG_CONFIG?=pkg-config
# Default allocator defaults to Jemalloc if it's not an ARM
MALLOC=libc
ifneq ($(uname_M),armv6l)
ifneq ($(uname_M),armv7l)
ifeq ($(uname_S),Linux)
MALLOC=jemalloc
endif
endif
endif
我们再去查看5.0
/* Default settings 这里版本5.0 支持的是c99特性
继续查看低版本,发现低于版本6.0 需要的是都是c99特性
*/
STD=-std=c99 -pedantic -DREDIS_STATIC=''
ifneq (,$(findstring clang,$(CC)))
ifneq (,$(findstring FreeBSD,$(uname_S)))
STD+=-Wno-c11-extensions
endif
endif
WARN=-Wall -W -Wno-missing-field-initializers
OPT=$(OPTIMIZATION)
PREFIX?=/usr/local
INSTALL_BIN=$(PREFIX)/bin
INSTALL=install
/*Default allocator defaults to Jemalloc if it's not an ARM
这里也值得注意 架构不是arm 的 默认内存分配器是jemalloc
*/
MALLOC=libc
ifneq ($(uname_M),armv6l)
ifneq ($(uname_M),armv7l)
ifeq ($(uname_S),Linux)
MALLOC=jemalloc
endif
endif
endif
C11特性
引用wiki的解释如下
GCC 4.9 Changes: “ISO C11 support is now at a similar level of completeness to ISO C99 support: substantially complete modulo bugs, extended identifiers (supported except for corner cases when -fextended-identifiers is used), floating-point issues (mainly but not entirely relating to optional C99 features from Annexes F and G) and the optional Annexes K (Bounds-checking interfaces) and L (Analyzability).
gcc版本在4.9 以上才有C11特性,我们的centos 7.7 默认gcc版本是4.8
C99特性
官方解释如下:
C99 is substantially completely supported as of GCC 4.5 (with -std=c99 -pedantic-errors used; -fextended-identifiers also needed to enable extended identifiers before GCC 5), modulo bugs and floating-point issues (mainly but not entirely relating to optional C99 features from Annexes F and G). The following table gives more details of the C99 support in different GCC versions.
c99特性是版本gcc 4.5有的
解决办法
降低redis版本
升级gcc版本 使其支持c11特性
显然我们采用第二种 升级gcc版本
升级gcc
yum -y install gcc gcc-c++ make tcl centos-release-scl devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils && scl enable devtoolset-9 bash
系统版本 | gcc版本 |
---|---|
centos 6 | 4.4.7 |
centos 7 | 4.8.5 |
centos 8 | 8.3.1 |