Wednesday, October 11, 2006

MySQL Benchmarking 4: Compiling Super-Smack on Solaris 10

I hate to start the blog post with the same "I've been really busy excuse" but honestly that's the truth. Ever since I wrote the last post, one important thing happened to me. My dentist prescribed me a mouth wash and it turned out that I was severely allergic to it. My upper lip became extremely swollen and remained like that for couple of days until I got a shot of steroid. Ughh, it was really painful. Anyways, time has just been flying by and I have a lot of catching up to do.

This is the part 4 of MySQL Benchmarking series. In the last post I showed you how you can compile Sysbench on Solaris 10. In this post, I will be showing you how you can compile Super-Smack on Solaris 10.

MySQL Super Smack was originally developed by Sasha Pachev (sasha at surveypro dot com), a former MySQL employee. After Sasha, Jeremy Zawodny of Yahoo! took over the maintenance of Super Smack. When Jeremey got really busy with Yahoo! stuff, Tony Bourke took over the Super Smack project.

Getting Super Smack to compile on Solaris 10 was really a headache even though a Sun blog post claimed it wasn't. Nonetheless, I finally succeeded with the help of Andy.

Download Super Smack source (the current version is 1.3).
wget http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz


Navigate to the directory and then uncompress and extract the software
gunzip super-smack-1.3.tar.gz

tar -xf super-smack-1.3.tar


Now set your environment as follows.
LDFLAGS=-lsocket -lnsl -lm
LD_LIBRARY_PATH=/usr/local/mysql/lib:/usr/ccs/lib:/usr/lib:/usr/local/lib:/lib:/usr/ucblib
PATH=/usr/bin:/usr/sbin:/usr/sfw/bin:/usr/ccs/bin:/opt/SUNWspro/bin:/usr/sbin:/usr/bin:/usr/local/bin:.:/usr/ccs/bin:/usr/local/mysql/bin
CXX=/usr/local/bin/g++
CFLAGS=-xarch=v9
CC=/opt/SUNWspro/bin/cc
CXXFLAGS=-m64

Depending on your compiler you may need the following instead
CFLAGS=-m64


Before continuing, ensure you have SUNWflexlex installed and /usr/sfw/bin in your path.

Next step is to run configure

[root@db:/home/fmashraqi/install/bench/super-smack-1.3] ./configure --with-mysql
checking for a BSD-compatible install... ./install-sh -c
checking whether build environment is sane... yes
checking whether make sets $(MAKE)... yes
checking for working aclocal... missing
checking for working autoconf... missing
checking for working automake... missing
checking for working autoheader... missing
checking for working makeinfo... missing
checking for sh... /bin/bash
checking for gcc... /opt/SUNWspro/bin/cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... no
checking whether /opt/SUNWspro/bin/cc accepts -g... yes
checking for /opt/SUNWspro/bin/cc option to accept ANSI C... none needed
checking whether we are using the GNU C++ compiler... yes
checking whether /usr/local/bin/g++ accepts -g... yes
checking how to run the C preprocessor... /opt/SUNWspro/bin/cc -E
checking for a BSD-compatible install... ./install-sh -c
checking whether ln -s works... yes
checking for flex... flex
checking for flex... (cached) flex
checking for yywrap in -lfl... no
checking for yywrap in -ll... yes
checking lex output file root... lex.yy
checking whether yytext is a pointer... yes
checking for bison... no
checking for byacc... no
checking for compress in -lz... yes
checking for crypt in -lcrypt... yes
checking for crypt... yes
checking for libmysqlclient...
checking for mysql_real_connect in -lmysqlclient... yes
checking for mysql.h...
checking for egrep... egrep
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for unistd.h... (cached) yes
checking whether time.h and sys/time.h may both be included... yes
checking return type of signal handlers... void
checking for gettimeofday... yes
checking for strerror... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing default-1 commands

Building with the following options:

MySQL Support..................... yes
PostgreSQL Support................ no
Oracle Support.................... no

If this is not what you intended, please re-run configure.

Thanks for using super-smack!


Now edit the src/Makefile and add
-lsocket -lnsl

to
LIBS = -L/usr/local/mysql/lib -lcrypt -lz  -lsocket -lnsl


Now run make. It will fail.

