版本简述

  • 4.29之后增加了io_uring支持.

  • 4.26-4.28期间增加与完善Linux AIO支持.

  • 4.25之后增加了Android的兼容性支持.

  • 4.00之后Linux支持signalfdeventfdtimerfd

命名规则

我们一般根据版本号来确定当前使用的libev版本, 打包后的文件命名规则是以libev-${version}.tar.gz形式出现.

注意:
不建议大家激进的跟进新版本, 最新的版本也不一定就是最好的.

在线阅读

可以从译者在这里提供的fork源在线阅读.

下载源码

推荐大家从Libev作者本人提供的服务器下载源码包, 这样下载的安全性也是有保障的.

注意:
鉴于国际网络互通的一些问题导致有些同学可能无法访问. 所以本站已缓存2015年以来的稳定版打包文件, 如有需要可以直接点击链接进行下载:

编译安装

1. 下载源码包

为了保证下载速度, 我们选择上述链接中的4.33版本下载到本地:

1
2
3
4
5
6
7
8
9
10
11
12
13
root@iZbp18k2vy63cz9njzffe8Z:~/build# wget https://libev.cn/downloads/libev-4.33.tar.gz
--2022-03-14 21:49:43-- https://libev.cn/downloads/libev-4.33.tar.gz
Resolving libev.cn (libev.cn)... 185.199.108.153, 185.199.110.153, 185.199.109.153, ...
Connecting to libev.cn (libev.cn)|185.199.108.153|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 569527 (556K) [application/gzip]
Saving to: ‘libev-4.33.tar.gz’

libev-4.33.tar.gz 100%[======================>] 556.18K 36.8KB/s in 18s

2022-03-14 21:50:03 (31.1 KB/s) - ‘libev-4.33.tar.gz’ saved [569527/569527]

root@iZbp18k2vy63cz9njzffe8Z:~/build#

2. 安装依赖

为了运行configure, 需要安装以下工具:

  • autoconf

  • automake

  • libtool

  • make

  • gcc/clang

3. 开始编译

  • 运行sh autogen.sh
1
2
3
4
5
6
7
8
9
10
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33# sh autogen.sh
libtoolize: putting auxiliary files in '.'.
libtoolize: linking file './ltmain.sh'
libtoolize: Consider adding 'AC_CONFIG_MACRO_DIRS([m4])' to configure.ac,
libtoolize: and rerunning libtoolize and aclocal.
libtoolize: Consider adding '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
configure.ac:12: installing './compile'
configure.ac:7: installing './missing'
Makefile.am: installing './depcomp'
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33#
  • 运行./configure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking whether make supports the include directive... yes (GNU style)
