gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master e723937: Installation: --disable-shared links


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e723937: Installation: --disable-shared links statically with dependencies also
Date: Fri, 12 Feb 2021 19:42:22 -0500 (EST)

branch: master
commit e723937db965cc22b544b8e575a2692cfedf3f62
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Installation: --disable-shared links statically with dependencies also
    
    Until now, when '--disable-shared' was given, only the main Gnuastro
    library was statically linked to the programs. All the other dependency
    libraries would be linked dynamically, even if a static version of that
    library also existed. This would make it hard to move the built binary to
    another system (which may have different versions of the shared libraries).
    
    The main problem was that the 'AC_LIB_HAVE_LINKFLAGS' Autoconf macro
    (provided by Gnulib), ignores the '--disable-shared' option. As a result,
    if a shared library existed, it would prefer that and return the shared
    library instead of the static library.
    
    With this commit, the issue has been fixed with a hack in the GNU
    Portability Library (or Gnulib). The hack is implemented as a
    'bootstrap_post_import_hook' in Gnuastro's 'bootstrap.conf'. In this hook,
    a step was added to only check for shared libraries if the 'enable_shared'
    variable has a value of 'yes'. With this hack, when '--disable-shared' is
    given, the the returned value of 'AC_LIB_HAVE_LINKFLAGS' is the absolute
    path of the static library (if it exists). If no static library exists on
    the system, then a shared library is still found and returned (with
    '-lNAME', where 'NAME' is the name of the library).
    
    Therefore when '--disable-shared' is given if any dependency has a static
    library, it will be statically linked into Gnuastro's programs (making them
    portable).
    
    This issue was found in a discussion with Sylvain Mottet.
    
    In the process three other issues have been found and addressed:
    
     - When building in '--disable-shared' mode (as I commonly do personally
       during development!), the BuildProgram step in 'make check' failed with
       the new features! The cause was that the 'lib/libgnuastro.la' file
       doesn't include static libraries in its 'dependency_libs' variable. It
       also prints a bad warning that this type of "shared" library isn't
       portable (but its not a shared library, so I am ignoring it for now). To
       fix this, just before the 'make' step finishes, we will re-write the
       value of 'dependency_libs' in 'lib/libgnuastro.la' to be the full set of
       libraries (including static) that have been found during the configure
       phase. This fixed the crash during 'make check'.
    
     - While doing this test in an environment where all dependencies had
       static libraries, I noticed that CFITSIO can also depend on the BZ2
       library if it was present when CFITSIO was built. So we now also check
       for the BZ2 library before CFITSIO.
    
     - When 'AC_LIB_HAVE_LINKFLAGS' goes searching for static libraries,
       instead of '-lpthread', it can return 'libpthread.a'. However, at least
       in Gnuastro's static build on a GNU/Linux system, the POSIX threads
       library (which is part of the host's C library) will crash (as described
       in 'configure.ac'). So with this commit, a step has been added in the
       final stage of setting the library linking list that will replace any
       string that ends with 'libpthread.a' with '-lpthread'.
---
 Makefile.am                  | 15 ++++++++-
 THANKS                       |  1 +
 bootstrap.conf               |  5 +++
 configure.ac                 | 77 +++++++++++++++++++++++++++-----------------
 doc/announce-acknowledge.txt |  1 +
 5 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index f0e2cac..45b97af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -170,7 +170,20 @@ EXTRA_DIST = COPYING.FDL genauthors .dir-locals.el 
.version \
 ## set MAKECMDGOALS to blank if there are no arguments, however, the way
 ## Automake works, its value is set to "all-am".
 all-local:
