]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
ltmain: Use shared objects built in source tree
authorSergey Poznyakoff <gray@gnu.org.ua>
Tue, 11 Jun 2024 11:20:15 +0000 (13:20 +0200)
committerIleana Dumitrescu <ileanadumitrescu95@gmail.com>
Tue, 27 Aug 2024 15:17:45 +0000 (18:17 +0300)
It has been discovered that under certain conditions libtool creates
wrappers that prefer installed versions of the shared objects over
those built in the source tree. As a result, any tests run in the
source tree produce unreliable results.

* build-aux/ltmain.in: Alter to use shared objects in source tree
  instead of installed.
* Makefile.am: Added in tests/bug_71489.at.
* tests/bug_71489.at: Contains test case for bug 71489.

Makefile.am
build-aux/ltmain.in
tests/bug_71489.at [new file with mode: 0644]

index 8cc621ea41a6a63e4dbe6bbb2847853b1cf58054..993a6e84d7c8664b52cae12d0c40cce2a121fb67 100644 (file)
@@ -728,6 +728,7 @@ TESTSUITE_AT        = tests/testsuite.at \
                  tests/stresstest.at \
                  tests/cmdline_wrap.at \
                  tests/bug_62343.at    \
+                 tests/bug_71489.at \
                  $(NOTHING_ELSE)
 
 EXTRA_DIST     += $(testsuite) $(TESTSUITE_AT) $(package_m4)
index 6337754157494b53db2df107de7cb87fccd99da1..fb43fef091cd1ecf37d6d363640be482f676a4dd 100644 (file)
@@ -4672,10 +4672,12 @@ func_mode_link ()
     xrpath=
     perm_rpath=
     temp_rpath=
+    temp_rpath_tail=
     thread_safe=no
     vinfo=
     vinfo_number=no
     weak_libs=
+    rpath_arg=
     single_module=$wl-single_module
     func_infer_tag $base_compile
 
@@ -5594,8 +5596,20 @@ func_mode_link ()
 
       # Now actually substitute the argument into the commands.
       if test -n "$arg"; then
-       func_append compile_command " $arg"
-       func_append finalize_command " $arg"
+       if test -n "$rpath_arg"; then
+          func_append finalize_rpath " ${arg##*,}"
+         unset rpath_arg
+       else
+         case $arg in
+          -Wl,-rpath,*)
+           func_append finalize_rpath " ${arg##*,}";;
+          -Wl,-rpath)
+           rpath_arg=1;;
+          *)
+            func_append compile_command " $arg"
+           func_append finalize_command " $arg"
+         esac
+        fi
       fi
     done # argument parsing loop
 
@@ -6246,7 +6260,10 @@ func_mode_link ()
              # Make sure the rpath contains only unique directories.
              case $temp_rpath: in
              *"$absdir:"*) ;;
-             *) func_append temp_rpath "$absdir:" ;;
+              *) case $absdir in
+                 "$progdir/"*) func_append temp_rpath "$absdir:" ;;
+                 *)            func_append temp_rpath_tail "$absdir:" ;;
+                 esac
              esac
            fi
 
@@ -6258,7 +6275,9 @@ func_mode_link ()
            *)
              case "$compile_rpath " in
              *" $absdir "*) ;;
-             *) func_append compile_rpath " $absdir" ;;
+             *) case $absdir in
+                 "$progdir/"*) func_append compile_rpath " $absdir" ;;
+                esac
              esac
              ;;
            esac
@@ -6332,7 +6351,9 @@ func_mode_link ()
            *)
              case "$compile_rpath " in
              *" $absdir "*) ;;
-             *) func_append compile_rpath " $absdir" ;;
+             *) case $absdir in
+                 "$progdir/"*) func_append compile_rpath " $absdir" ;;
+                esac
              esac
              ;;
            esac
@@ -6693,6 +6714,8 @@ func_mode_link ()
          fi # link_all_deplibs != no
        fi # linkmode = lib
       done # for deplib in $libs
