First I have tried to build the library on the Mac side. I have used the latest version (at the time of writing), which is 3.2.5. I have downloaded the sources and run ./configure --prefix=${HOME}/local to try it out. Bang. Configure does not have a clue about the Mac: it tells me it has no idea what is the build platform. Oh why... After deleting some .in files and running autoreconf --install --force I was able to run configure to the end. Up to make I say! It goes on for a while, with weird compiler warnings about undefined (but used) inline functions (that I gracefully ignore; one shalt trust thy fellow programmers). Suddenly, at the point of linking, and I get a weird error about not being able to link @GNUCAP_LDFLAGS@...
Never give up, never surrender! Mac is not listed as officially supported platform, so I have turned to trusted Linux. After murmuring some friendly curses about the stability of VMWare Fusion, and restarting openSuse, I have gained access to my Midnight Commander and started the now-familiar routine of configuring the package... just to get the same weird error exactly the same time during make.
What shall one do in such a case? If in doubt, ask Google. So I did. The search for the error message brought up two unanswered questions on the cgicc mailing lists. Drat and double drat! So what the heck is GNUCAP anyways? Google to the rescue! It is a circuit designer software. Ahem... what???
After some thinking (yes, I do it sometimes) I have tried a simpler search on Google and this article turned up: Remove stray @GNUCAP_LDFLAGS@. Yippee! Or so I thought...
After removing the garbage from cgicc/Makefile.am I am able to go on with building a little longer, but then, another linker error. Actually a lot of them. Unresolved symbols. Fun, oh fun! How come?
Back to the drawing board: make clean; clear; make, then wait for the first warning and ctrl-C. OK. The same function is named in the "inline, used but not defined" warning as one of my unresolved externals. Nice. This is GNU code! From the GNU domain! Supposedly tested on platforms ranging from wristwatches to mainframes.
All right, I am supposedly a good C++ programmer, so how difficult it is for me to find an inline function that has no definition? Perhaps older compilers were more lenient in allowing the function to go undefined and use the "out of line" copy during linking? So the designers ignored the warnings, because they have got away with it?
So what was that function anyway... what file, what line number. Aha. It is an assignment operator of HTTPCookie. File is the header, line number is... whaddaheck??? The line number points to the following line:
class CGICC_API HTTPCookie : public MStreamable
Now that does not look like an assignment operator! Furthermore, the class definition does not declare an assignment operator at all! I must use my Vulcan/android logic:
- There is no assignment operator declared
- The warning message points to the class declarations first line
- C++ implements the assignment operator for classes that do not declare one, if possible
- The code assumes that there is an assignment operator, since the compiler says it is being used
- So, according to the author's intent, the assignment operator must be generated, but it is not
Compiling the base turns out the same warning, pointing to the class definitions' first line. No assignment operator is declared in the base class either. No more base classes. All data members can be assigned. Insomnia leads to paranoia: Apple has its own version of g++, perhaps it is broken? We have seen it happen with other distributions. And Apple favors Objective-C and "hates" C++, so this must be a conspiracy... It is time to have breakfast, time is passing 6:30am...
Finally, stumped, I read the web page (yes, I am a programmer, I read documentation only when all else fails) and it says: it was tested on Linux with 3.3 gcc. Aha, this Mac has 4.x. So does the Linux, which has the same problem. (I was going back and forth).
So, "select is not broken", Apple is not evil, but the code is broken. But how and why? What do I know already?
- The assignment operator definition is not generated, but a declaration for the inline function is generated! That is weird and unexpected. What could make a compiler to do that?
- The original code is written for gcc 3.3, and beginning with 3.4 the hard working people of the gcc community have rewritten the C++ compiler front-end (as far as I understood it) twice.
- OK. So something tells g++ not to generate the inline function definition, only the declaration. That something is most probably g++ specific and has changed its meaning during the rewrite.
- According to my understanding of the way compilers work, that something should be located in the lines of the source code that precedes the class declaration or passed to the compiler as a command line option.
I am sorry to say, I have no clue why those pragmas failed. I have decided to drop further investigation, since the gcc documentation page I have found stated that after gcc 2.7 (if I recall correctly) they have no (good) effect for production code. Perhaps, gcc was unable to match up the implementation and the header files, and so it did not emit the object code for the inline functions into the .cpp files? Not all the headers and .cpp files had these pragmas, which, again may be a problem. But after all the struggle (I have also installed application etc.) I have lost my motive to investigate it any further for the time being.
