FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

unix pragma(link bug
Goto page Previous  1, 2
 
Post new topic   Reply to topic     Forum Index -> Build
View previous topic :: View next topic  
Author Message
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Mon May 23, 2005 9:18 am    Post subject: Reply with quote

teqdruid wrote:
In the specific case that the library you want to link to is in the current directory, all one needs to do is add -L-L. (the dot's for the current dir) to build's command line (or config file), and build will pass it on to dmd, and dmd will pass -L. to gcc, and gcc will add the current dir to it's search path for libraries.


But sometimes I've had problems trying to do that: "-L.. -lsomelib". I remember MinWin didn't link correctly like that. I had to write "../libminwin_gtk.a" for it to work. I don't know if it's a problem with MinWin, DMD or ld, but that's what happened. How about a case like that?
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
teqdruid



Joined: 11 May 2004
Posts: 390
Location: UMD

PostPosted: Mon May 23, 2005 10:16 am    Post subject: Reply with quote

Quote:
When you say "give it the name" do you mean the fully specified path and file name; in other words, one that starts with a "/"? Not a relative path or just the file name itself? If that's the case, why is GCC searching as you just told it exactly where the file is? If that is not the case, what do you really mean by "I'm not talking about the file name"? Please give me some examples to help me understand your terminalogy.


By name I just mean... ahh... the name. If I write "pragma(link, dl);" then the name is just "dl". Then, when build passes -L-ldl to dmd, gcc will look for a library called "dl" in it's search path. GCC has a list of directories in which it looks for libraries. The actual filename of the library is irrevelant. In this case, however, it's /usr/lib/libdl.a, but build doesn't need to know this.

Quote:
How does GCC search for the library file called "dl.a"? Does it do an exhustive search of the file system? Is there default locations in which libraries are expected to live? Is there a pre-defined list of directories that it searches through? I don't understand it otherwise.

There is a predefined list of locations. One can temporarily add a location to that list with the -L switch (you'd need -L-L if you're going through dmd). I'm not certain how that list is actually stored, although it's probably an environment variable. That's also irrevelent, however, as the -L option should be used to append to it if necessary.


Quote:
Hold on, you said before I had to do special processing if the library lives in the current directory. Which is it?

An alternative way to link in a library is to just specify the path and filename of the library. (or just the filename if it's in the current directory.) When you do this, you don't use the -l option, you just put it in the list of .o files to link.

In short, on unix, whenever Build encounters "pragma(link, <name>);" all build should do is:
-Add -L-l<name> to the dmd command that it runs. GCC will take care of the rest.

Quote:
But sometimes I've had problems trying to do that: "-L.. -lsomelib". I remember MinWin didn't link correctly like that. I had to write "../libminwin_gtk.a" for it to work. I don't know if it's a problem with MinWin, DMD or ld, but that's what happened. How about a case like that?

There shouldn't be any issues with something like this. Say a module uses this minwin library, then put:
Code:
pragma(link, minwin_gtk);

in the module. Then, when you run build, if the library isn't stored in one of the standard locations, you'll have to tell it where it is (you'll probably want to do this in a build config file). You'd invoke build as so if libminwin_gtk.a is in the parent directory:
Code:
build file.d -L-L..

There shouldn't be any issues with that (at least once build is fixed).
Back to top
View user's profile Send private message Send e-mail AIM Address
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Mon May 23, 2005 10:35 am    Post subject: Reply with quote

teqdruid wrote:
Code:
pragma(link, minwin_gtk);

in the module. Then, when you run build, if the library isn't stored in one of the standard locations, you'll have to tell it where it is (you'll probably want to do this in a build config file). You'd invoke build as so if libminwin_gtk.a is in the parent directory:
Code:
build file.d -L-L..

There shouldn't be any issues with that (at least once build is fixed).


You are aware that ld is very strict when it comes to specifying the paths for libraries, right? I mean, ld has to get this: "<some commands> -L.. -lminwin_gtk -Lanother/path -lmore -llibraries". And it would search libminwin_gtk.a in .. and libmore.a and liblibraries.a in another/path. So what would build do in this case:

Code:
pragma(link, lib1);
pragma(link, lib2);


And they're in different paths? I pass

Code:
build file.d -L-Lpath1 -L-Lpath2


How would build know if lib1 is in path1 and lib2 in path2 or viceversa?
Also, if lib2 depends on lib1, lib2 has to be before lib1 (I don't remember if I read that or if that was my trial/mistake experience). How can build know that?

Don't take it has a bad thing, I'm just trying to point out the problems I've had and the problems I think could happen. Also notice that my experience with gcc/ld is not that much.
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
teqdruid



Joined: 11 May 2004
Posts: 390
Location: UMD

PostPosted: Mon May 23, 2005 2:58 pm    Post subject: Reply with quote

Quote:
You are aware that ld is very strict when it comes to specifying the paths for libraries, right? I mean, ld has to get this: "<some commands> -L.. -lminwin_gtk -Lanother/path -lmore -llibraries". And it would search libminwin_gtk.a in .. and libmore.a and liblibraries.a in another/path. So what would build do in this case:


That is not consistent with the GCC man page. The order of -l's matter in that when searching for a symbol, gcc will start at the beginning of the list of .o files and libraries, and go to the end.

As long as I'm in here, here's some relevant information from the ld manpage:
Quote:
-larchive
--library=archive
Add archive file archive to the list of files to link. This option may be used any number of times.
ld will search its path-list for occurrences of "libarchive.a" for every archive specified.

On systems which support shared libraries, ld may also search for libraries with extensions other than
".a". Specifically, on ELF and SunOS systems, ld will search a directory for a library with an exten‐
sion of ".so" before searching for one with an extension of ".a". By convention, a ".so" extension
indicates a shared library.

The linker will search an archive only once, at the location where it is specified on the command
line. If the archive defines a symbol which was undefined in some object which appeared before the
archive on the command line, the linker will include the appropriate file(s) from the archive. How‐
ever, an undefined symbol in an object appearing later on the command line will not cause the linker
to search the archive again.

See the -( option for a way to force the linker to search archives multiple times.

You may list the same archive multiple times on the command line.

This type of archive searching is standard for Unix linkers. However, if you are using ld on AIX,
note that it is different from the behaviour of the AIX linker.

-Lsearchdir
--library-path=searchdir
Add path searchdir to the list of paths that ld will search for archive libraries and ld control
scripts. You may use this option any number of times. The directories are searched in the order in
which they are specified on the command line. Directories specified on the command line are searched
before the default directories. All -L options apply to all -l options, regardless of the order in
which the options appear.

If searchdir begins with "=", then the "=" will be replaced by the sysroot prefix, a path specified
when the linker is configured.

The default set of paths searched (without being specified with -L) depends on which emulation mode ld
is using, and in some cases also on how it was configured.

The paths can also be specified in a link script with the "SEARCH_DIR" command. Directories specified
this way are searched at the point in which the linker script appears in the command line.


It notes that the order of -L's is important, but how they are mixed with -l's isn't.

Also of note here, is that dmd invokes GCC. I'm not certain what the relation between GCC and ld is. Does GCC simply call ld? For contrast, here is the relevant information from the GCC man page:
Quote:
-llibrary
-l library
Search the library named library when linking. (The second alter‐
native 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 directo‐
ries 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 fash‐
ion. 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.

-Ldir
Add directory dir to the list of directories to be searched for -l.


Hopefully this information will help clear things up further.
Back to top
View user's profile Send private message Send e-mail AIM Address
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Mon May 23, 2005 3:11 pm    Post subject: Reply with quote

Like I said, my experience with gcc is not that much. I was just voicing my opinion. I hope Derek can satisfy all of our needs with regards to Build.
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Mon May 23, 2005 6:11 pm    Post subject: Reply with quote

teqdruid wrote:

In short, on unix, whenever Build encounters "pragma(link, <name>);" all build should do is:
-Add -L-l<name> to the dmd command that it runs. GCC will take care of the rest.

Ok, I think I got it. Here is what I'm planning to do ...

When running in a Posix environment (version != Windows), and Build finds "pragma(link, <name>);" it will place on the dmd command line "-L-l<name>". In other words, in non-Windows systems it will prefix the <name> with "-L-l". However, this will only happen when <name> represents a library. Build believes <name> is a library if it has the appropriate filename extension (".a" for Posix and ".lib" for Windows), or has no extension.

Are we all happy with this? Rolling Eyes Question
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Mon May 23, 2005 7:38 pm    Post subject: Reply with quote

It turns out that I had actually put in a change to fix this, but I did it wrong. Anyway, the fix is in place now (not released yet) and it was very easy to do.
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
teqdruid



Joined: 11 May 2004
Posts: 390
Location: UMD

PostPosted: Mon May 23, 2005 8:03 pm    Post subject: Reply with quote

Assuming it works as described, this should be good.

Is it in the SVN repos yet?
Back to top
View user's profile Send private message Send e-mail AIM Address
Derek Parnell



Joined: 22 Apr 2004
Posts: 408
Location: Melbourne, Australia

PostPosted: Mon May 23, 2005 8:27 pm    Post subject: Reply with quote

teqdruid wrote:
Is it in the SVN repos yet?

No Embarassed

I'm putting in a couple of changes in for the next release. But it should be there in a day or two.
_________________
--
Derek
skype name: derek.j.parnell
Back to top
View user's profile Send private message
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Thu May 26, 2005 8:00 pm    Post subject: Reply with quote

Ok, this came by accident but I think it proves my point (gdc 0.11, gcc 3.4.3, Mac OS X):

Code:

$ gdc -fversion=Posix -I../mango -L../mango -lmango -o zzz main.d
/usr/bin/ld: Undefined symbols:
__D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter
__ModuleInfo_5mango2io5Stdin
__ModuleInfo_5mango2io6Stdout
collect2: ld returned 1 exit status

$ gdc -fversion=Posix -I../mango -o zzz main.d -L../mango -lmango

$


Obviously my program depends on mango, so I had to put -lmango after the program.
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
teqdruid



Joined: 11 May 2004
Posts: 390
Location: UMD

PostPosted: Thu May 26, 2005 8:09 pm    Post subject: Reply with quote

So it looks like you had to put the -o zzz main.d before the -L and -l params. That's interesting. I have no idea why that would make any difference, but based on the programs I've built, I believe it's common practice to put the -L and -l type parameters last. I dunno why.

According the to the man pages that I cited, however, the ordering of the -L and -l parameters in relation to each other shouldn't matter. Does it?
Back to top
View user's profile Send private message Send e-mail AIM Address
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Thu May 26, 2005 8:29 pm    Post subject: Reply with quote

teqdruid wrote:
According the to the man pages that I cited, however, the ordering of the -L and -l parameters in relation to each other shouldn't matter. Does it?


I can't confirm that ATM, but I remember on Linux, for MinWin based apps libraries like -lXt etc always came after libminwin*. Also, remember DMD passes to GCC "-lphobos -lpthread -lm", and phobos depends on those two. I don't remember trying to link inverting that order.
Back to top
View user's profile Send private message Yahoo Messenger MSN Messenger
teqdruid



Joined: 11 May 2004
Posts: 390
Location: UMD

PostPosted: Thu May 26, 2005 8:37 pm    Post subject: Reply with quote

Note that my previous statement only applies to your example where you have only 1 -l. The ordering of multiple -l's can make a difference. It's a real pain sometimes. I've had it bite me in the ass before.
Back to top
View user's profile Send private message Send e-mail AIM Address
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Build All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group