This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: How do I link to a shared lib without having that lib's dependencies (the way MS link does)
- From: "H. J. Lu" <hjl at lucon dot org>
- To: David Wuertele <dave-gnus at bfnet dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Mon, 25 Apr 2005 16:28:58 -0700
- Subject: Re: How do I link to a shared lib without having that lib's dependencies (the way MS link does)
- References: <m34qdutt8d.fsf@bfnet.com>
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;