1
1

Merge pull request #1014 from ggouaillardet/poc/libnl_version_check

configury: check libnl version and warn in case of conflict
Этот коммит содержится в:
Jeff Squyres 2016-10-25 10:34:18 -04:00 коммит произвёл GitHub
родитель b1aedf457f f2a80dc09f
Коммит 582f290519
7 изменённых файлов: 332 добавлений и 101 удалений

280
config/opal_check_libnl.m4 Обычный файл
Просмотреть файл

@ -0,0 +1,280 @@
dnl -*- shell-script -*-
dnl
dnl Copyright (c) 2015-2016 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
dnl
dnl $HEADER$
dnl
dnl
dnl More libnl v1/v3 sadness: the two versions are not compatible
dnl and will not work correctly if simultaneously linked into the
dnl same applications. Unfortunately, they *will* link into the
dnl same image! On platforms like CentOS 7, libibverbs depends on
dnl libnl-3.so.200 and friends, so if libnl3-devel packages are not
dnl installed, but libnl-devel are, Open MPI should not try to use libnl.
dnl
dnl GROSS: libnl wants us to either use pkg-config (which we
dnl can't assume is always present) or we need to look in a
dnl particular directory for the right libnl3 include files. For
dnl now, just hard code the special path into this logic.
dnl
dnl _OPAL_CHECK_PACKAGE_LIB() invokes OPAL_LIBNL_SANITY_CHECK() in order
dnl to keep track of which libraries depend on libnl and which libraries
dnl depend on libnl3.
dnl Open MPI will not be able to build a component vs a given version of libnl
dnl if the other libnl version is required by some third party components.
dnl At the end of configure, display a summary of who is using what, and aborts
dnl if both libnl versions are required.
dnl OPAL_LIBNL_SANITY_INIT()
dnl --------------------------------------------------------------------
AC_DEFUN([OPAL_LIBNL_SANITY_INIT], [
opal_libnl_version=0
opal_libnlv1_libs=
opal_libnlv3_libs=
AC_ARG_WITH([libnl],
[AC_HELP_STRING([--with-libnl(=DIR)],
[Directory prefix for libnl (typically only necessary if libnl is installed in a location that the compiler/linker will not search by default)])])
# The --with options carry two pieces of information: 1) do
# you want a specific version of libnl, and 2) where that
# version of libnl lives. For simplicity, let's separate
# those two pieces of information.
case "$with_libnl" in
no)
# Nope, don't want it
opal_want_libnl=no
;;
"")
# Just try to build with libnl
opal_want_libnl=try
opal_libnl_location=
;;
yes)
# Yes, definitely want it
opal_want_libnl=yes
opal_libnl_location=
;;
*)
# Yes, definitely want it -- at a specific location
opal_want_libnl=yes
opal_libnl_location=$with_libnl
;;
esac
])
dnl OPAL_LIBNL_SANITY_CHECK(lib, function, LIBS)
dnl --------------------------------------------------------------------
AC_DEFUN([OPAL_LIBNL_SANITY_CHECK], [
case $host in
*linux*)
OPAL_VAR_SCOPE_PUSH([ldd_output libnl_version])
AC_LANG_PUSH(C)
cat > conftest_c.$ac_ext << EOF
extern void $2 (void);
int main(int argc, char *argv[[]]) {
$2 ();
return 0;
}
EOF
OPAL_LOG_COMMAND([$CC -o conftest $CFLAGS $CPPFLAGS conftest_c.$ac_ext $LDFLAGS -l$1 $LIBS $3],
[ldd_output=`ldd conftest`
libnl_version=0
AS_IF([echo $ldd_output | grep -q libnl.so],
[AS_IF([test $opal_libnl_version -eq 3],
[AC_MSG_WARN([lib nl version conflict: $opal_libnlv3_libs requires libnl-3 whereas $1 requires libnl])],
[opal_libnlv1_libs="$opal_libnlv1_libs $1"
OPAL_UNIQ([opal_libnlv1_libs])
opal_libnl_version=1])
libnl_version=1])
AS_IF([echo $ldd_output | grep -q libnl-3.so],
[AS_IF([test $libnl_version -eq 1],
[AC_MSG_WARN([lib $1 requires both libnl v1 and libnl v3 -- yoinks!])
AC_MSG_WARN([This is a configuration that is known to cause run-time crashes])
AC_MSG_ERROR([Cannot continue])])
AS_IF([test $opal_libnl_version -eq 1],
[AC_MSG_WARN([lib nl version conflict: $opal_libnlv1_libs requires libnl whereas $1 requires libnl-3])],
[opal_libnlv3_libs="$opal_libnlv3_libs $1"
OPAL_UNIQ([opal_libnlv3_libs])
opal_libnl_version=3])])
rm -f conftest conftest_c.$ac_ext],
[AC_MSG_WARN([Could not link a simple program with lib $1])])
AC_LANG_POP(C)
OPAL_VAR_SCOPE_POP([ldd_output libnl_version])
;;
esac
])
dnl
dnl Check for libnl-3.
dnl
dnl Inputs:
dnl
dnl $1: prefix where to look for libnl-3
dnl $2: var name prefix of _CPPFLAGS and _LDFLAGS and _LIBS
dnl
dnl Outputs:
dnl
dnl - Set $2_CPPFLAGS necessary to compile with libnl-3
dnl - Set $2_LDFLAGS necessary to link with libnl-3
dnl - Set $2_LIBS necessary to link with libnl-3
dnl - Set OPAL_HAVE_LIBNL3 1 if libnl-3 will be used
dnl
AC_DEFUN([OPAL_CHECK_LIBNL_V3],[
OPAL_VAR_SCOPE_PUSH([CPPFLAGS_save opal_tmp_CPPFLAGS LIBS_save LDFLAGS_save])
AC_MSG_NOTICE([checking for libnl v3])
AS_IF([test "$opal_want_libnl" != "no"],
[AS_IF([test -z "$opal_libnl_location"],
[AC_MSG_CHECKING([for /usr/include/libnl3])
AS_IF([test -d "/usr/include/libnl3"],
[opal_tmp_CPPFLAGS=-I/usr/include/libnl3
opal_libnlv3_happy=1
AC_MSG_RESULT([found])],
[AC_MSG_RESULT([not found])
AC_MSG_CHECKING([for /usr/local/include/libnl3])
AS_IF([test -d "/usr/local/include/libnl3"],
[opal_tmp_CPPFLAGS=-I/usr/local/include/netlink3
opal_libnlv3_happy=1
AC_MSG_RESULT([found])],
[opal_libnlv3_happy=0
AC_MSG_RESULT([not found])])])],
[AC_MSG_CHECKING([for $1/include/libnl3])
AS_IF([test -d "$1/include/libnl3"],
[opal_tmp_CPPFLAGS="-I$1/include/libnl3"
opal_libnlv3_happy=1
AC_MSG_RESULT([found])],
[opal_libnlv3_happy=0
AC_MSG_RESULT([not found])])])
CPPFLAGS_save=$CPPFLAGS
CPPFLAGS="$opal_tmp_CPPFLAGS $CPPFLAGS"
# Random note: netlink/version.h is only in libnl v3 - it is not in libnl v1.
# Also, nl_recvmsgs_report is only in libnl v3.
AS_IF([test $opal_libnlv3_happy -eq 1],
[OPAL_CHECK_PACKAGE([$2],
[netlink/version.h],
[nl-3],
[nl_recvmsgs_report],
[],
[$1],
[],
[],
[opal_libnlv3_happy=0])
# Note that OPAL_CHECK_PACKAGE is going to add
# -I$dir/include into $2_CPPFLAGS. But because libnl v3
# puts the headers in $dir/include/libnl3, we need to
# overwrite $2_CPPFLAGS with -I$dir/include/libnl3. We can do
# this unconditionally; we don't have to check for
# success (checking for success occurs below).
$2_CPPFLAGS=$opal_tmp_CPPFLAGS])
# If we found libnl-3, we *also* need libnl-route-3
LIBS_save=$LIBS
LDFLAGS_save=$LDFLAGS
AS_IF([test -n "$$2_LDFLAGS"],
[LDFLAGS="$$2_LDFLAGS $LDFLAGS"])
AS_IF([test $opal_libnlv3_happy -eq 1],
[AC_SEARCH_LIBS([nl_rtgen_request],
[nl-route-3],
[],
[opal_libnlv3_happy=0])])
LIBS=$LIBS_save
LDFLAGS=$LDFLAGS_save
# Just because libnl* is evil, double check that the
# netlink/version.h we found was for libnl v3. As far as we
# know, netlink/version.h only first appeared in version
# 3... but let's really be sure.
AS_IF([test $opal_libnlv3_happy -eq 1],
[AC_MSG_CHECKING([to ensure these really are libnl v3 headers])
AS_IF([test -n "$$2_CPPFLAGS"],
[CPPFLAGS="$$2_CPPFLAGS $CPPFLAGS"])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <netlink/netlink.h>
#include <netlink/version.h>
#ifndef LIBNL_VER_MAJ
#error "LIBNL_VER_MAJ not defined!"
#endif
/* to the best of our knowledge, version.h only exists in libnl v3 */
#if LIBNL_VER_MAJ != 3
#error "LIBNL_VER_MAJ != 3, I am sad"
#endif
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
opal_libnlv3_happy=0])])
CPPFLAGS=$CPPFLAGS_save],
[opal_libnlv3_happy=0])
# If we found everything
AS_IF([test $opal_libnlv3_happy -eq 1],
[$2_LIBS="-lnl-3 -lnl-route-3"
OPAL_HAVE_LIBNL3=1])
OPAL_VAR_SCOPE_POP
])
dnl
dnl Check for libnl.
dnl
dnl Inputs:
dnl
dnl $1: prefix where to look for libnl
dnl $2: var name prefix of _CPPFLAGS and _LDFLAGS and _LIBS
dnl
dnl Outputs:
dnl
dnl - Set $2_CPPFLAGS necessary to compile with libnl
dnl - Set $2_LDFLAGS necessary to link with libnl
dnl - Set $2_LIBS necessary to link with libnl
dnl - Set OPAL_HAVE_LIBNL3 0 if libnl will be used
dnl
AC_DEFUN([OPAL_CHECK_LIBNL_V1],[
AC_MSG_NOTICE([checking for libnl v1])
AS_IF([test "$opal_want_libnl" != "no"],
[OPAL_CHECK_PACKAGE([$2],
[netlink/netlink.h],
[nl],
[nl_connect],
[-lm],
[$1],
[],
[opal_libnlv1_happy=1],
[opal_libnlv1_happy=0])],
[opal_libnlv1_happy=0])
AS_IF([test $opal_libnlv1_happy -eq 1],
[$2_LIBS="-lnl -lm"
OPAL_HAVE_LIBNL3=0])
])
dnl
dnl Summarize libnl and libnl3 usage,
dnl and abort if conflict is found
dnl
dnl Print the list of libraries that use libnl,
dnl the list of libraries that use libnl3,
dnl and aborts if both libnl and libnl3 are used.
dnl
AC_DEFUN([OPAL_CHECK_LIBNL_SUMMARY],[
AC_MSG_CHECKING([for libraries that use libnl v1])
AS_IF([test -n "$opal_libnlv1_libs"],
[AC_MSG_RESULT([$opal_libnlv1_libs])],
[AC_MSG_RESULT([(none)])])
AC_MSG_CHECKING([for libraries that use libnl v3])
AS_IF([test -n "$opal_libnlv3_libs"],
[AC_MSG_RESULT([$opal_libnlv3_libs])],
[AC_MSG_RESULT([(none)])])
AS_IF([test -n "$opal_libnlv1_libs" && test -n "$opal_libnlv3_libs"],
[AC_MSG_WARN([libnl v1 and libnl v3 have been found as dependent libraries])
AC_ERROR([This is a configuration that is known to cause run-time crashes])])
])

