Bug 674696 - gcc resolves -lX to libX.so
Summary: gcc resolves -lX to libX.so
Status: RESOLVED UPSTREAM
Alias: None
Product: openSUSE 11.3
Classification: openSUSE
Component: Documentation (show other bugs)
Version: Final
Hardware: x86-64 openSUSE 11.3
: P5 - None : Minor with 1 vote (vote)
Target Milestone: ---
Assignee: Richard Biener
QA Contact: Karl Eichwalder
URL: info:/gcc-4.5/Link%20Options
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-24 13:23 UTC by Christopher Yeleighton
Modified: 2011-08-31 12:22 UTC (History)
1 user (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christopher Yeleighton 2011-02-24 13:23:57 UTC
User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.2.13) Gecko/20101203 SUSE/3.6.13-0.2.1 Firefox/3.6.13

The documentation for GCC Linker Options [1] states that -lX == find libX.a along the search path.  GCC at openSuSE does not comply, providing an undocumented extension.

Reproducible: Always

Steps to Reproduce:
{ rm -f liblib-search-bug.a &&
echo 'int openSuSE_gcc_bug_lib_search;' > lib-search-bug.c &&
gcc -shared lib-search-bug.c -o liblib-search-bug.so &&
gcc -L. lib-search-bug.c -llib-search-bug
}

Actual Results:  
ld: undefined reference to `main'

Expected Results:  
ld: cannot find -llib-search-bug

[1] <URL: info:/gcc-4.5/Link%20Options >
Comment 1 Christopher Yeleighton 2011-02-24 13:34:05 UTC
The fact that using -l with -L introduces a security risk is undocumented.  If GCC behaved as documented, the issue would be moot.

<URL: http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=18147&p=69196#p69196 >
Comment 2 Philipp Thomas 2011-02-24 17:13:11 UTC
The bug is in your example as gcc/ld behave as documented.

gcc -shared lib-search-bug.c -o liblib-search-bug.so

creates a shared library.

gcc -L. lib-search-bug.c -llib-search-bug

first compiles lib-search-bug.c (which does indeed have no 'main') to lib-search-bug.o and then tries to link to the shared library. In doing so it discovers that there is no main defined which has to be present to create an executable so ld exits without trying to link in the library.

If I modify your example to

# cat lib-search-bug-main.c

extern int openSuSE_gcc_bug_lib_search;

int main(int argc, char *argv[])
{
    openSuSE_gcc_bug_lib_search = 1;
    return 0;
}


And then do 

gcc -L. -o lib-search-bug lib-search-bug-main.c -llib-search-bug

I do indeed get

/usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: cannot find -llib-search-bug
collect2: ld returned 1 exit status
Comment 3 Christopher Yeleighton 2011-02-25 00:14:16 UTC
I am impressed.  However, in the circumstances you described, I get no error from gcc, so I dare reopen.

An update to my remark:

Actually, it turns out that RPATH depends on $LD_RUN_PATH, not on -L, and it is a problem only when classic ld is used, i.e. -fuse-linker-plugin is not used.
Comment 4 Richard Biener 2011-02-25 09:54:23 UTC
I am confused and fail to see your point.  Do you really complain that
-L. -lX finds libX.so in .?  That is a feature that works as intended.

What you instead get as a security feature is that if you try to
execute that built binary is

> ./a.out 
./a.out: error while loading shared libraries: libt2.so: cannot open shared object file: No such file or directory

because . is not in LD_LIBRARY_PATH.

You can circumvent this security measure by adding -Wl,-rpath=.

This is not a bug in GCC.
Comment 5 Christopher Yeleighton 2011-03-02 23:01:47 UTC
I take your word that it is the intended behavior, reclassify it as missing documentation and reopen.

I really complain that -lX finds libX.so because it is an undocumented extension.  I did not have security in mind, and -L. was only to avoid the necessity of putting liblib-search-bug.so into a system directory to demonstrate the problem.
Comment 6 Karl Eichwalder 2011-03-03 06:12:22 UTC
According to the devel guys it is not a bug.

The docs team does not provide SDK-like documentation.  Please, consider to add an article about gcc and linking options to the wiki (http://en.opensuse.org).
Comment 7 Christopher Yeleighton 2011-03-04 10:00:32 UTC
(In reply to comment #6)
> According to the devel guys it is not a bug.
> 
> The docs team does not provide SDK-like documentation.  

Consult <URL: info:/gcc-4.5/Link%20Options >, provided by openSUSE.  I do not know whether it is the documentation team or the development team responsible, but clearly someone should be.

> Please, consider to add
> an article about gcc and linking options to the wiki (http://en.opensuse.org).

Very gladly, but that will not make up for the deficiency in the documentation installed off line.  Additionally, were I expert enough do that, I would have no need to look at the info pages.

I am sorry for the reopening ping-pong, but it seems your invalidation was based on an invalid assumption :-(
Comment 8 Karl Eichwalder 2011-03-04 10:19:25 UTC
Info files are maintained by the package maintainers (in this case development).  It might be an upstream issue, though.
Comment 9 Christopher Yeleighton 2011-04-12 12:13:59 UTC
The point is, the manufacturer is willing to consider issues only after the distribution maintainers confirmed.
Comment 10 Richard Biener 2011-08-31 11:17:46 UTC
I'm still not understanding your issue (trying to cleanup my open bugs).  From
the gcc info page:

`-lLIBRARY'
`-l LIBRARY'
     Search the library named LIBRARY when linking.  (The second
     alternative with the library as a separate argument is only for
     POSIX compliance and is not recommended.)

     It makes a difference where in the command you write this option;
     the linker searches and processes libraries and object files in
     the order they are specified.  Thus, `foo.o -lz bar.o' searches
     library `z' after file `foo.o' but before `bar.o'.  If `bar.o'
     refers to functions in `z', those functions may not be loaded.

     The linker searches a standard list of directories for the library,
     which is actually a file named `libLIBRARY.a'.  The linker then
     uses this file as if it had been specified precisely by name.

     The directories searched include several standard system
     directories plus any that you specify with `-L'.

     Normally the files found this way are library files--archive files
     whose members are object files.  The linker handles an archive
     file by scanning through it for members which define symbols that
     have so far been referenced but not defined.  But if the file that
     is found is an ordinary object file, it is linked in the usual
     fashion.  The only difference between using an `-l' option and
     specifying a file name is that `-l' surrounds LIBRARY with `lib'
     and `.a' and searches several directories.

and,

`-LDIR'
     Add directory DIR to the list of directories to be searched for
     `-l'.

Which is consistent with gcc -L. -lX finding ./libX.so.

Or are you refering to the documentation not mentioning _shared_ libraries
(thus, the .so suffix compared to the .a suffix)?  The documentation
is probably unchanged from the distant past where there wasn't any ELF port.
On darwin, for example, .dylib, on migw64, for example, .lib suffixes are
used (and possibly different or no prefixes may apply).
Comment 11 Christopher Yeleighton 2011-08-31 12:15:13 UTC
(In reply to comment #10)
> Or are you refering to the documentation not mentioning _shared_ libraries
> (thus, the .so suffix compared to the .a suffix)?  The documentation

Your perspicacity is stupendous :-)
In other words, I am.

> is probably unchanged from the distant past where there wasn't any ELF port.
> On darwin, for example, .dylib, on migw64, for example, .lib suffixes are
> used (and possibly different or no prefixes may apply).
Comment 12 Richard Biener 2011-08-31 12:22:07 UTC
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50250