-       @if [ x$(MAKECMDGOALS) = x"all-am" ] && [ x$(GUIDEMESSAGE) = xyes ]; 
then    \
+
+        # If we are in static linking mode, correct the 'lib_dependencies'
+        # variable of 'libgnuastro.la'. Because by default it will not
+        # include static libraries!
+       @if [ "X$(MAKECMDGOALS)" = "Xall-am" ] && [ "X$(ENABLE_SHARED)" = "Xno" 
]; then \
+         $(AWK) '/^dependency_libs/{print 
"dependency_libs='\''$(CONFIG_LDADD)'\''"} \
+                 !/^dependency_libs/{print}' 
$(top_builddir)/lib/libgnuastro.la \
+                > $(top_builddir)/lib/libgnuastro_tmp.la; \
+         mv $(top_builddir)/lib/libgnuastro_tmp.la \
+            $(top_builddir)/lib/libgnuastro.la; \
+       fi
+
+        # Print a message if requested.
+       @if [ "X$(MAKECMDGOALS)" = "Xall-am" ] && [ x$(GUIDEMESSAGE) = xyes ]; 
then    \
         echo;                                                                  
     \
         echo 
"==================================================================="; \
         echo 
"==================================================================="; \
diff --git a/THANKS b/THANKS
index 401053a..6d36246 100644
--- a/THANKS
+++ b/THANKS
@@ -70,6 +70,7 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Francesco Montanari                  francesco.montanari@openmailbox.org
     Raphael Morales                      rmorales@iaa.es
     Carlos Morales Socorro               cmorsoc@gmail.com
+    Sylvain Mottet                       mottet@iap.fr
     Dmitrii Oparin                       doparin2@gmail.com
     Bertrand Pain                        bertrand.pain@inserm.fr
     William Pence                        william.pence@nasa.gov
diff --git a/bootstrap.conf b/bootstrap.conf
index 9611d58..bbf7318 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -131,6 +131,11 @@ bootstrap_post_import_hook()
       $m4_base/ax_pthread.m4 > $m4_base/ax_pthread_tmp.m4
   mv $m4_base/ax_pthread_tmp.m4 $m4_base/ax_pthread.m4
 
+  # Hack in 'AC_LIB_HAVE_LINKFLAGS' so it doesn't search for shared
+  # libraries when '--disable-shared' is used.
+  sed 's|if test -n \"$acl_shlibext\"; then|if test -n \"\$acl_shlibext\" -a 
\"X$enable_shared\" = \"Xyes\"; then|' bootstrapped/m4/lib-link.m4 > 
bootstrapped/m4/lib-link_tmp.m4
+  mv bootstrapped/m4/lib-link_tmp.m4 bootstrapped/m4/lib-link.m4
+
   # Add a value pointer to 'argp_option' for easy setting of option values.
   awk '{                                                                    \
          if($1=="struct" && $2=="argp_option")                              \
diff --git a/configure.ac b/configure.ac
index 0ed3b9f..70f9433 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,6 +65,8 @@ AC_SUBST(GAL_LT_VERSION)
 : ${CXXFLAGS=""}
 AC_PROG_CC
 AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_SED
 gl_EARLY
 AM_PROG_AR
 LT_INIT
@@ -161,7 +163,8 @@ CC="$PTHREAD_CC"
 # bug #52490, it can happen that sometimes, the C++ compiler doesn't
 # recognize it. So we need to do a separate check for C++.
 cxxflags_tmp=
