creytiv / re

Generic library for real-time communications with async IO support

Home Page:http://creytiv.com/re.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Public header preprocessor directives

lgrahl opened this issue · comments

commented

In May 2014, Alfred mentioned that you don't want a configuration file to detect which features have been enabled in re at compile time and would rather have the application do runtime checks (see this mail). And I'm mostly fine with that. However, there are quite a couple of issues with that approach when including the public headers of re in an application as I will explain in the following.

HAVE_INTTYPES_H

As an application depending on re, it makes sense to include re_types.h pretty much everywhere instead of inttypes.h because it is a useful abstraction. However, at the moment the application needs to define HAVE_INTTYPES_H itself or it will trigger unintended behaviour/compile errors in most of the cases (e.g. defining all of those types instead of simply including inttypes.h).

Suggested solution: -DHAVE_INTTYPES_H could be added to the Cflags of libre.pc depending on whether inttypes.h has been detected on the system. I'm not sure if we would also have to include -D__ssize_t_defined for Windows but it does fall into the same category.

RELEASE

The RELEASE definition triggers different behaviour when using re_mbuf. The application will most likely use mbuf structures but its build system may or may not define RELEASE.

Suggested solution: Same as for HAVE_INTTYPES_H but expose -DMBUF_DEBUG=1 (if RELEASE was set) in the Cflags.

WIN32-related

There a lot of WIN32-related definition checks in headers. This results in...

  • different definitions for MOD_PRE, MOD_EXT and EXPORT_SYM in re_mod.h,
  • different includes in re_net.h and re_sa.h, and
  • different type definitions in re_types.h.

IIRC, an application building on Windows pretty much has to define WIN32 to get anything working.

Suggested solution: Expose -DWIN32 in the Cflags if set. That might clash with other projects, though.

USE_ZLIB

crc32 would be redefined if USE_ZLIB is not set and zlib is being used.

Suggested solution: Expose -DUSE_ZLIB if set.

HAVE_GAI_STRERROR

While it will work fine for the library itself, gai_strerror will be overridden with a stub function when including re_net.h after having included all the necessary headers for working with gai_strerror.

Suggested solution: Adding -DHAVE_GAI_STRERROR (if set) to Cflags should do.

HAVE_INET6

The NET_ADDRSTRLEN definition depends on HAVE_INET6. It would be incorrect for the application if HAVE_INET6 is not set.

Suggested solution: Expose -DHAVE_INET6 if set.

USE_OPENSSL

A couple of OpenSSL functions and structs will be redefined when including re_sha.h without setting USE_OPENSSL.
In addition, tls_openssl_context is not defined if USE_OPENSSL is not defined.

Suggested solution: Expose -DUSE_OPENSSL if set.

VERSION, ARCH and OS

All of those will be redefined if not set. However, it doesn't really matter much since the sys_* functions exists. As such it doesn't make much sense to leave them in the public header.

Suggested solution: Move them into a private header file.

SOLARIS and HAVE_STDBOOL_H

SOLARIS and HAVE_STDBOOL_H trigger different behaviour in re_types.h.

Suggested solution: Expose them if they are set.


If we go with the suggested solutions, then we are really not far away from a (much more convenient) configuration header. So, it might make sense to reconsider it.

the idea was that the application should include re.mk in its Makefile.
then the application will get the same flags as re. is this possible in your app ?

my goal is to reduce the number of #ifdef s.

for example the following defines might be subject to removal:

HAVE_INTTYPES_H
HAVE_INET6
HAVE_GAI_STRERROR

what do you think about remove these ?

the goal should be that the re API is source and binary compatible,
independently of which flags are set/unset.

commented

is this possible in your app ?

I'm currently including it via CMake via the use of the pkgconfig file, so I don't think so. But perhaps CMake has a Makefile compatibility layer? No idea tbh. In any case, since re has a pkgconfig file, IMHO it should be striven for that the library can be used with pkg-config alone, essentially

cc foo.c `pkg-config --cflags --libs libre` -o foo

should work fine and not require foo.c to define HAVE_INTTYPES_H & co.

what do you think about remove these ?

That will probably resolve 90% of the issues but not all of them (like USE_ZLIB). I would also like an approach that resolves this issue 100% without generating any headers but at this point I'm uncertain whether that's possible. The alternative is of course to expose the defines directly in the pkgconfig file but that is a bit messy. Edit: This is actually what I've done in my Meson support branch for now (should I create a PR for that? 😉).

the pkg-config file is generated in Makefile:

libre.pc:
	@echo 'prefix='$(PREFIX) > libre.pc
	@echo 'exec_prefix=$${prefix}' >> libre.pc
	@echo 'libdir=$${prefix}/lib' >> libre.pc
	@echo 'includedir=$${prefix}/include/re' >> libre.pc
	@echo '' >> libre.pc
	@echo 'Name: libre' >> libre.pc
	@echo 'Description: ' >> libre.pc
	@echo 'Version: '$(VERSION) >> libre.pc
	@echo 'URL: http://creytiv.com/re.html' >> libre.pc
	@echo 'Libs: -L$${libdir} -lre' >> libre.pc
	@echo 'Libs.private: -L$${libdir} -lre ${LIBS}' >> libre.pc
	@echo 'Cflags: -I$${includedir}' >> libre.pc

so you could add all the mentioned flags to the Cflags section, would that work ?

commented

Could do but the defines are not prefixed so they might clash. I guess it would be an adequate compromise for now.

@lgrahl are you planning to do any work on this ?

I have added the item to the roadmap:

https://github.com/creytiv/re/wiki/Roadmap