diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8920d24..17e21f7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: libfabric_version: v1.13.x - config_name: MR-Basic, AV-map, memcpy sos_config: --enable-ofi-mr=basic --enable-av-map --disable-cxx --enable-memcpy - --enable-pmi-simple + --enable-pmi-simple --with-hwloc=no libfabric_version: v1.13.x - config_name: PMI MPI sos_config: --disable-fortran --enable-pmi-mpi CC=mpicc @@ -54,7 +54,7 @@ jobs: libfabric_version: v1.13.x - config_name: heap use malloc env_setup: export SHMEM_SYMMETRIC_HEAP_USE_MALLOC=1 - sos_config: --disable-threads --enable-error-checking --enable-pmi-simple + sos_config: --disable-threads --enable-error-checking --enable-pmi-simple --with-hwloc=no libfabric_version: v1.13.x # too slow, times out on Github (but passes on another Ubuntu 20.04 system)... #- config_name: CMA, MR Basic, RVA @@ -79,7 +79,7 @@ jobs: - config_name: huge pages, zero bounce env_setup: SHMEM_SYMMETRIC_HEAP_USE_HUGE_PAGES=1 SHMEM_BOUNCE_SIZE=0 sos_config: --enable-error-checking --enable-remote-virtual-addressing - --enable-pmi-simple --enable-ofi-fence + --enable-pmi-simple --enable-ofi-fence --with-hwloc=no libfabric_version: v1.13.x - config_name: auto algorithms env_setup: export SHMEM_BARRIER_ALGORITHM=auto; @@ -97,7 +97,7 @@ jobs: export SHMEM_COLLECT_ALGORITHM=linear; export SHMEM_FCOLLECT_ALGORITHM=linear sos_config: --enable-error-checking --enable-remote-virtual-addressing - --enable-pmi-simple + --enable-pmi-simple --with-hwloc=no libfabric_version: v1.13.x - config_name: tree algorithms env_setup: export SHMEM_BARRIER_ALGORITHM=tree; @@ -113,7 +113,7 @@ jobs: export SHMEM_FCOLLECT_ALGORITHM=recdbl; export SHMEM_OFI_STX_AUTO=1 sos_config: --enable-error-checking --enable-remote-virtual-addressing - --enable-pmi-simple --enable-manual-progress --enable-hard-polling + --enable-pmi-simple --enable-manual-progress --enable-hard-polling --with-hwloc=no libfabric_version: v1.13.x - config_name: ring reduce algorithm env_setup: export SHMEM_REDUCE_ALGORITHM=ring @@ -474,11 +474,11 @@ jobs: - config_name: ucx-1.9.0 ucx_version: v1.9.0 xpmem_version: master - sos_config: [--enable-pmi-simple --disable-fortran, + sos_config: [--enable-pmi-simple --disable-fortran --with-hwloc=no, --enable-pmi-mpi CC=mpicc --disable-fortran, --with-cma --enable-error-checking --enable-profiling - --enable-pmi-simple --disable-fortran, - --with-xpmem --enable-error-checking --enable-pmi-simple] + --enable-pmi-simple --disable-fortran --with-hwloc=no, + --with-xpmem --enable-error-checking --enable-pmi-simple --with-hwloc=no] steps: - name: Checking OS version run: | @@ -558,17 +558,17 @@ jobs: xpmem_version: master - name: Heap use malloc env_setup: export SHMEM_SYMMETRIC_HEAP_USE_MALLOC=1 - sos_config: --disable-threads --enable-error-checking --enable-pmi-simple + sos_config: --disable-threads --enable-error-checking --enable-pmi-simple --with-hwloc=no - name: Heap use huge pages, zero bounce env_setup: export SHMEM_SYMMETRIC_HEAP_USE_HUGE_PAGES=1; export SHMEM_BOUNCE_SIZE=0 sos_config: --enable-error-checking --enable-remote-virtual-addressing --enable-pmi-simple --enable-ofi-fence - sos_config: [--enable-pmi-simple, + sos_config: [--enable-pmi-simple --with-hwloc=no, --disable-fortran --enable-error-checking --enable-remote-virtual-addressing --disable-aslr-check --enable-pmi-simple, --with-cma --enable-error-checking --enable-profiling --enable-remote-virtual-addressing --enable-pmi-simple, --with-xpmem --enable-shr-atomics --enable-error-checking --enable-pmi-simple, - --enable-pmi-mpi CC=mpicc --disable-fortran] + --enable-pmi-mpi CC=mpicc --disable-fortran --with-hwloc=no] steps: - name: Checking OS version run: | @@ -576,7 +576,7 @@ jobs: - uses: actions/checkout@v2 - name: Install dependencies run: | - sudo apt-get install -y gfortran mpich libmpich-dev libev-dev libev-libevent-dev + sudo apt-get install -y gfortran mpich libmpich-dev libev-dev libev-libevent-dev libhwloc-dev sudo sysctl -w kernel.yama.ptrace_scope=0 sudo sysctl -w kernel.randomize_va_space=0 @@ -653,7 +653,7 @@ jobs: - uses: actions/checkout@v2 - name: Install dependencies run: | - sudo apt-get install -y gfortran mpich libmpich-dev libev-dev libev-libevent-dev + sudo apt-get install -y gfortran mpich libmpich-dev libev-dev libev-libevent-dev libhwloc-dev sudo sysctl -w kernel.yama.ptrace_scope=0 sudo sysctl -w kernel.randomize_va_space=0 diff --git a/config/oac_assert.m4 b/config/oac_assert.m4 new file mode 100644 index 00000000..922609b5 --- /dev/null +++ b/config/oac_assert.m4 @@ -0,0 +1,43 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow + + +dnl OAC_ASSERT_LITERAL: Assert if first argument is not an Autoconf literal +dnl +dnl 1 -> Variable which must be a literal +dnl 2 -> Argument reference string (usually an integer argument number) +dnl +dnl Assert that the first argument is a literal (in the Autoconf sense +dnl of the word) Second argument is the argument number (ie, a bare +dnl number) to make the error message easier to parse. +AC_DEFUN([OAC_ASSERT_LITERAL], +[AS_LITERAL_IF([$1], [], [m4_fatal([argument $2 ($1) must be a literal])])])dnl + + +dnl OAC_ASSERT_BEFORE: Assert the first argument is evaluated before +dnl the second argument +dnl +dnl 1 -> Macro which must be evaluated before second argument +dnl 2 -> Macro currently calling assert (for debugging print) +dnl +dnl Common usage would be similar to the commonly used check that +dnl OAC macros which require init to be called: +dnl OAC_ASSERT_BEFORE([OAC_INIT], [$0]) +AC_DEFUN([OAC_ASSERT_BEFORE], +[AC_PROVIDE_IFELSE([$1], [], [m4_fatal([$1 must be evaluated before $2])])])dnl + + +dnl OAC_ASSERT_PREFIX_DEFINED: Assert that the OAC program prefix is defined +dnl +dnl 1 -> Calling macro name +dnl +dnl Generally only internally useful, but assert that the program prefix has +dnl been defined, so that the calling macro can rely on oac_program_prefix +dnl having a rational value. +AC_DEFUN([OAC_ASSERT_PREFIX_DEFINED], +[m4_ifdef([_oac_program_prefix], [], + [m4_fatal([OAC prefix not defined. Evaluate OAC_PUSH_PREFIX before evaluating $1])])])dnl diff --git a/config/oac_check_package.m4 b/config/oac_check_package.m4 new file mode 100644 index 00000000..6ab607b6 --- /dev/null +++ b/config/oac_check_package.m4 @@ -0,0 +1,677 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl Copyright (c) 2022 Nanook Consulting. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ + + +dnl OAC_CHECK_PACKAGE: Search for the availability of a package +dnl +dnl 1 -> package name +dnl 2 -> prefix value +dnl 3 -> headers (space separated list) +dnl 4 -> libraries (space separated list) +dnl 5 -> function name +dnl 6 -> action if found +dnl 7 -> action if not found +dnl +dnl OAC_CHECK_PACKAGE has an argument length problem. Technically, M4 +dnl macros may only have 9 arguments, as argument values must be in the +dnl form of $X, where X is a single digit. This means we do some argument +dnl compression (life would be easier if the libraries and headers were +dnl split into primary and support) and use the M4 environment for passing +dnl some infrequently used arguments. +dnl +dnl OAC_CHECK_PACKAGE tries to find the correct CPPFLAGS, LDFLAGS, and libraries +dnl to use a particular package. It then verifies that the header is available +dnl via AC_CHECK_HEADERS and that the function specified is available via +dnl AC_CHECK_FUNC using the specified flags. To find the flags and libraries, +dnl OAC_CHECK_PACKAGE follows a 4 step search path: +dnl +dnl 1. If .pc is available to package config, the package config +dnl data is used. +dnl 2. If a OMPI-style wrapper compiler is found, the information from the +dnl wrapper compiler is used (NOTE: THIS IS OFF BY DEFAULT) +dnl 3. If with_ and/or with__libdir are specified, the +dnl filesystem is examined to look for the specified header and library +dnl in the specified path. +dnl 4. We try to find the specified header and function with no change +dnl in CPPFLAGS or LDFLAGS and adding the specified libraries to LIBS. +dnl +dnl It is the responsibility of the caller to register arguments of the form +dnl with-, with--libdir, and with-package name>-incdir. +dnl All three are optional, nothing will break if the caller doesn't specify them +dnl (and indeed, if the package being searched for isn't libnl3, it's likely the +dnl with--incdir is a complete waste of energy). +dnl +dnl By default, OAC_CHECK_PACKAGE will use for the module name to specify +dnl to pkg-config, meaning there is a .pc in the filesystem. If a +dnl different module name should be used, add a macro to the M4 environment named +dnl _pkgconfig_module with the value of the pkgconfig module name +dnl to use. For example, if the libevent module name is libevent_core, you could +dnl specify: +dnl +dnl m4_define([libevent_pkgconfig_module], [libevent_core]) +dnl +dnl Similarly, by default, OAC_CHECK_PACKAGE will use cc for the name +dnl of the wrapper compiler to investigate. This can be modified with the +dnl _wrapper_compiler macro in the m4 environment. +dnl +dnl Using pkg-config is on by default and using the wrapper compilers is off by +dnl default. The use of either can be controlled by setting the SHELL environment +dnl variables _USE_PKG_CONFIG and _USE_WRAPPER_COMPILER +dnl to 0 (to explicitly disable) or 1 (to explicitly enable). +dnl +dnl On return, will be evaluated if it appears that the package is +dnl available. will be evaluated if it appears that the package +dnl is not available. If it appears the package is available, the following SHELL +dnl environment variables will be set: +dnl +dnl _CPPFLAGS - CPPFLAGS to add when compiling sources depending on the package +dnl _LDFLAGS - LDFLAGS to add when linking against the package +dnl _STATIC_LDFLAGS - LDFLAGS to add when linking against the package when +dnl building a statically linked executable. +dnl _LIBS - Libraries to link to access the package +dnl _STATIC_LIBS - Libraries to link to access the package when building a +dnl statically linked executable. +dnl _PC_MODULES - Module name of the pkgconfig module used to generate +dnl the build information. Will be unset by OAC_CHECK_PACKAGE +dnl if pkg-config was not used to configure the package. Note +dnl that there is no need for a STATIC_PC_MODULES option, +dnl as that functionality is built into pkgconfig modules +dnl directly. +dnl _SUMMARY - A summary of the check package output, suitable for inclusion +dnl in a configure summary table. Will start with yes/no. +dnl _DETECT_METHOD - The method used to find the right flags. Will be one of +dnl 'pkg-config', 'wrapper compiler', or empty string +dnl +dnl Note that STATIC_LIBS and STATIC_LDFLAGS should not be added to +dnl LIBS and LDFLAGS unnecessarily. Even if the library being built +dnl is being built as a static library, that does not mean adding +dnl STATIC_LIBS to LIBS is the right call. Only when the executable +dnl is only linked against static libraries should STATIC_LIBS be +dnl added to LIBS. +AC_DEFUN([OAC_CHECK_PACKAGE],[ +# ****************************** START CHECK PACKAGE FOR $1 ****************************** + AC_REQUIRE([_OAC_CHECK_PACKAGE_STATIC_CHECK]) + OAC_ASSERT_LITERAL([$1])dnl + OAC_ASSERT_LITERAL([$2])dnl + OAC_VAR_SCOPE_PUSH([check_package_$2_save_CPPFLAGS check_package_$2_save_LDFLAGS check_package_$2_save_LIBS check_package_happy check_package_have_flags check_package_prefix check_package_libdir check_package_incdir check_package_pcfilename]) + + check_package_$2_save_CPPFLAGS="${CPPFLAGS}" + check_package_$2_save_LDFLAGS="${LDFLAGS}" + check_package_$2_save_LIBS="${LIBS}" + + $2_CPPFLAGS= + $2_LDFLAGS= + $2_STATIC_LDFLAGS= + $2_LIBS= + $2_STATIC_LIBS= + AS_UNSET([$2_PC_MODULES]) + + check_package_happy=1 + check_package_have_flags=0 + check_package_type= + + # build a sane environment + AS_IF([test "$with_$1" = "no"], + [AC_MSG_NOTICE([Package $1 disabled by user]) + check_package_happy=0], + [test "${with_$1}" = "yes"], + [check_package_prefix=], + [check_package_prefix="${with_$1}"]) + check_package_libdir= + AS_IF([test "${with_$1_libdir}" = "no" -o "${with_$1_libdir}" = "yes"], + [AC_MSG_ERROR(["yes" or "no" are not valid arguments for --with-$1-libdir])], + [test -n "${with_$1_libdir}"], + [check_package_libdir="${with_$1_libdir}"]) + check_package_incdir= + AS_IF([test "${with_$1_incdir}" = "no" -o "${with_$1_incdir}" = "yes"], + [AC_MSG_ERROR(["yes" or "no" are not valid arguments for --with-$1-incdir])], + [test -n "${with_$1_incdir}"], + [check_package_incdir="${with_$1_incdir}"]) + + AS_IF([test ${check_package_happy} -eq 1 -a ${check_package_have_flags} -eq 0], + [_OAC_CHECK_PACKAGE_PKGCONFIG([$1], [$2], + [check_package_type="pkg-config" + check_package_have_flags=1])]) + + AS_IF([test ${check_package_happy} -eq 1 -a ${check_package_have_flags} -eq 0], + [_OAC_CHECK_PACKAGE_WRAPPER_COMPILER([$1], [$2], + [check_package_type="wrapper compiler" + check_package_have_flags=1])]) + + AS_IF([test ${check_package_happy} -eq 1 -a ${check_package_have_flags} -eq 0], + [_OAC_CHECK_PACKAGE_GENERIC([$1], [$2], [$3], [$4], + [check_package_type="" + check_package_have_flags=1])]) + + AS_IF([test ${check_package_have_flags} -eq 0], [check_package_happy=0]) + + AS_IF([test ${check_package_happy} -eq 1 -a "${oac_cv_check_package_static_linker_flag}" = "yes"], + [AC_MSG_NOTICE([Copying STATIC_LIBS and STATIC_LDFLAGS to LIBS and LDFLAGS because static linking]) + OAC_APPEND([$2_LDFLAGS], [${$2_STATIC_LDFLAGS}]) + OAC_APPEND([$2_LIBS], [${$2_STATIC_LIBS}])]) + + AS_IF([test ${check_package_happy} -eq 1], + [_OAC_CHECK_PACKAGE_VERIFY([$1], [$2], [$3], [$5], + [check_package_happy=1], [check_package_happy=0])]) + + $2_DETECT_METHOD="${check_package_type}" + AS_IF([test -n "${check_package_type}"], + [check_package_type="${check_package_type}: "]) + + AS_IF([test ${check_package_happy} -eq 1], + [AS_IF([test -z "${check_package_prefix}"], + [$2_SUMMARY="yes (${check_package_type}default search paths)"], + [$2_SUMMARY="yes (${check_package_type}${check_package_prefix})"]) + $6], + [AS_IF([test "${with_$1}" = "no"], + [$2_SUMMARY="no (explicitly disabled)"], + [$2_SUMMARY="no (not found)"]) + AS_UNSET([$2_CPPFLAGS]) + AS_UNSET([$2_LDFLAGS]) + AS_UNSET([$2_STATIC_LDFLAGS]) + AS_UNSET([$2_LIBS]) + AS_UNSET([$2_STATIC_LIBS]) + $7]) + + CPPFLAGS="${check_package_$2_save_CPPFLAGS}" + LDFLAGS="${check_package_$2_save_LDFLAGS}" + LIBS="${check_package_$2_save_LIBS}" + + OAC_VAR_SCOPE_POP +# ****************************** END CHECK PACKAGE FOR $1 ****************************** +]) + + +dnl Retrieve arguments from pkg-config file +dnl +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> pcfile name (may be full path) +dnl 4 -> action if found +dnl 5 -> action if not found +dnl +dnl Read pkgconfig module $3 and set build variables based on return +dnl value. Results are cached based on the value in $1, even if the +dnl pkgconfig module name ($3) changes and that this macro is expanded +dnl inside OAC_CHECK_PACKAGE, which can pollute the results cache. +dnl +dnl On return, will be evaluated if it appears that +dnl the pkg-config data is available. will be +dnl evaluated if it appears that the package is not available. If it +dnl appears the package is available, the following SHELL environment +dnl variables will be set: +dnl +dnl _CPPFLAGS - CPPFLAGS to add when compiling sources depending on the package +dnl _LDFLAGS - LDFLAGS to add when linking against the package +dnl _STATIC_LDFLAGS - LDFLAGS to add when linking against the package when +dnl building a statically linked executable. +dnl _LIBS - Libraries to link to access the package +dnl _STATIC_LIBS - Libraries to link to access the package when building a +dnl statically linked executable. +dnl _PC_MODULES - Module name of the pkgconfig module used to generate +dnl the build information. Will be unset by OAC_CHECK_PACKAGE +dnl if pkg-config was not used to configure the package. Note +dnl that there is no need for a STATIC_PC_MODULES option, +dnl as that functionality is built into pkgconfig modules +dnl directly. +AC_DEFUN([OAC_CHECK_PACKAGE_PARSE_PKGCONFIG], [ + AC_REQUIRE([_OAC_CHECK_PACKAGE_PKGCONFIG_INIT]) + OAC_VAR_SCOPE_PUSH([check_package_pkgconfig_internal_result]) + + AC_CACHE_CHECK([if $1 pkg-config module exists], + [oac_cv_check_package_$1_pkg_config_exists], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--exists], [check_package_pkgconfig_internal_result], + [$2_PC_MODULES=$3 + oac_cv_check_package_$1_pkg_config_exists=yes], + [oac_cv_check_package_$1_pkg_config_exists=no])]) + + # if pkg-config --exists works, but getting one of the standard flags fails, we consider + # that a hard failure. It should not happen, outside of a weird system configuration + # issue where we're probably not going to like the results anyway. + AS_IF([test "${oac_cv_check_package_$1_pkg_config_exists}" = "yes"], + [AC_CACHE_CHECK([for $1 pkg-config cflags], + [oac_cv_check_package_$1_pkg_config_cppflags], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--cflags], + [oac_cv_check_package_$1_pkg_config_cppflags], [], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 cppflags from pkg-config])])]) + $2_CPPFLAGS="${oac_cv_check_package_$1_pkg_config_cppflags}" + + AC_CACHE_CHECK([for $1 pkg-config ldflags], + [oac_cv_check_package_$1_pkg_config_ldflags], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--libs-only-L --libs-only-other], + [oac_cv_check_package_$1_pkg_config_ldflags], [], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 ldflags from pkg-config])])]) + $2_LDFLAGS="${oac_cv_check_package_$1_pkg_config_ldflags}" + + AC_CACHE_CHECK([for $1 pkg-config static ldflags], + [oac_cv_check_package_$1_pkg_config_static_ldflags], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--static --libs-only-L --libs-only-other], + [oac_cv_check_package_$1_pkg_config_static_ldflags], [], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 static ldflags from pkg-config])])]) + $2_STATIC_LDFLAGS="${oac_cv_check_package_$1_pkg_config_static_ldflags}" + + AC_CACHE_CHECK([for $1 pkg-config libs], + [oac_cv_check_package_$1_pkg_config_libs], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--libs-only-l], + [oac_cv_check_package_$1_pkg_config_libs], [], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 libs from pkg-config])])]) + $2_LIBS="${oac_cv_check_package_$1_pkg_config_libs}" + + AC_CACHE_CHECK([for $1 pkg-config static libs], + [oac_cv_check_package_$1_pkg_config_static_libs], + [_OAC_CHECK_PACKAGE_PKGCONFIG_RUN([$3], [--static --libs-only-l], + [oac_cv_check_package_$1_pkg_config_static_libs], [], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 libs from pkg-config])])]) + $2_STATIC_LIBS="${oac_cv_check_package_$1_pkg_config_static_libs}" + + $4]) + + OAC_VAR_SCOPE_POP +]) + + +dnl Invalidate generic cached results (should rarely be needed) +dnl +dnl 1 -> package name +dnl 2 -> prefix value +dnl 3 -> headers (space separated list) +dnl 4 -> function name +dnl +dnl Rarely, packages change linking or in some other way make it +dnl difficult to determine all the correct arguments for +dnl OAC_CHECK_PACKAGE in one try. The TM interface is a good example +dnl of this, which has changed the name of the library (or its +dnl dependencies) throughout the years. Because OAC_CHECK_PACKAGE +dnl makes heavy use of caching (yay!), it is generally not useful to +dnl call OAC_CHECK_PACKAGE multiple times with the same package name, +dnl but different arguments. This macro may be expanded between calls +dnl to invalidate the caching for the generic (no pkg-config or +dnl wrapper config found) case. +AC_DEFUN([OAC_CHECK_PACKAGE_INVALIDATE_GENERIC_CACHE], [ + OAC_VAR_SCOPE_PUSH([check_package_verify_search_header]) + dnl today, all we cache in the generic case is the header and func libs + check_package_verify_search_header=`echo "$3" | cut -f1 -d' '` + AS_UNSET([ac_cv_header_]AS_TR_SH([${check_package_verify_search_header}])) + AS_UNSET([ac_cv_func_$4]) + OAC_VAR_SCOPE_POP +]) + + +dnl OAC_CHECK_PACKAGE_VERIFY_COMMANDS - macros to expand during +dnl verification we have a working package +dnl +dnl 1 -> macro name (must be double quoted) +dnl +dnl If extra verification is required (such as the libnl1 vs. libnl3 disaster), +dnl callers (like the libnl verification code) can register a hook for +dnl every time OAC_CHECK_PACKAGE verifies that a package actually links. This +dnl check will only be run after it is verified that the header can be found +dnl and that the function specified is found when linking. +dnl +dnl The macro specified must take 6 arguments: +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> headers (space separated list) +dnl 4 -> function name +dnl 5 -> action if found +dnl 6 -> action if not found +dnl +dnl The CPPFLAGS / LDFLAGS / LIBS can be retrieved via ${$2_CPPFLAGS}, +dnl ${$2_LDFLAGS}, and ${$2_LIBS}, respectively. +dnl +dnl Note that, because M4 really likes to expand macro names, the argument +dnl to OAC_CHECK_PACKAGE_VERIFY_COMMANDS must be overquoted. That is, +dnl if the macro name to be called is LIBNL_PACKAGE_VERIFY, the call to +dnl register should be: +dnl +dnl OAC_CHECK_PACKAGE_VERIFY_COMMANDS([[LIBNL_PACKAGE_VERIFY]]) +dnl +dnl If you see the macro being invoked without arguments, that almost certainly +dnl means you forgot to double quote. +AC_DEFUN([OAC_CHECK_PACKAGE_VERIFY_COMMANDS], +[m4_append([OAC_CHECK_PACKAGE_VERIFY_COMMAND_LIST], m4_dquote([$1]), [,])]) + + +dnl ************************************* INTERNAL HELPER ************************************* + +AC_DEFUN([_OAC_CHECK_PACKAGE_STATIC_CHECK], +[OAC_LINKER_STATIC_CHECK([oac_cv_check_package_static_linker_flag=yes], + [oac_cv_check_package_static_linker_flag=no])]) + +dnl ************************************* PKG-CONFIG ************************************* + + +dnl no arguments; here for an AC_REQUIRE to set $PKG_CONFIG +AC_DEFUN([_OAC_CHECK_PACKAGE_PKGCONFIG_INIT], +[AC_CHECK_PROG([PKG_CONFIG], [pkg-config], [pkg-config])]) + + +dnl 1 -> package +dnl 2 -> prefix +dnl 3 -> action if found flags +AC_DEFUN([_OAC_CHECK_PACKAGE_PKGCONFIG], [ + m4_ifdef([$1_pkgconfig_module], + [m4_define([pcname], [$1_pkgconfig_module])], + [m4_define([pcname], [$1])]) + AS_IF([test "${$1_USE_PKG_CONFIG}" != "0"], + [# search for the package using pkg-config. If the user provided a + # --with-$1 or --with-$1-libdir argument, be explicit about where + # we look for the pkg-config file, so we don't find the wrong one. + # If they specified --with-$1 only, we look in + # prefix/lib64/pkgconfig and if we don't find a file there, assume + # prefix/lib is the right answer. + AC_CACHE_CHECK([for $1 pkg-config name], + [oac_cv_check_package_$1_pcfilename], + [oac_cv_check_package_$1_pcfilename="pcname" + AS_IF([test -n "${check_package_libdir}"], + [oac_cv_check_package_$1_pcfilename="${check_package_libdir}/pkgconfig/pcname.pc"], + [test -z "${check_package_prefix}"], + [oac_cv_check_package_$1_pcfilename="pcname"], + [test -r "${check_package_prefix}/lib/pkgconfig/pcname.pc" -a -r "${check_package_prefix}/lib64/pkgconfig/pcname.pc"], + [AS_IF([test ! -L "${check_package_prefix}/lib" && + test ! -L "${check_package_prefix}/lib64"], + [AC_MSG_ERROR([Found pcname in both ${check_package_prefix}/lib/pkgconfig and +${check_package_prefix}/lib64/pkgconfig. This is confusing. Please add --with-$1-libdir=PATH +to configure to help disambiguate.])], + [check_package_cv_$1_pcfilename="${check_package_prefix}/lib/pkgconfig/pcname.pc"])], + [test -r "${check_package_prefix}/lib64/pkgconfig/pcname.pc"], + [oac_cv_check_package_$1_pcfilename="${check_package_prefix}/lib64/pkgconfig/pcname.pc"], + [oac_cv_check_package_$1_pcfilename="${check_package_prefix}/lib/pkgconfig/pcname.pc"])]) + OAC_CHECK_PACKAGE_PARSE_PKGCONFIG([$1], [$2], [${oac_cv_check_package_$1_pcfilename}], [$3])]) +]) + + +dnl 1 -> pc module/filename +dnl 2 -> argument string +dnl 3 -> result assignment string +dnl 4 -> action if found +dnl 5 -> action if not found +AC_DEFUN([_OAC_CHECK_PACKAGE_PKGCONFIG_RUN], [ + OAC_VAR_SCOPE_PUSH([check_package_pkgconfig_run_results check_package_pkgconfig_run_happy]) + check_package_pkgconfig_run_happy=no + AS_IF([test -n "${PKG_CONFIG}"], + [OAC_LOG_COMMAND([check_package_pkgconfig_run_results=`${PKG_CONFIG} $2 $1 2>&1`], + [AS_VAR_COPY([$3], [check_package_pkgconfig_run_results]) + check_package_pkgconfig_run_happy=yes]) + OAC_LOG_MSG([pkg-config output: ${check_package_pkgconfig_run_results}], [1])]) + AS_IF([test "${check_package_pkgconfig_run_happy}" = "yes"], [$4], [$5]) + OAC_VAR_SCOPE_POP +]) + + +dnl ************************************* WRAPPER COMPILERS ************************************* + + +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> action if found flags +dnl +dnl wrapper compiler is off by default; must be explicitly enabled +AC_DEFUN([_OAC_CHECK_PACKAGE_WRAPPER_COMPILER], [ + m4_ifdef([$1_wrapper_compiler], + [m4_define([wrapper_compiler_name], [$1_wrapper_compiler])], + [m4_define([wrapper_compiler_name], [$1cc])]) + AS_IF([test "${$1_USE_WRAPPER_COMPILER}" = "1"], + [# search for the package using wrapper compilers. If the user + # provided a --with-$1 argument, be explicit about where we look + # for the compiler, so we don't find the wrong one. + AC_CACHE_CHECK([for $1 wrapper compiler], + [oac_cv_check_package_$1_wrapper_compiler], + [AS_IF([test -z "${check_package_prefix}"], + [oac_cv_check_package_$1_wrapper_compiler="wrapper_compiler_name"], + [oac_cv_check_package_$1_wrapper_compiler="${check_package_prefix}/bin/wrapper_compiler_name"])]) + _OAC_CHECK_PACKAGE_WRAPPER_INTERNAL([$1], [$2], [${oac_cv_check_package_$1_wrapper_compiler}], [$3])]) +]) + + +dnl 1 -> package name +dnl 2 -> prefix +dnl 2 -> wrapper compiler +dnl 3 -> action if found flag +AC_DEFUN([_OAC_CHECK_PACKAGE_WRAPPER_INTERNAL], [ + OAC_VAR_SCOPE_PUSH([check_package_wrapper_internal_result check_package_wrapper_internal_tmp]) + + AC_CACHE_CHECK([if $1 wrapper compiler works], + [oac_cv_check_package_$1_wrapper_compiler_works], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:version], [check_package_wrapper_internal_result], + [oac_cv_check_package_$1_wrapper_compiler_works=yes], + [oac_cv_check_package_$1_wrapper_compiler_works=no])]) + + # if wrapper --showme:version works, but getting one of the standard flags fails, we consider + # that a hard failure. It should not happen, outside of a weird system configuration + # issue where we're probably not going to like the results anyway. + AS_IF([test ${oac_cv_check_package_$1_wrapper_compiler_works} = "yes"], + [AC_CACHE_CHECK([for $1 wrapper compiler cppflags], + [oac_cv_check_package_$1_wrapper_compiler_cppflags], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:incdirs], + [check_package_wrapper_internal_result], + [for check_package_wrapper_internal_tmp in ${check_package_wrapper_internal_result} ; do + OAC_APPEND([oac_cv_check_package_$1_wrapper_compiler_cppflags], ["-I${check_package_wrapper_internal_tmp}"]) + done], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 cppflags from wrapper compiler])])]) + $2_CPPFLAGS="${oac_cv_check_package_$1_wrapper_compiler_cppflags}" + + AC_CACHE_CHECK([for $1 wrapper compiler ldflags], + [oac_cv_check_package_$1_wrapper_compiler_ldflags], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:libdirs], + [check_package_wrapper_internal_result], + [for check_package_wrapper_internal_tmp in ${check_package_wrapper_internal_result} ; do + OAC_APPEND([oac_cv_check_package_$1_wrapper_compiler_ldflags], ["-L${check_package_wrapper_internal_tmp}"]) + done], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 ldflags from wrapper compiler])])]) + $2_LDFLAGS="${oac_cv_check_package_$1_wrapper_compiler_ldflags}" + + AC_CACHE_CHECK([for $1 wrapper compiler static ldflags], + [oac_cv_check_package_$1_wrapper_compiler_static_ldflags], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:libdirs_static], + [check_package_wrapper_internal_result], + [for check_package_wrapper_internal_tmp in ${check_package_wrapper_internal_result} ; do + OAC_APPEND([oac_cv_check_package_$1_wrapper_compiler_static_ldflags], ["-L${check_package_wrapper_internal_tmp}"]) + done], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 static ldflags from wrapper compiler])])]) + $2_STATIC_LDFLAGS="${oac_cv_check_package_$1_wrapper_compiler_static_ldflags}" + + AC_CACHE_CHECK([for $1 wrapper compiler libs], + [oac_cv_check_package_$1_wrapper_compiler_libs], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:libs], + [check_package_wrapper_internal_result], + [for check_package_wrapper_internal_tmp in ${check_package_wrapper_internal_result} ; do + OAC_APPEND([oac_cv_check_package_$1_wrapper_compiler_libs], ["-l${check_package_wrapper_internal_tmp}"]) + done], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 libs from wrapper compiler])])]) + $2_LIBS="$oac_cv_check_package_$1_wrapper_compiler_libs" + + AC_CACHE_CHECK([for $1 wrapper compiler static libs], + [oac_cv_check_package_$1_wrapper_compiler_static_libs], + [_OAC_CHECK_PACKAGE_WRAPPER_RUN([$3], [--showme:libs_static], + [check_package_wrapper_internal_result], + [for check_package_wrapper_internal_tmp in ${check_package_wrapper_internal_result} ; do + OAC_APPEND([oac_cv_check_package_$1_wrapper_compiler_static_libs], ["-l${check_package_wrapper_internal_tmp}"]) + done], + [AC_MSG_RESULT([error]) + AC_MSG_ERROR([An error occurred retrieving $1 static libs from wrapper compiler])])]) + $2_STATIC_LIBS="${oac_cv_check_package_$1_wrapper_compiler_static_libs}" + + $4]) + OAC_VAR_SCOPE_POP +]) + + +dnl 1 -> wrapper compiler +dnl 2 -> argument string +dnl 3 -> result assignment string +dnl 4 -> action if found +dnl 5 -> action if failed +AC_DEFUN([_OAC_CHECK_PACKAGE_WRAPPER_RUN], [ + OAC_VAR_SCOPE_PUSH([check_package_wrapper_run_results]) + OAC_LOG_COMMAND([check_package_wrapper_run_results=`$1 $2 2>&1`], + [AS_VAR_COPY([$3], [check_package_wrapper_run_results]) + $4], + [$5]) + OAC_LOG_MSG([wrapper output: ${check_package_wrapper_run_results}], [1]) + OAC_VAR_SCOPE_POP +]) + + +dnl ************************************* GENERIC GUESSING ************************************* + + +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> headers (space separated list) +dnl 4 -> libraries (space separated list) +dnl 5 -> action if found flags +AC_DEFUN([_OAC_CHECK_PACKAGE_GENERIC], [ + OAC_VAR_SCOPE_PUSH([check_package_generic_happy check_package_generic_lib]) + check_package_generic_happy=0 + + AS_IF([test -n "${check_package_prefix}"], + [_OAC_CHECK_PACKAGE_GENERIC_PREFIX([$1], [$2], [$3], [$4], [check_package_generic_happy=1])], + [AC_MSG_NOTICE([Searching for $1 in default search paths]) + $1_CPPFLAGS= + $1_LDFLAGS= + check_package_generic_happy=1]) + + AS_IF([test ${check_package_generic_happy} -eq 1], + [for check_package_generic_lib in $4 ; do + check_package_generic_lib=`echo ${check_package_generic_lib} | sed -e 's/^-l//'` + OAC_APPEND([$2_LIBS], ["-l${check_package_generic_lib}"]) + OAC_APPEND([$2_STATIC_LIBS], ["-l${check_package_generic_lib}"]) + done + + AC_MSG_CHECKING([for $1 cppflags]) + AC_MSG_RESULT([$$2_CPPFLAGS]) + AC_MSG_CHECKING([for $1 ldflags]) + AC_MSG_RESULT([$$2_LDFLAGS]) + AC_MSG_CHECKING([for $1 libs]) + AC_MSG_RESULT([$$2_LIBS]) + AC_MSG_CHECKING([for $1 static libs]) + AC_MSG_RESULT([$$2_STATIC_LIBS]) + + $5]) + OAC_VAR_SCOPE_POP +]) + + +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> headers (space separated list) +dnl 4 -> libraries (space separated list) +dnl 5 -> action if found flags +AC_DEFUN([_OAC_CHECK_PACKAGE_GENERIC_PREFIX], [ + OAC_VAR_SCOPE_PUSH([check_package_generic_search_header check_package_generic_search_lib check_package_generic_incdir]) + + check_package_generic_search_header=`echo "$3" | cut -f1 -d' '` + check_package_generic_search_lib=`echo "$4" | cut -f1 -d' ' | sed -e 's/^-l//'` + + check_package_generic_prefix_happy=0 + AS_IF([test -n "${check_package_incdir}"], + [check_package_generic_incdir="${check_package_incdir}"], + [check_package_generic_incdir="${check_package_prefix}/include"]) + AC_MSG_CHECKING([for $1 header at ${check_package_generic_incdir}]) + AS_IF([test -r ${check_package_generic_incdir}/${check_package_generic_search_header}], + [check_package_generic_prefix_happy=1 + $2_CPPFLAGS="-I${check_package_generic_incdir}" + AC_MSG_RESULT([found])], + [AC_MSG_RESULT([not found])]) + + AS_IF([test ${check_package_generic_prefix_happy} -eq 1], + [check_package_generic_prefix_happy=0 + AS_IF([test -n "${check_package_libdir}"], + [AC_MSG_CHECKING([for $1 library (${check_package_generic_search_lib}) in ${check_package_libdir}]) + ls ${check_package_libdir}/lib${check_package_generic_search_lib}.* 1>&/dev/null 2>&1 + AS_IF([test $? -eq 0], + [check_package_generic_prefix_happy=1 + $2_LDFLAGS="-L${check_package_libdir}" + AC_MSG_RESULT([found])], + [AC_MSG_RESULT([not found])])], + [check_package_generic_prefix_lib=0 + check_package_generic_prefix_lib64=0 + + ls ${check_package_prefix}/lib/lib${check_package_generic_search_lib}.* 1>&/dev/null 2>&1 + AS_IF([test $? -eq 0], [check_package_generic_prefix_lib=1]) + ls ${check_package_prefix}/lib64/lib${check_package_generic_search_lib}.* 1>&/dev/null 2>&1 + AS_IF([test $? -eq 0], [check_package_generic_prefix_lib64=1]) + + AC_MSG_CHECKING([for $1 library (${check_package_generic_search_lib}) in ${check_package_prefix}]) + AS_IF([test ${check_package_generic_prefix_lib} -eq 1 -a ${check_package_generic_prefix_lib64} -eq 1], + [AS_IF([test ! -L "${check_package_prefix}/lib" && + test ! -L "${check_package_prefix}/lib64"], + [AC_MSG_ERROR([Found library $check_package_generic_search_lib in both ${check_package_prefix}/lib and +${check_package_prefix}/lib64. This has confused configure. Please add --with-$1-libdir=PATH to configure to help +disambiguate.])], + [check_package_generic_prefix_happy=1 + $2_LDFLAGS=-L${check_package_prefix}/lib + AC_MSG_RESULT([found -- lib])])], + [test ${check_package_generic_prefix_lib} -eq 1], + [check_package_generic_prefix_happy=1 + $2_LDFLAGS=-L${check_package_prefix}/lib + AC_MSG_RESULT([found -- lib])], + [test $check_package_generic_prefix_lib64 -eq 1], + [check_package_generic_prefix_happy=1 + $2_LDFLAGS=-L${check_package_prefix}/lib64 + AC_MSG_RESULT([found -- lib64])], + [AC_MSG_RESULT([not found])])])]) + + AS_IF([test ${check_package_generic_prefix_happy} -eq 1], [$5]) + OAC_VAR_SCOPE_POP +]) + + +dnl ************************************* OPERATIONAL CHECK ************************************* + + +dnl 1 -> package name +dnl 2 -> prefix +dnl 3 -> headers (space separated list) +dnl 4 -> function name +dnl 5 -> action if found +dnl 6 -> action if not found +AC_DEFUN([_OAC_CHECK_PACKAGE_VERIFY],[ + OAC_VAR_SCOPE_PUSH([check_package_verify_search_header check_package_verify_happy]) + + check_package_verify_search_header=`echo "$3" | cut -f1 -d' '` + + OAC_APPEND([CPPFLAGS], [${$2_CPPFLAGS}]) + OAC_APPEND([LDFLAGS], [${$2_LDFLAGS}]) + OAC_APPEND([LIBS], [${$2_LIBS}]) + + check_package_verify_happy=1 + + AS_IF([test ${check_package_verify_happy} -eq 1], + [AC_CHECK_HEADER([${check_package_verify_search_header}], + [check_package_verify_happy=1], [check_package_verify_happy=0])]) + + dnl Note that we use AC_CHEC_FUNC here instead of AC_CHECK_LIB, because we're pretty sure we've + dnl found the library already (and have added it to LIBS). Now we're just trying to verify + dnl that the library we found contains the bits we need. + AS_IF([test ${check_package_verify_happy} -eq 1], + [AC_CHECK_FUNC([$4], [check_package_verify_happy=1], [check_package_verify_happy=0])]) + + m4_ifdef([OAC_CHECK_PACKAGE_VERIFY_COMMAND_LIST], + [m4_foreach([list_item], [OAC_CHECK_PACKAGE_VERIFY_COMMAND_LIST], + [AS_IF([test ${check_package_verify_happy} -eq 1], + [m4_apply(m4_unquote([list_item]), [[$1], [$2], [$3], [$4], + [check_package_verify_happy=1], + [check_package_verify_happy=0]])])])]) + + AS_IF([test ${check_package_verify_happy} -eq 1], + [$5], [$6]) + OAC_VAR_SCOPE_POP +]) diff --git a/config/oac_linker.m4 b/config/oac_linker.m4 new file mode 100644 index 00000000..2fd2d506 --- /dev/null +++ b/config/oac_linker.m4 @@ -0,0 +1,32 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ + + +dnl OAC_LINKER_STATIC_CHECK: Check if a linker or compiler flag will force +dnl static linking +dnl +dnl 1 -> action if static linking +dnl 2 -> action if not static linking +AC_DEFUN([OAC_LINKER_STATIC_CHECK], [ +OAC_VAR_SCOPE_PUSH([oac_linker_arg]) +AC_CACHE_CHECK([if static link flag supplied], + [oac_cv_linker_found_static_linker_flag], + [oac_cv_linker_found_static_linker_flag="no" + for oac_linker_arg in ${CFLAGS} ${LDFLAGS} ; do + AS_IF([test "${oac_linker_arg}" = "-static" -o \ + "${oac_linker_arg}" = "--static" -o \ + "${oac_linker_arg}" = "-Bstatic" -o \ + "${oac_linker_arg}" = "-Wl,-static" -o \ + "${oac_linker_arg}" = "-Wl,--static" -o \ + "${oac_linker_arg}" = "-Wl,-Bstatic"], + [oac_cv_linker_found_static_linker_flag="yes"]) + done]) +AS_IF([test "${oac_cv_linker_found_static_linker_flag}" = "yes"], [$1], [$2]) +OAC_VAR_SCOPE_POP +]) diff --git a/config/oac_list.m4 b/config/oac_list.m4 new file mode 100644 index 00000000..b4b12c7e --- /dev/null +++ b/config/oac_list.m4 @@ -0,0 +1,235 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2018 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +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-2023 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2014 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015-2017 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2021-2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ + + +dnl OAC_UNIQ: Uniqify the string-seperated words in the input variable +dnl +dnl 1 -> variable name to be uniq-ized +AC_DEFUN([OAC_UNIQ],[ +OAC_VAR_SCOPE_PUSH([oac_uniq_name oac_uniq_done oac_uniq_i oac_uniq_found oac_uniq_count oac_uniq_newval oac_uniq_val]) + +oac_uniq_name=$1 + +# Go through each item in the variable and only keep the unique ones +oac_uniq_count=0 +for oac_uniq_val in ${$1}; do + oac_uniq_done=0 + oac_uniq_i=1 + oac_uniq_found=0 + + # Loop over every token we've seen so far + oac_uniq_done="`expr ${oac_uniq_i} \> ${oac_uniq_count}`" + while test ${oac_uniq_found} -eq 0 && test ${oac_uniq_done} -eq 0; do + # Have we seen this token already? Prefix the comparison with + # "x" so that "-Lfoo" values won't be cause an error. + oac_uniq_eval="expr x${oac_uniq_val} = x\${oac_uniq_array_$oac_uniq_i}" + oac_uniq_found=`eval ${oac_uniq_eval}` + + # Check the ending condition + oac_uniq_done="`expr ${oac_uniq_i} \>= ${oac_uniq_count}`" + + # Increment the counter + oac_uniq_i="`expr ${oac_uniq_i} + 1`" + done + + # If we didn't find the token, add it to the "array" + if test ${oac_uniq_found} -eq 0; then + oac_uniq_eval="oac_uniq_array_${oac_uniq}_i=${oac_uniq_val}" + eval ${oac_uniq_eval} + oac_uniq_count="`expr ${oac_uniq_count} + 1`" + else + oac_uniq_i="`expr ${oac_uniq_i} - 1`" + fi +done + +# Take all the items in the "array" and assemble them back into a +# single variable +oac_uniq_i=1 +oac_uniq_done="`expr ${oac_uniq_i} \> ${oac_uniq_count}`" +oac_uniq_newval= +while test ${oac_uniq_done} -eq 0; do + oac_uniq_eval="oac_uniq_newval=\"${oac_uniq_newval} \${oac_uniq_array_$oac_uniq_i}\"" + eval ${oac_uniq_eval} + + oac_uniq_eval="unset oac_uniq_array_${oac_uniq_i}" + eval ${oac_uniq_eval} + + oac_uniq_done="`expr ${oac_uniq_i} \>= ${oac_uniq_count}`" + oac_uniq_i="`expr ${oac_uniq_i} + 1`" +done + +# Done; do the assignment + +oac_uniq_newval="`echo ${oac_uniq_newval}`" +oac_uniq_eval="${oac_uniq_name}=\"${oac_uniq_newval}\"" +eval ${oac_uniq_eval} + +OAC_VAR_SCOPE_POP +])dnl + + +dnl OAC_APPEND: Append argument to list +dnl +dnl 1 -> variable name to append to +dnl 2 -> string to append +dnl +dnl Append the given argument ($2) to the variable name passed as $1. +dnl The list is assumed to be space separated, and $1 must be a string +dnl literal (ie, no indirection is supported). +AC_DEFUN([OAC_APPEND], +[OAC_ASSERT_LITERAL([$1]) +AS_IF([test -z "${$1}"], [$1="$2"], [$1="${$1} $2"]) +])dnl + + +dnl OAC_APPEND_UNIQ: Append argument to list if not already there +dnl +dnl 1 -> variable name to append to +dnl 2 -> string to append +dnl +dnl uniquely append arguments to a space separated list. $1 is a +dnl string literal variable name into which the arguments are +dnl inserted. $2 is a space separated list of arguments to add, each +dnl of which is individually unique-checked before insertion. +dnl +dnl This could probably be made more efficient :(. +AC_DEFUN([OAC_APPEND_UNIQ], +[OAC_ASSERT_LITERAL([$1]) +OAC_VAR_SCOPE_PUSH([oac_list_arg oac_list_found oac_list_val]) +for oac_list_arg in $2; do + oac_list_found=0; + for oac_list_val in ${$1}; do + AS_IF([test "x${oac_list_val}" = "x${oac_list_arg}"], + [oac_list_found=1 + break]) + done + AS_IF([test "${oac_list_found}" = "0"], + [OAC_APPEND([$1], [${oac_list_arg}])]) +done +OAC_VAR_SCOPE_POP +])dnl + + +dnl OAC_FLAGS_APPEND_UNIQ: Uniquely append argument to list +dnl +dnl 1 -> variable name to append to +dnl 2 -> string to append +dnl +dnl Append new_argument to variable if: +dnl +dnl - the argument does not begin with -I, -L, or -l, or +dnl - the argument begins with -I, -L, or -l, and it's not already in variable +dnl +dnl This macro assumes a space separated list. +AC_DEFUN([OAC_FLAGS_APPEND_UNIQ], +[OAC_ASSERT_LITERAL([$1]) +OAC_VAR_SCOPE_PUSH([oac_list_prefix oac_list_append oac_list_arg oac_list_val]) +for oac_list_arg in $2; do + oac_list_append=1 + AS_CASE([${oac_list_arg}], + [-I*|-L*|-l*], + [for oac_list_val in ${$1}; do + AS_IF([test "x${oal_list_val}" = "x${oac_list_arg}"], + [oac_list_append=0]) + done]) + AS_IF([test ${oac_list_append} -eq 1], + [OAC_APPEND([$1], [$oac_list_arg])]) +done +OAC_VAR_SCOPE_POP +])dnl + + +dnl OAC_FLAGS_PREPEND_UNIQ: Uniquely prepend argument to list +dnl +dnl 1 -> variable name to prepend to +dnl 2 -> string to append +dnl +dnl Prepend new_argument to variable if: +dnl +dnl - the argument does not begin with -I, -L, or -l, or +dnl - the argument begins with -I, -L, or -l, and it's not already in variable +dnl +dnl This macro assumes a space separated list. +AC_DEFUN([OAC_FLAGS_PREPEND_UNIQ], +[OAC_ASSERT_LITERAL([$1]) +OAC_VAR_SCOPE_PUSH([oac_list_prefix oac_list_prepend oac_list_arg oac_list_val]) +for oac_list_arg in $2; do + oac_list_prepend=1 + AS_CASE([${oac_list_arg}], + [-I*|-L*|-l*], + [for oac_list_val in ${$1}; do + AS_IF([test "x${oal_list_val}" = "x${oac_list_arg}"], + [oac_list_prepend=0]) + done]) + AS_IF([test ${oac_list_prepend} -eq 1], + [AS_IF([test -z "${$1}"], [$1="$2"], [$1="$2 ${$1}"])]) +done +OAC_VAR_SCOPE_POP +])dnl + + +dnl OAC_FLAGS_APPEND_MOVE: Uniquely add libraries to list +dnl +dnl 1 -> variable name to append to +dnl 2 -> string to append +dnl +dnl add new_arguments to the end of variable. +dnl +dnl If an argument in new_arguments does not begin with -I, -L, or -l OR +dnl the argument begins with -I, -L, or -l and it is not already in +dnl variable, it is appended to variable. +dnl +dnl If an argument in new_argument begins with a -l and is already in +dnl variable, the existing occurrences of the argument are removed from +dnl variable and the argument is appended to variable. This behavior +dnl is most useful in LIBS, where ordering matters and being rightmost +dnl is usually the right behavior. +dnl +dnl This macro assumes a space separated list. +AC_DEFUN([OAC_FLAGS_APPEND_MOVE], +[OAC_ASSERT_LITERAL([$1]) +OAC_VAR_SCOPE_PUSH([oac_list_arg oac_list_append oac_list_val oac_list_tmp_variable]) +for oac_list_arg in $2; do + AS_CASE([${oac_list_arg}], + [-I*|-L*], + [oac_list_append=1 + for oac_list_val in ${$1} ; do + AS_IF([test "x${oac_list_val}" = "x${oac_list_arg}"], + [oac_list_append=0]) + done + AS_IF([test ${oac_list_append} -eq 1], + [OAC_APPEND([$1], [${oac_list_arg}])])], + [-l*], + [oac_list_tmp_variable= + for oac_list_val in ${$1}; do + AS_IF([test "x${oac_list_val}" != "x${oac_list_arg}"], + [OAC_APPEND([oac_list_tmp_variable], [${oac_list_val}])]) + done + OAC_APPEND([oac_list_tmp_variable], [${oac_list_arg}]) + $1="${oac_list_tmp_variable}"], + [OAC_APPEND([$1], [${oac_list_arg}])]) +done +OAC_VAR_SCOPE_POP +])dnl diff --git a/config/oac_log.m4 b/config/oac_log.m4 new file mode 100644 index 00000000..b826ba37 --- /dev/null +++ b/config/oac_log.m4 @@ -0,0 +1,62 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2018 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +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-2020 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2014 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015-2017 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2021-2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ + + +dnl OAC_LOG_MSG: Log message in config.log, including prefix +dnl giving line number +dnl +dnl 1 -> the message to log +AC_DEFUN([OAC_LOG_MSG], +[AS_ECHO(["configure:__oline__: $1"]) >&AS_MESSAGE_LOG_FD])dnl + + +dnl OAC_LOG_MSG_NOPREFIX: Log message in config.log, with no prefix +dnl +dnl 1 -> the message to log +AC_DEFUN([OAC_LOG_MSG_NOPREFIX], +[AS_ECHO([$1]) >&AS_MESSAGE_LOG_FD])dnl + + +dnl OAC_LOG_FILE: Dump the specified file into config.log +dnl +dnl 1 -> filename of file to dump into config.log +AC_DEFUN([OAC_LOG_FILE], +[AS_IF([test -n "$1" && test -f "$1"], [cat $1 >&AS_MESSAGE_LOG_FD])])dnl + + +dnl OAC_LOG_COMMAND: Run command, logging output, and checking status +dnl +dnl 1 -> command to execute +dnl 2 -> action if successful +dnl 3 -> action if if fail +AC_DEFUN([OAC_LOG_COMMAND],[ +OAC_LOG_MSG([$1]) +$1 1>&AS_MESSAGE_LOG_FD 2>&1 +oac_log_command_status=$? +OAC_LOG_MSG([\$? = $oac_log_command_status]) +AS_IF([test $oac_log_command_status -eq 0], + [$2], [$3]) +AS_UNSET([oac_log_command_status])]) diff --git a/config/oac_var_scope.m4 b/config/oac_var_scope.m4 new file mode 100644 index 00000000..cf699235 --- /dev/null +++ b/config/oac_var_scope.m4 @@ -0,0 +1,105 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl University Research and Technology +dnl Corporation. All rights reserved. +dnl Copyright (c) 2004-2018 The University of Tennessee and The University +dnl of Tennessee Research Foundation. All rights +dnl reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +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-2020 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2014 Intel, Inc. All rights reserved. +dnl Copyright (c) 2015-2017 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2021-2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ + + +dnl OAC_VAR_SCOPE_INIT +dnl +dnl Initialization macro (that is AC_REQUIREd by OAC_VAR_SCOPE_PUSH / +dnl OAC_VAR_SCOPE_POP) for the var scope subsystem. Defines the two +dnl shell functions that implement the configure-time part of the var +dnl scope evaluation system. +AC_DEFUN([OAC_VAR_SCOPE_INIT], +[oac_var_scope_push() +{ + oac_var_scope_push_lineno=$[]1 + shift + # First, check to see if any of these variables are already set. + # This is a simple sanity check to ensure we're not already + # overwriting pre-existing variables (that have a non-empty + # value). It's not a perfect check, but at least it's something. + for oac_var_scope_tmp_var in $[]@; do + AS_VAR_SET_IF([$oac_var_scope_tmp_var], + [AS_VAR_COPY([oac_var_scope_tmp_var_val], [$oac_var_scope_tmp_var]) + m4_pattern_allow([OAC_]) + AC_MSG_ERROR([Found configure shell variable clash at line $oac_var_scope_push_lineno! +[OAC_VAR_SCOPE_PUSH] called on "$oac_var_scope_tmp_var", +but it is already defined with value "$oac_var_scope_tmp_var_val" +This usually indicates an error in configure. +Cannot continue.]) + m4_pattern_forbid([OAC_])]) + done + AS_UNSET([oac_var_scope_push_lineno]) + AS_UNSET([oac_var_scope_tmp_var]) + AS_UNSET([oac_var_scope_tmp_var_val]) +} + +oac_var_scope_pop() +{ + # Iterate over all the variables and unset them all + for oac_var_scope_tmp_var in $[]@; do + AS_UNSET([$oac_var_scope_tmp_var]) + done + AS_UNSET([oac_var_scope_tmp_var]) +}]) + + +dnl OAC_VAR_SCOPE_PUSH: Create a new variable scope +dnl +dnl 1 -> space seperated list of variable names to push into the new scope +dnl +dnl Scope-check that the vars in the space-separated vars list are not already +dnl in use. Generate a configure-time error if a conflict is found. Note that +dnl the in use check is defined as "defined", so even if a var in vars list is +dnl set outside of OAC_VAR_SCOPE_PUSH, the check will still trip. +AC_DEFUN([OAC_VAR_SCOPE_PUSH],[ +AC_REQUIRE([OAC_VAR_SCOPE_INIT])dnl +m4_pushdef([oac_var_scope_stack], [$1])dnl +m4_foreach_w([oac_var_scope_var], [$1], + [m4_set_add([oac_var_scope_active_set], oac_var_scope_var, + [], [m4_fatal([$0 found the variable ]oac_var_scope_var[ +active in a previous scope.])])])dnl +oac_var_scope_push ${LINENO} $1 +])dnl + + +dnl OAC_VAR_SCOPE_POP: pop off the current variable scope +dnl +dnl Unset the last set of variables set in OAC_VAR_SCOPE_POP. Every call to +dnl OAC_VAR_SCOPE_PUSH should have a matched call to this macro. +AC_DEFUN([OAC_VAR_SCOPE_POP],[ +AC_REQUIRE([OAC_VAR_SCOPE_INIT])dnl +m4_ifdef([oac_var_scope_stack], [], + [m4_pattern_allow([OAC_]) + m4_fatal([$0 was called without a defined +variable stack. This usually means that $0 was called more +times than OAC_VAR_SCOPE_PUSH.]) + m4_pattern_forbid([OAC_])])dnl +m4_foreach_w([oac_var_scope_var], oac_var_scope_stack, + [m4_set_remove([oac_var_scope_active_set], oac_var_scope_var)])dnl +oac_var_scope_pop oac_var_scope_stack +m4_popdef([oac_var_scope_stack])dnl +])dnl + diff --git a/config/opal_config_3rdparty.m4 b/config/opal_config_3rdparty.m4 new file mode 100644 index 00000000..e931850a --- /dev/null +++ b/config/opal_config_3rdparty.m4 @@ -0,0 +1,99 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2009-2018 Cisco Systems, Inc. All rights reserved +dnl Copyright (c) 2013 Los Alamos National Security, LLC. All rights reserved. +dnl Copyright (c) 2015-2018 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2020-2021 Amazon.com, Inc. or its affiliates. All Rights +dnl reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +dnl OPAL_3RDPARTY_WITH(short package name, long package name, +dnl internal supported, disabled ok) +dnl +dnl Basic --with-pkg/--with-pkg-libdir handling for 3rd party +dnl packages, with the big long description of internal/external/path +dnl handling. +dnl +dnl At the end of this macro, with_pkg will contain an empty string or +dnl a path (the later implying external). Further, the shell variable +dnl opal_pkg_mode will be set to "internal", "external", +dnl "unspecified", or "disabled". If a path is given to --with-pkg, then +dnl opal_pkg_mode will be set to external. If "internal supported" is +dnl not defined, then opal_pkg_mode will not be internal. If +dnl "disabled ok" is not defined, then opal_pkg_mode will not be +dnl "disabled". +dnl +dnl If m4_ifdef(internal support) does not evaluate to true (ie, at +dnl autogen time), the references to internal in the help strings will +dnl be removed and internal will not be a supported option. +dnl +dnl If m4_ifval(ddisbaled ok) does not evaluate to true (ie, at autogen +dnl time), then --without-pkg will not be a valid configure option and +dnl will raise an error. +dnl +dnl $1: short package name +dnl $2: long pacakage name +AC_DEFUN([OPAL_3RDPARTY_WITH], [ + m4_ifval([$4], + [m4_ifdef([$3], + [AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1(=DIR)], + [Build $2 support. DIR can take one of four values: "internal", "external", "no", or a valid directory name. "internal" forces Open MPI to use its internal copy of $2. "external" forces Open MPI to use an external installation of $2. Supplying a valid directory name also forces Open MPI to use an external installation of $2, and adds DIR/include, DIR/lib, and DIR/lib64 to the search path for headers and libraries. "no" means that Open MPI will not build components that require this package. If no argument is specified, Open MPI will search default locations for $2 and fall back to an internal version if one is not found.])])], + [AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1(=DIR)], + [Build $2 support. DIR can take one of three values: "external", "no", or a valid directory name. "external" forces Open MPI to use an external installation of $2. Supplying a valid directory name also forces Open MPI to use an external installation of $2, and adds DIR/include, DIR/lib, and DIR/lib64 to the search path for headers and libraries. "no" means that Open MPI will not build components that require this package. If no argument is specified, Open MPI will search default locations for $2 and error if one is not found.])])])], + [m4_ifdef([$3], + [AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1(=DIR)], + [Build $2 support. DIR can take one of three values: "internal", "external", or a valid directory name. "internal" forces Open MPI to use its internal copy of $2. "external" forces Open MPI to use an external installation of $2. Supplying a valid directory name also forces Open MPI to use an external installation of $2, and adds DIR/include, DIR/lib, and DIR/lib64 to the search path for headers and libraries. Note that Open MPI no longer supports --without-$1. If no argument is specified, Open MPI will search default locations for $2 and fall back to an internal version if one is not found.])])], + [AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1(=DIR)], + [Build $2 support. DIR can take one of two values: "external" or a valid directory name. "external" forces Open MPI to use an external installation of $2. Supplying a valid directory name also forces Open MPI to use an external installation of $2, and adds DIR/include, DIR/lib, and DIR/lib64 to the search path for headers and libraries. Note that Open MPI no longer supports --without-$1. If no argument is specified, Open MPI will search default locations for $2 and error if one is not found.])])])]) + + AC_ARG_WITH([$1-libdir], + [AS_HELP_STRING([--with-$1-libdir=DIR], + [Search for $2 libraries in DIR. Should only be used if an external copy of $2 is being used.])]) + + # Bozo check + m4_ifval([$4], [], + [AS_IF([test "$with_$1" = "no"], + [AC_MSG_WARN([It is not possible to configure Open MPI --without-$1]) + AC_MSG_ERROR([Cannot continue])])]) + + AS_IF([test "$with_$1_libdir" = "no" -o "$with_$1_libdir" = "yes"], + [AC_MSG_WARN([yes/no are invalid responses for --with-$1-libdir. Please specify a path.]) + AC_MSG_ERROR([Cannot continue])]) + + # Make sure the user didn't specify --with-$1=internal and + # --with-$1-libdir=whatever (because you can only specify + # --with-$1-libdir when external $2 is being used). + AS_IF([test "$with_$1" = "internal" && test -n "$with_$1_libdir"], + [AC_MSG_WARN([Both --with-$1=internal and --with-$1-libdir=DIR]) + AC_MSG_WARN([were specified, which does not make sense.]) + AC_MSG_ERROR([Cannot continue])]) + + # clean up $with_$1 so that it contains only a path or empty + # string. To determine internal or external preferences, use + # $opal_$1_mode. + AS_IF([test "$with_$1" = "yes"], [with_$1=]) + AS_CASE([$with_$1], + ["internal"], [with_$1="" + opal_$1_mode="internal"], + ["external"], [with_$1="" + opal_$1_mode="external"], + ["no"], [with_$1="" + opal_$1_mode="disabled"], + [""], [opal_$1_mode="unspecified"], + [opal_$1_mode="external"]) + + m4_ifdef([$3], [], + [AS_IF([test "$opal_$1_mode" = "internal"], + [AC_MSG_WARN([Invalid argument to --with-$1: internal.]) + AC_MSG_ERROR([Cannot continue])])]) +]) diff --git a/config/opal_config_hwloc.m4 b/config/opal_config_hwloc.m4 new file mode 100644 index 00000000..779e3daa --- /dev/null +++ b/config/opal_config_hwloc.m4 @@ -0,0 +1,274 @@ +dnl -*- autoconf -*- +dnl +dnl Copyright (c) 2009-2017 Cisco Systems, Inc. All rights reserved +dnl Copyright (c) 2014-2018 Research Organization for Information Science +dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2020-2022 Amazon.com, Inc. or its affiliates. All Rights reserved. +dnl Copyright (c) 2020 Intel, Inc. All rights reserved. +dnl Copyright (c) 2022 IBM Corporation. All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +dnl Check for / configure hwloc package. Prefer finding an +dnl external hwloc, build our internal one if required. If we can +dnl not find an external hwloc and the internal one fails to +dnl configure, abort. +dnl +dnl This macro will change the environment in the following way: +dnl +dnl * opal_hwloc_mode - either external or internal. If internal, +dnl --with-hwloc should be ignored by other packages +dnl * CPPFLAGS, LDFLAGS, LIBS - Updated to build against hwloc. +dnl Note that the values may be updated right before +dnl config.status. +dnl +dnl OPAL_WRAPPER_FLAGS_ADD will be called to add the correct LDFLAGS, +dnl STATIC_LDFLAGS, LIBS, and STATIC_LIBS for hwloc. +dnl +dnl The following environment variables will only be set if +dnl opal_hwloc_mode is "internal": +dnl +dnl * opal_hwloc_BUILD_CPPFLAGS - the C Preprocessor flags +dnl necessary to run the preprocessor on a file which relies +dnl on hwloc headers. This will be folded into the global +dnl CPPFLAGS (see note above). +dnl * opal_hwloc_BUILD_LIBS - the libraries necessary to link +dnl source which uses hwloc. Cannot be added to LIBS yet, +dnl because then other execution tests later in configure +dnl (there are sadly some) would fail if the path in LDFLAGS +dnl was not added to LD_LIBRARY_PATH. +dnl * opal_hwloc_WRAPPER_LIBS - the linker flags necessary to +dnl add to the wrapper compilers in order to link an opal +dnl application when opal is built as a static library. +AC_DEFUN([OPAL_CONFIG_HWLOC], [ + OPAL_VAR_SCOPE_PUSH([external_hwloc_happy internal_hwloc_happy opal_hwloc_STATIC_LDFLAGS opal_hwloc_LIBS opal_hwloc_STATIC_LIBS]) + + opal_show_subtitle "Configuring hwloc" + + OPAL_3RDPARTY_WITH([hwloc], [hwloc], [package_hwloc]) + + # unless internal specifically requested by the user, try to find + # an external that works. + external_hwloc_happy=0 + AS_IF([test "$opal_hwloc_mode" != "internal"], + [_OPAL_CONFIG_HWLOC_EXTERNAL( + [external_hwloc_happy=1 + opal_hwloc_mode="external"], + [external_hwloc_happy=0 + AS_IF([test "$opal_hwloc_mode" = "external"], + [AC_MSG_ERROR([External hwloc requested but not found.])])])]) + + internal_hwloc_happy=0 + m4_ifdef([package_hwloc], + [AS_IF([test "$external_hwloc_happy" = "0"], + [_OPAL_CONFIG_HWLOC_INTERNAL([internal_hwloc_happy=1 + opal_hwloc_mode="internal"])])]) + + AS_IF([test "$external_hwloc_happy" = "0" -a "$internal_hwloc_happy" = "0"], + [AC_MSG_ERROR([Could not find viable hwloc build.])]) + + dnl this will work even if there is no hwloc package included, + dnl because hwloc_tarball and hwloc_directory will evaluate to an + dnl empty string. These are relative to the 3rd-party/ directory. + OPAL_3RDPARTY_EXTRA_DIST="$OPAL_3RDPARTY_EXTRA_DIST hwloc_tarball" + OPAL_3RDPARTY_DISTCLEAN_DIRS="$OPAL_3RDPARTY_DISTCLEAN_DIRS hwloc_directory" + + OPAL_WRAPPER_FLAGS_ADD([LDFLAGS], [${opal_hwloc_LDFLAGS}]) + OPAL_WRAPPER_FLAGS_ADD([STATIC_LDFLAGS], [${opal_hwloc_STATIC_LDFLAGS}]) + OPAL_WRAPPER_FLAGS_ADD([LIBS], [${opal_hwloc_LIBS}]) + OPAL_WRAPPER_FLAGS_ADD([STATIC_LIBS], [${opal_hwloc_STATIC_LIBS}]) + OPAL_WRAPPER_FLAGS_ADD([PC_MODULES], [${opal_hwloc_PC_MODULES}]) + + AC_CONFIG_COMMANDS_PRE([OPAL_CONFIG_HWLOC_INTERNAL_LIBS_HANDLER]) + + OPAL_SUMMARY_ADD([Miscellaneous], [hwloc], [], [$opal_hwloc_mode]) + + OPAL_VAR_SCOPE_POP +]) + + +dnl _OPAL_CONFIG_HWLOC_EXTERNAL(action-if-happy, action-if-not-happy) +dnl +dnl only safe to call from OPAL_CONFIG_HWLOC, assumes variables from +dnl there are set. +AC_DEFUN([_OPAL_CONFIG_HWLOC_EXTERNAL], [ + OPAL_VAR_SCOPE_PUSH([opal_hwloc_min_num_version opal_hwloc_min_version opal_hwlox_max_num_version opal_hwloc_CPPFLAGS_save opal_hwloc_LDFLAGS_save opal_hwloc_LIBS_save opal_hwloc_external_support]) + + OAC_CHECK_PACKAGE([hwloc], + [opal_hwloc], + [hwloc.h], + [hwloc], + [hwloc_topology_init], + [opal_hwloc_external_support=yes], + [opal_hwloc_external_support=no]) + + # need these set for the tests below. + opal_hwloc_CPPFLAGS_save=$CPPFLAGS + opal_hwloc_LDFLAGS_save=$LDFLAGS + opal_hwloc_LIBS_save=$LIBS + + OPAL_FLAGS_APPEND_UNIQ([CPPFLAGS], [$opal_hwloc_CPPFLAGS]) + OPAL_FLAGS_APPEND_UNIQ([LDFLAGS], [$opal_hwloc_LDFLAGS]) + OPAL_FLAGS_APPEND_UNIQ([LIBS], [$opal_hwloc_LIBS]) + + opal_hwloc_min_num_version=OMPI_HWLOC_NUMERIC_MIN_VERSION + opal_hwloc_min_version=OMPI_HWLOC_NUMERIC_MIN_VERSION + AS_IF([test "$opal_hwloc_external_support" = "yes"], + [AC_MSG_CHECKING([if external hwloc version is version OMPI_HWLOC_MIN_VERSION or greater]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + ]], [[ +#if HWLOC_API_VERSION < $opal_hwloc_min_num_version +#error "hwloc API version is less than $opal_hwloc_min_version" +#endif + ]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_WARN([external hwloc version is too old (OMPI_HWLOC_MIN_VERSION or later required)]) + opal_hwloc_external_support="no"])]) + + # Ensure that we are not using Hwloc >= v3.x. Open MPI does not + # (yet) support Hwloc >= v3.x (which will potentially have ABI and + # API breakage compared to <= v2.x), and using it would lead to + # complicated failure cases. Hence, we just abort outright if we + # find an external Hwloc >= v3.x. + AS_IF([test "$opal_hwloc_external_support" = "yes"], + [AC_MSG_CHECKING([if external hwloc version is less than version 3.0.0]) + opal_hwloc_max_num_version=0x00030000 + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + ]], [[ +#if HWLOC_API_VERSION >= $opal_hwloc_max_num_version +#error "hwloc API version is >= $opal_hwloc_max_num_version" +#endif + ]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_WARN([External hwloc version is too new (less than v3.0.0 is required)]) + dnl Yes, the URL below will be wrong for master + dnl builds. But this is "good enough" -- we're + dnl more concerned about getting the URL correct + dnl for end-user builds of official release Open + dnl MPI distribution tarballs. + AC_MSG_WARN([See https://docs.open-mpi.org/en/v$OMPI_MAJOR_VERSION.$OMPI_MINOR_VERSION.x/installing-open-mpi/required-support-libraries.html for more details]) + AC_MSG_ERROR([Cannot continue])])]) + + AS_IF([test "$opal_hwloc_external_support" = "yes"], + [AC_CHECK_DECLS([HWLOC_OBJ_OSDEV_COPROC], [], [], [#include +]) + AC_CHECK_FUNCS([hwloc_topology_dup])]) + + CPPFLAGS="$opal_hwloc_CPPFLAGS_save" + LDFLAGS="$opal_hwloc_LDFLAGS_save" + LIBS="$opal_hwloc_LIBS_save" + + AS_IF([test "$opal_hwloc_external_support" = "yes"], + [dnl Do not add hwloc libs to LIBS until late, because + dnl it will screw up other tests (like the pthread tests) + opal_hwloc_BUILD_LIBS="${opal_hwloc_LIBS}" + + $1], + [$2]) + + OPAL_VAR_SCOPE_POP +]) + +dnl _OPAL_CONFIG_HWLOC_INTERNAL(action-if-happy, action-if-not-happy) +dnl +dnl Configure the packaged hwloc. Only needs to be run if the +dnl external hwloc is not going to be used. Assumes that if +dnl this function is called, that success means the internal package +dnl will be used. +AC_DEFUN([_OPAL_CONFIG_HWLOC_INTERNAL], [ + OPAL_VAR_SCOPE_PUSH([subconfig_happy internal_hwloc_location extra_configure_args found_enable_plugins hwloc_config_arg pkg_config_file pkg_config_happy]) + + extra_configure_args= + + # look for a --{enable/disable}-plugins option in the top level + # configure arguments, so that we can add --enable-plugins if + # appropriate. + found_enable_plugins=0 + eval "set x $ac_configure_args" + shift + for hwloc_config_arg + do + case $hwloc_config_arg in + --enable-plugins|--enable-plugins=*|--disable-plugins) + found_enable_plugins=1 + ;; + esac + done + + # while the plugins in hwloc are not explicitly using Open MPI's dlopen + # interface, it seems rude to enable plugins in hwloc if the builder asked + # us not to use plugins in Open MPI. So only enable plugins in hwloc if there's + # a chance we're going to do so. We enable plugins by default so that libhwloc + # does not end up with a dependency on libcuda, which would mean everything else + # would end up with a dependency on libcuda (and similar). + AS_IF([test $found_enable_plugins -eq 0 -a "$enable_dlopen" != "no"], + [extra_configure_args="--enable-plugins"]) + + # Note: To update the version of hwloc shipped, update the + # constant in autogen.pl. + OPAL_EXPAND_TARBALL([3rd-party/hwloc_tarball], [3rd-party/hwloc_directory], [configure]) + OPAL_SUBDIR_ENV_CLEAN([opal_hwloc_configure]) + PAC_CONFIG_SUBDIR_ARGS([3rd-party/hwloc_directory], [$extra_configure_args], [[--enable-debug]], + [subconfig_happy=1], [subconfig_happy=0]) + OPAL_SUBDIR_ENV_RESTORE([opal_hwloc_configure]) + + AS_IF([test ${subconfig_happy} -eq 1], + [internal_hwloc_location="3rd-party/hwloc_directory" + + dnl We do not consider it an error if pkg-config doesn't work / exist / etc. + pkg_config_file="${OMPI_TOP_BUILDDIR}/3rd-party/hwloc_directory/hwloc.pc" + pkg_config_happy=0 + + OAC_CHECK_PACKAGE_PARSE_PKGCONFIG([hwloc_internal], [opal_hwloc], [${pkg_config_file}], [pkg_config_happy=1]) + + dnl Don't pull LDFLAGS, because we don't have a good way to avoid + dnl a -L to our install directory, which can cause some weirdness + dnl if there's an old OMPI install there. And it makes filtering + dnl redundant flags easier. + opal_hwloc_LDFLAGS= + + dnl with no pkg-config data, guess. assume that -L${libdir} is already added to LDFLAGS + AS_IF([test $pkg_config_happy -eq 0], + [opal_hwloc_STATIC_LDFLAGS= + opal_hwloc_LIBS="-lhwloc" + opal_hwloc_STATIC_LIBS= + opal_hwloc_PC_MODULES=]) + + # note: because we only ship/commit a tarball (and not the + # source directory), the source is always expanded in the + # builddir, so we only need to add a -I to the builddir. + # Overwrite the OAC_CHECK_PACKAGE_PARSE PKGCONFIG results, + # because it's the install dir location, not the build + # location. + opal_hwloc_CPPFLAGS="-I$OMPI_TOP_BUILDDIR/$internal_hwloc_location/include -I$OMPI_TOP_SRCDIR/$internal_hwloc_location/include" + opal_hwloc_BUILD_CPPFLAGS="${opal_hwloc_CPPFLAGS}" + + # No need to update LDFLAGS, because they will install into + # our tree and in the mean time are referenced by their .la + # files. + opal_hwloc_BUILD_LIBS="$OMPI_TOP_BUILDDIR/$internal_hwloc_location/hwloc/libhwloc.la" + opal_hwloc_WRAPPER_LIBS="${opal_hwloc_LIBS}" + + # no need to add to DIST_SUBDIRS, because we only ship the + # tarball. This is relative to the 3rd-party/ directory. + OPAL_3RDPARTY_SUBDIRS="$OPAL_3RDPARTY_SUBDIRS hwloc_directory" + + $1], [$2]) + + OPAL_VAR_SCOPE_POP +]) + + +dnl We need to delay adding .la files to LIBS until the very end of +dnl configure, to avoid pulling it into other configure tests. +AC_DEFUN([OPAL_CONFIG_HWLOC_INTERNAL_LIBS_HANDLER], [ + OPAL_FLAGS_APPEND_UNIQ([CPPFLAGS], [${opal_hwloc_CPPFLAGS}]) + OPAL_FLAGS_APPEND_UNIQ([LDFLAGS], [$opal_hwloc_LDFLAGS]) + OPAL_FLAGS_APPEND_MOVE([LIBS], [${opal_hwloc_BUILD_LIBS}]) +]) diff --git a/config/opal_functions.m4 b/config/opal_functions.m4 index 84ebc71b..080cef6e 100644 --- a/config/opal_functions.m4 +++ b/config/opal_functions.m4 @@ -16,6 +16,8 @@ dnl Copyright (c) 2009-2020 Cisco Systems, Inc. All rights reserved. dnl Copyright (c) 2014 Intel, Inc. All rights reserved. dnl Copyright (c) 2015-2017 Research Organization for Information Science dnl and Technology (RIST). All rights reserved. +dnl Copyright (c) 2021 Amazon.com, Inc. or its affiliates. All Rights +dnl reserved. dnl dnl $COPYRIGHT$ dnl @@ -200,274 +202,52 @@ dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -AC_DEFUN([OPAL_LOG_MSG],[ # 1 is the message # 2 is whether to put a prefix or not -if test -n "$2"; then - echo "configure:__oline__: $1" >&5 -else - echo $1 >&5 -fi])dnl +AC_DEFUN([OPAL_LOG_MSG], +[AS_IF([test -n "$2"], [OAC_LOG_MSG([$1])], [OAC_LOG_MSG_NOPREFIX([$1])])]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -AC_DEFUN([OPAL_LOG_FILE],[ -# 1 is the filename -if test -n "$1" && test -f "$1"; then - cat $1 >&5 -fi])dnl +m4_copy([OAC_LOG_FILE], [OPAL_LOG_FILE]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -AC_DEFUN([OPAL_LOG_COMMAND],[ -# 1 is the command -# 2 is actions to do if success -# 3 is actions to do if fail -echo "configure:__oline__: $1" >&5 -$1 1>&5 2>&1 -opal_status=$? -OPAL_LOG_MSG([\$? = $opal_status], 1) -if test "$opal_status" = "0"; then - unset opal_status - $2 -else - unset opal_status - $3 -fi])dnl +m4_copy([OAC_LOG_COMMAND], [OPAL_LOG_COMMAND]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -AC_DEFUN([OPAL_UNIQ],[ -# 1 is the variable name to be uniq-ized -opal_name=$1 - -# Go through each item in the variable and only keep the unique ones - -opal_count=0 -for val in ${$1}; do - opal_done=0 - opal_i=1 - opal_found=0 - - # Loop over every token we've seen so far - - opal_done="`expr $opal_i \> $opal_count`" - while test "$opal_found" = "0" && test "$opal_done" = "0"; do - - # Have we seen this token already? Prefix the comparison with - # "x" so that "-Lfoo" values won't be cause an error. - - opal_eval="expr x$val = x\$opal_array_$opal_i" - opal_found=`eval $opal_eval` - - # Check the ending condition - - opal_done="`expr $opal_i \>= $opal_count`" - - # Increment the counter - - opal_i="`expr $opal_i + 1`" - done - - # If we didn't find the token, add it to the "array" - - if test "$opal_found" = "0"; then - opal_eval="opal_array_$opal_i=$val" - eval $opal_eval - opal_count="`expr $opal_count + 1`" - else - opal_i="`expr $opal_i - 1`" - fi -done - -# Take all the items in the "array" and assemble them back into a -# single variable - -opal_i=1 -opal_done="`expr $opal_i \> $opal_count`" -opal_newval= -while test "$opal_done" = "0"; do - opal_eval="opal_newval=\"$opal_newval \$opal_array_$opal_i\"" - eval $opal_eval - - opal_eval="unset opal_array_$opal_i" - eval $opal_eval - - opal_done="`expr $opal_i \>= $opal_count`" - opal_i="`expr $opal_i + 1`" -done - -# Done; do the assignment - -opal_newval="`echo $opal_newval`" -opal_eval="$opal_name=\"$opal_newval\"" -eval $opal_eval - -# Clean up - -unset opal_name opal_i opal_done opal_newval opal_eval opal_count])dnl +m4_copy([OAC_UNIQ], [OPAL_UNIQ]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -# OPAL_APPEND_UNIQ(variable, new_argument) -# ---------------------------------------- -# Append new_argument to variable if not already in variable. This assumes a -# space separated list. -# -# This could probably be made more efficient :(. -AC_DEFUN([OPAL_APPEND_UNIQ], [ -for arg in $2; do - opal_found=0; - for val in ${$1}; do - if test "x$val" = "x$arg" ; then - opal_found=1 - break - fi - done - if test "$opal_found" = "0" ; then - if test -z "$$1"; then - $1="$arg" - else - $1="$$1 $arg" - fi - fi -done -unset opal_found -]) +m4_copy([OAC_APPEND], [OPAL_APPEND]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -# Remove all duplicate -I, -L, and -l flags from the variable named $1 -AC_DEFUN([OPAL_FLAGS_UNIQ],[ - # 1 is the variable name to be uniq-ized - opal_name=$1 - - # Go through each item in the variable and only keep the unique ones - - opal_count=0 - for val in ${$1}; do - opal_done=0 - opal_i=1 - opal_found=0 - - # Loop over every token we've seen so far - - opal_done="`expr $opal_i \> $opal_count`" - while test "$opal_found" = "0" && test "$opal_done" = "0"; do - - # Have we seen this token already? Prefix the comparison - # with "x" so that "-Lfoo" values won't be cause an error. - - opal_eval="expr x$val = x\$opal_array_$opal_i" - opal_found=`eval $opal_eval` - - # Check the ending condition - - opal_done="`expr $opal_i \>= $opal_count`" - - # Increment the counter - - opal_i="`expr $opal_i + 1`" - done - - # Check for special cases where we do want to allow repeated - # arguments (per - # http://www.open-mpi.org/community/lists/devel/2012/08/11362.php - # and - # https://github.com/open-mpi/ompi/issues/324). - - case $val in - -Xclang) - opal_found=0 - opal_i=`expr $opal_count + 1` - ;; - -framework) - opal_found=0 - opal_i=`expr $opal_count + 1` - ;; - --param) - opal_found=0 - opal_i=`expr $opal_count + 1` - ;; - esac - - # If we didn't find the token, add it to the "array" +m4_copy([OAC_APPEND_UNIQ], [OPAL_APPEND_UNIQ]) - if test "$opal_found" = "0"; then - opal_eval="opal_array_$opal_i=$val" - eval $opal_eval - opal_count="`expr $opal_count + 1`" - else - opal_i="`expr $opal_i - 1`" - fi - done - - # Take all the items in the "array" and assemble them back into a - # single variable - - opal_i=1 - opal_done="`expr $opal_i \> $opal_count`" - opal_newval= - while test "$opal_done" = "0"; do - opal_eval="opal_newval=\"$opal_newval \$opal_array_$opal_i\"" - eval $opal_eval - - opal_eval="unset opal_array_$opal_i" - eval $opal_eval - - opal_done="`expr $opal_i \>= $opal_count`" - opal_i="`expr $opal_i + 1`" - done - - # Done; do the assignment - - opal_newval="`echo $opal_newval`" - opal_eval="$opal_name=\"$opal_newval\"" - eval $opal_eval - - # Clean up +dnl ####################################################################### +dnl ####################################################################### +dnl ####################################################################### - unset opal_name opal_i opal_done opal_newval opal_eval opal_count -])dnl +m4_copy([OAC_FLAGS_APPEND_UNIQ], [OPAL_FLAGS_APPEND_UNIQ]) dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -# OPAL_FLAGS_APPEND_UNIQ(variable, new_argument) -# ---------------------------------------------- -# Append new_argument to variable if: -# -# - the argument does not begin with -I, -L, or -l, or -# - the argument begins with -I, -L, or -l, and it's not already in variable -# -# This macro assumes a space separated list. -AC_DEFUN([OPAL_FLAGS_APPEND_UNIQ], [ - OPAL_VAR_SCOPE_PUSH([opal_tmp opal_append]) - - for arg in $2; do - opal_tmp=`echo $arg | cut -c1-2` - opal_append=1 - AS_IF([test "$opal_tmp" = "-I" || test "$opal_tmp" = "-L" || test "$opal_tmp" = "-l"], - [for val in ${$1}; do - AS_IF([test "x$val" = "x$arg"], [opal_append=0]) - done]) - AS_IF([test "$opal_append" = "1"], - [AS_IF([test -z "$$1"], [$1=$arg], [$1="$$1 $arg"])]) - done - - OPAL_VAR_SCOPE_POP -]) +m4_copy([OAC_FLAGS_APPEND_MOVE], [OPAL_FLAGS_APPEND_MOVE]) dnl ####################################################################### dnl ####################################################################### @@ -480,87 +260,128 @@ dnl ####################################################################### # of the assignment in foo=`which `). This macro ensures that we # get a sane executable value. AC_DEFUN([OPAL_WHICH],[ -# 1 is the variable name to do "which" on -# 2 is the variable name to assign the return value to - -OPAL_VAR_SCOPE_PUSH([opal_prog opal_file opal_dir opal_sentinel]) + # 1 is the variable name to do "which" on + # 2 is the variable name to assign the return value to + + OPAL_VAR_SCOPE_PUSH([opal_prog opal_file opal_dir opal_sentinel]) + + opal_prog=$1 + + # There are 3 cases: + + # 1. opal_prog is an absolute filename. If that absolute filename + # exists and is executable, return $2 with that name. Otherwise, + # $2 is unchanged. + + # 2. opal_prog is a relative filename (i.e., it contains one or + # more /, but does not begin with a /). If that file exists + # relative to where we are right now in the filesystem and is + # executable, return the absolute path of that value in $2. + # Otherwise, $2 is unchanged. + + # 3. opal_prog contains no /. Search the PATH for an executable + # with the appropriate name. If found, return the absolute path + # in $2. Otherwise, $2 is unchanged. + + # Note that these three cases are exactly what which(1) does. + + # Note the double square brackets around the case expressions for + # m4 escaping. + case $opal_prog in + [[\\/]]* | ?:[[\\/]]* ) + # Case 1: absolute + AS_IF([test -x "$opal_prog"], + [$2=$opal_prog]) + ;; + + *[[\\/]]*) + # Case 2: relative with 1 or more / + AS_IF([test -x "$opal_prog"], + [$2="$cwd/$opal_prog"]) + ;; + + *) + # Case 3: no / at all + IFS_SAVE=$IFS + IFS=$PATH_SEPARATOR + for opal_dir in $PATH; do + AS_IF([test -x "$opal_dir/$opal_prog"], + [$2="$opal_dir/$opal_prog"]) + done + IFS=$IFS_SAVE + ;; + esac -opal_prog=$1 - -IFS_SAVE=$IFS -IFS="$PATH_SEPARATOR" -for opal_dir in $PATH; do - if test -x "$opal_dir/$opal_prog"; then - $2="$opal_dir/$opal_prog" - break - fi -done -IFS=$IFS_SAVE - -OPAL_VAR_SCOPE_POP + OPAL_VAR_SCOPE_POP ])dnl dnl ####################################################################### dnl ####################################################################### dnl ####################################################################### -# Declare some variables; use OPAL_VAR_SCOPE_POP to ensure that they -# are cleaned up / undefined. -AC_DEFUN([OPAL_VAR_SCOPE_PUSH],[ - - # Is the private index set? If not, set it. - if test "x$opal_scope_index" = "x"; then - opal_scope_index=1 - fi - +AC_DEFUN([OPAL_VAR_SCOPE_INIT], +[opal_var_scope_push() +{ + opal_var_scope_push_lineno=$[]1 + shift # First, check to see if any of these variables are already set. # This is a simple sanity check to ensure we're not already # overwriting pre-existing variables (that have a non-empty # value). It's not a perfect check, but at least it's something. - for opal_var in $1; do - opal_str="opal_str=\"\$$opal_var\"" - eval $opal_str - - if test "x$opal_str" != "x"; then - AC_MSG_WARN([Found configure shell variable clash at line $LINENO!]) - AC_MSG_WARN([[OPAL_VAR_SCOPE_PUSH] called on "$opal_var",]) - AC_MSG_WARN([but it is already defined with value "$opal_str"]) - AC_MSG_WARN([This usually indicates an error in configure.]) - AC_MSG_ERROR([Cannot continue]) - fi + for opal_var_scope_tmp_var in $[]@; do + AS_VAR_SET_IF([$opal_var_scope_tmp_var], + [AS_VAR_COPY([opal_var_scope_tmp_var_val], [$opal_var_scope_tmp_var]) + AC_MSG_WARN([Found configure shell variable clash at line $opal_var_scope_push_lineno!]) + AC_MSG_WARN([[OPAL_VAR_SCOPE_PUSH] called on "$opal_var_scope_tmp_var",]) + AC_MSG_WARN([but it is already defined with value "$opal_var_scope_tmp_var_val"]) + AC_MSG_WARN([This usually indicates an error in configure.]) + AC_MSG_ERROR([Cannot continue])]) done + AS_UNSET([opal_var_scope_push_lineno]) + AS_UNSET([opal_var_scope_tmp_var]) + AS_UNSET([opal_var_scope_tmp_var_val]) +} - # Ok, we passed the simple sanity check. Save all these names so - # that we can unset them at the end of the scope. - opal_str="opal_scope_$opal_scope_index=\"$1\"" - eval $opal_str - unset opal_str - - env | grep opal_scope - opal_scope_index=`expr $opal_scope_index + 1` -])dnl - -# Unset a bunch of variables that were previously set -AC_DEFUN([OPAL_VAR_SCOPE_POP],[ - # Unwind the index - opal_scope_index=`expr $opal_scope_index - 1` - opal_scope_test=`expr $opal_scope_index \> 0` - if test "$opal_scope_test" = "0"; then - AC_MSG_WARN([[OPAL_VAR_SCOPE_POP] popped too many OPAL configure scopes.]) - AC_MSG_WARN([This usually indicates an error in configure.]) - AC_MSG_ERROR([Cannot continue]) - fi - - # Get the variable names from that index - opal_str="opal_str=\"\$opal_scope_$opal_scope_index\"" - eval $opal_str - +opal_var_scope_pop() +{ # Iterate over all the variables and unset them all - for opal_var in $opal_str; do - unset $opal_var + for opal_var_scope_tmp_var in $[]@; do + AS_UNSET([$opal_var_scope_tmp_var]) done + AS_UNSET([opal_var_scope_tmp_var]) +}]) + +# OPAL_VAR_SCOPE_PUSH(vars list) +# ------------------------------ +# Scope-check that the vars in the space-separated vars list are not already +# in use. Generate a configure-time error if a conflict is found. Note that +# the in use check is defined as "defined", so even if a var in vars list is +# set outside of OPAL_VAR_SCOPE_PUSH, the check will still trip. +AC_DEFUN([OPAL_VAR_SCOPE_PUSH],[ + AC_REQUIRE([OPAL_VAR_SCOPE_INIT])dnl + m4_pushdef([opal_var_scope_stack], [$1])dnl + m4_foreach_w([opal_var_scope_var], [$1], + [m4_set_add([opal_var_scope_active_set], opal_var_scope_var, + [], [m4_fatal([OPAL_VAR_SCOPE_PUSH found the variable ]opal_var_scope_var[ +active in a previous scope.])])])dnl + opal_var_scope_push ${LINENO} $1 ])dnl +# OPAL_VAR_SCOPE_POP() +# -------------------- +# Unset the last set of variables set in OPAL_VAR_SCOPE_POP. Every call to +# OPAL_VAR_SCOPE_PUSH should have a matched call to this macro. +AC_DEFUN([OPAL_VAR_SCOPE_POP],[ + AC_REQUIRE([OPAL_VAR_SCOPE_INIT])dnl + m4_ifdef([opal_var_scope_stack], [], + [m4_fatal([OPAL_VAR_SCOPE_POP was called without a defined +variable stack. This usually means that OPAL_VAR_SCOPE_POP was called more +times than OPAL_VAR_SCOPE_PUSH.])])dnl + m4_foreach_w([opal_var_scope_var], opal_var_scope_stack, + [m4_set_remove([opal_var_scope_active_set], opal_var_scope_var)])dnl + opal_var_scope_pop opal_var_scope_stack + m4_popdef([opal_var_scope_stack])dnl +])dnl dnl ####################################################################### dnl ####################################################################### @@ -576,8 +397,8 @@ AC_DEFUN([OPAL_WITH_OPTION_MIN_MAX_VALUE], [ max_value=[$2] AC_MSG_CHECKING([maximum length of ]m4_translit($1, [_], [ ])) AC_ARG_WITH([max-]m4_translit($1, [_], [-]), - AC_HELP_STRING([--with-max-]m4_translit($1, [_], [-])[=VALUE], - [maximum length of ]m4_translit($1, [_], [ ])[s. VALUE argument has to be specified (default: [$2]).])) + [AS_HELP_STRING([--with-max-]m4_translit($1, [_], [-])[=VALUE], + [maximum length of ]m4_translit($1, [_], [ ])[s. VALUE argument has to be specified (default: [$2]).])]) if test ! -z "$with_max_[$1]" && test "$with_max_[$1]" != "no" ; then # Ensure it's a number (hopefully an integer!), and >0 expr $with_max_[$1] + 1 > /dev/null 2> /dev/null diff --git a/config/opal_setup_wrappers.m4 b/config/opal_setup_wrappers.m4 index 36795a56..bf101280 100644 --- a/config/opal_setup_wrappers.m4 +++ b/config/opal_setup_wrappers.m4 @@ -1,4 +1,4 @@ -dnl -*- shell-script -*- +dnl -*- autoconf -*- dnl dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana dnl University Research and Technology @@ -11,12 +11,13 @@ dnl University of Stuttgart. All rights reserved. dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl All rights reserved. dnl Copyright (c) 2006-2010 Oracle and/or its affiliates. All rights reserved. -dnl Copyright (c) 2009-2016 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2009-2021 Cisco Systems, Inc. All rights reserved. dnl Copyright (c) 2015-2017 Research Organization for Information Science dnl and Technology (RIST). All rights reserved. dnl Copyright (c) 2016 IBM Corporation. All rights reserved. dnl Copyright (c) 2020 Triad National Security, LLC. All rights dnl reserved. +dnl Copyright (c) 2021-2022 Amazon.com, Inc. or its affiliates. All Rights reserved. dnl $COPYRIGHT$ dnl dnl Additional copyrights may follow @@ -41,8 +42,12 @@ AC_DEFUN([OPAL_WRAPPER_FLAGS_ADD], [ [$1], [CXXFLAGS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_cxxflags], [$2])], [$1], [FCFLAGS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_fcflags], [$2])], [$1], [LDFLAGS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_ldflags], [$2])], - [$1], [LIBS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_libs], [$2])], + [$1], [STATIC_LDFLAGS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_static_ldflags], [$2])], + [$1], [LIBS], [OPAL_FLAGS_APPEND_MOVE([wrapper_extra_libs], [$2])], + [$1], [STATIC_LIBS], [OPAL_FLAGS_APPEND_UNIQ([wrapper_extra_static_libs], [$2])], + [$1], [PC_MODULES], [OPAL_APPEND_UNIQ([wrapper_extra_pkgconfig_modules], [$2])], [m4_fatal([Unknown wrapper flag type $1])]) + opal_show_verbose "Adding \"$2\" to \"$1\"" ]) @@ -77,51 +82,80 @@ AC_DEFUN([OPAL_WRAPPER_FLAGS_ADD], [ # _prefix, configure is not. There's no known use case for # doing so, and we'd like to force the issue. AC_DEFUN([OPAL_SETUP_WRAPPER_INIT],[ + dnl for OPAL_CC + AC_REQUIRE([OPAL_SETUP_CC]) + + opal_show_subtitle "Wrapper compiler setup" + + OPAL_VAR_SCOPE_PUSH([wrapper_cc_tmp]) + AC_ARG_WITH([wrapper_cc], + [AS_HELP_STRING([--with-wrapper-cc=path], + [Set a different wrapper C compiler than the one used to build Open MPI])], + [], [with_wrapper_cc="$OPAL_CC"]) + + AC_MSG_CHECKING([for wrapper C compiler]) + + if test "$with_wrapper_cc" = "yes" || test "$with_wrapper_cc" = "no" ; then + AC_MSG_ERROR([--with-wrapper-cc must have an argument.]) + fi + + # Get the full path to the wrapper compiler. If it doesn't exist + # assume that the path is not currently valid. + wrapper_tmp="$(type -p "$with_wrapper_cc")" + if test -z "$wrapper_tmp" ; then + AC_MSG_WARN([could not find "$with_wrapper_cc" in path]) + fi + WRAPPER_CC=$with_wrapper_cc + + AC_MSG_RESULT([$WRAPPER_CC]) + + AC_SUBST([WRAPPER_CC]) + AC_ARG_WITH([wrapper-cflags], - [AC_HELP_STRING([--with-wrapper-cflags], + [AS_HELP_STRING([--with-wrapper-cflags], [Extra flags to add to CFLAGS when using mpicc])]) AS_IF([test "$with_wrapper_cflags" = "yes" || test "$with_wrapper_cflags" = "no"], [AC_MSG_ERROR([--with-wrapper-cflags must have an argument.])]) AC_ARG_WITH([wrapper-cflags-prefix], - [AC_HELP_STRING([--with-wrapper-cflags-prefix], + [AS_HELP_STRING([--with-wrapper-cflags-prefix], [Extra flags (before user flags) to add to CFLAGS when using mpicc])]) AS_IF([test "$with_wrapper_cflags_prefix" = "yes" || test "$with_wrapper_cflags_prefix" = "no"], [AC_MSG_ERROR([--with-wrapper-cflags-prefix must have an argument.])]) - AC_ARG_WITH([wrapper-cxxflags], - [AC_HELP_STRING([--with-wrapper-cxxflags], - [Extra flags to add to CXXFLAGS when using mpiCC/mpic++])]) - AS_IF([test "$with_wrapper_cxxflags" = "yes" || test "$with_wrapper_cxxflags" = "no"], - [AC_MSG_ERROR([--with-wrapper-cxxflags must have an argument.])]) - - AC_ARG_WITH([wrapper-cxxflags-prefix], - [AC_HELP_STRING([--with-wrapper-cxxflags-prefix], - [Extra flags to add to CXXFLAGS when using mpiCC/mpic++])]) - AS_IF([test "$with_wrapper_cxxflags_prefix" = "yes" || test "$with_wrapper_cxxflags_prefix" = "no"], - [AC_MSG_ERROR([--with-wrapper-cxxflags-prefix must have an argument.])]) - m4_ifdef([project_ompi], [ + AC_ARG_WITH([wrapper-cxxflags], + [AS_HELP_STRING([--with-wrapper-cxxflags], + [Extra flags to add to CXXFLAGS when using mpiCC/mpic++])]) + AS_IF([test "$with_wrapper_cxxflags" = "yes" || test "$with_wrapper_cxxflags" = "no"], + [AC_MSG_ERROR([--with-wrapper-cxxflags must have an argument.])]) + + AC_ARG_WITH([wrapper-cxxflags-prefix], + [AS_HELP_STRING([--with-wrapper-cxxflags-prefix], + [Extra flags to add to CXXFLAGS when using mpiCC/mpic++])]) + AS_IF([test "$with_wrapper_cxxflags_prefix" = "yes" || test "$with_wrapper_cxxflags_prefix" = "no"], + [AC_MSG_ERROR([--with-wrapper-cxxflags-prefix must have an argument.])]) + AC_ARG_WITH([wrapper-fcflags], - [AC_HELP_STRING([--with-wrapper-fcflags], + [AS_HELP_STRING([--with-wrapper-fcflags], [Extra flags to add to FCFLAGS when using mpifort])]) AS_IF([test "$with_wrapper_fcflags" = "yes" || test "$with_wrapper_fcflags" = "no"], [AC_MSG_ERROR([--with-wrapper-fcflags must have an argument.])]) AC_ARG_WITH([wrapper-fcflags-prefix], - [AC_HELP_STRING([--with-wrapper-fcflags-prefix], + [AS_HELP_STRING([--with-wrapper-fcflags-prefix], [Extra flags (before user flags) to add to FCFLAGS when using mpifort])]) AS_IF([test "$with_wrapper_fcflags_prefix" = "yes" || test "$with_wrapper_fcflags_prefix" = "no"], [AC_MSG_ERROR([--with-wrapper-fcflags-prefix must have an argument.])])]) AC_ARG_WITH([wrapper-ldflags], - [AC_HELP_STRING([--with-wrapper-ldflags], + [AS_HELP_STRING([--with-wrapper-ldflags], [Extra flags to add to LDFLAGS when using wrapper compilers])]) AS_IF([test "$with_wrapper_ldflags" = "yes" || test "$with_wrapper_ldflags" = "no"], [AC_MSG_ERROR([--with-wrapper-ldflags must have an argument.])]) AC_ARG_WITH([wrapper-libs], - [AC_HELP_STRING([--with-wrapper-libs], + [AS_HELP_STRING([--with-wrapper-libs], [Extra flags to add to LIBS when using wrapper compilers])]) AS_IF([test "$with_wrapper_libs" = "yes" || test "$with_wrapper_libs" = "no"], [AC_MSG_ERROR([--with-wrapper-libs must have an argument.])]) @@ -142,6 +176,7 @@ AC_DEFUN([OPAL_SETUP_WRAPPER_INIT],[ AS_IF([test "$enable_wrapper_rpath" = "no" && test "$enable_wrapper_runpath" = "yes"], [AC_MSG_ERROR([--enable-wrapper-runpath cannot be selected with --disable-wrapper-rpath])]) + OPAL_VAR_SCOPE_POP ]) # OPAL_LIBTOOL_CONFIG(libtool-variable, result-variable, @@ -234,6 +269,7 @@ AC_DEFUN([OPAL_SETUP_RUNPATH],[ [OPAL_LIBTOOL_CONFIG([wl],[wl_fc],[--tag=FC],[]) LDFLAGS="$LDFLAGS_save ${wl_fc}--enable-new-dtags" AC_LANG_PUSH([Fortran]) + AC_MSG_CHECKING([if Fortran linker supports RUNPATH]) AC_LINK_IFELSE([AC_LANG_SOURCE([[program test end program]])], [runpath_fc_args="${wl_fc}--enable-new-dtags" @@ -264,31 +300,91 @@ AC_DEFUN([RPATHIFY_LDFLAGS_INTERNAL],[ esac done - # Now add in the RPATH args for @{libdir}, and the RUNPATH args - rpath_tmp=`echo ${$2} | sed -e s/LIBDIR/@{libdir}/` - $1="${$1} $rpath_out $rpath_tmp ${$3}" + $1="${$1} $rpath_out" ]) OPAL_VAR_SCOPE_POP ]) -AC_DEFUN([RPATHIFY_LDFLAGS],[RPATHIFY_LDFLAGS_INTERNAL([$1], [rpath_args], [runpath_args])]) +AC_DEFUN([RPATHIFY_LDFLAGS],[RPATHIFY_LDFLAGS_INTERNAL([$1], [rpath_args])]) -AC_DEFUN([RPATHIFY_FC_LDFLAGS],[RPATHIFY_LDFLAGS_INTERNAL([$1], [rpath_fc_args], [runpath_fc_args])]) - -dnl -dnl Avoid some repetitive code below -dnl -AC_DEFUN([_OPAL_SETUP_WRAPPER_FINAL_PKGCONFIG],[ - AC_MSG_CHECKING([for $1 pkg-config LDFLAGS]) - $1_PKG_CONFIG_LDFLAGS=`echo "$$1_WRAPPER_EXTRA_LDFLAGS" | sed -e 's/@{libdir}/\${libdir}/g'` - AC_SUBST([$1_PKG_CONFIG_LDFLAGS]) - AC_MSG_RESULT([$$1_PKG_CONFIG_LDFLAGS]) -]) +AC_DEFUN([RPATHIFY_FC_LDFLAGS],[RPATHIFY_LDFLAGS_INTERNAL([$1], [rpath_fc_args])]) # OPAL_SETUP_WRAPPER_FINAL() # --------------------------- +# +# Here are the situations that we need to cover with wrapper compilers +# and pkg-config files: +# +# 1) --enable-shared --disable-static (today's default): Any +# application linking against libmpi will be a dynamically linked +# application +# 2) --enable-shared --enable-static: An application linking against +# libmpi will dynamically link against libmpi unless -static (or +# similar) is passed, in which case it will static link against +# libmpi (and the static versions of all of libmpi's dependencies). +# 3) --disable-shared --enable-static: Any application linking against +# libmpi will link against libmpi.a. That application will link +# against the dynamic versions of libmpi's dependencies, unless +# -static is passed. +# +# There is one situation we should explicitly handle in terms of +# wrapper compilers (someone could parse out all the right pkg-config +# or wrapper compiler options to get the right dependent libraries, of +# course): +# +# 1) --enable-shared --enable-static: An application links via +# /usr/lib/libmpi.a instead of -lmpi. We'll make no attempts to +# recognize this case with the wrapper compiler +# +# So, we essentially have 5 cases above to cover with the wrapper +# compiler and pkg-config. For the wrapper compiler, this means: +# +# 1) --enable-shared --disable-static: Regardless of the -static flag, +# we only add the -L${libdir} -lmpi +# 2) --enable-shared --enable-static / no -static flag: we add +# -L${libdir} -lmpi +# 3) --enable-shared --enable-static / -static flag: we add +# -L${libdir} -lmpi plus the LDFLAGS and LIBS for our dependencies +# AND their reported dependencies (ie the results of pkg-config --libs +# --static for all our dependencies). +# 4) --disable-shared --enable-static / no -static flag: We add +# -L${libdir} -lmpi plus the LDFLAGS and LIBS for our dependencies, +# but not their dependencies (ie, the results of pkg-config --libs for +# all our dependencies) +# 5) --disable-shared --enable-static / -static flag: We add +# -L${libdir} -lmpi plus the LDFLAGS and LIBs for our dependencies +# AND their reported dependencies (ie, the results of pkg-config +# --libs --static for all our dependencies) +# +# For the pkg-config modules, this means: +# +# 1) --enable-shared --disable-static: We add -L${libdir} -lmpi to +# Libs and Libs.private, Modules, and Modules.private are empty +# 2/3) --enable-shared --enable-static: We add -L${libdir} -lmpi to +# Libs, Libs.private contains all the -L/-ls from our dependencies +# that don't have pkg-config modules, Modules is empty, and +# Modules.private contains all the modules for our dependencies. +# 4/5) --disable-shared --enable-static: We add -L${libdir} -lmpi to +# Libs, Libs.private contains all the -L/-ls from our dependencies that +# don't have pkg-config modules, Modules contains all the modules for +# our dependencies, and Modules.private is empty. +# +# 2/3 means that `pkg-config --libs mpi` would return -L${libdir} +# -lmpi and `pkg-config --libs --static mpi` would return +# -L${libdir} -lmpi -Lnon-pkg-config-dependency +# -lnon-pkg-config-dependency ...., plus all the `pkg-config --libs +# --static` results for all our pkg-config dependencies. +# +# 4/5 means that `pkg-config --libs mpi` would return -L${libdir} +# -lmpi -Lnon-pkg-config-dependency -lnon-pkg-config-dependency ...., +# plus all the `pkg-config --libs` results for all our pkg-config +# dependencies AND that `pkg-config --libs --static mpi` would return +# -L${libdir} -lmpi -Lnon-pkg-config-dependency +# -lnon-pkg-config-dependency ...., plus all the `pkg-config --libs +# --static` results for all our pkg-config dependencies. AC_DEFUN([OPAL_SETUP_WRAPPER_FINAL],[ + OPAL_VAR_SCOPE_PUSH([wrapper_tmp_arg wrapper_finalize_opal_libs wrapper_finalize_ompi_libs]) # Setup RPATH support, if desired WRAPPER_RPATH_SUPPORT=disabled @@ -298,189 +394,262 @@ AC_DEFUN([OPAL_SETUP_WRAPPER_FINAL],[ [AC_MSG_WARN([RPATH support requested but not available]) AC_MSG_ERROR([Cannot continue])]) - # Note that we have to setup _PKG_CONFIG_LDFLAGS for the - # pkg-config files to parallel the - # _WRAPPER_EXTRA_LDFLAGS. This is because pkg-config - # will not understand the @{libdir} notation in - # *_WRAPPER_EXTRA_LDFLAGS; we have to translate it to ${libdir}. + AC_DEFINE_UNQUOTED(WRAPPER_RPATH_SUPPORT, "$WRAPPER_RPATH_SUPPORT", + [Whether the wrapper compilers add rpath flags by default]) # We now have all relevant flags. Substitute them in everywhere. - m4_ifdef([project_opal], [ - AC_MSG_CHECKING([for OPAL CPPFLAGS]) - if test "$WANT_INSTALL_HEADERS" = "1" ; then - OPAL_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi' - fi - OPAL_WRAPPER_EXTRA_CPPFLAGS="$OPAL_WRAPPER_EXTRA_CPPFLAGS $opal_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags" - AC_SUBST([OPAL_WRAPPER_EXTRA_CPPFLAGS]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_CPPFLAGS]) - - AC_MSG_CHECKING([for OPAL CFLAGS]) - OPAL_WRAPPER_EXTRA_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" - AC_SUBST([OPAL_WRAPPER_EXTRA_CFLAGS]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_CFLAGS]) - - AC_MSG_CHECKING([for OPAL CFLAGS_PREFIX]) - OPAL_WRAPPER_EXTRA_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" - AC_SUBST([OPAL_WRAPPER_EXTRA_CFLAGS_PREFIX]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_CFLAGS_PREFIX]) - - AC_MSG_CHECKING([for OPAL CXXFLAGS]) - OPAL_WRAPPER_EXTRA_CXXFLAGS="$wrapper_extra_cxxflags $with_wrapper_cxxflags" - AC_SUBST([OPAL_WRAPPER_EXTRA_CXXFLAGS]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_CXXFLAGS]) - - AC_MSG_CHECKING([for OPAL CXXFLAGS_PREFIX]) - OPAL_WRAPPER_EXTRA_CXXFLAGS_PREFIX="$with_wrapper_cxxflags_prefix" - AC_SUBST([OPAL_WRAPPER_EXTRA_CXXFLAGS_PREFIX]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_CXXFLAGS_PREFIX]) - - AC_MSG_CHECKING([for OPAL LDFLAGS]) - OPAL_WRAPPER_EXTRA_LDFLAGS="$opal_mca_wrapper_extra_ldflags $wrapper_extra_ldflags $with_wrapper_ldflags" - RPATHIFY_LDFLAGS([OPAL_WRAPPER_EXTRA_LDFLAGS]) - AC_SUBST([OPAL_WRAPPER_EXTRA_LDFLAGS]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_LDFLAGS]) - - # Convert @{libdir} to ${libdir} for pkg-config - _OPAL_SETUP_WRAPPER_FINAL_PKGCONFIG([OPAL]) - - # wrapper_extra_libs doesn't really get populated until after the mca system runs - # since most of the libs come from libtool. So this is the first time we can - # uniq them. ROMIO in particular adds lots of things already in wrapper_extra_libs, - # and this cleans the duplication up a bunch. Always add everything the user - # asked for, as they know better than us. - AC_MSG_CHECKING([for OPAL LIBS]) - OPAL_WRAPPER_EXTRA_LIBS="$opal_mca_wrapper_extra_libs" - OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_EXTRA_LIBS], [$wrapper_extra_libs]) - OPAL_WRAPPER_EXTRA_LIBS="$OPAL_WRAPPER_EXTRA_LIBS $with_wrapper_libs" - AC_SUBST([OPAL_WRAPPER_EXTRA_LIBS]) - AC_MSG_RESULT([$OPAL_WRAPPER_EXTRA_LIBS]) - ]) - m4_ifdef([project_orte], [ - AC_MSG_CHECKING([for ORTE CPPFLAGS]) - if test "$WANT_INSTALL_HEADERS" = "1" ; then - ORTE_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi' - fi - ORTE_WRAPPER_EXTRA_CPPFLAGS="$ORTE_WRAPPER_EXTRA_CPPFLAGS $orte_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags" - AC_SUBST([ORTE_WRAPPER_EXTRA_CPPFLAGS]) - AC_MSG_RESULT([$ORTE_WRAPPER_EXTRA_CPPFLAGS]) - - AC_MSG_CHECKING([for ORTE CFLAGS]) - ORTE_WRAPPER_EXTRA_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" - AC_SUBST([ORTE_WRAPPER_EXTRA_CFLAGS]) - AC_MSG_RESULT([$ORTE_WRAPPER_EXTRA_CFLAGS]) - - AC_MSG_CHECKING([for ORTE CFLAGS_PREFIX]) - ORTE_WRAPPER_EXTRA_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" - AC_SUBST([ORTE_WRAPPER_EXTRA_CFLAGS_PREFIX]) - AC_MSG_RESULT([$ORTE_WRAPPER_EXTRA_CFLAGS_PREFIX]) - - AC_MSG_CHECKING([for ORTE LDFLAGS]) - ORTE_WRAPPER_EXTRA_LDFLAGS="$orte_mca_wrapper_extra_ldflags $wrapper_extra_ldflags $with_wrapper_ldflags" - RPATHIFY_LDFLAGS([ORTE_WRAPPER_EXTRA_LDFLAGS]) - AC_SUBST([ORTE_WRAPPER_EXTRA_LDFLAGS]) - AC_MSG_RESULT([$ORTE_WRAPPER_EXTRA_LDFLAGS]) - - # Convert @{libdir} to ${libdir} for pkg-config - _OPAL_SETUP_WRAPPER_FINAL_PKGCONFIG([ORTE]) - - AC_MSG_CHECKING([for ORTE LIBS]) - ORTE_WRAPPER_EXTRA_LIBS="$orte_mca_wrapper_extra_libs" - OPAL_FLAGS_APPEND_UNIQ([ORTE_WRAPPER_EXTRA_LIBS], [$wrapper_extra_libs]) - ORTE_WRAPPER_EXTRA_LIBS="$ORTE_WRAPPER_EXTRA_LIBS $with_wrapper_libs" - AC_SUBST([ORTE_WRAPPER_EXTRA_LIBS]) - AC_MSG_RESULT([$ORTE_WRAPPER_EXTRA_LIBS]) - - m4_ifdef([project_ompi], [], [ - # these are used by orte_info/ompi_info (yes, they are named poorly) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CFLAGS, "$ORTE_WRAPPER_EXTRA_CFLAGS", - [Additional CFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CFLAGS_PREFIX, "$ORTE_WRAPPER_EXTRA_CFLAGS_PREFIX", - [Additional CFLAGS_PREFIX to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_LDFLAGS, "$ORTE_WRAPPER_EXTRA_LDFLAGS", - [Additional LDFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_LIBS, "$ORTE_WRAPPER_EXTRA_LIBS", - [Additional LIBS to pass through the wrapper compilers]) - ]) + dnl Add LIBS into the extra wrapper libs, since this is as last + dnl minute as we can get. We do the temp variable bit because of + dnl libevent and hwloc dependencies. LIBS is going to contain + dnl libevent/libev/hwloc libraries, but their dependencies are + dnl already in wrapper_extra_libs. We do not want to move -lhwloc + dnl (for example) to the far right, right of its dependencies. So + dnl we start with our base libs, and add all the wrapper extra + dnl bits to that. + wapper_tmp_arg="${LIBS}" + OPAL_FLAGS_APPEND_MOVE([wrapper_tmp_arg], [${wrapper_extra_libs}]) + wrapper_extra_libs="${wrapper_tmp_arg}" + + dnl We do not want ${includedir} to be expanded, as we want that + dnl expansion to happen in the wrapper or pkg-config. + m4_ifdef([project_opal], [ + AC_MSG_CHECKING([for OPAL wrapper CPPFLAGS]) + AS_IF([test "$WANT_INSTALL_HEADERS" = "1"], + [OPAL_WRAPPER_CPPFLAGS='-I${includedir} -I${includedir}/openmpi'], + [OPAL_WRAPPER_CPPFLAGS='-I${includedir}']) + OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_CPPFLAGS], [$opal_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags]) + AC_SUBST([OPAL_WRAPPER_CPPFLAGS]) + AC_MSG_RESULT([$OPAL_WRAPPER_CPPFLAGS]) + + AC_MSG_CHECKING([for OPAL wrapper CFLAGS]) + OPAL_WRAPPER_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" + AC_SUBST([OPAL_WRAPPER_CFLAGS]) + AC_MSG_RESULT([$OPAL_WRAPPER_CFLAGS]) + + AC_MSG_CHECKING([for OPAL wrapper CFLAGS_PREFIX]) + OPAL_WRAPPER_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" + AC_SUBST([OPAL_WRAPPER_CFLAGS_PREFIX]) + AC_MSG_RESULT([$OPAL_WRAPPER_CFLAGS_PREFIX]) + + AC_MSG_CHECKING([for OPAL wrapper CXXFLAGS]) + OPAL_WRAPPER_CXXFLAGS="$wrapper_extra_cxxflags $with_wrapper_cxxflags" + AC_SUBST([OPAL_WRAPPER_CXXFLAGS]) + AC_MSG_RESULT([$OPAL_WRAPPER_CXXFLAGS]) + + AC_MSG_CHECKING([for OPAL wrapper CXXFLAGS_PREFIX]) + OPAL_WRAPPER_CXXFLAGS_PREFIX="$with_wrapper_cxxflags_prefix" + AC_SUBST([OPAL_WRAPPER_CXXFLAGS_PREFIX]) + AC_MSG_RESULT([$OPAL_WRAPPER_CXXFLAGS_PREFIX]) + + wrapper_finalize_opal_libs="-l${OPAL_LIB_NAME}" + + dnl No matter the configuration (see the 5 cases above), the base + dnl flags should contain a -L${libdir} and -lopen-pal, so that those + dnl are found. + OPAL_WRAPPER_LDFLAGS='-L${libdir}' + OPAL_WRAPPER_LIBS="${wrapper_finalize_opal_libs}" + OPAL_WRAPPER_LIBS_STATIC= + OPAL_WRAPPER_LDFLAGS_STATIC= + + AS_IF(dnl shared only case. We add no flags beyond the base -L/-l + [test "${enable_shared}" != "no" -a "${enable_static}" != "yes"], + [], + dnl building both shared and static libraries. The base + dnl case remains the same as the shared-only case (because + dnl the app will link against the shared library, but the + dnl static case is the full dependency tree. Our full + dnl dependency tree is both the wrapper_extra_libs and + dnl wrapper_extra_static_libs, because wrapper_extra_libs + dnl was not added to the normal case. + [test "${enable_shared}" != "no" -a "${enable_static}" = "yes"], + [OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS_STATIC], [${opal_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OPAL_WRAPPER_LIBS_STATIC], [${opal_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS_STATIC], [${opal_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OPAL_WRAPPER_LIBS_STATIC], [${opal_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])], + dnl building static only. The base case is that we need to + dnl list our dependencies, but not the full treee, because + dnl we assume that our dependencies will be shared libraries + dnl (unless they too were built static only, in which case + dnl their dependencies will be our direct dependencies if + dnl their modules are setup correctly). The static case is + dnl our full dependency tree, but we only need to list the + dnl second leve explicitly, because the wrapper compiler + dnl and/or pkg-config merge use the normal case data in the + dnl static case. + [OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS], [${opal_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OPAL_WRAPPER_LIBS], [${opal_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS_STATIC], [${opal_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OPAL_WRAPPER_LIBS_STATIC], [${opal_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])]) + + dnl Add the user-provided flags + OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS], [${with_wrapper_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OPAL_WRAPPER_LIBS], [${with_wrapper_libs}]) + + RPATHIFY_LDFLAGS([OPAL_WRAPPER_LDFLAGS]) + RPATHIFY_LDFLAGS([OPAL_WRAPPER_LDFLAGS_STATIC]) + + OPAL_FLAGS_APPEND_UNIQ([OPAL_WRAPPER_LDFLAGS], [${runpath_args}]) + + AC_MSG_CHECKING([for OPAL wrapper LDFLAGS]) + AC_SUBST([OPAL_WRAPPER_LDFLAGS]) + AC_MSG_RESULT([$OPAL_WRAPPER_LDFLAGS]) + + AC_MSG_CHECKING([for OPAL wrapper static LDFLAGS]) + AC_SUBST([OPAL_WRAPPER_LDFLAGS_STATIC]) + AC_MSG_RESULT([$OPAL_WRAPPER_LDFLAGS_STATIC]) + + AC_MSG_CHECKING([for OPAL wrapper LIBS]) + AC_SUBST([OPAL_WRAPPER_LIBS]) + AC_MSG_RESULT([$OPAL_WRAPPER_LIBS]) + + AC_MSG_CHECKING([for OPAL wrapper static LIBS]) + AC_SUBST([OPAL_WRAPPER_LIBS_STATIC]) + AC_MSG_RESULT([$OPAL_WRAPPER_LIBS_STATIC]) ]) m4_ifdef([project_ompi], [ - AC_MSG_CHECKING([for OMPI CPPFLAGS]) - if test "$WANT_INSTALL_HEADERS" = "1" ; then - OMPI_WRAPPER_EXTRA_CPPFLAGS='-I${includedir}/openmpi' - fi - OMPI_WRAPPER_EXTRA_CPPFLAGS="$OMPI_WRAPPER_EXTRA_CPPFLAGS $ompi_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags" - AC_SUBST([OMPI_WRAPPER_EXTRA_CPPFLAGS]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_CPPFLAGS]) - - AC_MSG_CHECKING([for OMPI CFLAGS]) - OMPI_WRAPPER_EXTRA_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" - AC_SUBST([OMPI_WRAPPER_EXTRA_CFLAGS]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_CFLAGS]) - - AC_MSG_CHECKING([for OMPI CFLAGS_PREFIX]) - OMPI_WRAPPER_EXTRA_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" - AC_SUBST([OMPI_WRAPPER_EXTRA_CFLAGS_PREFIX]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_CFLAGS_PREFIX]) - - AC_MSG_CHECKING([for OMPI CXXFLAGS]) - OMPI_WRAPPER_EXTRA_CXXFLAGS="$wrapper_extra_cxxflags $with_wrapper_cxxflags" - AC_SUBST([OMPI_WRAPPER_EXTRA_CXXFLAGS]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_CXXFLAGS]) - - AC_MSG_CHECKING([for OMPI CXXFLAGS_PREFIX]) - OMPI_WRAPPER_EXTRA_CXXFLAGS_PREFIX="$with_wrapper_cxxflags_prefix" - AC_SUBST([OMPI_WRAPPER_EXTRA_CXXFLAGS_PREFIX]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_CXXFLAGS_PREFIX]) - - AC_MSG_CHECKING([for OMPI FCFLAGS]) - OMPI_WRAPPER_EXTRA_FCFLAGS="$wrapper_extra_fcflags $with_wrapper_fcflags" - if test "$OMPI_FC_MODULE_FLAG" != "" ; then - OMPI_WRAPPER_EXTRA_FCFLAGS="$OMPI_WRAPPER_EXTRA_FCFLAGS $OMPI_FC_MODULE_FLAG"'${libdir}' - fi - AC_SUBST([OMPI_WRAPPER_EXTRA_FCFLAGS]) + AC_MSG_CHECKING([for OMPI wrapper CPPFLAGS]) + AS_IF([test "$WANT_INSTALL_HEADERS" = "1"], + [OMPI_WRAPPER_CPPFLAGS='-I${includedir} -I${includedir}/openmpi'], + [OMPI_WRAPPER_CPPFLAGS='-I${includedir}']) + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_CPPFLAGS], [$ompi_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags]) + AC_SUBST([OMPI_WRAPPER_CPPFLAGS]) + AC_MSG_RESULT([$OMPI_WRAPPER_CPPFLAGS]) + + AC_MSG_CHECKING([for OMPI wrapper CFLAGS]) + OMPI_WRAPPER_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" + AC_SUBST([OMPI_WRAPPER_CFLAGS]) + AC_MSG_RESULT([$OMPI_WRAPPER_CFLAGS]) + + AC_MSG_CHECKING([for OMPI wrapper CFLAGS_PREFIX]) + OMPI_WRAPPER_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" + AC_SUBST([OMPI_WRAPPER_CFLAGS_PREFIX]) + AC_MSG_RESULT([$OMPI_WRAPPER_CFLAGS_PREFIX]) + + AC_MSG_CHECKING([for OMPI wrapper CXXFLAGS]) + OMPI_WRAPPER_CXXFLAGS="$wrapper_extra_cxxflags $with_wrapper_cxxflags" + AC_SUBST([OMPI_WRAPPER_CXXFLAGS]) + AC_MSG_RESULT([$OMPI_WRAPPER_CXXFLAGS]) + + AC_MSG_CHECKING([for OMPI wrapper CXXFLAGS_PREFIX]) + OMPI_WRAPPER_CXXFLAGS_PREFIX="$with_wrapper_cxxflags_prefix" + AC_SUBST([OMPI_WRAPPER_CXXFLAGS_PREFIX]) + AC_MSG_RESULT([$OMPI_WRAPPER_CXXFLAGS_PREFIX]) + + AC_MSG_CHECKING([for OMPI wrapper FCFLAGS]) + OMPI_WRAPPER_FCFLAGS='-I${includedir}'" ${wrapper_extra_fcflags} ${with_wrapper_fcflags}" + AS_IF([test -n "${OMPI_FC_MODULE_FLAG}"], + [dnl deal with some interesting expansion behavior in OPAL_APPEND + wrapper_tmp_arg="${OMPI_FC_MODULE_FLAG}"'${libdir}' + OPAL_APPEND([OMPI_WRAPPER_FCFLAGS], [${wrapper_tmp_arg}])]) + AC_SUBST([OMPI_WRAPPER_FCFLAGS]) AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_FCFLAGS]) - AC_MSG_CHECKING([for OMPI FCFLAGS_PREFIX]) - OMPI_WRAPPER_EXTRA_FCFLAGS_PREFIX="$with_wrapper_fcflags_prefix" - AC_SUBST([OMPI_WRAPPER_EXTRA_FCFLAGS_PREFIX]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_FCFLAGS_PREFIX]) - - AC_MSG_CHECKING([for OMPI LDFLAGS]) - OMPI_WRAPPER_EXTRA_LDFLAGS="$ompi_mca_wrapper_extra_ldflags $wrapper_extra_ldflags $with_wrapper_ldflags" - OMPI_WRAPPER_EXTRA_FC_LDFLAGS=$OMPI_WRAPPER_EXTRA_LDFLAGS - RPATHIFY_LDFLAGS([OMPI_WRAPPER_EXTRA_LDFLAGS]) - AC_SUBST([OMPI_WRAPPER_EXTRA_LDFLAGS]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_LDFLAGS]) - RPATHIFY_FC_LDFLAGS([OMPI_WRAPPER_EXTRA_FC_LDFLAGS]) - AC_SUBST([OMPI_WRAPPER_EXTRA_FC_LDFLAGS]) - - # Convert @{libdir} to ${libdir} for pkg-config - _OPAL_SETUP_WRAPPER_FINAL_PKGCONFIG([OMPI]) - - AC_MSG_CHECKING([for OMPI LIBS]) - OMPI_WRAPPER_EXTRA_LIBS="$ompi_mca_wrapper_extra_libs" - OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_EXTRA_LIBS], [$wrapper_extra_libs]) - OMPI_WRAPPER_EXTRA_LIBS="$OMPI_WRAPPER_EXTRA_LIBS $with_wrapper_libs" - OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_EXTRA_LIBS], [$LIBS]) - AC_SUBST([OMPI_WRAPPER_EXTRA_LIBS]) - AC_MSG_RESULT([$OMPI_WRAPPER_EXTRA_LIBS]) - - # language binding support. C++ is a bit different, as the - # compiler should work even if there is no MPI C++ bindings - # support. However, we do want it to fail if there is no C++ - # compiler. - if test "$WANT_MPI_CXX_SUPPORT" = "1" ; then - OMPI_WRAPPER_CXX_LIB="-l${with_libmpi_name}_cxx" - OMPI_WRAPPER_CXX_REQUIRED_FILE="" - elif test "$CXX" = "none"; then - OMPI_WRAPPER_CXX_LIB="" + AC_MSG_CHECKING([for OMPI wrapper FCFLAGS_PREFIX]) + OMPI_WRAPPER_FCFLAGS_PREFIX="$with_wrapper_fcflags_prefix" + AC_SUBST([OMPI_WRAPPER_FCFLAGS_PREFIX]) + AC_MSG_RESULT([$OMPI_WRAPPER_FCFLAGS_PREFIX]) + + wrapper_finalize_ompi_libs="-l${OMPI_LIBMPI_NAME}" + + dnl No matter the configuration (see the 5 cases above), the base + dnl flags should contain a -L${libdir} and -lmpi, so that those + dnl are found. + OMPI_WRAPPER_LDFLAGS='-L${libdir}' + OMPI_WRAPPER_LIBS="${wrapper_finalize_ompi_libs}" + OMPI_WRAPPER_LIBS_STATIC= + OMPI_WRAPPER_LDFLAGS_STATIC= + + AS_IF(dnl shared only case. We add no flags beyond the base -L/-l + [test "${enable_shared}" != "no" -a "${enable_static}" != "yes"], + [], + dnl building both shared and static libraries. The base + dnl case remains the same as the shared-only case (because + dnl the app will link against the shared library, but the + dnl static case is the full dependency tree. Our full + dnl dependency tree is both the wrapper_extra_libs and + dnl wrapper_extra_static_libs, because wrapper_extra_libs + dnl was not added to the normal case. + [test "${enable_shared}" != "no" -a "${enable_static}" = "yes"], + [OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS_STATIC], [${ompi_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OMPI_WRAPPER_LIBS_STATIC], [${wrapper_finalize_opal_libs} ${ompi_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS_STATIC], [${ompi_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OMPI_WRAPPER_LIBS_STATIC], [${ompi_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])], + dnl building static only. The base case is that we need to + dnl list our dependencies, but not the full treee, because + dnl we assume that our dependencies will be shared libraries + dnl (unless they too were built static only, in which case + dnl their dependencies will be our direct dependencies if + dnl their modules are setup correctly). The static case is + dnl our full dependency tree, but we only need to list the + dnl second leve explicitly, because the wrapper compiler + dnl and/or pkg-config merge use the normal case data in the + dnl static case. + [OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS], [${ompi_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OMPI_WRAPPER_LIBS], [${wrapper_finalize_opal_libs} ${ompi_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS_STATIC], [${ompi_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OMPI_WRAPPER_LIBS_STATIC], [${ompi_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])]) + + dnl Add the user-provided flags + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS], [${with_wrapper_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OMPI_WRAPPER_LIBS], [${with_wrapper_libs}]) + + dnl fortran FTW! + OMPI_WRAPPER_FC_LIBS="${OMPI_FORTRAN_USEMPIF08_LIB} ${OMPI_FORTRAN_USEMPI_LIB} ${OMPI_FORTRAN_MPIFH_LINK} ${OMPI_WRAPPER_LIBS}" + OMPI_WRAPPER_FC_LIBS_STATIC=${OMPI_WRAPPER_LIBS_STATIC} + OMPI_WRAPPER_FC_LDFLAGS=$OMPI_WRAPPER_LDFLAGS + OMPI_WRAPPER_FC_LDFLAGS_STATIC=$OMPI_WRAPPER_LDFLAGS + + RPATHIFY_LDFLAGS([OMPI_WRAPPER_LDFLAGS]) + RPATHIFY_LDFLAGS([OMPI_WRAPPER_LDFLAGS_STATIC]) + RPATHIFY_FC_LDFLAGS([OMPI_WRAPPER_FC_LDFLAGS]) + RPATHIFY_FC_LDFLAGS([OMPI_WRAPPER_FC_LDFLAGS_STATIC]) + + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_LDFLAGS], [${runpath_args}]) + OPAL_FLAGS_APPEND_UNIQ([OMPI_WRAPPER_FC_LDFLAGS], [${runpath_fc_args}]) + + AC_MSG_CHECKING([for OMPI wrapper LDFLAGS]) + AC_SUBST([OMPI_WRAPPER_LDFLAGS]) + AC_MSG_RESULT([$OMPI_WRAPPER_LDFLAGS]) + + AC_MSG_CHECKING([for OMPI wrapper static LDFLAGS]) + AC_SUBST([OMPI_WRAPPER_LDFLAGS_STATIC]) + AC_MSG_RESULT([$OMPI_WRAPPER_LDFLAGS_STATIC]) + + AC_MSG_CHECKING([for OMPI wrapper LIBS]) + AC_SUBST([OMPI_WRAPPER_LIBS]) + AC_MSG_RESULT([$OMPI_WRAPPER_LIBS]) + + AC_MSG_CHECKING([for OMPI wrapper static LIBS]) + AC_SUBST([OMPI_WRAPPER_LIBS_STATIC]) + AC_MSG_RESULT([$OMPI_WRAPPER_LIBS_STATIC]) + + AC_MSG_CHECKING([for OMPI wrapper Fortran LDFLAGS]) + AC_SUBST([OMPI_WRAPPER_FC_LDFLAGS]) + AC_MSG_RESULT([$OMPI_WRAPPER_FC_LDFLAGS]) + + AC_MSG_CHECKING([for OMPI wrapper Fortran static LDFLAGS]) + AC_SUBST([OMPI_WRAPPER_FC_LDFLAGS_STATIC]) + AC_MSG_RESULT([$OMPI_WRAPPER_LDFLAGS_STATIC]) + + AC_MSG_CHECKING([for OMPI wrapper Fortran LIBS]) + AC_SUBST([OMPI_WRAPPER_FC_LIBS]) + AC_MSG_RESULT([$OMPI_WRAPPER_FC_LIBS]) + + AC_MSG_CHECKING([for OMPI wrapper Fortran static LIBS]) + AC_SUBST([OMPI_WRAPPER_FC_LIBS_STATIC]) + AC_MSG_RESULT([$OMPI_WRAPPER_FC_LIBS_STATIC]) + + # language binding support. C++ is a bit different, as the + # compiler should work even if there is no MPI C++ bindings + # support. However, we do want it to fail if there is no C++ + # compiler. + if test "$CXX" = "none"; then OMPI_WRAPPER_CXX_REQUIRED_FILE="not supported" else - OMPI_WRAPPER_CXX_LIB="" OMPI_WRAPPER_CXX_REQUIRED_FILE="" fi - AC_SUBST([OMPI_WRAPPER_CXX_LIB]) AC_SUBST([OMPI_WRAPPER_CXX_REQUIRED_FILE]) if test "$OMPI_TRY_FORTRAN_BINDINGS" -gt "$OMPI_FORTRAN_NO_BINDINGS" ; then @@ -506,24 +675,299 @@ AC_DEFUN([OPAL_SETUP_WRAPPER_FINAL],[ [chmod +x ompi/tools/wrappers/ompi_wrapper_script]) fi - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CFLAGS, "$OMPI_WRAPPER_EXTRA_CFLAGS", - [Additional CFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CFLAGS_PREFIX, "$OMPI_WRAPPER_EXTRA_CFLAGS_PREFIX", - [Additional CFLAGS_PREFIX to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CXXFLAGS, "$OMPI_WRAPPER_EXTRA_CXXFLAGS", - [Additional CXXFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_CXXFLAGS_PREFIX, "$OMPI_WRAPPER_EXTRA_CXXFLAGS_PREFIX", - [Additional CXXFLAGS_PREFIX to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_FCFLAGS, "$OMPI_WRAPPER_EXTRA_FCFLAGS", - [Additional FCFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_FCFLAGS_PREFIX, "$OMPI_WRAPPER_EXTRA_FCFLAGS_PREFIX", - [Additional FCFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_LDFLAGS, "$OMPI_WRAPPER_EXTRA_LDFLAGS", - [Additional LDFLAGS to pass through the wrapper compilers]) - AC_DEFINE_UNQUOTED(WRAPPER_EXTRA_LIBS, "$OMPI_WRAPPER_EXTRA_LIBS", - [Additional LIBS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OMPI_WRAPPER_CFLAGS, "$OMPI_WRAPPER_CFLAGS", + [CFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OMPI_WRAPPER_CXXFLAGS, "$OMPI_WRAPPER_CXXFLAGS", + [CXXFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OMPI_WRAPPER_FCFLAGS, "$OMPI_WRAPPER__FCFLAGS", + [FCFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OMPI_WRAPPER_LDFLAGS, "$OMPI_WRAPPER_LDFLAGS", + [LDFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OMPI_WRAPPER_LIBS, "$OMPI_WRAPPER_LIBS", + [LIBS to pass through the wrapper compilers]) + + dnl #################################################################### + dnl Setup variables for pkg-config files + dnl + dnl Add all our dependent libraries to libs.Private for users that want + dnl to static build, unless we're only building static libraries, in + dnl which case, add the dependent libraries to libs itself, since any + dnl linking will require the full set of libraries. + dnl #################################################################### + AC_MSG_CHECKING([for OMPI pkg-config Cflags]) + OMPI_PC_CFLAGS="${OMPI_WRAPPER_CPPFLAGS} ${OMPI_WRAPPER_CFLAGS} ${OMPI_WRAPPER_CFLAGS_PREFIX}" + OMPI_PC_CFLAGS=`echo ${OMPI_PC_CFLAGS} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_CFLAGS]) + AC_MSG_RESULT([${OMPI_PC_CFLAGS}]) + + AC_MSG_CHECKING([for OMPI pkg-config Libs]) + OMPI_PC_LIBS="${OMPI_WRAPPER_LDFLAGS} ${OMPI_WRAPPER_LIBS}" + OMPI_PC_LIBS=`echo ${OMPI_PC_LIBS} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_LIBS]) + AC_MSG_RESULT([${OMPI_PC_LIBS}]) + + AC_MSG_CHECKING([for OMPI pkg-config Libs.private]) + OMPI_PC_LIBS_PRIVATE="${OMPI_WRAPPER_LDFLAGS_STATIC} ${OMPI_WRAPPER_LIBS_STATIC}" + OMPI_PC_LIBS_PRIVATE=`echo ${OMPI_PC_LIBS_PRIVATE} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_LIBS_PRIVATE]) + AC_MSG_RESULT([${OMPI_PC_LIBS_PRIVATE}]) + + AC_MSG_CHECKING([for OMPI pkg-config Fortran Cflags]) + OMPI_PC_FC_CFLAGS="${OMPI_WRAPPER_FCFLAGS} ${OMPI_WRAPPER_FCFLAGS_PREFIX}" + OMPI_PC_FC_CFLAGS=`echo ${OMPI_PC_FC_CFLAGS} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_FC_CFLAGS]) + AC_MSG_RESULT([${OMPI_PC_FC_CFLAGS}]) + + AC_MSG_CHECKING([for OMPI pkg-config Fortran Libs]) + OMPI_PC_FC_LIBS="${OMPI_WRAPPER_FC_LDFLAGS} ${OMPI_WRAPPER_FC_LIBS}" + OMPI_PC_FC_LIBS=`echo ${OMPI_PC_FC_LIBS} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_FC_LIBS]) + AC_MSG_RESULT([${OMPI_PC_FC_LIBS}]) + + AC_MSG_CHECKING([for OMPI pkg-config Fortran Libs.private]) + OMPI_PC_FC_LIBS_PRIVATE="${OMPI_WRAPPER_FC_LDFLAGS_STATIC} ${OMPI_WRAPPER_FC_LIBS_STATIC}" + OMPI_PC_FC_LIBS_PRIVATE=`echo ${OMPI_PC_FC_LIBS_PRIVATE} | sed -e 's/@{/\${/g'` + AC_SUBST([OMPI_PC_FC_LIBS_PRIVATE]) + AC_MSG_RESULT([${OMPI_PC_FC_LIBS_PRIVATE}]) + + OMPI_PC_MODULES= + OMPI_PC_MODULES_PRIVATE= + AS_IF([test "${enable_shared}" != "no" -a "${enable_static}" != "yes"], + [], + [test "${enable_shared}" != "no" -a "${enable_static}" = "yes"], + [OMPI_PC_MODULES_PRIVATE="${wrapper_extra_pkgconfig_modules} ${ompi_mca_wrapper_extra_pc_modules}"], + [OMPI_PC_MODULES="${wrapper_extra_pkgconfig_modules} ${ompi_mca_wrapper_extra_pc_modules}"]) + + AC_MSG_CHECKING([for OMPI pkg-config Modules]) + AC_SUBST([OMPI_PC_MODULES]) + AC_MSG_RESULT([${OMPI_PC_MODULES}]) + + AC_MSG_CHECKING([for OMPI pkg-config Modules.private]) + AC_SUBST([OMPI_PC_MODULES_PRIVATE]) + AC_MSG_RESULT([${OMPI_PC_MODULES_PRIVATE}]) ]) - AC_DEFINE_UNQUOTED(WRAPPER_RPATH_SUPPORT, "$WRAPPER_RPATH_SUPPORT", - [Whether the wrapper compilers add rpath flags by default]) + m4_ifdef([project_oshmem], [ + AC_MSG_CHECKING([for OSHMEM wrapper CPPFLAGS]) + AS_IF([test "$WANT_INSTALL_HEADERS" = "1"], + [OSHMEM_WRAPPER_CPPFLAGS='-I${includedir} -I${includedir}/openmpi'], + [OSHMEM_WRAPPER_CPPFLAGS='-I${includedir}']) + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_CPPFLAGS], [$oshmem_mca_wrapper_extra_cppflags $wrapper_extra_cppflags $with_wrapper_cppflags]) + AC_SUBST([OSHMEM_WRAPPER_CPPFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_CPPFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper CFLAGS]) + OSHMEM_WRAPPER_CFLAGS="$wrapper_extra_cflags $with_wrapper_cflags" + AC_SUBST([OSHMEM_WRAPPER_CFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_CFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper CFLAGS_PREFIX]) + OSHMEM_WRAPPER_CFLAGS_PREFIX="$with_wrapper_cflags_prefix" + AC_SUBST([OSHMEM_WRAPPER_CFLAGS_PREFIX]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_CFLAGS_PREFIX]) + + AC_MSG_CHECKING([for OSHMEM wrapper CXXFLAGS]) + OSHMEM_WRAPPER_CXXFLAGS="$wrapper_extra_cxxflags $with_wrapper_cxxflags" + AC_SUBST([OSHMEM_WRAPPER_CXXFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_CXXFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper CXXFLAGS_PREFIX]) + OSHMEM_WRAPPER_CXXFLAGS_PREFIX="$with_wrapper_cxxflags_prefix" + AC_SUBST([OSHMEM_WRAPPER_CXXFLAGS_PREFIX]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_CXXFLAGS_PREFIX]) + + AC_MSG_CHECKING([for OSHMEM wrapper FCFLAGS]) + OSHMEM_WRAPPER_FCFLAGS='-I${includedir}'" ${wrapper_extra_fcflags} ${with_wrapper_fcflags}" + AS_IF([test -n "${OMPI_FC_MODULE_FLAG}"], + [dnl deal with some interesting expansion behavior in OPAL_APPEND + wrapper_tmp_arg="${OMPI_FC_MODULE_FLAG}"'${libdir}' + OPAL_APPEND([OSHMEM_WRAPPER_FCFLAGS], [${wrapper_tmp_arg}])]) + AC_SUBST([OSHMEM_WRAPPER_FCFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_EXTRA_FCFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper FCFLAGS_PREFIX]) + OSHMEM_WRAPPER_FCFLAGS_PREFIX="$with_wrapper_fcflags_prefix" + AC_SUBST([OSHMEM_WRAPPER_FCFLAGS_PREFIX]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_FCFLAGS_PREFIX]) + + dnl No matter the configuration (see the 5 cases above), the + dnl base flags should contain a -L${libdir} and -loshmem -lmpi, + dnl so that those are found. + OSHMEM_WRAPPER_LDFLAGS='-L${libdir}' + OSHMEM_WRAPPER_LIBS="-loshmem ${wrapper_finalize_ompi_libs}" + OSHMEM_WRAPPER_LIBS_STATIC= + OSHMEM_WRAPPER_LDFLAGS_STATIC= + + AS_IF(dnl shared only case. We add no flags beyond the base -L/-l + [test "${enable_shared}" != "no" -a "${enable_static}" != "yes"], + [], + dnl building both shared and static libraries. The base + dnl case remains the same as the shared-only case (because + dnl the app will link against the shared library, but the + dnl static case is the full dependency tree. Our full + dnl dependency tree is both the wrapper_extra_libs and + dnl wrapper_extra_static_libs, because wrapper_extra_libs + dnl was not added to the normal case. + [test "${enable_shared}" != "no" -a "${enable_static}" = "yes"], + [OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS_STATIC], [${oshmem_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OSHMEM_WRAPPER_LIBS_STATIC], [${wrapper_finalize_opal_libs} ${oshmem_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS_STATIC], [${oshmem_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OSHMEM_WRAPPER_LIBS_STATIC], [${oshmem_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])], + dnl building static only. The base case is that we need to + dnl list our dependencies, but not the full treee, because + dnl we assume that our dependencies will be shared libraries + dnl (unless they too were built static only, in which case + dnl their dependencies will be our direct dependencies if + dnl their modules are setup correctly). The static case is + dnl our full dependency tree, but we only need to list the + dnl second leve explicitly, because the wrapper coshmemler + dnl and/or pkg-config merge use the normal case data in the + dnl static case. + [OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS], [${oshmem_mca_wrapper_extra_ldflags} ${wrapper_extra_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OSHMEM_WRAPPER_LIBS], [${wrapper_finalize_opal_libs} ${oshmem_mca_wrapper_extra_libs} ${wrapper_extra_libs}]) + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS_STATIC], [${oshmem_mca_wrapper_extra_static_ldflags} ${wrapper_extra_static_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OSHMEM_WRAPPER_LIBS_STATIC], [${oshmem_mca_wrapper_extra_static_libs} ${wrapper_extra_static_libs}])]) + + dnl Add the user-provided flags + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS], [${with_wrapper_ldflags}]) + OPAL_FLAGS_APPEND_MOVE([OSHMEM_WRAPPER_LIBS], [${with_wrapper_libs}]) + + dnl fortran FTW! + OSHMEM_WRAPPER_FC_LIBS="-loshmem ${OMPI_FORTRAN_MPIFH_LINK}" + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_FC_LIBS], [${OSHMEM_WRAPPER_LIBS}]) + OSHMEM_WRAPPER_FC_LIBS_STATIC=${OSHMEM_WRAPPER_LIBS_STATIC} + OSHMEM_WRAPPER_FC_LDFLAGS=$OSHMEM_WRAPPER_LDFLAGS + OSHMEM_WRAPPER_FC_LDFLAGS_STATIC=$OSHMEM_WRAPPER_LDFLAGS + + RPATHIFY_LDFLAGS([OSHMEM_WRAPPER_LDFLAGS]) + RPATHIFY_LDFLAGS([OSHMEM_WRAPPER_LDFLAGS_STATIC]) + RPATHIFY_FC_LDFLAGS([OSHMEM_WRAPPER_FC_LDFLAGS]) + RPATHIFY_FC_LDFLAGS([OSHMEM_WRAPPER_FC_LDFLAGS_STATIC]) + + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_LDFLAGS], [${runpath_args}]) + OPAL_FLAGS_APPEND_UNIQ([OSHMEM_WRAPPER_FC_LDFLAGS], [${runpath_fc_args}]) + + AC_MSG_CHECKING([for OSHMEM wrapper LDFLAGS]) + AC_SUBST([OSHMEM_WRAPPER_LDFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_LDFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper static LDFLAGS]) + AC_SUBST([OSHMEM_WRAPPER_LDFLAGS_STATIC]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_LDFLAGS_STATIC]) + + AC_MSG_CHECKING([for OSHMEM wrapper LIBS]) + AC_SUBST([OSHMEM_WRAPPER_LIBS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_LIBS]) + + AC_MSG_CHECKING([for OSHMEM wrapper static LIBS]) + AC_SUBST([OSHMEM_WRAPPER_LIBS_STATIC]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_LIBS_STATIC]) + + AC_MSG_CHECKING([for OSHMEM wrapper Fortran LDFLAGS]) + AC_SUBST([OSHMEM_WRAPPER_FC_LDFLAGS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_FC_LDFLAGS]) + + AC_MSG_CHECKING([for OSHMEM wrapper Fortran static LDFLAGS]) + AC_SUBST([OSHMEM_WRAPPER_FC_LDFLAGS_STATIC]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_FC_LDFLAGS_STATIC]) + + AC_MSG_CHECKING([for OSHMEM wrapper Fortran LIBS]) + AC_SUBST([OSHMEM_WRAPPER_FC_LIBS]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_FC_LIBS]) + + AC_MSG_CHECKING([for OSHMEM wrapper Fortran static LIBS]) + AC_SUBST([OSHMEM_WRAPPER_FC_LIBS_STATIC]) + AC_MSG_RESULT([$OSHMEM_WRAPPER_FC_LIBS_STATIC]) + + # language binding support. C++ is a bit different, as the + # coshmemler should work even if there is no MPI C++ bindings + # support. However, we do want it to fail if there is no C++ + # coshmemler. + if test "$CXX" = "none"; then + OSHMEM_WRAPPER_CXX_REQUIRED_FILE="not supported" + else + OSHMEM_WRAPPER_CXX_REQUIRED_FILE="" + fi + AC_SUBST([OSHMEM_WRAPPER_CXX_REQUIRED_FILE]) + + if test "$OMPI_TRY_FORTRAN_BINDINGS" -gt "$OMPI_FORTRAN_NO_BINDINGS" ; then + OSHMEM_WRAPPER_FORTRAN_REQUIRED_FILE="" + else + OSHMEM_WRAPPER_FORTRAN_REQUIRED_FILE="not supported" + fi + AC_SUBST([OSHMEM_WRAPPER_FORTRAN_REQUIRED_FILE]) + + AC_DEFINE_UNQUOTED(OSHMEM_WRAPPER_CFLAGS, "$OSHMEM_WRAPPER_CFLAGS", + [CFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OSHMEM_WRAPPER_CXXFLAGS, "$OSHMEM_WRAPPER_CXXFLAGS", + [CXXFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OSHMEM_WRAPPER_FCFLAGS, "$OSHMEM_WRAPPER__FCFLAGS", + [FCFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OSHMEM_WRAPPER_LDFLAGS, "$OSHMEM_WRAPPER_LDFLAGS", + [LDFLAGS to pass through the wrapper compilers]) + AC_DEFINE_UNQUOTED(OSHMEM_WRAPPER_LIBS, "$OSHMEM_WRAPPER_LIBS", + [LIBS to pass through the wrapper compilers]) + + dnl #################################################################### + dnl Setup variables for pkg-config files + dnl + dnl Add all our dependent libraries to libs.Private for users that want + dnl to static build, unless we're only building static libraries, in + dnl which case, add the dependent libraries to libs itself, since any + dnl linking will require the full set of libraries. + dnl #################################################################### + AC_MSG_CHECKING([for OSHMEM pkg-config Cflags]) + OSHMEM_PC_CFLAGS="${OSHMEM_WRAPPER_CPPFLAGS} ${OSHMEM_WRAPPER_CFLAGS} ${OSHMEM_WRAPPER_CFLAGS_PREFIX}" + OSHMEM_PC_CFLAGS=`echo ${OSHMEM_PC_CFLAGS} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_CFLAGS]) + AC_MSG_RESULT([${OSHMEM_PC_CFLAGS}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Libs]) + OSHMEM_PC_LIBS="${OSHMEM_WRAPPER_LDFLAGS} ${OSHMEM_WRAPPER_LIBS}" + OSHMEM_PC_LIBS=`echo ${OSHMEM_PC_LIBS} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_LIBS]) + AC_MSG_RESULT([${OSHMEM_PC_LIBS}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Libs.private]) + OSHMEM_PC_LIBS_PRIVATE="${OSHMEM_WRAPPER_LDFLAGS_STATIC} ${OSHMEM_WRAPPER_LIBS_STATIC}" + OSHMEM_PC_LIBS_PRIVATE=`echo ${OSHMEM_PC_LIBS_PRIVATE} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_LIBS_PRIVATE]) + AC_MSG_RESULT([${OSHMEM_PC_LIBS_PRIVATE}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Fortran Cflags]) + OSHMEM_PC_CFLAGS="${OSHMEM_WRAPPER_FCFLAGS} ${OSHMEM_WRAPPER_FCFLAGS_PREFIX}" + OSHMEM_PC_CFLAGS=`echo ${OSHMEM_PC_CFLAGS} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_FC_CFLAGS]) + AC_MSG_RESULT([${OSHMEM_PC_FC_CFLAGS}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Fortran Libs]) + OSHMEM_PC_FC_LIBS="${OSHMEM_WRAPPER_FC_LDFLAGS} ${OSHMEM_WRAPPER_FC_LIBS}" + OSHMEM_PC_FC_LIBS=`echo ${OSHMEM_PC_FC_LIBS} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_FC_LIBS]) + AC_MSG_RESULT([${OSHMEM_PC_FC_LIBS}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Fortran Libs.private]) + OSHMEM_PC_FC_LIBS_PRIVATE="${OSHMEM_WRAPPER_FC_LDFLAGS_STATIC} ${OSHMEM_WRAPPER_FC_LIBS_STATIC}" + OSHMEM_PC_FC_LIBS_PRIVATE=`echo ${OSHMEM_PC_FC_LIBS_PRIVATE} | sed -e 's/@{/\${/g'` + AC_SUBST([OSHMEM_PC_FC_LIBS_PRIVATE]) + AC_MSG_RESULT([${OSHMEM_PC_FC_LIBS_PRIVATE}]) + + OSHMEM_PC_MODULES= + OSHMEM_PC_MODULES_PRIVATE= + AS_IF([test "${enable_shared}" != "no" -a "${enable_static}" != "yes"], + [], + [test "${enable_shared}" != "no" -a "${enable_static}" = "yes"], + [OSHMEM_PC_MODULES_PRIVATE="${wrapper_extra_pkgconfig_modules} ${oshmem_mca_wrapper_extra_pc_modules}"], + [OSHMEM_PC_MODULES="${wrapper_extra_pkgconfig_modules} ${oshmem_mca_wrapper_extra_pc_modules}"]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Modules]) + AC_SUBST([OSHMEM_PC_MODULES]) + AC_MSG_RESULT([${OSHMEM_PC_MODULES}]) + + AC_MSG_CHECKING([for OSHMEM pkg-config Modules.private]) + AC_SUBST([OSHMEM_PC_MODULES_PRIVATE]) + AC_MSG_RESULT([${OSHMEM_PC_MODULES_PRIVATE}]) + ]) + + OPAL_VAR_SCOPE_POP ]) diff --git a/configure.ac b/configure.ac index 08eece31..39197dda 100755 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,8 @@ AC_CONFIG_HEADERS([src/config.h]) AC_CANONICAL_HOST +OPAL_CONFIGURE_SETUP + OPAL_CHECK_ATTRIBUTES AS_IF([test "$opal_cv___attribute__deprecated" = 1], [SHMEM_AC_HAVE_ATTRIBUTE_DEPRECATED=1], @@ -74,6 +76,16 @@ AC_ARG_ENABLE([completion-polling], [AC_HELP_STRING([--enable-completion-polling], [Enable polling in quiet, fence, and local completion operations (default:disabled)])]) +AC_ARG_ENABLE([hwloc-enforce-single-socket], + [AC_HELP_STRING([--enable-hwloc-enforce-single-socket], + [Repin process to ensure it has affinity to cores within a single socket (default:disabled)])]) +AS_IF([test "$enable_hwloc_enforce_single_socket" = "yes"], [AC_DEFINE([HWLOC_ENFORCE_SINGLE_SOCKET], [1], [Repin process to ensure it has affinity to cores within a single socket])]) + +AC_ARG_ENABLE([hwloc-enforce-single-numa-node], + [AC_HELP_STRING([--enable-hwloc-enforce-single-numa-node], + [Repin process to ensure it has affinity to cores within a single NUMA node (default:disabled)])]) +AS_IF([test "$enable_hwloc_enforce_single_numa_node" = "yes"], [AC_DEFINE([HWLOC_ENFORCE_SINGLE_NUMA_NODE], [1], [Repin process to ensure it has affinity to cores within a single NUMA node])]) + AC_ARG_ENABLE([manual-progress], [AC_HELP_STRING([--enable-manual-progress], [Enable intermittent progress calls inside transport layer (default:disabled)])]) @@ -121,6 +133,35 @@ AS_IF([test "$enable_threads" != "no"], [ ]) AM_CONDITIONAL([HAVE_PTHREADS], [test "$HAVE_POSIX_THREADS" = "1"]) +AS_IF([test "$with_hwloc" != "no"], [ + OPAL_VAR_SCOPE_PUSH([external_hwloc_happy internal_hwloc_happy opal_hwloc_STATIC_LDFLAGS opal_hwloc_LIBS opal_hwloc_STATIC_LIBS]) + OPAL_3RDPARTY_WITH([hwloc], [hwloc], [package_hwloc]) + _OPAL_CONFIG_HWLOC_EXTERNAL( + [external_hwloc_happy=1 + opal_hwloc_mode="external" + AC_DEFINE([USE_HWLOC], [1], [Enable hwloc. Default behavior is to automatically enable hwloc if installation can be found])], + [AS_IF([test -n "$with_hwloc"], + [AC_MSG_ERROR([Could not find viable hwloc build.])], + [external_hwloc_happy=0 + AC_MSG_WARN([Could not find viable hwloc build.])])] + ) + + OPAL_3RDPARTY_EXTRA_DIST="$OPAL_3RDPARTY_EXTRA_DIST hwloc_tarball" + OPAL_3RDPARTY_DISTCLEAN_DIRS="$OPAL_3RDPARTY_DISTCLEAN_DIRS hwloc_directory" + + OPAL_WRAPPER_FLAGS_ADD([LDFLAGS], [${opal_hwloc_LDFLAGS}]) + OPAL_WRAPPER_FLAGS_ADD([STATIC_LDFLAGS], [${opal_hwloc_STATIC_LDFLAGS}]) + OPAL_WRAPPER_FLAGS_ADD([LIBS], [${opal_hwloc_LIBS}]) + OPAL_WRAPPER_FLAGS_ADD([STATIC_LIBS], [${opal_hwloc_STATIC_LIBS}]) + OPAL_WRAPPER_FLAGS_ADD([PC_MODULES], [${opal_hwloc_PC_MODULES}]) + + AC_CONFIG_COMMANDS_PRE([OPAL_CONFIG_HWLOC_INTERNAL_LIBS_HANDLER]) + + OPAL_SUMMARY_ADD([Miscellaneous], [hwloc], [], [$opal_hwloc_mode]) + + OPAL_VAR_SCOPE_POP + ]) + AS_IF([test "$enable_threads" != "no"], [ AS_IF([test "$enable_openmp" != "no"], [ AC_OPENMP @@ -832,6 +873,9 @@ fi if test -n "$with_pmi" -a "$with_pmi" != "no" -a "$with_pmi" != "yes" ; then DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --with-pmi=${with_pmi}" fi +if test -n "$with_hwloc" -a "$with_hwloc" != "no" -a "$with_hwloc" != "yes" ; then + DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --with-hwloc=${with_hwloc}" +fi if test "$enable_pmi_simple" = "yes" ; then DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --enable-pmi-simple" fi @@ -885,6 +929,10 @@ if test "$transport_xpmem" = "yes" ; then WRAPPER_COMPILER_EXTRA_LIBS="$XPMEM_LIBS" fi +if test -n "opal_hwloc_LDFLAGS"; then + WRAPPER_COMPILER_EXTRA_LDFLAGS="$WRAPPER_COMPILER_EXTRA_LDFLAGS $opal_hwloc_LDFLAGS" +fi + CPPFLAGS="$CPPFLAGS $pmi_CPPFLAGS" LDFLAGS="$LDFLAGS $pmi_LDFLAGS $aslr_LDFLAGS" LIBS="$LIBS $pmi_LIBS" @@ -902,7 +950,8 @@ AS_IF([test "$enable_pmi_simple" = "yes"], AC_MSG_CHECKING([for OPAL LDFLAGS]) RPATHIFY_LDFLAGS([WRAPPER_COMPILER_EXTRA_LDFLAGS]) -WRAPPER_COMPILER_EXTRA_LDFLAGS=`echo "$WRAPPER_COMPILER_EXTRA_LDFLAGS" | sed -e 's/@{libdir}/\${libdir}/g'` +AS_IF([test "$enable_wrapper_rpath" = "yes"], + [WRAPPER_COMPILER_EXTRA_LDFLAGS="$WRAPPER_COMPILER_EXTRA_LDFLAGS -Wl,-rpath -Wl,${libdir}"]) AC_MSG_RESULT([$WRAPPER_COMPILER_EXTRA_LDFLAGS]) AC_SUBST(WRAPPER_COMPILER_EXTRA_LDFLAGS) AC_SUBST(WRAPPER_COMPILER_EXTRA_LIBS) @@ -988,6 +1037,11 @@ if test "$enable_threads" != "no"; then else echo " Thread support: no" fi +if test "$opal_hwloc_mode" = "external"; then + echo " hwloc support: yes" +else + echo " hwloc support: no" +fi if test "$enable_error_checking" != "yes"; then echo " Error checking: no" else diff --git a/src/init.c b/src/init.c index c6086e36..01ca23df 100644 --- a/src/init.c +++ b/src/init.c @@ -98,6 +98,11 @@ int shmem_internal_thread_level; unsigned int shmem_internal_rand_seed; +#ifdef USE_HWLOC +#include +hwloc_topology_t shmem_internal_topology; +#endif + #ifdef ENABLE_THREADS shmem_internal_mutex_t shmem_internal_mutex_alloc; shmem_internal_mutex_t shmem_internal_mutex_rand_r; @@ -378,6 +383,46 @@ shmem_internal_heap_postinit(void) shmem_internal_data_base, shmem_internal_data_length); #ifdef HAVE_SCHED_GETAFFINITY +#ifdef USE_HWLOC + ret = hwloc_topology_init(&shmem_internal_topology); + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_exit, "hwloc_topology_init failed (%s). Please verify your hwloc installation\n", strerror(errno)); + + ret = hwloc_topology_set_io_types_filter(shmem_internal_topology, HWLOC_TYPE_FILTER_KEEP_ALL); + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_exit, "hwloc_topology_set_io_types_filter failed (%s). Please verify your hwloc installation\n", strerror(errno)); + + ret = hwloc_topology_load(shmem_internal_topology); + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_exit, "hwloc_topology_load failed (%s). Please verify your hwloc installation\n", strerror(errno)); +#if defined(HWLOC_ENFORCE_SINGLE_SOCKET) || defined(HWLOC_ENFORCE_SINGLE_NUMA_NODE) + hwloc_bitmap_t bindset = hwloc_bitmap_alloc(); + hwloc_bitmap_t bindset_all = hwloc_bitmap_alloc(); + hwloc_bitmap_t bindset_covering_obj = hwloc_bitmap_alloc(); + + ret = hwloc_get_proc_last_cpu_location(shmem_internal_topology, getpid(), bindset, HWLOC_CPUBIND_PROCESS); + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_cleanup, "hwloc_get_proc_last_cpu_location failed (%s). Please verify your hwloc installation\n", strerror(errno)); + + ret = hwloc_get_proc_cpubind(shmem_internal_topology, getpid(), bindset_all, HWLOC_CPUBIND_PROCESS); + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_cleanup, "hwloc_get_proc_cpubind failed (%s). Please verify your hwloc installation\n", strerror(errno)); +#ifdef HWLOC_ENFORCE_SINGLE_SOCKET + hwloc_obj_t covering_obj = hwloc_get_next_obj_covering_cpuset_by_type(shmem_internal_topology, bindset, HWLOC_OBJ_PACKAGE, NULL); + SHMEM_CHECK_GOTO_MSG(!covering_obj, hwloc_cleanup, + "hwloc_get_next_obj_covering_cpuset_by_type failed (could not detect object of type 'HWLOC_OBJ_PACKAGE' in provided cpuset). Please verify your hwloc installation\n"); +#else /* HWLOC_ENFORCE_SINGLE_NUMA_NODE */ + hwloc_obj_t covering_obj = hwloc_get_next_obj_covering_cpuset_by_type(shmem_internal_topology, bindset, HWLOC_OBJ_NUMANODE, NULL); + SHMEM_CHECK_GOTO_MSG(!covering_obj, hwloc_cleanup, + "hwloc_get_next_obj_covering_cpuset_by_type failed (could not detect object of type 'HWLOC_OBJ_NUMANODE' in provided cpuset). Please verify your hwloc installation\n"); +#endif + hwloc_bitmap_and(bindset_covering_obj, bindset_all, covering_obj->cpuset); + ret = hwloc_set_proc_cpubind(shmem_internal_topology, getpid(), bindset_covering_obj, HWLOC_CPUBIND_PROCESS); /* Include HWLOC_CPUBIND_STRICT in flags? */ + SHMEM_CHECK_GOTO_MSG(ret != 0, hwloc_cleanup, "hwloc_set_proc_cpubind failed (%s). Please verify your hwloc installation\n", strerror(errno)); + + hwloc_cleanup: + hwloc_bitmap_free(bindset); + hwloc_bitmap_free(bindset_all); + hwloc_bitmap_free(bindset_covering_obj); +#endif // HWLOC_ENFORCE_SINGLE_SOCKET || HWLOC_ENFORCE_SINGLE_NUMA_NODE + hwloc_exit: +#endif // USE_HWLOC + if (shmem_internal_params.DEBUG) { cpu_set_t my_set; @@ -413,7 +458,7 @@ shmem_internal_heap_postinit(void) free(cores_str_wrap); } } -#endif +#endif // HAVE_SCHED_GETAFFINITY /* Initialize transport devices */ ret = shmem_transport_init(); diff --git a/src/shmem_internal.h b/src/shmem_internal.h index a3bebd97..5befc852 100644 --- a/src/shmem_internal.h +++ b/src/shmem_internal.h @@ -51,6 +51,11 @@ extern int shmem_external_heap_device; extern unsigned int shmem_internal_rand_seed; +#ifdef USE_HWLOC +#include +extern hwloc_topology_t shmem_internal_topology; +#endif + #define SHMEM_INTERNAL_HEAP_OVERHEAD (1024*1024) #define SHMEM_INTERNAL_DIAG_STRLEN 1024 #define SHMEM_INTERNAL_DIAG_WRAPLEN 72 @@ -173,6 +178,14 @@ extern unsigned int shmem_internal_rand_seed; } \ } while(0) +#define SHMEM_CHECK_GOTO_MSG(ret, lbl, ...) \ + do { \ + if (ret) { \ + RAISE_WARN_MSG(__VA_ARGS__); \ + goto lbl; \ + } \ + } while(0) + #ifdef ENABLE_ERROR_CHECKING #define SHMEM_ERR_CHECK_INITIALIZED() \ do { \ diff --git a/src/transport_ofi.c b/src/transport_ofi.c index 6a0a9217..e5ae8baa 100644 --- a/src/transport_ofi.c +++ b/src/transport_ofi.c @@ -39,6 +39,10 @@ #define fnmatch(P, S, F) strcmp(P, S) #endif +#ifdef USE_HWLOC +#include +#endif + #define SHMEM_INTERNAL_INCLUDE #include "shmem.h" #include "shmem_internal.h"