libtool-patches
[Top][All Lists]
Advanced

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

[PATCH 2/3] support POSIX nm, prefer POSIX nm for AIX


From: Michael Haubenwallner
Subject: [PATCH 2/3] support POSIX nm, prefer POSIX nm for AIX
Date: Mon, 21 Mar 2016 18:01:50 +0100

In BSD mode, the AIX nm does not tell whether a symbol is weak, we need
to use POSIX mode instead.
* m4/libtool.m4 (LT_PATH_NM): For AIX, search for nm supporting the -P
flag (POSIX mode).  When AIX nm is found, add the -C and -l flags.  Add
detection of POSIX compatible nm.
(_LT_CMD_GLOBAL_SYMBOLS): Support POSIX-compatible nm.  Reorder to allow
for platform specific hooks during transformation of global_symbol_pipe
into C source code.  For AIX, set hook to transform even weak text
symbols as normal text symbols, like before with AIX nm in BSD mode.
For AIX, update symcode to support nm in any known mode.
(_LT_LINKER_SHLIBS): For AIX, use global_symbol_pipe to simplify forming
the export_symbols_cmds, add check for C++ to warn when nm fails to mark
symbols as weak.
---
 m4/libtool.m4 | 118 +++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 71 insertions(+), 47 deletions(-)

diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 513e2ae..131dd48 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -3696,10 +3696,10 @@ _LT_DECL([], [want_nocaseglob], [1],
 
 # LT_PATH_NM
 # ----------
-# find the pathname to a BSD- or MS-compatible name lister
+# find the pathname to a BSD-, POSIX- or MS-compatible name lister
 AC_DEFUN([LT_PATH_NM],
 [AC_REQUIRE([AC_PROG_CC])dnl
-AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+AC_CACHE_CHECK([for BSD-, POSIX- or MS-compatible name lister (nm)], 
lt_cv_path_NM,
 [if test -n "$NM"; then
   # Let the user override the test.
   lt_cv_path_NM=$NM
@@ -3720,10 +3720,11 @@ else
        #   nm: unknown option "B" ignored
        # Tru64's nm complains that /dev/null is an invalid object file
        # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
-       # AIX nm needs -X32_64 to accept both 32 and 64 bit objects
+       # AIX nm needs -X32_64 to accept both 32 and 64 bit objects,
+       # and never tells weakiness of symbols in BSD mode
        tmp_nmflags=-B
        if test no != "$gl_cv_powerpc_aix_object_mode"; then
-         tmp_nmflags='-X32_64 -B'
+         tmp_nmflags='-X32_64 -P'
        fi
        case $build_os in
        mingw*) lt_bad_file=conftest.nm/nofile ;;
@@ -3752,6 +3753,14 @@ else
     IFS=$lt_save_ifs
   done
   : ${lt_cv_path_NM=no}
+  if test no != "$lt_cv_path_NM" -a no != "$gl_cv_powerpc_aix_object_mode"; 
then
+    # AIX nm needs the '-C' flag to disable demangling,
+    # and the '-l' flag to tell the weakiness of symbols.
+    case `$lt_cv_path_NM -V 2>&1` in
+    *GNU* | *'with BFD'*) ;;
+    *) lt_cv_path_NM="$lt_cv_path_NM -Cl" ;;
+    esac
+  fi
 fi])
 if test no != "$lt_cv_path_NM"; then
   NM=$lt_cv_path_NM
@@ -3777,7 +3786,7 @@ else
 fi
 test -z "$NM" && NM=nm
 AC_SUBST([NM])
-_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+_LT_DECL([], [NM], [1], [A BSD-, POSIX- or MS-compatible name lister])dnl
 
 AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
   [lt_cv_nm_interface="BSD nm"
@@ -3792,6 +3801,8 @@ AC_CACHE_CHECK([the name lister ($NM) interface], 
[lt_cv_nm_interface],
   cat conftest.out >&AS_MESSAGE_LOG_FD
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
+  elif $GREP '^[[       ]]*_*some_variable[[    ]][[    ]]*[[BD]]' 
conftest.out > /dev/null; then
+    lt_cv_nm_interface="POSIX nm"
   fi
   rm -f conftest*])
 ])# LT_PATH_NM
@@ -3957,8 +3968,30 @@ symcode='[[BCDEGRST]]'
 # Regexp to match symbols that can be accessed directly from C.
 sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
 
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  # Gets list of data symbols to import.
+  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+  # Adjust the below global symbol transforms to fixup imported variables.
+  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
+  lt_c_name_lib_hook="\
+  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
+  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
+else
+  # Disable hooks by default.
+  lt_cv_sys_global_symbol_to_import=
+  lt_cdecl_hook=
+  lt_c_name_hook=
+  lt_c_name_lib_hook=
+fi
+
 # Define system-specific variables.
 case $host_os in
+aix[[4-9]]*)
+  # in default mode, AIX nm with -l marks weak symbols by an extra '*'
+  symcode='[[BDLTVWZ\*]]'
+  lt_cdecl_hook=" -e 's/^W/T/p'" # weak text symbol
+  ;;
 aix*)
   symcode='[[BCDT]]'
   ;;
@@ -3999,23 +4032,6 @@ case `$NM -V 2>&1` in
   symcode='[[ABCDGIRSTW]]' ;;
 esac
 