Просмотреть файл

@ -138,6 +138,10 @@ AC_DEFUN([_OPAL_CHECK_PACKAGE_LIB], [
test "$ac_cv_search_$3" != "none required"],
[$1_LIBS="$ac_cv_search_$3 $4"],
[$1_LIBS="$4"])
# libnl v1 and libnl3 are known *not* to coexist
# for each library, figure out whether it depends on libnl or libnl3 or none
# so conflicts can be reported and/or prevented
OPAL_LIBNL_SANITY_CHECK([$2], [$3], [$$1_LIBS])
$7],
[$8])

Просмотреть файл

@ -14,7 +14,7 @@ dnl Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
dnl Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
dnl Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved.
dnl Copyright (c) 2014 Intel, Inc. All rights reserved.
dnl Copyright (c) 2015 Research Organization for Information Science
dnl Copyright (c) 2015-2016 Research Organization for Information Science
dnl and Technology (RIST). All rights reserved.
dnl
dnl $COPYRIGHT$
@ -98,6 +98,8 @@ OPAL_CONFIGURE_USER="`whoami`"
OPAL_CONFIGURE_HOST="`hostname | head -n 1`"
OPAL_CONFIGURE_DATE="`date`"
OPAL_LIBNL_SANITY_INIT
#
# Save these details so that they can be used in opal_info later
#