-for flg in $CXXFLAGS; do
+for flg in $CXXFLAGS
+do
   AS_IF([test "$flg" = \-Qunused-arguments],
         [ AC_LANG(C++)
           AX_CHECK_COMPILE_FLAG([-Qunused-arguments],
@@ -274,18 +277,21 @@ missing_optional_lib=no
 # Keep the original LIBS to re-set in the end.
 orig_LIBS="$LIBS"
 
-# Order is important here.
-AC_LIB_HAVE_LINKFLAGS([m], [], [#include <math.h>])
-AS_IF([test "x$LIBM" = x],
-      [missing_mandatory=yes; has_cmath=no],
-      [LDADD="$LIBM $LDADD"; LIBS="$LIBM $LIBS"])
 
+
+
+
+# Start of library linking list
+# -----------------------------
+#
+# Note that 'AC_LIB_HAVE_LINKFLAGS' automatically links with the math
+# library ('-lm').
 AC_LIB_HAVE_LINKFLAGS([gsl], [gslcblas], [
 #include <gsl/gsl_rng.h>
 void junk(void) { gsl_rng_env_setup(); } ])
 AS_IF([test "x$LIBGSL" = x],
       [missing_mandatory=yes; has_gsl=no; has_gslcblas=no],
-      [LDADD="$LTLIBGSL $LDADD"; LIBS="$LIBGSL $LIBS"])
+      [LDADD="$LIBGSL $LDADD"; LIBS="$LIBGSL $LIBS"])
 
 
 # Since version 0.42, if 'libcurl' is installed, CFITSIO will link with it
@@ -301,21 +307,24 @@ AS_IF([test "x$LIBGSL" = x],
 # librtmp, libldap). So if you intend to make Gnuastro statically, then
 # build Libcurl in static-only mode so you won't have to check for all
 # these extra libraries here.
+#
+# Similarly, if the Bzip2 library was activated when building CFITSIO, it
+# will be necessary in a static build to CFITSIO.
 AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
 AS_IF([test "x$LIBZ" = x], [],
-      [LDADD="$LTLIBZ $LDADD"; LIBS="$LIBZ $LIBS"])
+      [LDADD="$LIBZ $LDADD"; LIBS="$LIBZ $LIBS"])
+
+
+AC_LIB_HAVE_LINKFLAGS([bz2], [], [#include <bzlib.h>])
+AS_IF([test "x$LIBBZ2" = x], [],
+      [LDADD="$LIBBZ2 $LDADD"; LIBS="$LIBBZ2 $LIBS"])
 
 
 AC_LIB_HAVE_LINKFLAGS([curl], [], [#include <curl/curl.h>])
 AS_IF([test "x$LIBCURL" = x], [],
-      [LDADD="$LTLIBCURL $LDADD"; LIBS="$LIBCURL $LIBS"])
+      [LDADD="$LIBCURL $LDADD"; LIBS="$LIBCURL $LIBS"])
 
 
-# Older versions of CFITSIO don't install a shared library, only a static
-# one. Eventhough we add '-lm' to LDADD, on some systems, it complains
-# about not finding basic math libraries. Therefore the configure script
-# can't find CFITSIO, eventhough it exists. The solution is to manually add
-# the math-library as a dependency of CFITSIO.
 AC_LIB_HAVE_LINKFLAGS([cfitsio], [], [
 #include <fitsio.h>
 void junk(void) {
@@ -324,7 +333,7 @@ fitsfile *f;
 ffopen(&f, "junk", READONLY, &status);} ])
 AS_IF([test "x$LIBCFITSIO" = x],
       [missing_mandatory=yes; has_cfitsio=no],
-      [LDADD="$LTLIBCFITSIO $LDADD"; LIBS="$LIBCFITSIO $LIBS"])
+      [LDADD="$LIBCFITSIO $LDADD"; LIBS="$LIBCFITSIO $LIBS"])
 
 
 AC_LIB_HAVE_LINKFLAGS([wcs], [], [
@@ -337,7 +346,7 @@ wcspih(header, 1, 0, 0, &nreject, &nwcs, &wcs);
 } ])
 AS_IF([test "x$LIBWCS" = x],
       [missing_mandatory=yes; has_wcslib=no],
-      [LDADD="$LTLIBWCS $LDADD"; LIBS="$LIBWCS $LIBS"])
+      [LDADD="$LIBWCS $LDADD"; LIBS="$LIBWCS $LIBS"])
 
 
 AC_ARG_WITH([libjpeg],
@@ -355,35 +364,26 @@ void junk(void) {
 } ]) ])
 AS_IF([test "x$LIBJPEG" = x],
       [missing_optional_lib=yes; has_libjpeg=no; anywarnings=yes],
-      [LDADD="$LTLIBJPEG $LDADD"; LIBS="$LIBJPEG $LIBS"])
+      [LDADD="$LIBJPEG $LDADD"; LIBS="$LIBJPEG $LIBS"])
 AM_CONDITIONAL([COND_HASLIBJPEG], [test "x$has_libjpeg" = "xyes"])
 
 
