The Libevent book is a handy reference.
@libevent//:event_openssl
target is not usable on Windows.@libevent//sample:https-client
fails because of this.For better or worse, I kept the same library targets as the official release. These targets are described in the preliminaries chapter in the book.
@libevent//:event_core
- All core event and buffer functionality. This library contains all the event_base, evbuffer, bufferevent, and utility functions.@libevent//:event_extra
- This library defines protocol-specific functionality that you may or may not want for your application, including HTTP, DNS, and RPC.@libevent//:event
- This library exists for historical reasons; it contains the contents of both libevent_core and libevent_extra. You shouldn’t use it; it may go away in a future version of Libevent.@libevent//:event_pthreads
- This library adds threading and locking implementations based on the pthreads portable threading library. It is separated from libevent_core so that you don’t need to link against pthreads to use Libevent unless you are actually using Libevent in a multithreaded way.@libevent//:event_openssl
- This library provides support for encrypted communications using bufferevents and the OpenSSL library. It is separated from libevent_core so that you don’t need to link against OpenSSL to use Libevent unless you are actually using encrypted connections.Upstream releases can be found at https://github.com/libevent/libevent/releases
The official build uses CMake to generate two files, evconfig-private.h
and event2/event-config.h
. The general strategy is to generate them ourselves and then modify them for portability. Ordinarily CMake detects the capabilities of the target platform and writes these files accordingly, but this workflow doesn't happen on Bazel, so we will have to edit these files and provide our own feature detection.
Run cmake
to generate evconfig-private.h
and event2/event-config.h
in build/include
.
mkdir build && cd build cmake ..
From here I used the generated files as a starting point and decided to make the config files platform specific for better organization. So for example, I renamed evconfig-private.h
to evconfig-private_linux.h
and then made evconfig-private.h
into a platform selector file. I did the same with event2/event-config.h
. When you rename these files, be sure to fix the strings used by the #include
guards as well. These files get overlayed onto the tree in the Bazel Central Registry.
I also factored out the version constants like EVENT__PACKAGE_VERSION
into a seperate file, event2-config_common.h
, which may allow the platform specific files to be reused between versions since only the version constants in event2-config_common.h
may need to be updated. Use caution with this strategy. If new feature detection macros are introduced, the platform specific configuration files will also need to be updated.
Since we cannot guarantee that the user is running a Bazel build targeting an identical platform as the CMake target, some feature test macros will have to be updated for portability. For example, strlcpy
was introduced in glibc 2.38. The generated value of EVENT__HAVE_STRLCPY
will depend entirely on the platform (or in this case, the version of glibc on the platform) that CMake ran on. In this case, I changed the macro to
/* Define to 1 if you have the `strlcpy' function. */ #if EVENT__GLIBC_PREREQ(2, 38) #define EVENT__HAVE_STRLCPY 1 #endif
so that it is correct regardless of the platform CMake ran on.
Figuring out which macros need to be fixed requires some testing. One thing you could try is running CMake on the oldest platform you would like to support, and running it on the newest platform you would like to support, and looking at the diff between the generated files. From there it may require some research to figure out what the correct feature test is.
Another class of macros that may need to be fixed for portability are the SIZEOF
constants in the config files, for example EVENT__SIZEOF_LONG
, since this may differ between 32-bit and 64-bit platforms. Note that sizeof(type)
cannot be used by the preprocessor. Normally CMake computes the values that will be used on the target platform. We have to manually get these right. For gcc
and clang
, some of these constants are provided by the compiler. You can see some of the predefined symbols that may be useful with the following command:
${CC:-gcc} -dM -E - $@ < /dev/null
I added a test @libevent//test:test-config
to check that the some of the values in the configuration headers are correct.
BUILD.bazel
Next you will have to create the BUILD.bazel
file. Commands like
ls -1 include/*.h | sort | awk '{ print "\""$0"\","}'
are helpful for getting the list of files in a format that can be copy-pasted.
Two files are handled non-intuitively:
arc4random.c
is textually included by evutil_rand.c when arc4random() is not available. It is not compiled by itself. Put this file in textual_hdrs
.epoll_sub.c
appears to only be needed when using an ancient version of glibc, and will conflict with glibc when a modern version is in use. For simplicity this file can be omitted from the build.