Просмотреть файл

@ -1449,6 +1449,8 @@ m4_ifdef([project_orte], [ORTE_CONFIG_FILES])
m4_ifdef([project_ompi], [OMPI_CONFIG_FILES])
m4_ifdef([project_oshmem], [OSHMEM_CONFIG_FILES])
OPAL_CHECK_LIBNL_SUMMARY
AC_OUTPUT
OPAL_SUMMARY_PRINT

Просмотреть файл

@ -1,5 +1,7 @@
#
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2016 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -29,16 +31,16 @@ component_install =
endif
AM_CPPFLAGS = \
$(opal_reachable_netlink_LIBNL_CPPFLAGS) \
-DHAVE_LIBNL3=$(HAVE_LIBNL3)
$(opal_reachable_netlink_CPPFLAGS) \
-DOPAL_HAVE_LIBNL3=$(OPAL_HAVE_LIBNL3)
mcacomponentdir = $(opallibdir)
mcacomponent_LTLIBRARIES = $(component_install)
mca_reachable_netlink_la_SOURCES = $(sources)
mca_reachable_netlink_la_LDFLAGS = -module -avoid-version
mca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBNL_LIBS)
mca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBS)
noinst_LTLIBRARIES = $(component_noinst)
libmca_reachable_netlink_la_SOURCES =$(sources)
libmca_reachable_netlink_la_LDFLAGS = -module -avoid-version
libmca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBNL_LIBS)
libmca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBS)

