Bug 80915

Summary: MySQL port building requires -O on 4.x releases and 4-STABLE
Product: Ports & Packages Reporter: Clifton Royston <cliftonr>
Component: Individual Port(s)Assignee: Alex Dupre <ale>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   

Description Clifton Royston 2005-05-11 21:50:00 UTC
  /usr/ports/databases/mysql41-server and
  /usr/ports/databases/mysql40-server
do *not* build on 4.x systems unless *some* level of optimization is
turned on.

  'CFLAGS='  fails on 4.x releases;
  'CFLAGS=-O' works. (as does -O -pipe and probably higher levels.)

  Not tested on 5-STABLE.

  The "failure" result in this case is for the link step of executing "make" or "make install" in the ports directory to bomb with a huge stream of "undefined reference" errors at the link step for mysqld.
Example output is given below.

  I'm guessing that the machines where ports building is tested may have
'-O -pipe' or similar as a minimum setting.  However /etc/make.conf has
no default setting for CFLAGS, so with the "out of box" default
settings of everything the build of this port will consistently fail.

  The problem appears to be, from some cursory digging through the
sources, that a number of MySQL functions including MySQL's internal
interfaces to the thread libraries are defined only via inlining if the
OS *platform* is known to support it, but inlining is not actually
enabled (at least in GCC 2.95) unless -O or better is set.

  I tracked this down once I realized that the key difference between
the system where I could build it and the system where I couldn't was
that the former's /etc/make.conf was heavily customized, and the
latter's was untouched except for the variables set by "use.perl ports".

Fix: 

(Untested) Add to port Makefile  /usr/ports/databases/mysql41-server/Makefile 
an else clause to existing test:

.if defined(BUILD_OPTIMIZED)
CFLAGS+=        -O3 -fno-omit-frame-pointer
 [...]
.endif

as follows:

.else
CFLAGS+= -O
.endif

  The same fix also appears to be needed for /usr/ports/databases/mysql40-server/Makefile
How-To-Repeat:       Set /etc/make.conf to empty (or minimal file); optionally deinstall or pkg_delete any mysql packages installed; cd to /usr/ports/databases/mysql41-server/

# cp /dev/null /etc/make.conf
# cd /usr/ports/databases/mysql41-server/
# make NOCLEANDEPENDS=yes FORCE_PKG_REGISTER=yes clean install

  After a considerable compilation time, you should see the near-final link step bomb out with hundreds of unresolved reference lines:
Making all in share
/usr/local/bin/libtool15 --preserve-dup-deps --mode=link cc  -DDBUG_OFF  -DNEWSALT  -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -DNEWSALT  -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -felide-constructors -fno-rtti -fno-exceptions   -fno-implicit-templates -fno-exceptions -fno-rtti -DMYSQLD_NET_RETRY_COUNT=1000000
-o mysqld  sql_lex.o sql_handler.o  item.o item_sum.o item_buff.o  item_func.o i-o mysqld  sql_lex.o sql_handler.o  item.o item_sum.o item_buff.o  item_func.o item_cmpfunc.o  item_strfunc.o item_timefunc.o  thr_malloc.o item_create.o  item_subselect.o item_row.o  item_geofunc.o field.o strfunc.o  key.o sql_class.o sql_list.o  net_serv.o protocol.o sql_state.o  lock.o my_lock.o sql_string.o  sql_manager.o sql_map.o mysqld.o  password.o hash_filo.o hostname.o  set_var.o sql_parse.o sql_yacc.o  sql_base.o table.o sql_select.o  sql_insert.o sql_prepare.o sql_error.o  sql_update.o sql_delete.o uniques.o  sql_do.o procedure.o item_uniq.o sql_test.o log.o log_event.o  init.o derror.o sql_acl.o  unireg.o des_key_file.o discover.o  time.o opt_range.o opt_sum.o  records.o filesort.o handler.o  ha_heap.o ha_myisam.o ha_myisammrg.o  ha_berkeley.o ha_innodb.o ha_isam.o  ha_isammrg.o ha_ndbcluster.o sql_db.o  sql_table.o sql_rename.o sql_crypt.o  sql_load.o mf_iocache.o field_conv.o  sql_s
 how.o sql_udf.o sql_analyse.o  sql_cache.o slave.o sql_repl.o  sql_union.o sql_derived.o client.o  sql_client.o mini_client_errors.o  pack.o stacktrace.o repl_failsafe.o  gstream.o spatial.o sql_help.o  protocol_cursor.o tztime.o my_time.o  ha_example.o ha_archive.o ha_tina.o  ha_blackhole.o -L../bdb/build_unix -ldb  ../innobase/usr/libusr.a ../innobase/srv/libsrv.a