-# Check libtiff: If an LZMA libray (part of the XZ Utils) is present,
-# libtiff has probably been built with it. So we'll also need to link with
-# the LZMA library. But if libtiff hasn't been linked with it and its
-# present, there is no problem, the linker will just pass over it. So we
-# don't need to stop the build if this fails.
 AC_ARG_WITH([libtiff],
             [AS_HELP_STRING([--without-libtiff],
                             [disable support for libtiff])],
             [], [with_libtiff=yes])
 AS_IF([test "x$with_libtiff" != xno],
-      [ AC_LIB_HAVE_LINKFLAGS([lzma], [], [#include <lzma.h>])
-        AC_LIB_HAVE_LINKFLAGS([tiff], [], [
+      [ AC_LIB_HAVE_LINKFLAGS([tiff], [], [
 #include <tiffio.h>
 void junk(void) {TIFF *tif=TIFFOpen("junk", "r");} ])
       ])
-AS_IF([test "x$LIBLZMA" = x], [],
-      [LDADD="$LTLIBLZMA $LDADD"; LIBS="$LIBLZMA $LIBS"])
 AS_IF([test "x$LIBTIFF" = x],
       [missing_optional_lib=yes; has_libtiff=no; anywarnings=yes],
-      [LDADD="$LTLIBTIFF $LDADD"; LIBS="$LIBTIFF $LIBS"])
+      [LDADD="$LIBTIFF $LDADD"; LIBS="$LIBTIFF $LIBS"])
 AM_CONDITIONAL([COND_HASLIBTIFF], [test "x$has_libtiff" = "xyes"])
 
 
-# Check libgit2. Note that very old versions of libgit2 don't have the
-# 'git_libgit2_init' function.
+# libgit2 (very old versions of libgit2 don't have the 'git_libgit2_init').
 AC_ARG_WITH([libgit2],
             [AS_HELP_STRING([--without-libgit2],
                             [disable support for libgit2])],
@@ -395,12 +395,28 @@ void junk(void) {git_libgit2_init();} ])
       ])
 AS_IF([test "x$LIBGIT2" = x],
       [missing_optional_lib=yes; has_libgit2=0],
-      [LDADD="$LTLIBGIT2 $LDADD"; LIBS="$LIBGIT2 $LIBS"])
+      [LDADD="$LIBGIT2 $LDADD"; LIBS="$LIBGIT2 $LIBS"])
 AC_DEFINE_UNQUOTED([GAL_CONFIG_HAVE_LIBGIT2], [$has_libgit2],
                    [libgit2 is installed on the system])
 AS_IF([test "x$has_libgit2" = "x1"], [], [anywarnings=yes])
 
 
+# End of library linking list
+# ---------------------------
+#
+# If we are in static mode, convert any string ending in 'libpthread.a' to
+# '-lpthread' (because pthread is part of the C library and atleast in
+# Gnuastro's usage so far, can't be statically linked (gives errors on
+# undefined symbols like '_dl_pagesize' or '_dl_init_static_tls').
+AS_IF([test "x$enable_shared" = "xno"],
+      [ LDADD=$(AS_ECHO(["$LDADD"]) \
+           | $AWK '{for(i=1; i<=NF; ++i) { \
+                      if( $i ~ /libpthread.a/ ) \
+                        $i="-lpthread" } \
+                    print $0}')
+      ])
+
+
 
 
 
@@ -923,6 +939,7 @@ AM_CONDITIONAL([COND_WARP],        [test $enable_warp = 
yes])
 # linking flags and put them in the Makefiles.
 LIBS="$orig_LIBS"
 AC_SUBST(CONFIG_LDADD, [$LDADD])
+AC_SUBST(ENABLE_SHARED, [$enable_shared])
 AS_ECHO(["linking flags (LDADD) ... $LDADD"])
 
 
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index 3c8c7fc..48fa070 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -2,6 +2,7 @@ Alphabetically ordered list to acknowledge in the next release.
 
 Mark Calabretta
 Raul Infante-Sainz
+Sylvain Mottet
 Francois Ochsenbein
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]