-if test "$lt_cv_nm_interface" = "MS dumpbin"; then
-  # Gets list of data symbols to import.
-  lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
-  # Adjust the below global symbol transforms to fixup imported variables.
-  lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
-  lt_c_name_hook=" -e 's/^I .* \(.*\)$/  {\"\1\", (void *) 0},/p'"
-  lt_c_name_lib_hook="\
-  -e 's/^I .* \(lib.*\)$/  {\"\1\", (void *) 0},/p'\
-  -e 's/^I .* \(.*\)$/  {\"lib\1\", (void *) 0},/p'"
-else
-  # Disable hooks by default.
-  lt_cv_sys_global_symbol_to_import=
-  lt_cdecl_hook=
-  lt_c_name_hook=
-  lt_c_name_lib_hook=
-fi
-
 # Transform an extracted symbol line into a proper C declaration.
 # Some systems (esp. on ia64) link data and code symbols differently,
 # so use this general approach.
@@ -4073,6 +4089,9 @@ for ac_symprfx in "" "_"; do
 "     s[1]~/address@hidden/{print f,s[1],s[1]; next};"\
 "     s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
 "     ' prfx=^$ac_symprfx]"
+  elif test "$lt_cv_nm_interface" = "POSIX nm"; then
+    symxfrm="\\2 $ac_symprfx\\1 \\1"
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^[[      
]]*$ac_symprfx$sympat[[         ]][[    ]]*\($symcode$symcode*\)[[      ]][[    
]]*.*$opt_cr$/$symxfrm/p'"
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[    
]]\($symcode$symcode*\)[[       ]][[    
]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
   fi
@@ -4954,19 +4973,33 @@ m4_if([$1], [CXX], [
   _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   case $host_os in
   aix[[4-9]]*)
-    # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-    # Without the "-l" option, or with the "-B" option, AIX nm treats
-    # weak defined symbols like other global defined symbols, whereas
-    # GNU nm marks them as "W".
-    # While the 'weak' keyword is ignored in the Export File, we need
-    # it in the Import File for the 'aix-soname' feature, so we have
-    # to replace the "-B" option with "-P" for AIX nm.
-    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } 
else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
-    else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e 
'\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 
2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") 
|| (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 
== "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print 
\$ 1 } } }'\'' | sort -u > $export_symbols'
+    if test aix != $with_aix_soname; then
+      # Unfortunately, in BSD mode or without the '-l' flag,
+      # AIX nm does not tell the weakiness of symbols, which we
+      # warn the user about in C++ when we create an Import File.
+      # GNU g++ (version range unknown yet) seems to have a bug to
+      # export even this weak data symbol as weak text symbol...
+      AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+         [template<int v> struct Weaky { static const int x; };
+          template<int v> int const Weaky<v>::x = v;
+          template class Weaky<0>;],
+         [return Weaky<0>().x;])],
+        [AS_CASE([`$NM -gp conftest.$ac_objext`],
+          [*Weaky*' '[[CVWZ]]' '*], [],
+          [*' '[[CVWZ]]' '*Weaky*], [],
+          [*Weaky*' '[[BDLT]]'* '*], [],
+          [AC_MSG_WARN(
+            [$NM fails to mark symbols as weak (for the Import Files).])])])
     fi
+    # For both GNU and AIX nm, the '-g' flag shows public (global)
+    # symbols only, and the '-p' flag disables sorting to improve
+    # performance.
+    # Depending on the NM, weak symbols may be marked as:
+    # '[[VWZ]]'   with AIX nm in POSIX mode
+    # '[[BDLT]]*' with AIX nm in default mode (POSIX like)
+    # '[[CVW]]'   with GNU nm in either BSD or POSIX mode
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM -gp $libobjs $convenience | 
$global_symbol_pipe | $EGREP -v " ($exclude_expsyms)$" | awk '\''{ kw = "" } 
/^([[CVWZ]]|[[BDLT]]\*) / { kw = " weak" } { print $ 3 kw }'\'' | sort -u > 
$export_symbols'
     ;;
   pw32*)
     _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
@@ -5409,19 +5442,10 @@ _LT_EOF
        exp_sym_flag='-Bexport'
        no_entry_flag=
       else
-       # If we're using GNU nm, then we don't want the "-C" option.
-       # -C means demangle to GNU nm, but means don't demangle to AIX nm.
-       # Without the "-l" option, or with the "-B" option, AIX nm treats
-       # weak defined symbols like other global defined symbols, whereas
-       # GNU nm marks them as "W".
-       # While the 'weak' keyword is ignored in the Export File, we need
-       # it in the Import File for the 'aix-soname' feature, so we have
-       # to replace the "-B" option with "-P" for AIX nm.
-       if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } 
else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
-       else
-         _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e 
'\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 
2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") 
|| (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 
== "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print 
\$ 1 } } }'\'' | sort -u > $export_symbols'
-       fi
+       # For both GNU and AIX nm, the '-g' flag shows public (global)
+       # symbols only, and the '-p' flag disables sorting to improve
+       # performance.  For the weak symbol handling see the CXX tag.
+       _LT_TAGVAR(export_symbols_cmds, $1)='$NM -gp $libobjs $convenience | 
$global_symbol_pipe | $EGREP -v " ($exclude_expsyms)$" | awk '\''{ kw = "" } 
/^([[CVWZ]]|[[BDLT]]\*) / { kw = " weak" } { print $ 3 kw }'\'' | sort -u > 
$export_symbols'
        aix_use_runtimelinking=no
 
        # Test if we are trying to use run time linking or normal
-- 
2.4.6




reply via email to

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