./innobase/dict/libdict.a ../innobase/que/libque.a ../innobase/srv/libsrv.a ../innobase/ibuf/libibuf.a ../innobase/row/librow.a ../innobase/pars/libpars.a ../innobase/btr/libbtr.a ../innobase/trx/libtrx.a ../innobase/read/libread.a ../innobase/usr/libusr.a ../innobase/buf/libbuf.a ../innobase/ibuf/libibuf.a ../innobase/eval/libeval.a ../innobase/log/liblog.a ../innobase/fsp/libfsp.a ../innobase/fut/libfut.a ../innobase/fil/libfil.a ../innobase/lock/liblock.a ../innobase/mtr/libmtr.a ../innobase/page/libpage.a ../innobase/rem/librem.a ../innobase/thr/libthr.a ../innobase/sync/libsync.a ../innobase/data/libdata.a ../innobase/mach/libmach.a ../innobase/ha/libha.a ../innobase/dyn/libdyn.a ../innobase/mem/libmem.a
./innobase/sync/libsync.a ../innobase/ut/libut.a ../innobase/os/libos.a ../innobase/ut/libut.a     ../myisam/libmyisam.a  ../myisammrg/libmyisammrg.a  ../heap/libheap.a  ../vio/libvio.a  ../mysys/libmysys.a  ../dbug/libdbug.a  ../regex/libregex.a  ../strings/libmystrings.a -lz   -lwrap -DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -L/usr/local/lib -l
lthread -llgcc_r -lcrypt -lm  -DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE
 -I/usr/local/include/pthread/linuxthreads -L/usr/local/lib -llthread -llgcc_r
cc -DDBUG_OFF -DNEWSALT -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -DNEWSALT -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -felide-constructors -fno-rtti -fno-exceptions -fno-implicit-templates -fno-exceptions -fno-rtti -DMYSQLD_NET_RETRY_COUNT=1000000 -o mysqld sql_lex.o sql_handler.o item.o item_sum.o item_buff.o item_func.o item_cmpfunc.o item_strfunc.o item_timefunc.o thr_malloc.o item_create.o item_subselect.o item_row.o item_geofunc.o field.o strfunc.o key.o sql_class.o sql_list.o net_serv.o protocol.o sql_state.o lock.o my_lock.o sql_string.o sql _manager.o sql_map.o mysqld.o password.o hash_filo.o hostname.o set_var.o sql_parse.o sql_yacc.o sql_base.o table.o sql_select.o sql_insert.o sql_prepare.o sql_error.o sql_update.o sql_delete.o uniques.o sql_do.o procedure.o item_uniq.o sql_test.o log.o log_event.o init.o derror.o sql_acl.o unireg.o des_key_file.o discover.o time.o opt_range.o opt
 _sum.o records.o filesort.o handler.o ha_heap.o ha_myisam.o ha_myisammrg.o ha_berkeley.o ha_innodb.o ha_isam.o ha_isammrg.o ha_ndbcluster.o sql_db.o sql_table.o sql_rename.o sql_crypt.o sql_load.o mf_iocache.o field_conv.o sql_show.o sql_udf.o sql_analyse.o sql_cache.o slave.o sql_repl.o sql_union.o sql_derived.o client.o sql_client.o mini_client_errors.o pack.o stacktrace.o repl_failsafe.o gstream.o spatial.o sql_help.o protocol_cursor.o tztime.o my_time.o ha_example.o ha_archive.o ha_tina.o ha_blackhole.o -DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads  -L/usr/ports/databases/mysql41-server/work/mysql-4.1.11/bdb/build_unix
