Fail to build mysql connector/c (libmysql) from so

2019-07-17 01:48发布

问题:

I am trying to build MySQL's "Connector/C" from source in cygwin and there are problems.

-some context-

We could talk a lot about why anyone would want use libmysql in cygwin. In this case, it is just simpler to do some unix development on a windows box with the cygwin tool set.

From my research, it looks like I could get an older version (5.1, maybe) of the connector to build OK. But cygwin support trailed off when the MySQL developers switched from ./configure to cmake driven build configuration.

The version of the source tar-ball that MySQL offers up for download is 6.0.2 so that is the one I'm working on.

-one (sort-of) solved problem-

The first problem I encountered was an incompatible redeclaration of dtoa() found in stdlib.h. (Many others who have tried to build various recent versions encountered this problem, also - if google is any guide.) There are various suggestions lurking on the net to resolve this. My choice: temporarily replacing stdlib.h with one that has the dtoa() definition removed. Ugly, true. But it works.

(This 'fix' eliminates an early compile error and the process runs clear through to linking, where it fails for apparently unrelated reasons.)

-an unsolved problem-

The libmysql code relies on yaSSL. This seems to be the case even though I gave cmake the -DWITH_OPENSSL=1 parameter, which is accepted only after I added the openssl-devel package to my environment with the cygwin setup-tool/package-manager. yaSSL seems to be using 'pure virtual' class members. From my (somewhat limited) knowledge of the internals of C++, this means that the compiler implicitly assumes the declaration of the special symbol/function __cxa_pure_virtual() and this causes the linker to search for a (single) definition of the __cxa_pure_virtual() function.

The way the code and build process are structured, each of the yaSSL source implementation files is compiled into an object file. Many of those files reference another that defines (i.e. contains an implementation of) __cxa_pure_virtual(). In the linking stage, each object that contains a definition conflicts with each other. (Because the symbol is defined as extern, or more specifically:

extern "C" {
  int __cxa_pure_virtual() {
    assert("Pure virtual method called." == "Aborted");
    return 0;
  }
}

These definitions are in a shared namespace. Thus, the linker has not been given a rule by which to decide which one to link-to from each reference.) The result is a multiple definition error, e.g.:

CMakeFiles/libmysql.dir/__/extlib/yassl/taocrypt/src/algebra.cpp.o:algebra.cpp:(.text+0x40): multiple definition of `___cxa_pure_virtual'
CMakeFiles/libmysql.dir/__/extlib/yassl/taocrypt/src/aes.cpp.o:aes.cpp:(.text+0x0): first defined here

I've tried some highly simplistic attempts to resolve this problem.

  • I removed all definitions of __cxa_pure_virtual() but that just replaces the multiple-definition errors with undefined-reference errors.
  • I changed all definitions of __cxa_pure_virtual() to inline in the vain hope that the compiler would remove the external reference from a function that was used inline. (I'm not sure when C++ uses a lookup-table as a layer of indirection but it seems that inline may not be an option in those cases.) If I remember the specific result of that test: it created the same result as no definition of __cxa_pure_virtual().
  • I started looking for uses of pure-virtual functions in the libmysql source but that seemed like a rabbit hole...
  • I considered studying the build process in order to place a definition of __cxa_pure_virtual() in an independent object file (and, then, I would remove the definition from every other object file).

I'm looking for options between (and including)

  1. the minimum modification to the project to make it build something useful, and
  2. the correct patch-set that makes the build process work correctly on all currently supported platforms and cygwin.

"Between" because there might be some intermediate alternatives that should be considered. So, the way I see it, the most important question here is, "What is the simplest/easiest fix for the multiple-definition error (in this context)?" maybe followed closely by, "What kinds of things should be fed back to the MySQL team so that the build process can be (re-)ported to cygwin?"

-final notes-

If MySQL's developers have abandoned cygwin support, I don't know what would bring their attention back to that platform.

I would like to see that developers who have cause to work in cygwin could retain the option to test their code against a cygwin/unix build of the MySQL connector.

There might be some value in the community maintaining a knowledge base containing, at least, the bare minimum set of hacks to make the latest version (and, maybe, some recent versions) of the connector build usefully in cygwin. A good first step toward that might be some discussion here on stackoverflow, maybe even as comments and answers on this thread.

回答1:

Why do you need Connector/C built with Cygwin? Would not normal win32 libmysql.dll suffice?

Some ideas to get it compiling:

a)you're trying to compile Connector/C with gcc as C++ compiler, better don't. Use g++.

b)cmake . -DSKIP_SSL=1 (looking into CMakeLists.txt suggests it will remove yassl)

And yes, MySQL has abandoned cygwin (and it did not support it for many years now). I do not know what might get Oracle to reenable it back, they are currently rather into cutting platform support (e.g HPUX and AIX are abandoned). Also personally,I would not see much value in Cygwin port, it is not the hottest platform, as long as you can use native Windows port.