checking dependency style of gcc... gcc3
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for sysroot... no
checking for a working dd... /usr/bin/dd
checking how to truncate binary pipes... /usr/bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking sys/inotify.h usability... yes
checking sys/inotify.h presence... yes
checking for sys/inotify.h... yes
checking sys/epoll.h usability... yes
checking sys/epoll.h presence... yes
checking for sys/epoll.h... yes
checking sys/event.h usability... no
checking sys/event.h presence... no
checking for sys/event.h... no
checking port.h usability... no
checking port.h presence... no
checking for port.h... no
checking poll.h usability... yes
checking poll.h presence... yes
checking for poll.h... yes
checking sys/timerfd.h usability... yes
checking sys/timerfd.h presence... yes
checking for sys/timerfd.h... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking sys/eventfd.h usability... yes
checking sys/eventfd.h presence... yes
checking for sys/eventfd.h... yes
checking sys/signalfd.h usability... yes
checking sys/signalfd.h presence... yes
checking for sys/signalfd.h... yes
checking linux/aio_abi.h usability... yes
checking linux/aio_abi.h presence... yes
checking for linux/aio_abi.h... yes
checking linux/fs.h usability... yes
checking linux/fs.h presence... yes
checking for linux/fs.h... yes
checking for inotify_init... yes
checking for epoll_ctl... yes
checking for kqueue... no
checking for port_create... no
checking for poll... yes
checking for select... yes
checking for eventfd... yes
checking for signalfd... yes
checking for clock_gettime... yes
checking for nanosleep... yes
checking for __kernel_rwf_t... yes
checking for library containing floor... -lm
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33#
  • 运行make && make install
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33# make && make install
make all-am
make[1]: Entering directory '/root/build/libev-4.33'
/bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -g -O3 -MT ev.lo -MD -MP -MF .deps/ev.Tpo -c -o ev.lo ev.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -g -O3 -MT ev.lo -MD -MP -MF .deps/ev.Tpo -c ev.c -fPIC -DPIC -o .libs/ev.o
ev.c:2143:31: warning: ‘ev_default_loop_ptr’ initialized and declared ‘extern’
EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
^~~~~~~~~~~~~~~~~~~
libtool: compile: gcc -DHAVE_CONFIG_H -I. -g -O3 -MT ev.lo -MD -MP -MF .deps/ev.Tpo -c ev.c -o ev.o >/dev/null 2>&1
mv -f .deps/ev.Tpo .deps/ev.Plo
/bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -g -O3 -MT event.lo -MD -MP -MF .deps/event.Tpo -c -o event.lo event.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -g -O3 -MT event.lo -MD -MP -MF .deps/event.Tpo -c event.c -fPIC -DPIC -o .libs/event.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -g -O3 -MT event.lo -MD -MP -MF .deps/event.Tpo -c event.c -o event.o >/dev/null 2>&1
mv -f .deps/event.Tpo .deps/event.Plo
/bin/bash ./libtool --tag=CC --mode=link gcc -g -O3 -version-info 4:0:0 -o libev.la -rpath /usr/local/lib ev.lo event.lo -lm
libtool: link: gcc -shared -fPIC -DPIC .libs/ev.o .libs/event.o -lm -g -O3 -Wl,-soname -Wl,libev.so.4 -o .libs/libev.so.4.0.0
libtool: link: (cd ".libs" && rm -f "libev.so.4" && ln -s "libev.so.4.0.0" "libev.so.4")
libtool: link: (cd ".libs" && rm -f "libev.so" && ln -s "libev.so.4.0.0" "libev.so")
libtool: link: ar cru .libs/libev.a ev.o event.o
ar: 'u' modifier ignored since 'D' is the default (see 'U')
libtool: link: ranlib .libs/libev.a
libtool: link: ( cd ".libs" && rm -f "libev.la" && ln -s "../libev.la" "libev.la" )
make[1]: Leaving directory '/root/build/libev-4.33'
make[1]: Entering directory '/root/build/libev-4.33'
/usr/bin/mkdir -p '/usr/local/lib'
/bin/bash ./libtool --mode=install /usr/bin/install -c libev.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libev.so.4.0.0 /usr/local/lib/libev.so.4.0.0
libtool: install: (cd /usr/local/lib && { ln -s -f libev.so.4.0.0 libev.so.4 || { rm -f libev.so.4 && ln -s libev.so.4.0.0 libev.so.4; }; })
libtool: install: (cd /usr/local/lib && { ln -s -f libev.so.4.0.0 libev.so || { rm -f libev.so && ln -s libev.so.4.0.0 libev.so; }; })
libtool: install: /usr/bin/install -c .libs/libev.lai /usr/local/lib/libev.la
libtool: install: /usr/bin/install -c .libs/libev.a /usr/local/lib/libev.a
libtool: install: chmod 644 /usr/local/lib/libev.a
libtool: install: ranlib /usr/local/lib/libev.a
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/sbin" ldconfig -n /usr/local/lib
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
/usr/bin/mkdir -p '/usr/local/include'
/usr/bin/install -c -m 644 ev.h ev++.h event.h '/usr/local/include'
/usr/bin/mkdir -p '/usr/local/share/man/man3'
/usr/bin/install -c -m 644 ev.3 '/usr/local/share/man/man3'
make[1]: Leaving directory '/root/build/libev-4.33'
root@iZbp18k2vy63cz9njzffe8Z:~/build/libev-4.33#

注意: 上述编译期间如无报错, 那么最终头文件与库文件都将会被安装的/usr/local的相关目录下.

测试运行

为了检查我们是否正常安装好, 可以就地编写一个简单的demo来进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <ev.h>

static ev_idle idle;

static void idle_cb(struct ev_loop* loop, ev_idle *idle, int revents) {
puts("idle start.");
ev_idle_stop(loop, idle);
}

int main(int argc, char const *argv[])
{
struct ev_loop* loop = EV_DEFAULT;

// 注册一个空闲事件.
ev_idle_init(&idle, idle_cb);
ev_idle_start(loop, &idle);

ev_run(loop, 0);
return 0;
}

上述示例注册空闲(idle)事件后进入到事件循环内部, 空闲(idle)事件回调打印输出后立刻调用方法停止.

由于loop内部再未注册任何其它事件, 所以ev_run将在停止后返回并且整个进程正常退出.

代码完成之后我们手动指定头文件与库文件的路径然后编译运行:

1
2
3
4
root@iZbp18k2vy63cz9njzffe8Z:~/build# cc -o main main.c  -L/usr/local/lib -I/usr/local/include/ -lev -Wl,-rpath,/usr/local/lib
root@iZbp18k2vy63cz9njzffe8Z:~/build# ./main
idle start.
root@iZbp18k2vy63cz9njzffe8Z:~/build#

可以看到程序执行成功, Libev已经本成功安装好了.