About a year and a half ago I wrote a patch to get mysqlcc (”MySQL Control Center”) to build with newer versions of mysql and the gcc compiler. This post can be found here and I’ve received several replies on this blog and through e-mail since.
After mysql 5.5 was released, I received a few questions about getting mysqlcc to work with this new version of the still very popular database.
Personally I have not yet decided if I should stick to mysql – now a commercial product from Oracle – or switch to its really free sister (*) MariaDB or even PostgreSQL.
At first I thought “Are people still using this?” and, together with a complete lack of time, did not do too much with this all.
But the, curiosity caught up with me and I started to do some investigation…
The error messages
Trying to build mysqlcc against mysql 5.5 gives these errors:
main.cpp:(.text+0xae): undefined reference to `my_print_help' main.cpp:(.text+0xcd): undefined reference to `my_print_variables' tmp/main.o: In function `main': main.cpp:(.text+0x1dd): undefined reference to `handle_options'
After some quick “googling” I found out that since mysql 5.5 the libmysqlclient library (libmysqlclient.so.18.0.0) does not export several functions that were exported with the previous versions. A discussion about this can be found here. Basically, they were unofficial and now are hidden functions. They can be exported by altering a CMakeLists.txt file and rebuilding mysql 5.5, but this is not always an option. I did try it and in the end I got it to work, but I was convinced that it was not the right way to fix this. After all, I don’t think Oracle would listen to me and change their library
The patch
OK, so I had to patch mysqlcc.
These now “hidden” functions all were related to passing command-line parameters to mysql, like the location of the socket, etc. Most users would never use this (I never have) and simply start mysqlcc from a menu, not from a prompt.
I simply removed all these calls in mysqlcc, resulting in this patch:
--- mysqlcc-1.0.1-src/src/main.cpp 2011-07-08 07:40:01.000000000 -0300 +++ mysqlcc-1.0.1-src_patched/src/main.cpp 2011-12-19 09:31:11.000000000 -0200 @@ -176,13 +176,7 @@ print_version(); printf("usage: %s [options] [database]\n\n", progname); printf("Options:\n"); - my_print_help(my_long_options); -#ifndef WIN32 //Win32 doesn't support load_defaults yet. - print_defaults("my", load_default_groups); -#endif - - my_print_variables(my_long_options); exit(-1); } @@ -192,14 +186,8 @@ int pid = 0; int t = 0; int ret = -1; - char **save_argv; - load_defaults("my",load_default_groups,&argc,&argv); - save_argv = argv; progname= argv[0]; - if (handle_options(&argc, &argv, my_long_options, get_one_option)) - exit(-1); if (!argv[0] || !argv[1] || (pid = atoi(argv[0])) <= 0 || (t= atoi(argv[1])) <= 0) ret = mysqlcc_main(argc, argv); - free_defaults(save_argv); return ret; }
The patch can also be downloaded here.
It works
After patching and building, I could use mysqlcc on my mysql 5.5 server:
Just remember that it will not handle any command line option after this patch, not even "-v" to see the version...
(*) My and Maria are both daughters of Ulf Michael Widenius, the "father" of both databases.
]]> http://underpop.online.fr/n/nielshorn/2011/12/mysqlcc-revisited-making-it-work-with-mysql-5-5/feed/ 3 http://underpop.online.fr/n/nielshorn/2010/06/getting-mysqlcc-to-build-with-newer-gcc-compilers-and-mysql-headers/ http://underpop.online.fr/n/nielshorn/2010/06/getting-mysqlcc-to-build-with-newer-gcc-compilers-and-mysql-headers/#comments Fri, 18 Jun 2010 00:42:31 +0000 Niels Horn http://underpop.online.fr/n/nielshorn/?p=425 mysqlcc revisitedI used to use MySQL Control Center (’mysqlcc’) quite a lot until a few years ago, when I switched to phpMyAdmin.
The biggest advantage of phpMyAdmin is that it is actively maintained, while mysqlcc has not seen updates for almost three years.
mysqlcc’s interface also had a bit of an “old-fashioned” look, as it is still based on the Qt3 library (known from KDE3).
Anyway, these days I took a second look at it, because of a question about building it on Slackware 13.1 on the SlackBuilds mailing list.
My first reaction was like “Hey, try something more modern”, but on second thoughts I decided to give it a try and examine the source code and the build-time error messages from gcc.
The error messages
Without any modification, gcc throws several messages at you like this:
src/main.cpp:93: error: 'gptr' was not declared in this scope
So I took a look at main.cpp and noticed that the lines causing the error message are part of a structure of ‘my_option’ lines:
static struct my_option my_long_options[] =
The lines that give the error are:
{"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, 1}, {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", (gptr*) &my_net_buffer_length, (gptr*) &my_net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 512*1024*1024L, 0, 1024, 0}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", (gptr*) &my_max_allowed_packet, (gptr*) &my_max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, 0, 1024, 0}, {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", (gptr*) &opt_local_infile, (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, 0},
These errors are caused by the newer versions of MySQL, where mysql.h does not define the type of gptr any longer.
The next logical step was to check the definition of ‘my_option’ and see what types were expected here.
‘my_option’ is a structure defined in <my_getopt.h>, included in main.cpp.
In previous versions of MySQL this was defined as:
struct my_option { const char *name; /* Name of the option */ int id; /* unique id or short option */ const char *comment; /* option comment, for autom. --help */ gptr *value; /* The variable value */ gptr *u_max_value; /* The user def. max variable value */ const char **str_values; /* Pointer to possible values */ ulong var_type; enum get_opt_arg_type arg_type; longlong def_value; /* Default value */ longlong min_value; /* Min allowed value */ longlong max_value; /* Max allowed value */ longlong sub_size; /* Subtract this from given value */ long block_size; /* Value should be a mult. of this */ int app_type; /* To be used by an application */ };
But in newer versions of MySQL it is defined as:
struct my_option { const char *name; /* Name of the option */ int id; /* unique id or short option */ const char *comment; /* option comment, for autom. --help */ uchar **value; /* The variable value */ uchar **u_max_value; /* The user def. max variable value */ struct st_typelib *typelib; /* Pointer to possible values */ ulong var_type; enum get_opt_arg_type arg_type; longlong def_value; /* Default value */ longlong min_value; /* Min allowed value */ longlong max_value; /* Max allowed value */ longlong sub_size; /* Subtract this from given value */ long block_size; /* Value should be a mult. of this */ void *app_type; /* To be used by an application */ };
So we find that:
gptr*
has been replaced byuchar**
The solution was to change the (gptr*) casts in main.cpp to (uchar**).
After the change, trying to compile mysqlcc again, the next error jumped at me:
src/main.cpp:158: warning: deprecated conversion from string constant to 'char*'
This one was simple and caused by the new gcc compiler… Just changed line 158 from:
add_argument(id, "");
to
add_argument(id, (char*)"");
But, trying once more to compile mysqlcc, we get one more error message:
src/main.cpp:118: error: invalid conversion from 'int' to 'void*'
Now, line 118 is actually the end of the structure of my_option lines, so the error is hidden inside.
After re-reading the new and old definitions of my_option I found that:
app_type
was defined asint
and is now defined asvoid*
Knowing this, the error message makes sense, and there is one line (93-95) in the structure that uses a non-zero value. Changing that line from:
{"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, 1},
to:
{"connect_timeout", OPT_CONNECT_TIMEOUT, "", (uchar**) &opt_connect_timeout, (uchar**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, 0, (void*)1},
solved this last error and now mysqlcc built without problems
The result
And yes, the result worked fine as can be seen here:
The patches
Instead of applying all the changes manually, you can use the following file to patch your sources:
--- mysqlcc-0.9.8-src/src/main.cpp 2006-08-11 17:29:12.000000000 -0300 +++ mysqlcc-0.9.8-src_patched/src/main.cpp 2010-06-17 20:49:35.000000000 -0300 @@ -90,28 +90,28 @@ {"version", 'V', "Print version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (gptr*) &opt_connect_timeout, - (gptr*) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, - 0, 1}, + {"connect_timeout", OPT_CONNECT_TIMEOUT, "", (uchar**) &opt_connect_timeout, + (uchar**) &opt_connect_timeout, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3600*12, 0, + 0, (void*)1}, - {"select_limit", OPT_SELECT_LIMIT, "", (gptr*) &select_limit, - (gptr*) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, + {"select_limit", OPT_SELECT_LIMIT, "", (uchar**) &select_limit, + (uchar**) &select_limit, 0, GET_ULONG, REQUIRED_ARG, 1000L, 1, ~0L, 0, 1, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", - (gptr*) &my_net_buffer_length, (gptr*) &my_net_buffer_length, 0, GET_ULONG, + (uchar**) &my_net_buffer_length, (uchar**) &my_net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 512*1024*1024L, 0, 1024, 0}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", - (gptr*) &my_max_allowed_packet, (gptr*) &my_max_allowed_packet, 0, GET_ULONG, + (uchar**) &my_max_allowed_packet, (uchar**) &my_max_allowed_packet, 0, GET_ULONG, REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, 0, 1024, 0}, {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", - (gptr*) &opt_local_infile, - (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + (uchar**) &opt_local_infile, + (uchar**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"max_join_size", OPT_MAX_JOIN_SIZE, "", (gptr*) &max_join_size, - (gptr*) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, + {"max_join_size", OPT_MAX_JOIN_SIZE, "", (uchar**) &max_join_size, + (uchar**) &max_join_size, 0, GET_ULONG, REQUIRED_ARG, 1000000L, 1, ~0L, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -155,7 +155,7 @@ break; } if (opt->var_type == GET_NO_ARG && opt->arg_type == NO_ARG) //Boolean options - add_argument(id, ""); + add_argument(id, (char*)""); else add_argument(id, argument); }
The patch can also be downloaded here.
]]> http://underpop.online.fr/n/nielshorn/2010/06/getting-mysqlcc-to-build-with-newer-gcc-compilers-and-mysql-headers/feed/ 11