Where to stick config.h

I keep running in to issues with how folks use config.h, so I thought I'd clear up any confusion folks have. For those who haven't been following along at home, the autotools (i.e. autoconf and autoheader in this case) generate a file called config.h which contains a bunch of defines to help control the build based on what things exist or don't exist on your system. There are two main rules for this file that lots of folks get wrong:

  1. config.h should ALWAYS be the first thing included by EVERY non-header C/C++ file in your project.
  2. config.h should NEVER NEVER NEVER NEVER NEVER NEVER be installed.

Why?

For the first point, you must ensure that config.h is included first, because it sets behaviors. It must be included before any system headers because it may contain things that control the behavior of the system headers. It must be included before any local headers because it's going to define things like HAVE_SYS_STAT_H which will let you know if it's safe to include sys/stat.h (it is, by the way - it exists everywhere you care about - but that's not the point here) There is nothing, and I do mean NOTHING to be gained by including it anywhere else, in any other order, or in fact, even about putting any extra effort into thinking about where it might be cool to include config.h. The ONLY thing you will accomplish is making your software more fragile.

For the second point, it must never be installed because it unconditionally sets a bunch of defines based on the state of the machine where configure was run. That state has nothing to do with the state of the machine where your headers are installed, so the settings found in config.h are at best coincidentally correct, and at worst out-right lies. In addition, it's probably not just you using autotools for your project. autoconf and automake are, for better or for worse, pretty much the most common build system out there. So if your are shipping a config.h and your shipped headers are including it, and someone is trying to use autotools in their project which consumes your code... FAIL. Symbols will collide and all manner of pain will ensue.

*NOTE* Renaming config.h to something else does not mitigate this. The problem is the common non-prefixed name of config.h defines... like PACKAGE or VERSION.

Now, you might respond that your public headers need defines from config.h to operate properly. There are two answers to this. One is that you need to redesign your public headers, as they are unclean. (and nobody likes dirty headers) Two is that, for your project, if every non-header file includes config.h before they include anything else,  then the defines will be quite happily present in scope when any of your headers are read. Be warned though - don't count on this too heavily in your public headers ... because then you'll be counting on someone out there having run the same set of autoconf checks you did. (Yes. Proper public headers are tricky)Don't forget that many OS features have defined and standard feature check macros you can test without having to do an autoconf test for the feature.

In short though - just include config.h FIRST in all of your implementation files and NEVER under ANY circumstances install it, and you'll be golden.

2 comments

Trying to Find a Usable C++ IDE for Linux

Dear LazyWeb,

I'm looking for a usable C++ IDE for Linux and I'm wondering if you've seen one. Before you start giving the normal suggestions (Ecliipse, NetBeans, just-use-vi) let start off by saying that I've tried Eclipse, Netbeans and Code::Blocks and KDevelop several times, and that I normally hack in some combination of vi and emacs. (yes yes, I know I'm supposed to religiously pick one and be rude to the other... consider me a postmodern hacker)

For it to be usable by me, it must be able to:

  1. Handle the fact that my build is run with autoconf/automake.
  2. Properly rename a method and have that show up throughout the codebase.
  3. Properly encapsulate a variable with getter/setting methods.
  4. Correctly answer the question "where is this method being used"
  5. Run without consuming all of my RAM and CPU resources.
  6. Quickly and easily open a new project/branch (I have 93 different branches of Drizzle in my source dir right now. Going through a 10 step process to open any given branch in the IDE== FAIL)

Bonus points given for:

  1. Allowing me to deal with one or more bzr branches in a sane manner
  2. Supporting an option like emacs where the tab key NEVER inserts a tab character and instead ALWAYS indents the line its on.
  3. Figuring out by the existence of a configure.ac file that perhaps a Makefile will appear if it runs "autoreconf -f -i; ./configure"

If you think you have the answer, try this as a test:

  • bzr branch lp:drizzle
  • Open the drizzle directory as a "project"
  • Build
  • Find some method on the Session object in drizzled/session.h.  Rename it using the IDE. Build again.
  • Find the method errmsg_printf in drizzled/errmsg_print.h. Find out every place that uses it. See if that matches what grep -r '\berrmsg_printf\b' would tell you.

Anybody? If you have an IDE and it can actually deal with my daily Drizzle development, I will happily blog both that it can and how to get started.

10 comments

Build fixes for Snow Leopard

Eric Lambert found some build issues with the new release of OSX today. They're real pleasing. The first is that for some reason test programs testing for fdatasync() compile and run with no problem, but when trying to then use it in the main program, it doesn't work. (because it doesn't exist) So we had to add a special test program check (ugh - thanks Apple) And then they "upgraded" readline. Except they only half-upgraded, so it has half of the newer readline interface but not the other half. The fix to this is simple.

Download and install a real copy of readline instead of the half-baked pile-of-shit copy of editline wrappers that Apple ships. Works like a charm.

You know, it's fine if you want a (wanna-be) BSD system (which is actually non-free) and all. Whatever. But if you aren't going to ship readline, then don't ship readline. OR, man up and ship readline but then just link all of your BSD and closed source programs with editline. But don't put a cripppled and mostly worthless replacement wrapper - leave me with a real copy of readline so that my GPL programs actually work.

Or just stop shipping closed source garbarge.

4 comments
Tags: mysql drizzle

Compiling with -O3

Mark Callaghan was just asking about what gcc compilation flags people use. (Not sure if Facebook Notes recognize pingbacks or not, so I sort of hope Mark is reading planetmysql, too)

Most of the distros build with -O2 (except for Gentoo, which compiles with as many flags as they can find) It's also the default in autoconf, the rationale being, I believe, that -O3 doesn't give discernable benefit for most things, but does require a considerably higher CPU cost during the compile. If you are, say, Debian, and you're compiling over 10k packages, streamlining the compile for the normal case is probably a great idea.

In Drizzle, however, we do override that default and build with -O3 at all times. I did some testing in our benchmark system about a month ago, mainly because I wanted to verify that -O3 was worth the extra effort that's in our autoconf files to do the override. I don't remember the exact numbers (I can re-run if someone really wants to know) but it was significant (something is telling me 25%) My next step was going to be compiling with -O2 and each of the individual optimizations that are in -O3 and not in -O2 to try to find out where the win was coming from. Haven't done it yet, though.

The original reason I bumped us to -O3 had nothing to do with performance though, oddly enough, it had to do with an increased set of warnings generated in some of the warning flags. Again, rather uselessly I do not remember the exact warning that gets generated only under -O3 (and I don't ever see if because we fixed it and moved on) but it's perhaps another reason why one should build free of compiler warnings - some of those "dangerous" constructs that the dev things the compiler is "wrong" about actually might be problematic at higher optimization levels. :)

9 comments
Tags: mysql drizzle

Valgrinding Drizzle: As if By Magic...

Kristian Nielsen was just noticing that some valgrind issues have made it in to Drizzle's trunk. I just wanted to follow up and say that, as if we knew he was going to check, Brian and I spent much of yesterday (Friday) cleaning them all up.

We were merging in Jay's replication work and noticed a memory leak (not related to Jay's work - it was in another branch that was also being tested as part of the overall process) That brought us to the Valgrind situation.

There are a couple of remaining issues, one of which is on Stewart's plate for as soon as it's a reasonable time down in Australia. As soon as it's clean, we'll push those fixes along with Jay's replication work. Additionally, we're adding Valgrind to the set of things that a branch has to pass to be pushed into trunk. We honestly should have done this a while ago - but things happen. We're expecting to push the Valgrind-clean tree on Monday, although as with all code it'll be pushed when it's correct, not just because I happened to say the word Monday.

0 comments
Tags: mysql drizzle