Просмотреть файл

@ -1,6 +1,8 @@
# -*- shell-script -*-
#
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2015-2016 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -40,7 +42,6 @@ dnl LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
dnl ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
dnl POSSIBILITY OF SUCH DAMAGE.
dnl Check for libnl; prefer version 3 instead of version 1. Abort (i.e.,
dnl AC_MSG_ERROR) if neither libnl v1 or v3 can be found.
dnl
@ -50,95 +51,42 @@ dnl - Set $1 to the CPPFLAGS necessary to compile with libnl
dnl - Set $2 to the LIBS necessary to link with libnl
dnl - If $3 is 1, AC_MSG_ERROR (i.e., abort) if neither libnl or
dnl libnl3 can be found
dnl - Set HAVE_LIBNL3 to 1 if libnl3 will be used; 0 if libnl1 will be used
dnl - AC_SUBST $HAVE_LIBNL3
dnl - AC_DEFINE HAVE_LIBNL3
dnl - Set OPAL_HAVE_LIBNL3 to 1 if libnl v3 will be used; 0 if libnl v1 will be used
dnl - AC_SUBST $OPAL_HAVE_LIBNL3
dnl - AC_DEFINE OPAL_HAVE_LIBNL3
dnl
dnl --------------------------------------------------------
AC_DEFUN([OPAL_REACHABLE_NETLINK_CHECK_LIBNL3],[
# More libnl v1/v3 sadness: the two versions are not compatible
# and will not work correctly if simultaneously linked into the
# same applications. Unfortunately, they *will* link into the
# same image! On platforms like SLES 12, libibverbs depends on
# libnl-3.so.200 and friends, while a naive implementation of
# our configure logic would link libnl.so.1 to libdaplusnic,
# resulting in both versions in the dependency map at the same
# time. As a coarse fix, just check for libnl-3 first and use
# it if present on the system.
AC_DEFUN([OPAL_REACHABLE_NETLINK_CHECK_LIBNL_Vx],[
# GROSS: libnl wants us to either use pkg-config (which we
# can't assume is always present) or we need to look in a
# particular directory for the right libnl3 include files. For
# now, just hard code the special path into this logic.
# Default to a numeric value (this value gets AC_DEFINEd)
OPAL_HAVE_LIBNL3=0
save_CPPFLAGS=$CPPFLAGS
save_LIBS=$LIBS
###################################################
# NOTE: We *must* check for libnl3 before libnl.
###################################################
$1="-I/usr/include/libnl3"
CPPFLAGS="$$1 $CPPFLAGS"
AC_MSG_CHECKING([for /usr/include/libnl3])
AS_IF([test -d "/usr/include/libnl3"],
[AC_MSG_RESULT([present])
AC_CHECK_HEADER(
[netlink/version.h],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[
#include <netlink/netlink.h>
#include <netlink/version.h>
#ifndef LIBNL_VER_MAJ
#error "LIBNL_VER_MAJ not defined!"
#endif
/* to the best of our knowledge, version.h only exists in libnl3 */
#if LIBNL_VER_MAJ < 3
#error "LIBNL_VER_MAJ < 3, this is very unusual"
#endif
]],[[/* empty body */]])],
[HAVE_LIBNL3=1], dnl our program compiled
[HAVE_LIBNL3=0])], dnl our program failed to compile
[HAVE_LIBNL3=0], dnl AC_CHECK_HEADER failed
[#include <netlink/netlink.h>
])],
[AC_MSG_RESULT([missing])
HAVE_LIBNL3=0]) dnl "/usr/include/libnl3" does not exist
AS_IF([test $opal_libnl_version -ne 1],
[OPAL_CHECK_LIBNL_V3([$opal_libnl_location], [opal_reachable_netlink])])
AS_IF([test $opal_libnl_version -ne 3 &&
test -z "$opal_reachable_netlink_LIBS"],
[OPAL_CHECK_LIBNL_V1([$opal_libnl_location], [opal_reachable_netlink])])
# nl_recvmsgs_report is a symbol that is only present in v3
AS_IF([test "$HAVE_LIBNL3" -eq 1],
[AC_SEARCH_LIBS([nl_recvmsgs_report], [nl-3],
[# We also need libnl-route-3
AC_SEARCH_LIBS([nl_rtgen_request], [nl-route-3],
[$2="-lnl-3 -lnl-route-3"
HAVE_LIBNL3=1],
[HAVE_LIBNL3=0])],
[HAVE_LIBNL3=0])])
AS_IF([test "$opal_want_libnl" = "yes" &&
test "$opal_reachable_netlink_LIBS" = ""],
[AC_MSG_WARN([--with-libnl specified, but not found])
AC_MSG_ERROR([Cannot continue])])
AS_IF([test "$HAVE_LIBNL3" -eq 1],
[AC_MSG_NOTICE([using libnl-3])],
[# restore $1 since we are falling back to libnl (v1)
$1=""
AC_SEARCH_LIBS([nl_connect], [nl],
[$2="-lnl"],
[AC_MSG_WARN([Cannot find libnl-3 nor libnl])
AS_IF([test "$3" = "1"],
[AC_MSG_ERROR([Cannot continue])])
])
AC_MSG_NOTICE([using libnl (v1)])])
# Final result
AC_SUBST([OPAL_HAVE_LIBNL3])
AC_DEFINE_UNQUOTED([OPAL_HAVE_LIBNL3], [$OPAL_HAVE_LIBNL3],
[Whether we have libl v1 or libnl v3])
# libnl_utils.h does not include configure-generated config.h,
# so it may not see the HAVE_LIBNL3 #define. Hence, we set
# HAVE_LIBNL3 as both a C preprocessor macro (in case some
# other file includes config.h before libnl_utils.h) and a
# Makefile macro (so that the app can set HAVE_LIBNL3 via
# CPPFLAGS). Also, this macro may be used in multiple
# different libraries; setting HAVE_LIBNL3 both ways lets the
# application choose which way to set it.
AC_SUBST([HAVE_LIBNL3])
AC_DEFINE_UNQUOTED([HAVE_LIBNL3],[$HAVE_LIBNL3],
[set to 1 if should use libnl v3, set to 0 for libnl v11])
AC_SUBST([opal_reachable_netlink_CPPFLAGS])
AC_SUBST([opal_reachable_netlink_LDFLAGS])
AC_SUBST([opal_reachable_netlink_LIBS])
LIBS=$save_LIBS
AS_UNSET([save_LIBS])
CPPFLAGS=$save_CPPFLAGS
AS_UNSET([save_CPPFLAGS])
AS_IF([test "$opal_reachable_netlink_LIBS" = ""],
[opal_reachable_netlink_happy=0])
])
dnl ==============================================================
@ -159,16 +107,7 @@ AC_DEFUN([MCA_opal_reachable_netlink_CONFIG],[
])
AS_IF([test $opal_reachable_netlink_happy -eq 1],
[OPAL_REACHABLE_NETLINK_CHECK_LIBNL3(
[opal_reachable_netlink_LIBNL_CPPFLAGS],
[opal_reachable_netlink_LIBNL_LIBS],
[0])
])
AS_IF([test "$opal_reachable_netlink_LIBNL_LIBS" == ""],
[opal_reachable_netlink_happy=0])
AC_SUBST(opal_reachable_netlink_LIBNL_CPPFLAGS)
AC_SUBST(opal_reachable_netlink_LIBNL_LIBS)
[OPAL_REACHABLE_NETLINK_CHECK_LIBNL_Vx])
AS_IF([test $opal_reachable_netlink_happy -eq 1],
[$1],

Просмотреть файл

@ -1,5 +1,7 @@
/*
* Copyright (c) 2014-2015, Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2014-2015 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
*
* Portions of this software copied from libfabric
* (https://github.com/ofiwg/libfabric)
@ -42,9 +44,9 @@
#ifndef LIBNL_UTILS_H
#define LIBNL_UTILS_H
#if !defined (HAVE_LIBNL3)
#error You must define HAVE_LIBNL3 to 0 or 1 before including libnl_utils.h
#elif HAVE_LIBNL3
#if !defined (OPAL_HAVE_LIBNL3)
#error You must define OPAL_HAVE_LIBNL3 to 0 or 1 before including libnl_utils.h
#elif OPAL_HAVE_LIBNL3
#include "libnl3_utils.h"
#else
#include "libnl1_utils.h"