+
+      func_append temp_rpath "$temp_rpath_tail"
       if test link = "$pass"; then
        if test prog = "$linkmode"; then
          compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
diff --git a/tests/bug_71489.at b/tests/bug_71489.at
new file mode 100644 (file)
index 0000000..adb5db7
--- /dev/null
@@ -0,0 +1,391 @@
+# bug_71489.at test local version of installed program is used
+
+## --------------------- ##
+##      Bug testing      ##
+## --------------------- ##
+
+AT_BANNER([Testing bug 71489:])
+
+AT_SETUP([Use local version])
+
+AT_KEYWORDS([bug_71489])
+
+# Create root test directory.
+top_dir=test71489_1
+mkdir $top_dir
+top_dir=$(cd $top_dir; pwd)
+
+# Create the libtool library that the program will depend on.
+lib=$top_dir/lib
+mkdir $lib
+
+# Create the external library. This is a very simple autotools program, which
+# contains one function.
+AT_DATA([[$lib/Makefile.am]],
+[[
+lib_LTLIBRARIES = libltb1.la
+libltb1_la_SOURCES = libltb1.c
+libltb1_la_CPPFLAGS=-I$(top_srcdir)
+]])
+
+AT_DATA([["$lib/libltb1.c"]],
+[[
+#include <stdio.h>
+
+void
+ltb_version (void)
+{
+  printf ("ltbug: %s\n", LTBUG_ID);
+}
+]])
+
+# Create src directory, which is linked to the library created above.
+src=$top_dir/src
+mkdir $src
+
+AT_DATA([["$src/Makefile.am"]],
+[[
+bin_PROGRAMS = ltb1
+ltb1_SOURCES = main.c
+ltb1_LDFLAGS = $(CF_LIB_FLAGS)
+ltb1_LDADD = ../lib/libltb1.la
+AM_CPPFLAGS = -I$(top_srcdir)
+]])
+
+AT_DATA([["$src/main.c"]],
+[[
+#include <ltb1.h>
+
+int
+main (int argc, char **argv)
+{
+  ltb_version ();
+  return 0;
+}
+]])
+
+# Create root autotools files and code.
+AT_DATA([["$top_dir/Makefile.am"]],
+[[
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = lib src
+noinst_HEADERS = ltb1.h
+EXTRA_DIST = test.sh
+]])
+
+AT_DATA([["$top_dir/configure.ac"]],
+[[
+AC_PREREQ([2.69])
+AC_INIT([ltbug], ]AT_PACKAGE_VERSION[, ]AT_PACKAGE_BUGREPORT[)AC_CONFIG_SRCDIR([src/main.c])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([foreign])
+
+# Checks for programs.
+AC_PROG_CC
+LT_PREREQ([2.4.6])
+LT_INIT
+
+AC_ARG_VAR([LTBUG_ID],[Identifier of the bug case])
+if test -z "$LTBUG_ID"; then
+  LTBUG_ID=local
+fi
+AC_DEFINE_UNQUOTED([LTBUG_ID],["$LTBUG_ID"],
+ [Text string identifying the library])
+
+AC_SUBST([CF_LIB_FLAGS],['-L$(libdir) -Wl,-rpath -Wl,$(libdir)'])
+
+AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile])
+
+AC_OUTPUT
+]])
+
+AT_DATA([["$top_dir/ltb1.h"]],
+[[
+extern void ltb_version (void);
+extern void ltb2_version (void);
+]])
+
+echo "Running autoreconf on project directory"
+(
+    cd $top_dir
+    pwd
+    LT_AT_LIBTOOLIZE([--install])
+    LT_AT_AUTORECONF([-i])
+)
+
+# Create two directories, one which has the local copy and one which has
+# the installed copy.
+mkdir build_inst build_local prefix_dir
+
+prefix=$(cd prefix_dir; pwd)
+
+echo "Building and installing library"
+(
+    cd build_inst
+    LT_AT_CONFIGURE([--prefix=$prefix  LTBUG_ID='installed'], [$top_dir/configure])
+    LT_AT_MAKE([])
+    LT_AT_MAKE([install])
+)
+
+echo "Building local copy of the project"
+(
+    cd build_local
+    LT_AT_CONFIGURE([--prefix=$prefix], [$top_dir/configure])
+    LT_AT_MAKE([])
+    LT_AT_MAKE([install])
+)
+
+# Although we have installed ltbug, we still expect that we are using the local version.
+cat > expout <<EOF
+ltbug: local
+EOF
+
+case $host_os in
+mingw* | windows*)
+  awk '{printf ("%s\r\n", [$]0);}' < expout > expout.t && mv -f expout.t expout
+  ;;
+cygwin*)
+  awk '{printf ("%s\n", [$]0);}' < expout > expout.t && mv -f expout.t expout
+  ;;
+esac
+
+build_local/src/ltb1 > stdout
+
+echo "Comparing expout to the build binary"
+AT_CHECK([cmp -s stdout expout], [0])
+
+rm -rf $top_dir $lib $src build_inst build_local prefix_dir
+
+# Test local version of installed program is used with external library.
+
+# Create root test directory.
+top_dir=test71489_2
+mkdir $top_dir
+top_dir=$(cd $top_dir; pwd)
+
+ext_lib_dir=$top_dir/ltb2dep
+ltb2=$top_dir/ltb2
+
+# Create ltb2 directory. This will contain two libraries,
+# liba and libb. liba will depend on an external libtool library.
+mkdir $ltb2
+
+# Create the directory which will contain the external dependency liba relies on.
+mkdir $ext_lib_dir
+
+# Create the external library. This is a very simple autotools program, which
+# contains one function.
+AT_DATA([[$ext_lib_dir/configure.ac]],
+[[
+AC_PREREQ([2.69])
+AC_INIT([libltb2dep], ]AT_PACKAGE_VERSION[, ]AT_PACKAGE_BUGREPORT[)
+AC_CONFIG_SRCDIR([main.c])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([foreign])
+
+AC_PROG_CC
+LT_PREREQ([2.4.6])
+LT_INIT
+
+AC_ARG_VAR([LTBUG_ID],[Identifier of the bug case])
+if test -z "$LTBUG_ID"; then
+  LTBUG_ID="local version"
+fi
+AC_DEFINE_UNQUOTED([LTBUG_ID],["$LTBUG_ID"],
+ [Text string identifying the library])
+
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
+]])
+
+
+AT_DATA([["$ext_lib_dir/Makefile.am"]],
+[[
+lib_LTLIBRARIES = libltb2dep.la
+libltb2dep_la_SOURCES = main.c
+]])
+
+AT_DATA([["$ext_lib_dir/main.c"]],
+[[
+#include <stdio.h>
+void
+dummy (void)
+{
+}
+]])
+
+# Create liba, which is linked to the external library created above.
+mkdir "$ltb2/liba"
+
+AT_DATA([["$ltb2/liba/Makefile.am"]],
+[[
+lib_LTLIBRARIES = libltb2a.la
+libltb2a_la_SOURCES = libltb2a.c
+libltb2a_la_LIBADD = -L$(libdir) -lltb2dep
+]])
+
+# Print out the flag LTBUG_ID. This will show if we are using the installed version
+# of this library or the local version.
+AT_DATA([["$ltb2/liba/libltb2a.c"]],
+[[
+#include <stdio.h>
+void
+ltb2a_version (void)
+{
+  printf ("ltb2a: %s\n", LTBUG_ID);
+}
+]])
+
+# Create libb, which is NOT linked to the external library.
+mkdir "$ltb2/libb"
+
+AT_DATA([["$ltb2/libb/Makefile.am"]],
+[[
+lib_LTLIBRARIES = libltb2b.la
+libltb2b_la_SOURCES = libltb2b.c
+]])
+
+# The same as for libltb2a.c. Print out the LTBUG_ID flag and see if the local or
+# installed version is used.
+AT_DATA([["$ltb2/libb/libltb2b.c"]],
+[[
+#include <stdio.h>
+void
+ltb2b_version (void)
+{
+  printf ("ltb2b: %s\n", LTBUG_ID);
+}
+]])
+
+mkdir $ltb2/src
+
+AT_DATA([["$ltb2/src/Makefile.am"]],
+[[
+bin_PROGRAMS = ltb2
+ltb2_SOURCES = main.c
+ltb2_LDADD = ../liba/libltb2a.la ../libb/libltb2b.la
+AM_CPPFLAGS = -I$(top_srcdir)
+]])
+
+# Create a program which outputs the version, local or installed, for both
+# liba and libb.
+AT_DATA([["$ltb2/src/main.c"]],
+[[
+#include <ltb2.h>
+int
+main (int argc, char **argv)
+{
+  ltb2a_version ();
+  ltb2b_version ();
+  return 0;
+}
+]])
+
+AT_DATA([["$ltb2/Makefile.am"]],
+[[
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = liba libb src
+noinst_HEADERS = ltb2.h
+]])
+
+AT_DATA([["$ltb2/configure.ac"]],
+[[
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([ltb2], ]AT_PACKAGE_VERSION[, ]AT_PACKAGE_BUGREPORT[)
+
+AC_CONFIG_SRCDIR([src/main.c])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([foreign])
+
+AC_PROG_CC
+LT_PREREQ([2.4.6])
+LT_INIT
+
+AC_ARG_VAR([LTBUG_ID],[Identifier of the bug case])
+if test -z "$LTBUG_ID"; then
+  LTBUG_ID=local
+fi
+AC_DEFINE_UNQUOTED([LTBUG_ID],["$LTBUG_ID"],
+ [Text string identifying the library])
+
+AC_CONFIG_FILES([Makefile liba/Makefile libb/Makefile src/Makefile])
+
+AC_OUTPUT
+]])
+
+AT_DATA([["$ltb2/ltb2.h"]],
+[[
+extern void ltb2a_version (void);
+extern void ltb2b_version (void);
+]])
+
+echo "Running autoreconf on dependency library and project directory"
+(
+    cd $ext_lib_dir
+    LT_AT_LIBTOOLIZE([--install])
+    LT_AT_AUTORECONF([-i])
+    cd -
+    cd $ltb2
+    LT_AT_LIBTOOLIZE([--install])
+    LT_AT_AUTORECONF([-i])
+)
+
+mkdir build_dep build_inst build_local prefix_dir
+
+prefix=$(cd prefix_dir; pwd)
+
+echo "Building dependency library"
+(
+    cd build_dep
+    LT_AT_CONFIGURE([--prefix=$prefix], [$ext_lib_dir/configure])
+    LT_AT_MAKE([])
+    LT_AT_MAKE([install])
+)
+
+echo "Building and installing project"
+(
+    cd build_inst
+    LT_AT_CONFIGURE([--prefix=$prefix LTBUG_ID='installed'], [$ltb2/configure])
+    LT_AT_MAKE([])
+    LT_AT_MAKE([install])
+)
+
+echo "Building local copy of the project"
+(
+    cd build_local
+    LT_AT_CONFIGURE([--prefix=$prefix], [$ltb2/configure])
+    LT_AT_MAKE([])
+)
+
+# Although we have installed ltb2, we still expect that we are using the local
+# version of ltb2a and ltb2b.
+cat > expout <<EOF
+ltb2a: local
+ltb2b: local
+EOF
+
+case $host_os in
+mingw* | windows*)
+  awk '{printf ("%s\r\n", [$]0);}' < expout > expout.t && mv -f expout.t expout
+  ;;
+cygwin*)
+  awk '{printf ("%s\n", [$]0);}' < expout > expout.t && mv -f expout.t expout
+  ;;
+esac
+
+build_local/src/ltb2 > stdout
+
+echo "Comparing expout to the build binary"
+AT_CHECK([cmp -s stdout expout], [0])
+
+AT_CLEANUP