1

I have a header file named api.h which contains my library's public functions. I would like the function void func_xxx(); to be declared in api.h only if the user enables it using ./configure --enable-xxx. Is this possible? Ideally I do not want to use #ifdef for this? I know how to implement the --enable-xxx flag in my configure.ac script but I do not know how to add the function declaration to api.h if --enable-xxx is used.

Thanks for your help

Linoliumz
  • 2,381
  • 3
  • 28
  • 35
  • 1
    why do you want to avoid `#ifdef` for that, if you don't mind me asking? – Andreas Grapentin Jul 24 '14 at 07:43
  • My goal is that the user does not need to use -DHAVE_XXX in order to compile his program. – Linoliumz Jul 24 '14 at 07:51
  • 1
    he doesn't, though. autotools will take care of that. unless I misunderstood you =) – Andreas Grapentin Jul 24 '14 at 07:52
  • Thanks for your comments, I will take a closer look at this. – Linoliumz Jul 24 '14 at 07:57
  • I see that I can achieve what I want if I include config.h in api.h? (But this is normally not advised!?). Other than this I still have no idea how to do it i.e. gcc -c program.c fails if program.c includes api.h and uses func_xxx(). – Linoliumz Jul 24 '14 at 08:46
  • do you have a source as to why it is not advised to include config.h? Including this file is the main method of communication between autotools and the C code. – Andreas Grapentin Jul 24 '14 at 08:56
  • Here are two sources for not installing config.h: http://stackoverflow.com/a/19694763/363778, http://inaugust.com/post/68. The first link also describes a work around which I might use. – Linoliumz Jul 24 '14 at 09:08
  • quoting from your source "config.h should ALWAYS be the first thing included by EVERY non-header C/C++ file in your project." including and installing are two different things =) EDIT: I totally misunderstood your question, sorry. I did not get that you want to change an installed header file at library compile time. my bad. – Andreas Grapentin Jul 24 '14 at 09:58
  • in recent versions of autotools preprocessor defines are usually set by configure setting variables like, CPPFLAGS, AM_CPPFLAGS, target_CPPFLAGS etc. you don't need to use config.h – arved Jul 24 '14 at 11:33

1 Answers1

1

What you want to achieve is not good practice because, as you mentioned, you would need #ifpreprocessor macros, dragging config.h to the public interface, and hence, having to install it. Config files are not meant to be installed.

I suggest that you do that at runtime, this is suggested practice in books like API design for C++, a very recommende read, by the way:

bool isFuncXXXEnabled();
void funcxxx();

Your code:

if (isFuncXXXEnabled()) {
}
else {
}

In your .cpp file you can disable the body of the function, because `config.h will not be exposed in the public interface.

Germán Diago
  • 7,473
  • 1
  • 36
  • 59
  • 1
    Good answer. Other than "config files are not meant to be installed", a reason to do it this way is that if your `api.h` can change depending on how someone configured the library, then programs that work fine on one system could fail to compile on another (or, if they were installed as binary packages through a package manager, they could crash!) – ptomato Jul 24 '14 at 15:18
  • Well, that is true, but I think there is a tradeoff here. The standard solution is that, AFAIK. Without depending on the config you should do much more complicated machinery like machine-generating an api.h file from an api.h.in, without #ifdefs, at the time of generating. You could do this replacing autoconf variables or similar, but I don't know how good this idea would be. – Germán Diago Jul 24 '14 at 16:33
  • 1
    Thanks I appreciate your answer, it completely decouples my API from the user's code. Another less optimal solution is to create an installable config file using the ax_prefix_config_h.m4 macro from http://www.gnu.org/software/autoconf-archive/ax_prefix_config_h.html – Linoliumz Jul 25 '14 at 21:02
  • 1
    "but I don't know how good this idea would be.". It is not a good idea e.g. if I build my library using compiler A and the user compiles his code using compiler B then his code might break because api.h has been built specifically for compiler A (e.g. api.h might use non standard extensions from compiler A). – Linoliumz Jul 25 '14 at 21:31