make  all-recursive
Making all in src
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c super-smack.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c client.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c engines.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c die.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c dictionary.cc
yacc -d super-smack-yacc.yy && mv y.tab.c super-smack-yacc.cc
if test -f y.tab.h; then if cmp -s y.tab.h super-smack-yacc.h; then rm -f y.tab.h; else mv
y.tab.h super-smack-yacc.h; fi; else :; fi
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c super-smack-yacc.cc
flex super-smack-lex.ll && mv lex.yy.c super-smack-lex.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c super-smack-lex.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c query.cc
query.cc: In member function `void Query_report::fd_send(int)':
query.cc:200: warning: cast from pointer to integer of different size
query.cc:200: warning: cast from pointer to integer of different size
query.cc:219: warning: cast from pointer to integer of different size
query.cc:219: warning: cast from pointer to integer of different size
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c parse.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c libsmack.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c mysql-client.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c pg-client.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c ora-client.cc
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c tcp_client.cc
In file included from tcp_client.cc:2:
tcp_client.h: In member function `TcpClient::operator void*()':
tcp_client.h:58: warning: cast to pointer from integer of different
size
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o super-smack
super-smack.o client.o engines.o die.o dictionary.o
super-smack-yacc.o super-smack-lex.o query.o parse.o libsmack.o
mysql-client.o pg-client.o ora-client.o tcp_client.o
-L/usr/local/mysql/lib -lmysqlclient -L/usr/local/mysql/lib -lcrypt
-lz -lsocket -lnsl
Undefined first referenced
symbol in file
yyerror(char const*) super-smack-yacc.o
ld: fatal: Symbol referencing errors. No output written to
super-smack
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `super-smack'
Current working directory
/home/fmashraqi/install/bench/super-smack-1.3/src
*** Error code 1
The following command caused the error:
set fnord ; amf=$2; dot_seen=no; target=`echo all-recursive | sed s/-recursive//`; list='src'; for subdir in $list; do echo "Making $target in $subdir"; if test "$subdir" = "."; then dot_seen=yes; local_target="$target-am"; else local_target="$target"; fi; (cd $subdir && make $local_target) || case "$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac;
done; if test "$dot_seen" = "no"; then make "$target-am" || exit 1; fi; test -z "$fail"
make: Fatal error: Command failed for target `all-recursive'
Current working directory
/home/fmashraqi/install/bench/super-smack-1.3
*** Error code 1
make: Fatal error: Command failed for target `all-recursive-am'


When it does fail, edit the following line (around 107) of super-smack-yacc.cc and search for
YYCONST
and remove it.

Before:
void yyerror(YYCONST char *);


End:
void yyerror(char *);


Then run make again and then make install.

Running make:

make  all-recursive
Making all in src
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c super-smack-yacc.cc
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o super-smack
super-smack.o client.o engines.o die.o dictionary.o
super-smack-yacc.o super-smack-lex.o query.o parse.o libsmack.o
mysql-client.o pg-client.o ora-client.o tcp_client.o
-L/usr/local/mysql/lib -lmysqlclient -L/usr/local/mysql/lib -lcrypt
-lz -lsocket -lnsl
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c gen-data.cc
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o gen-data gen-data.o
die.o -L/usr/local/mysql/lib -lcrypt -lz -lsocket -lnsl
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c test-dictionary.cc
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o test-dictionary
test-dictionary.o dictionary.o die.o libsmack.o
-L/usr/local/mysql/lib -lcrypt -lz -lsocket -lnsl
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c test-client.cc
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o test-client
test-client.o client.o engines.o die.o dictionary.o query.o
libsmack.o mysql-client.o pg-client.o ora-client.o
-L/usr/local/mysql/lib -lmysqlclient -L/usr/local/mysql/lib -lcrypt
-lz -lsocket -lnsl
/usr/local/bin/g++ -DHAVE_CONFIG_H -I. -I. -I..
-I/usr/local/mysql/include -m64 -c test_tcp_client.cc
In file included from test_tcp_client.cc:1:
tcp_client.h: In member function `TcpClient::operator void*()':
tcp_client.h:58: warning: cast to pointer from integer of different
size
/usr/local/bin/g++ -m64 -lsocket -lnsl -lm -o test_tcp_client
test_tcp_client.o tcp_client.o -L/usr/local/mysql/lib -lcrypt -lz
-lsocket -lnsl


Now run make install
Making install in src
/bin/bash ../mkinstalldirs /usr/local/bin
.././install-sh -c super-smack /usr/local/bin/super-smack
.././install-sh -c gen-data /usr/local/bin/gen-data
/bin/bash ./mkinstalldirs /usr/share/smacks /var/smack-data
cp -rp ./smacks/* /usr/share/smacks


Super Smack should build compile fine now. However when you will try to run it, you will get "wrong ELFClass errors"

$ super-smack
ld.so.1: super-smack: fatal: /usr/local/lib/libstdc++.so.5: wrong ELF
class: ELFCLASS32
Killed


This is because of a 32 bit libstdc++.so being used

[root@db:/home/fmashraqi/install/bench/super-smack-1.3] file /usr/local/bin/super-smack
/usr/local/bin/super-smack: ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, not stripped
[root@db:/home/fmashraqi/install/bench/super-smack-1.3] file /usr/local/lib/libstdc++.so
/usr/local/lib/libstdc++.so: ELF 32-bit MSB dynamic lib SPARC Version 1, dynamically linked, not stripped


To correct the error, we need to use an alternative 64-bit libstdc++.so
crle -64 -u -l /usr/local/lib/sparcv9


on your system this may be (but the above worked for me)
crle -64 -u -l /usr/sfw/lib/sparcv9


You can also try modifying LIBS environment variable to avoid the above crle stuff.

LIBS=-R/usr/sfw/lib/sparcv9 -R/usr/local/mysql/lib -lnsl -lsocket


At this point Super Smack should be working.

Stay tuned as in future we will be putting all these tools to some good use.