building cmake 3.14.4 on Centos5 fail due to missing EPOLL_CLOEXEC in cmlibuv
Build error
/opt/rh/devtoolset-2/root/usr/bin/gcc -DLIBARCHIVE_STATIC -D_GNU_SOURCE -IUtilities -I/work/src/Utilities -I/work/src/Utilities/cmlibuv/include -I/work/src/Utilities/cmlibuv/src -I/work/src/Utilities/cmlibuv/src/unix -ISource -w -O3 -DNDEBUG -std=gnu99 -MD -MT Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o -MF Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o.d -o Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o -c /work/src/Utilities/cmlibuv/src/unix/linux-core.c
/work/src/Utilities/cmlibuv/src/unix/linux-core.c: In function ‘uv__platform_loop_init’:
/work/src/Utilities/cmlibuv/src/unix/linux-core.c:88:22: error: ‘EPOLL_CLOEXEC’ undeclared (first use in this function)
fd = epoll_create1(EPOLL_CLOEXEC);
^
Link to related file
Possible cause
EPOLL_CLOEXEC
seems to be available only with kernel 2.6.27 and onward. See https://linux.die.net/man/2/epoll_create1 and https://github.com/grpc/grpc/issues/7147
Will updating libuv addresses the problem ?
While a related fix has been integrated upstream to address a similar issue on android, the proposed fix doesn't address this particular problem. See https://github.com/libuv/libuv/commit/ab5859129b2c1da33815673862d39ee6105f6437#diff-ef6a692d0a1d5779d26d4f57afcf3d42
Possible fix
In libuv integrated in cmake:
this may not be the correct approach because when the symbol is effectively available, indeed EPOLL_CLOEXEC
is not a macro but part of an enum. That said, i think this is a valid approach in the upstream libuv where O_CLOEXEC
is used. When O_CLOEXEC
is available, it is an alias of EPOLL_CLOEXEC
defined using #define O_CLOEXEC EPOLL_CLOEXEC
diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c
index 3341b94e1f..1400045228 100644
--- a/Utilities/cmlibuv/src/unix/linux-core.c
+++ b/Utilities/cmlibuv/src/unix/linux-core.c
@@ -66,6 +66,11 @@
# define CLOCK_MONOTONIC_COARSE 6
#endif
+/* Available from 2.6.32 onwards. */
+#ifndef EPOLL_CLOEXEC
+# define EPOLL_CLOEXEC 02000000
+#endif
+
/* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't
* include that file because it conflicts with <time.h>. We'll just have to
* define it ourselves.
A similar fix could be integrated in upstream libuv.
How to reproduce
cd /tmp
git clone https://gitlab.kitware.com/cmake/cmake
docker pull dockcross/manylinux1-x64
docker run --rm dockcross/manylinux1-x64 > dockcross-manylinux1-x64
chmod u+x dockcross-manylinux1-x64
dockcross-manylinux1-x64 cmake -GNinja -Hcmake -Bcmake-build
dockcross-manylinux1-x64 cmake --build cmake-build
[485/966] Building C object Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o
FAILED: Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o
/opt/rh/devtoolset-2/root/usr/bin/gcc -DLIBARCHIVE_STATIC -D_GNU_SOURCE -IUtilities -I/work/cmake/Utilities -I/work/cmake/Utilities/cmlibuv/include -I/work/cmake/Utilities/cmlibuv/src -I/work/cmake/Utilities/cmlibuv/src/unix -ISource -w -std=gnu99 -MD -MT Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o -MF Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o.d -o Utilities/cmlibuv/CMakeFiles/cmlibuv.dir/src/unix/linux-core.c.o -c /work/cmake/Utilities/cmlibuv/src/unix/linux-core.c
/work/cmake/Utilities/cmlibuv/src/unix/linux-core.c: In function ‘uv__platform_loop_init’:
/work/cmake/Utilities/cmlibuv/src/unix/linux-core.c:88:22: error: ‘EPOLL_CLOEXEC’ undeclared (first use in this function)
fd = epoll_create1(EPOLL_CLOEXEC);
^
/work/cmake/Utilities/cmlibuv/src/unix/linux-core.c:88:22: note: each undeclared identifier is reported only once for each function it appears in
[494/966] Building CXX object Utilities/cmjsoncpp/CMakeFiles/cmjsoncpp.dir/src/lib_json/json_value.cpp.o
ninja: build stopped: subcommand failed.