-ldb ../innobase/usr/libusr.a ../innobase/srv/libsrv.a ../innobase/dict/libdict.a ../innobase/que/libque.a ../innobase/srv/libsrv.a ../innobase/ibuf/libibuf.a ../innobase/row/librow.a ../innobase/pars/libpars.a ../innobase/btr/libbtr.a ../innobase/trx/libtrx.a ../innobase/read/libread.a ../innobase/usr/libusr.a ../inno
base/buf/libbuf.a ../innobase/ibuf/libibuf.a ../innobase/eval/libeval.a ../innobase/log/liblog.a ../innobase/fsp/libfsp.a ../innobase/fut/libfut.a ../innobase/fil/libfil.a ../innobase/lock/liblock.a ../innobase/mtr/libmtr.a ../innobase/page
/libpage.a ../innobase/rem/librem.a ../innobase/thr/libthr.a ../innobase/sync/libsync.a ../innobase/data/libdata.a ../innobase/mach/libmach.a ../innobase/ha/libha.a ../innobase/dyn/libdyn.a ../innobase/mem/libmem.a ../innobase/sync/libsync.a ../innobase/ut/libut.a ../innobase/os/libos.a ../innobase/ut/libut.a ../myisam/libmyisam.a ../myisammrg/libmyisammrg.a ../heap/libheap.a ../vio/libvio.a ../mysys/libmysys.a ../dbug/libdbug.a ../regex/libregex.a ../strings/libmystrings.a -lz -lwrap -L/usr/local/lib -llthread -llgcc_r -lcrypt -lm -llthread -llgcc_r
./innobase/srv/libsrv.a(srv0srv.o): In function `srv_get_n_threads':
srv0srv.o(.text+0x2a1): undefined reference to `mutex_enter_func'
srv0srv.o(.text+0x2de): undefined reference to `mutex_exit'
./innobase/srv/libsrv.a(srv0srv.o): In function `srv_get_thread_type':
srv0srv.o(.text+0x89a): undefined reference to `mutex_enter_func'
srv0srv.o(.text+0x8e0): undefined reference to `mutex_exit'
./innobase/srv/libsrv.a(srv0srv.o): In function `srv_init':
srv0srv.o(.text+0x90a): undefined reference to `mem_alloc_func'

(and so on for page after page of output.)
  Same problem also observed with /usr/ports/databases/mysql40-server/

  The same problem should also be seen with or without WITH_LINUXTHREADS=yes
Comment 1 Pav Lucistnik freebsd_committer freebsd_triage 2005-05-20 19:09:15 UTC
Responsible Changed
From-To: freebsd-ports-bugs->ale

Over to maintainer to decide 

In my opinion, if someone changes default CFLAGS, he knows what he's doing 
and should be ready to bear consequences. I don't think port should hold 
user's hand 

Plus included patch will kill any user provided optimizations, like -O2 or -O3.
Comment 2 cliftonr 2005-06-10 19:14:05 UTC
pav:

I believe your comments indicate that you misunderstood the PR
(ports/80915); in fact you read it backwards, so to speak.  

The port is *broken* with the *default* CFLAGS value (which is empty).

The port *only* works if you *change* CFLAGS to a *non-default* setting
which includes -O.  That is not the official default setting.

The problem is masked for many advanced FreeBSD users, who will have
edited their /etc/make.conf at some point to turn on -O -pipe and then
forgotten about it.  I suspect that's why it wasn't discovered before
now.

That is why my instructions for reproducing the bug begin by telling
you to get rid of all customizations in /etc/make.conf.  Please try
actually reproducing this on a clean install of 4.x and you will see
what I mean.

I agree with you it's perfectly acceptable for a port to break if
you've done custom tweaks to your make settings.  It's not acceptable
for a port to *require* custom tweaks to your make settings, especially
if it doesn't tell you about it.  

(The failure symptoms in this case are particularly mystifying too.  It
required several weeks of off-and-on tinkering and quite a leap of
imagination to get from what appears to be a link problem with
libraries to a compiler optimization setting.)

  -- Clifton

-- 
          Clifton Royston  --  cliftonr@tikitechnologies.com 
         Tiki Technologies Lead Programmer/Software Architect
"I'm gonna tell my son to grow up pretty as the grass is green
And whip-smart as the English Channel's wide..."
                                            -- 'Whip-Smart', Liz Phair
Comment 3 Alex Dupre freebsd_committer freebsd_triage 2005-06-14 14:32:22 UTC
State Changed
From-To: open->closed

CFLAGS is set by default to -O -pipe. 
Setting it to null (empty string) in make.conf is not a default behaviour.