From 2243bcd0684f5c4361d3291c9a0e138052f626a9 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 1 Dec 2019 12:29:50 +0200 Subject: Solve the problem of -Wl options emitted by *-config tools See the comment in am/wlelim.m4 for details. The problem was first partially addressed on 2010-02-19 (commit 35ac66f056). This commit provides a generalized solution. * am/gssapi.m4: Allow for "yes" and "probe" argument values. * am/wlelim.m4: New file. Macros for eliminating the -Wl,option flags from shell variables. * configure.ac: Use Wl elimination on LTLIBINTL, LTLIBICONV, MU_AUTHLIBS, SERV_AUTHLIBS, DBMLIBS, and PYTHON_LIBS. Remove the Wl elimination kludge used previously on GSSAPI_LIBS. (MU_LINK_POSTFLAGS): Remove the variable. Fix displaying the status of GSSAPI support * mu/libexec/Makefile.am: Use MU_COMMON_LIBRARIES instead of MU_LINK_POSTFLAGS. --- am/gssapi.m4 | 15 ++--- am/wlelim.m4 | 147 +++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 73 +++++++++++------------- mu/libexec/Makefile.am | 2 +- 4 files changed, 188 insertions(+), 49 deletions(-) create mode 100644 am/wlelim.m4 diff --git a/am/gssapi.m4 b/am/gssapi.m4 index 8e4f5d709..ed25ddabf 100644 --- a/am/gssapi.m4 +++ b/am/gssapi.m4 @@ -14,11 +14,10 @@ AC_DEFUN([MU_CHECK_GSSAPI], GSSAPI_PREFIX=[$1] GSSAPI_IMPL="none" # First try krb5-config - if test "$GSSAPI_PREFIX" != "yes"; then - krb5_path="$GSSAPI_PREFIX/bin" - else - krb5_path="$PATH" - fi + case $GSSAPI_PREFIX in + yes|probe) krb5_path="$PATH";; + *) krb5_path="$GSSAPI_PREFIX/bin" + esac AC_PATH_PROG(KRB5CFGPATH, krb5-config, none, $krb5_path) AC_CHECK_HEADER(gss.h, [wantgss=yes], [wantgss=no]) if test $wantgss != no; then @@ -47,12 +46,14 @@ int main() { return gss_check_version ("0.0.9") == (char*) 0; }], saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" saved_LIBS="$LIBS" - if test "$GSSAPI_PREFIX" != "yes"; then + case $GSSAPI_PREFIX in + yes|probe) ;; + *) GSSAPI_CFLAGS="-I$GSSAPI_PREFIX/include" GSSAPI_LDFLAGS="-L$GSSAPI_PREFIX/lib" CPPFLAGS="$CPPFLAGS $GSSAPI_CFLAGS" LDFLAGS="$LDFLAGS $GSSAPI_LDFLAGS" - fi + esac ## Check for new MIT kerberos V support AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, diff --git a/am/wlelim.m4 b/am/wlelim.m4 new file mode 100644 index 000000000..4a87feb13 --- /dev/null +++ b/am/wlelim.m4 @@ -0,0 +1,147 @@ +dnl This file is part of GNU mailutils. +dnl Copyright (C) 2019 Free Software Foundation, Inc. +dnl +dnl GNU Mailutils is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl GNU Mailutils is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Mailutils. If not, see . + +# Some packages provide configuration helper tools that emit the cc +# flags to be used when linking a program with that package. Normally +# the output of such a tool consists of a series of -l (eventualy -L) +# options in the right order. However, some tools thoughtlessly emit +# linker options (-Wl,option) as well. The most notorious example of +# these is krb5-config. Such options cannot be reliably used with +# libtool. The `-Wl,-rpath -Wl,DIR' option is particularly harmful. +# When creating the wrapper script for a program, libtool adds all DIRs +# given to it with the -rpath options to the beginning of the installation +# library directory list. When the wrapper relinks the program for local +# use (e.g. in testsuite), it will append the path in the source tree to +# that list *after* all these rpaths. As a result, when running the +# program, it will pick the libraries installed in the system instead of +# their local versions from the source tree. +# +# This module provides macros for eliminating the -Wl options from the +# shell variables. +# +# Obviously, libtool should be fixed to place rpaths from the source tree +# before any other directories. +# +# For the record, there are also other issues that can cause wrong libraries +# to be used on some systems. See, for example this libtool bug report: +# https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27510 +# This issue has not been addressed yet. + +dnl MU_WLELIM_INIT +dnl -------------- +dnl Initialize the Wl elimination procedure by emitting auxiliary shell +dnl functions used in it. +dnl Normally you don't need to use this macro explicitly, as it will be +dnl called exactly once by the first expansion of the MU_WLELIM_VAR or +dnl MU_WLELIM_SUBST (see below). +AC_DEFUN([MU_WLELIM_INIT],[ +m4_ifdef([MU_WLELIM_INIT_SENTINEL],[], +[# The following three functions were inspired by libtool. + +# func_append VAR STRING +# ---------------------- +# Append STRING to the value of the variable VAR. Unless VAR is empty +# or undefined, precede STRING with a single space +func_append() +{ + eval "@S|@1=\@S|@@S|@1\@S|@{@S|@1:+ }\@S|@2" +} + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"@S|@\\]\)|\\\1|g' + +# func_quote_for_eval ARG... +# -------------------------- +# Quote ARGs to be evaled later. Leave return in the variable +# func_quote_for_eval_result. +func_quote_for_eval() +{ + func_quote_for_eval_result= + for arg + do + case @S|@arg in + *[\\\`\"\@S|@]*) + _G_arg=`echo "@S|@arg" | @S|@{SED:-sed} "@S|@sed_quote_subst"` ;; + *) + _G_arg=@S|@1 ;; + esac + func_append func_quote_for_eval_result "@S|@_G_arg" + done +} + +# func_append_quoted VAR STRING +# ----------------------------- +# Append space character and STRING to the value of the variable VAR. +# Take care to properly quote the STRING, so that @S|@VAR will be evaled +# correctly. +func_append_quoted() +{ + func_quote_for_eval "@S|@2" + eval "@S|@1=\@S|@@S|@1\\ \@S|@func_quote_for_eval_result" +} + +# func_elim_linker_options2 VAR ARG... +# ------------------------------------ +# Eliminate ARGs that contain linker command line options (-Wl,...). +# Append the remaining ones to the value of the variable VAR. +func_elim_linker_options2() +{ + elim_linker_options_var=@S|@1 + shift + eval @S|@elim_linker_options_var= + for opt + do + case @S|@opt in + -Wl,*) ;; + *) func_append_quoted @S|@elim_linker_options_var "@S|@opt" + esac + done +} + +# func_elim_linker_options VAR +# ---------------------------- +# Eliminate linker command line options from the value of the variable +# VAR. +func_elim_linker_options() +{ + eval func_elim_linker_options2 @S|@1 \@S|@@S|@1 +} +m4_define([MU_WLELIM_INIT_SENTINEL],[TRUE])]) +]) + +dnl MU_WLELIM_VAR(VARNAME) +dnl ---------------------- +dnl Mark shell variable VARNAME as needing linker option elimination. +AC_DEFUN([MU_WLELIM_VAR],[MU_WLELIM_INIT +m4_set_add(mu_linker_substvars,$1)]) + +dnl MU_WLELIM_SUBST(VARNAME) +dnl ------------------------ +dnl AC_SUBST the variable VARNAME and mark it as needing linker option +dnl elimination. +AC_DEFUN([MU_WLELIM_SUBST],[AC_SUBST($@) +MU_WLELIM_VAR($1)]) + +dnl MU_WLELIM_COMMIT +dnl ---------------- +dnl Commit the changes by eliminating the linker options from all variables +dnl collected so far. +AC_DEFUN([MU_WLELIM_COMMIT],[m4_set_foreach(mu_linker_substvars,VAR, + [func_elim_linker_options VAR +])]) + +dnl END of wlelim.m4 diff --git a/configure.ac b/configure.ac index 1a2f459db..16669dd9c 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,8 @@ dnl Other variables AC_SUBST(mu_aux_dir,'$(top_srcdir)/mu-aux') AC_SUBST(MU_SIEVE_MODDIR,'$(libdir)/$(PACKAGE)') +MU_WLELIM_VAR([LTLIBINTL]) +MU_WLELIM_VAR([LTLIBICONV]) AC_SUBST(MU_COMMON_LIBRARIES,'$(LTLIBINTL) $(LTLIBICONV)') AC_SUBST(MU_APP_LIBRARIES,'${top_builddir}/lib/libmuaux.la') @@ -121,9 +123,6 @@ AH_BOTTOM([ #define DEFAULT_TEXT_DOMAIN PACKAGE ]) -AC_SUBST(MU_LINK_POSTFLAGS,[`for opt in $LTLIBICONV; do case $opt in -[[lL]]*) echo $opt;; esac; done|tr '\n' ' '`]) - - # Check for large file support AC_SYS_LARGEFILE @@ -161,7 +160,7 @@ AC_ARG_ENABLE([experimental], # Initialize authlibs -AC_SUBST(MU_AUTHLIBS) +MU_WLELIM_SUBST(MU_AUTHLIBS) AC_SUBST(MU_AUTHINCS) dnl Check for arguments @@ -236,50 +235,37 @@ case "${withval}" in *) AC_MSG_ERROR(bad value ${withval} for --without-readline) ;; esac],[status_readline=probe]) -AC_SUBST(SERV_AUTHLIBS) +MU_WLELIM_SUBST(SERV_AUTHLIBS) AC_SUBST(SERV_AUTHINCS) AC_ARG_WITH([gssapi], AC_HELP_STRING([--with-gssapi@<:@=PATH@:>@], [use GSSAPI authentication]), [status_gssapi=$withval], - [status_gssapi=no]) + [status_gssapi=probe]) -if test "x$status_gssapi" != "xno"; then +if test "$status_gssapi" != "no"; then MU_CHECK_GSSAPI($status_gssapi) if test "$GSSAPI_IMPL" = "none"; then AC_CACHE_SAVE AC_MSG_RESULT([GSSAPI libraries not found]) + if test "$status_gsapi" = probe; then + status_gssapi=no + else + AC_MSG_FAILURE([The requested GSSAPI library not found or is unusable]) + fi else - # Output produced by `krb5-config --libs' may contain `-Wl,-rpath -Wl,DIR' - # options. Once they are added to SERV_AUTHLIBS, libtool, when creating - # relink command line in wrapper files for executables, places them at the - # beginnig of the option list and adds its own -rpath directives at - # the end. Executables created by such command will look for the runtime - # libraries first in DIR and then in the local tree subdirectories. Thus, - # if DIR contains libraries from a previous installation of Mailutils, the - # programs will use old libraries. - # - # Obviously, libtool should be fixed to place user-added -rpath directives - # after the ones added by it. For the time being I work around this bug by - # removing any -Wl directives from GSSAPI_LIBS. - # - for arg in $GSSAPI_LIBS - do - case $arg in - -Wl,*) ;; - *) SERV_AUTHLIBS="$SERV_AUTHLIBS $arg" - esac - done - SERV_AUTHINCS="$SERV_AUTHINCS $GSSAPI_CFLAGS" + SERV_AUTHLIBS="${SERV_AUTHLIBS}${SERV_AUTHLIBS:+ }$GSSAPI_LIBS" + SERV_AUTHINCS="${SERV_AUTHINCS}${SERV_AUTHINCS:+ }$GSSAPI_CFLAGS" AC_DEFINE(WITH_GSSAPI,1,[Define if mailutils is using GSSAPI]) + status_gssapi=yes fi fi AM_CONDITIONAL([MU_COND_GSSAPI],[test "$status_gssapi" = "yes"]) MU_CHECK_GSASL(0.2.3, [ AC_DEFINE(WITH_GSASL,1,[Define if mailutils is using GNU SASL]) - MU_AUTHLIBS="$MU_AUTHLIBS $GSASL_LIBS" + MU_AUTHLIBS="${MU_AUTHLIBS}${MU_AUTHLIBS:+ }$GSASL_LIBS" status_gsasl=yes]) AM_CONDITIONAL([MU_COND_GSASL],[test "$status_gsasl" = "yes"]) @@ -295,7 +281,7 @@ AC_ARG_WITH(cram-passwd, esac]) MU_CHECK_GNUTLS([1.2.1],[ - MU_AUTHLIBS="$MU_AUTHLIBS $TLS_LIBS" + MU_AUTHLIBS="${MU_AUTHLIBS}${MU_AUTHLIBS:+ }$TLS_LIBS" AC_DEFINE(WITH_GNUTLS,1,[Define if mailutils is using GNU TLS]) AC_DEFINE(WITH_TLS,1,[Define if mailutils is using TLS]) status_gnutls=yes @@ -348,7 +334,7 @@ AH_BOTTOM( ################################## # DBM Support ################################## -AC_SUBST(DBMLIBS) +MU_WLELIM_SUBST(DBMLIBS) AC_SUBST(DBMINCLUDES) enable_dbm= @@ -797,7 +783,7 @@ AC_DEFUN([MU_SQL_LDADD],[ if test "$USE_LOADABLE_MODULES" = yes; then $1=$2 else - SQLLIB="$SQLLIB $2" + SQLLIB="${SQLLIB}${SQLLIB:+ }$2" fi ]) @@ -939,9 +925,9 @@ if test -n "$SQL_MODULES"; then do ${module:-dummy}_init if test $USE_LOADABLE_MODULES = yes; then - SQL_LOADABLE_MODULES="$SQL_LOADABLE_MODULES ${module}.la" + SQL_LOADABLE_MODULES="${SQL_LOADABLE_MODULES}${SQL_LOADABLE_MODULES:+ }${module}.la" else - SQL_LIBOBJS="$SQL_LIBOBJS ${module}.o" + SQL_LIBOBJS="${SQL_LIBOBJS}${SQL_LIBOBJS:+ }${module}.o" fi done S=`echo "$SQL_LIBOBJS" | @@ -974,7 +960,7 @@ if test $status_ldap = maybe; then AC_CHECK_LIB(ldap, ldap_bind,[ status_ldap=yes AC_DEFINE(WITH_LDAP, 1, [Define to 1 if you want to use -lldap]) - MU_AUTHLIBS="$MU_AUTHLIBS -lldap"], + MU_AUTHLIBS="${MU_AUTHLIBS}${MU_AUTHLIBS:+ }-lldap"], [status_ldap=no]) fi @@ -1020,7 +1006,7 @@ MU_ENABLE_SUPPORT(prog) # FIXME: Should be --with-radius MU_ENABLE_SUPPORT(radius, [AM_GNU_RADIUS(1.6, - [MU_AUTHLIBS="$MU_AUTHLIBS -lgnuradius" + [MU_AUTHLIBS="${MU_AUTHLIBS}${MU_AUTHLIBS:+ }-lgnuradius" mu_cv_enable_radius=yes], [mu_cv_enable_radius=no])]) @@ -1029,7 +1015,7 @@ if test x"$testpam" = x"yes"; then if test x"$ac_cv_header_security_pam_appl_h" = x"yes"; then AC_CHECK_LIB(dl, dlopen, [LDL=-ldl], [LDL=]) AC_CHECK_LIB(pam, pam_start, - [MU_AUTHLIBS="$MU_AUTHLIBS -lpam $LDL" + [MU_AUTHLIBS="${MU_AUTHLIBS}${MU_AUTHLIBS:+ }-lpam $LDL" ac_cv_have_libpam="yes"],, $LDL) AC_DEFINE(USE_LIBPAM,1,[Enable use of PAM]) status_pam=yes @@ -1215,7 +1201,7 @@ case "${enableval}" in *) AC_MSG_ERROR(bad value ${enableval} for --enable-python) ;; esac],[status_python=yes]) -AC_SUBST(PYTHON_LIBS) +MU_WLELIM_SUBST(PYTHON_LIBS) AC_SUBST(PYTHON_INCLUDES) AC_SUBST(PYTHON_MAJOR) @@ -1326,9 +1312,12 @@ MU_ENABLE_BUILD(pop3d,,,["$mu_build_servers" = yes],,[server_list]) MU_ENABLE_BUILD(imap4d,,,["$mu_build_servers" = yes],,[server_list]) MU_ENABLE_BUILD(comsat,,,["$mu_build_servers" = yes],,[server_list]) -MU_ENABLE_BUILD(mda,[mu_build_mda_tools=yes],,["$mu_build_servers" = yes],,[server_list]) -MU_ENABLE_BUILD(lmtpd,[mu_build_mda_tools=yes],,["$mu_build_servers" = yes],,[server_list]) -MU_ENABLE_BUILD(putmail,[mu_build_mda_tools=yes],,["$mu_build_clients" = yes],,[client_list]) +MU_ENABLE_BUILD(mda,[mu_build_mda_tools=yes],, + ["$mu_build_servers" = yes],,[server_list]) +MU_ENABLE_BUILD(lmtpd,[mu_build_mda_tools=yes],, + ["$mu_build_servers" = yes],,[server_list]) +MU_ENABLE_BUILD(putmail,[mu_build_mda_tools=yes],, + ["$mu_build_clients" = yes],,[client_list]) AM_CONDITIONAL([MU_COND_MDA_TOOLS],[test "$mu_build_mda_tools" = yes]) MU_ENABLE_BUILD(frm,,,["$mu_build_clients" = yes],,[client_list]) @@ -1405,6 +1394,8 @@ if test -z "$PERL"; then fi AC_SUBST([GITINFO],'$(PERL) $(mu_aux_dir)/gitinfo') +MU_WLELIM_COMMIT + AC_CONFIG_COMMANDS([status],[ cat <