diff --git a/configure.ac b/configure.ac index d103ab170a..1d5bc2909b 100644 --- a/configure.ac +++ b/configure.ac @@ -799,6 +799,31 @@ m4_ifdef([project_ompi], [OMPI_FIND_MPI_AINT_COUNT_OFFSET]) # checkpoint results AC_CACHE_SAVE +################################## +# Linker characteristics +################################## + +AC_MSG_CHECKING([the linker for support for the -fini option]) +LDFLAGS_save=$LDFLAGS +LDFLAGS="$LDFLAGS_save -Wl,-fini -Wl,finalize" +AC_TRY_LINK([void finalize (void) {}], [], [AC_MSG_RESULT([yes]) + opal_ld_have_fini=1], [AC_MSG_RESULT([no]) + opal_ld_have_fini=0]) +LDFLAGS=$LDFLAGS_save + +opal_destructor_use_fini=0 +opal_no_destructor=0 +if test x$opal_cv___attribute__destructor = x0 ; then + if test x$opal_ld_have_fini = x1 ; then + opal_destructor_use_fini=1 + else + opal_no_destructor=1; + fi +fi + +AC_DEFINE_UNQUOTED(OPAL_NO_LIB_DESTRUCTOR, [$opal_no_destructor], + [Whether libraries can be configured with destructor functions]) +AM_CONDITIONAL(OPAL_DESTRUCTOR_USE_FINI, [test x$opal_destructor_use_fini = x1]) ################################## # Libraries diff --git a/opal/Makefile.am b/opal/Makefile.am index 360474ab0e..dddfe4b6cb 100644 --- a/opal/Makefile.am +++ b/opal/Makefile.am @@ -55,6 +55,12 @@ lib@OPAL_LIB_PREFIX@open_pal_la_LIBADD = \ lib@OPAL_LIB_PREFIX@open_pal_la_DEPENDENCIES = $(lib@OPAL_LIB_PREFIX@open_pal_la_LIBADD) lib@OPAL_LIB_PREFIX@open_pal_la_LDFLAGS = -version-info $(libopen_pal_so_version) +if OPAL_DESTRUCTOR_USE_FINI + +lib@OPAL_LIB_PREFIX@open_pal_la_LDFLAGS += -Wl,-fini -Wl,opal_cleanup + +endif + # included subdirectory Makefile.am's and appended-to variables headers = noinst_LTLIBRARIES = diff --git a/opal/runtime/opal_finalize.c b/opal/runtime/opal_finalize.c index dc583e4424..0105d66069 100644 --- a/opal/runtime/opal_finalize.c +++ b/opal/runtime/opal_finalize.c @@ -57,6 +57,18 @@ extern int opal_initialized; extern int opal_util_initialized; +extern bool opal_init_called; + +static void __opal_attribute_destructor__ opal_cleanup (void) +{ + if (!opal_initialized) { + /* nothing to do */ + return; + } + + /* finalize the class/object system */ + opal_class_finalize(); +} int opal_finalize_util(void) @@ -101,8 +113,9 @@ opal_finalize_util(void) opal_datatype_finalize(); - /* finalize the class/object system */ - opal_class_finalize(); +#if OPAL_NO_LIB_DESTRUCTOR + opal_cleanup (); +#endif free (opal_process_info.nodename); opal_process_info.nodename = NULL; diff --git a/opal/runtime/opal_init.c b/opal/runtime/opal_init.c index f2c681f7cf..f2f36179bb 100644 --- a/opal/runtime/opal_init.c +++ b/opal/runtime/opal_init.c @@ -74,6 +74,7 @@ const char opal_version_string[] = OPAL_IDENT_STRING; int opal_initialized = 0; +bool opal_init_called = false; int opal_util_initialized = 0; /* We have to put a guess in here in case hwloc is not available. If hwloc is available, this value will be overwritten when the @@ -266,6 +267,18 @@ opal_init_util(int* pargc, char*** pargv) return OPAL_SUCCESS; } +#if OPAL_NO_LIB_DESTRUCTOR + if (opal_init_called) { + /* can't use show_help here */ + fprintf (stderr, "opal_init_util: attempted to initialize after finalize without compiler " + "support for either __attribute__(destructor) or linker support for -fini -- process " + "will likely abort\n"); + return OPAL_ERR_NOT_SUPPORTED; + } +#endif + + opal_init_called = true; + /* set the nodename right away so anyone who needs it has it. Note * that we don't bother with fqdn and prefix issues here - we let * the RTE later replace this with a modified name if the user