This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How do I link to a shared lib without having that lib's dependencies (the way MS link does)


On Mon, Apr 25, 2005 at 02:57:22PM -0700, David Wuertele wrote:
> Some of you might remember this thread:
> 
>   http://thread.gmane.org/gmane.comp.gnu.binutils/1048
> 
> I have re-tested with GNU ld version 2.15.92.0.2 20040927 and the
> problem still remains.
> 
> To rehash the original problem of August 2003, I have two libraries:
> libB.so, and libA.so.  libA.so depends on libB.so.  I want to compile
> a program that ONLY uses libA.so's interface.  I do NOT have libB.so
> on my disk.  But ld gives an error:
> 
>   gcc -o prog prog.c -L./A -lA
>   /usr/bin/ld: warning: libB.so, needed by ./A/libA.so, not found (try using -rpath or -rpath-link)
>   ./A/libA.so: undefined reference to `libB_func'
>   collect2: ld returned 1 exit status
> 
> Some people tried to tell me that -rpath-link would solve my problem.
> They were wrong.   -rpath-link would only help if I have libB.so on my
> filesystem.  I do not.
> 
> Nick Clifton and Ian Lance Taylor posted different patches to deal
> with the problem, mainly by downgrading the "error" to a "warning".
> Either of those patches would probably solve my problem, but before I
> go and track those down and try to apply them I was wondering if
> anyone could tell me whether this problem has already been solved in
> the binutils head revision.
> 
> I did a CVS checkout and looked in the ChangeLog but I did not
> recognize anything that resembled their patches.  Can anyone point me
> at the solution?
> 

Here is something you can try. You need to pass

	-Wl,--ignore-needed libA.so -Wl,--no-ignore-needed

to gcc.


H.J.
----
2005-04-25  H.J. Lu  <hongjiu.lu@intel.com>

	* emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Ignore
	DT_NEEDED entry if ignore_needed is TRUE.

	* ldlang.c (new_afile): Set p->ignore_needed.

	* ldlang.h (lang_input_statement_type): Add ignore_needed field.

	* ldmain.c (ignore_needed): New global var.
	(ignore_undefined_symbol): New local variable
	(abfd_undefined_symbol): Likewise.
	(check_ignore_undefined_symbol): New local function.
	(undefined_symbol): Don't complain if the undefined symbol in a
	dynamic library whose ignore_needed is TRUE.

	* ldmain.h (ignore_needed): Declare.

	* lexsup.c (option_values): Add OPTION_IGNORE_NEEDED and
	OPTION_NO_IGNORE_NEEDED.
	(ld_options): Likewise.
	(parse_args): Handle them.

2005-04-25  H.J. Lu  <hongjiu.lu@intel.com>

	* emultempl/elf32.em (gld${EMULATION_NAME}_check_needed): Ignore
	DT_NEEDED entry if ignore_needed is TRUE.

	* ldlang.c (new_afile): Set p->ignore_needed.

	* ldlang.h (lang_input_statement_type): Add ignore_needed field.

	* ldmain.c (ignore_needed): New global var.
	(ignore_undefined_symbol): New local variable
	(abfd_undefined_symbol): Likewise.
	(check_ignore_undefined_symbol): New local function.
	(undefined_symbol): Don't complain if the undefined symbol in a
	dynamic library whose ignore_needed is TRUE.

	* ldmain.h (ignore_needed): Declare.

	* lexsup.c (option_values): Add OPTION_IGNORE_NEEDED and
	OPTION_NO_IGNORE_NEEDED.
	(ld_options): Likewise.
	(parse_args): Handle them.

--- ld/emultempl/elf32.em.needed	2005-04-25 12:18:11.000000000 -0700
+++ ld/emultempl/elf32.em	2005-04-25 16:26:55.000000000 -0700
@@ -740,6 +740,12 @@ gld${EMULATION_NAME}_check_needed (lang_
   if (global_found)
     return;
 
+  if (s->ignore_needed && global_needed->by == s->the_bfd)
+    {
+      global_found = TRUE;
+      return;
+    }
+
   /* If this input file was an as-needed entry, and wasn't found to be
      needed at the stage it was linked, then don't say we have loaded it.  */
   if (s->as_needed
--- ld/ldlang.c.needed	2005-04-25 12:18:11.000000000 -0700
+++ ld/ldlang.c	2005-04-25 15:41:01.000000000 -0700
@@ -845,6 +845,7 @@ new_afile (const char *name,
   p->symbol_count = 0;
   p->dynamic = config.dynamic_link;
   p->add_needed = add_needed;
+  p->ignore_needed = ignore_needed;
   p->as_needed = as_needed;
   p->whole_archive = whole_archive;
   p->loaded = FALSE;
--- ld/ldlang.h.needed	2005-04-25 12:18:11.000000000 -0700
+++ ld/ldlang.h	2005-04-25 15:37:43.000000000 -0700
@@ -275,6 +275,10 @@ typedef struct lang_input_statement_stru
      satisfying references from regular files, or always.  */
   bfd_boolean as_needed;
 
+  /* Whether this entry should cause its DT_NEEDED entries to be
+     ignored.  */
+  bfd_boolean ignore_needed;
+
   /* Whether to include the entire contents of an archive.  */
   bfd_boolean whole_archive;
 
--- ld/ldmain.c.needed	2005-03-16 14:24:23.000000000 -0800
+++ ld/ldmain.c	2005-04-25 16:20:28.000000000 -0700
@@ -101,6 +101,9 @@ bfd_boolean as_needed;
    in DT_NEEDED tags.  */
 bfd_boolean add_needed = TRUE;
 
+/* Nonzero means ignore DT_NEEDED entries for dynamic libraries.  */
+bfd_boolean ignore_needed = FALSE;
+
 /* TRUE if we should demangle symbol names.  */
 bfd_boolean demangling;
 
@@ -1301,6 +1304,16 @@ warning_find_reloc (bfd *abfd, asection 
   free (relpp);
 }
 
+static bfd_boolean ignore_undefined_symbol;
+static bfd *abfd_undefined_symbol;
+
+static void
+check_ignore_undefined_symbol (lang_input_statement_type *s)
+{
+  if (s->ignore_needed && abfd_undefined_symbol == s->the_bfd)
+    ignore_undefined_symbol = TRUE;
+}
+
 /* This is called when an undefined symbol is found.  */
 
 static bfd_boolean
@@ -1314,6 +1327,17 @@ undefined_symbol (struct bfd_link_info *
   static char *error_name;
   static unsigned int error_count;
 
+  /* Check if we should ignore the undefined symbol in a dynamic
+     library.  */
+  if ((bfd_get_file_flags (abfd) & DYNAMIC))
+    {
+      ignore_undefined_symbol = FALSE;
+      abfd_undefined_symbol = abfd;
+      lang_for_each_input_file (check_ignore_undefined_symbol);
+      if (ignore_undefined_symbol)
+	return TRUE;
+    }
+
 #define MAX_ERRORS_IN_A_ROW 5
 
   if (config.warn_once)
--- ld/ldmain.h.needed	2005-03-03 09:24:16.000000000 -0800
+++ ld/ldmain.h	2005-04-25 15:38:06.000000000 -0700
@@ -34,6 +34,7 @@ extern bfd_boolean version_printed;
 extern bfd_boolean whole_archive;
 extern bfd_boolean as_needed;
 extern bfd_boolean add_needed;
+extern bfd_boolean ignore_needed;
 extern bfd_boolean demangling;
 extern int g_switch_value;
 extern const char *output_filename;
--- ld/lexsup.c.needed	2005-04-04 09:59:21.000000000 -0700
+++ ld/lexsup.c	2005-04-25 15:40:36.000000000 -0700
@@ -119,6 +119,8 @@ enum option_values
   OPTION_WHOLE_ARCHIVE,
   OPTION_ADD_NEEDED,
   OPTION_NO_ADD_NEEDED,
+  OPTION_IGNORE_NEEDED,
+  OPTION_NO_IGNORE_NEEDED,
   OPTION_AS_NEEDED,
   OPTION_NO_AS_NEEDED,
   OPTION_WRAP,
@@ -319,6 +321,12 @@ static const struct ld_option ld_options
   { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_NEEDED},
     '\0', NULL, N_("Do not set DT_NEEDED tags for DT_NEEDED entries\n"
 		   "\t\t\t\tin following dynamic libs"), TWO_DASHES },
+  { {"ignore-needed", no_argument, NULL, OPTION_IGNORE_NEEDED},
+    '\0', NULL, N_("Ignore DT_NEEDED entries in following dynamic\n"
+		   "\t\t\t\tlibs"), TWO_DASHES },
+  { {"no-ignore-needed", no_argument, NULL, OPTION_NO_IGNORE_NEEDED},
+    '\0', NULL, N_("Do npt ignore DT_NEEDED entries in following\n"
+		   "\t\t\t\tdynamic libs"), TWO_DASHES },
   { {"as-needed", no_argument, NULL, OPTION_AS_NEEDED},
     '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"),
     TWO_DASHES },
@@ -1252,6 +1260,12 @@ parse_args (unsigned argc, char **argv)
 	case OPTION_NO_ADD_NEEDED:
 	  add_needed = FALSE;
 	  break;
+	case OPTION_IGNORE_NEEDED:
+	  ignore_needed = TRUE;
+	  break;
+	case OPTION_NO_IGNORE_NEEDED:
+	  ignore_needed = FALSE;
+	  break;
 	case OPTION_AS_NEEDED:
 	  as_needed = TRUE;
 	  break;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]