Thread overview | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 16, 2005 Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Perhaps some kind soul can help me here. I've spent many hours trying to make these procedures work to no avail. I imagine I could get bald soon. I'm trying to use Derek's build utility to create an executable. I would be asking him about this problem, but I'm beginning to think that the problem isn't in build: it's more likely something wrong with the Digitalmars link.exe or, perhaps, my head. (That said, if you have any idea's here Derek, please tell. We can discuss it more on dsource if need be.) My platform is Windows XP. My compiler is dmd 0.123. I'm using build version 2.07 What I've done: Using the build tools facility for creating library files, I've managed to put together three lib files (from Antonio's projects): dool.lib, dui.lib, and dantfw.lib. Both dui.lib and dantfw.lib use dool quite liberally. Building these libraries has been quite easy. I do something like this (using dui as an example): # build build.d -allobj -I\Projects\D\dool\trunk\src -Xdool The build.d is a file at the root of the project directory tree that imports all appropriate modules needed to form the library; it's kind of like an All.d for the build utility. This directs build to collect the appropriate modules for compilation. Furthermore, build.d contains a pragma(tartget,"dui.lib") to indicate the name of the output file. A library file is automatically created because no "main" or "winmain" exists in any of the dui modules. All object files in the project are included in the library via the -allobj switch. To create dool.lib and dantfw.lib, I follow the same procedure. I then put the three library files into the \dmd\lib directory for future use. THE PROBLEM: The next step is to build an actual application using dui.lib, dool.lib, and dantfw.lib. This should be a piece of cake! The application is leds, Antonio's D IDE, which I want to successfully compile on Windows using the new dynamic DUI interface. First of all, I should make it clear that I've succeed in compiling leds with Derkek's build. It's easy if I don't use any pre-compiled library files. Just aim build at the project, give it enough information so that it knows where to find the dui, dool, and dantfw source modules and fire away. It compiles and links all the required object files for leds in a snap. But I want to be able to use the library files I created priorly. That is not so easy, I found out. I try a command like so: # build leds\Leds.d -allobj -Xdui -Xdool -Xdantfw -I\Projects\D\dui\src -I\Projects\D\dool\trunk\src -I\Projects\D\dantfw\trunk\src dool.lib dantfw.lib dui.lib This doesn't work. During the link phase it fails: #leds\Scintilla.obj(Scintilla) # Error 42: Symbol Undefined #_D4dool9Character12CharacterT_a10CharacterT7toLowerFaZa #leds\CodeView.obj(CodeView) # Error 42: Symbol Undefined #_D4dool9Character12CharacterT_a10CharacterT7isAlnumFaZi #\Projects\D\dantfw\trunk\src\dantfw.lib(Parser) # Error 42: Symbol Undefined #_D4dool9Character12CharacterT_a10CharacterT7isAlphaFaZi #\Projects\D\dantfw\trunk\src\dantfw.lib(GtkToDUI) # Error 42: Symbol Undefined #_D4dool9Character12CharacterT_a10CharacterT7toUpperFaZa #\Projects\D\dantfw\trunk\src\dantfw.lib(GtkToDUI) # Error 42: Symbol Undefined #_D4dool9Character12CharacterT_a10CharacterT7isUpperFaZi This is from dool's Character.d file which contains a template like this: # public class CharacterT(T) { .. } # ... # alias CharacterT!(char) Character; # alias CharacterT!(dchar) CharacterD; # alias CharacterT!(wchar) CharacterW; The last three aliases end the file. The template is filled with several static methods like toUpper, toLower, isAlnum, isAlpha, etc. So how do I fix the above problem? Simple, I do this: # build leds\Leds.d -allobj -Xdui -Xdool -Xdantfw -I\Projects\D\dui\src -I\Projects\D\dool\trunk\src -I\Projects\D\dantfw\trunk\src dool.lib dantfw.lib dui.lib dool\Character.obj Notice, all I did is tacked on the Character.obj. Everything compiles successfully. But no matter what I do, I cannot get those symbol errors eliminated by including dool.lib alone which is supposed to contain Character.obj already! And it does indeed from the checks I've made: #\dm\bin\libunres -l Character.obj #\dm\bin\libunres -l dool.lib And in both cases find that the symbols defined above do indeed exist. Dool.lib has them in there! So why doesn't optlink see them?! Why does linking with Character.obj work while linking with dool.lib does not? Furthermore, it appears that Character.obj is the only file in dool.lib that seems to be causing the trouble. No other object files needed to be added to the command line to get the program to link. Is this some sort problem with storing templates in a library file? I thought library files were extremely simple structures that merely archived object files. Is there something more to them that is tricky? I really want this to work. It's the only way to have build do it's intended task for me. If I can't make use of the libraries I build, what good are libraries in D? Thanks for listening! - JJR |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Reimer | On Mon, 16 May 2005 04:43:05 -0700, John Reimer wrote: > Perhaps some kind soul can help me here. I've spent many hours trying to make these procedures work to no avail. I imagine I could get bald soon. [snip] I'm thinking about your issue now ... hang on, it might take awhile as you've got lots of things going on here... Firstly, the compiler needs .d files to *compile* applications. This means that if you import a file, its a ".d" file that is imported (used by the compiler) and not the .obj file or any library. Secondly, the linker uses .obj and .lib files and never used .d files. This means, from the point of view of the source file being compiled, that you source code *must* have all the imported ".d" source files available too. These can be either the full implementation of modules or just their stubs - it doesn't matter. So, if you are compiling a file called "xyzzy.d", and it imports "abc.d" and that imports "ghj.d", then at the time of compiling xyzzy.d, you must have both abc.d and ghj.d available and visible to the compiler. This will create an xyzzy.obj (only). To link this, with the modules 'abc' and 'ghj', which are stored in the library 'qwerty.lib', you only need to supply 'xyzzy.obj' and 'qwerty'.lib'. If you are using Build, and do not want to use any of the 'excess' object files, then place in those source files (eg. abc.d and ghj.d in this example), the Build pragma(nolink). eg. version(build) pragma(nolink); This will cause Build to make sure that their object files are not passed on to the linker. The net result is that 'dmd' will get the source file for 'xyzzy.d' and not get the 'abc.obj' and 'ghj.obj' files. You will most likely use the dmd lib pragma or the build link pragma ... eg. version(build) pragma(link, "dool.lib", "dui.lib", "dantfw.lib"); The -X switch on Build command line will ensure that Build doesn't try to compile any files in these packages. Hope this helps. Let me know how it goes. Use DSource forum if you like. -- Derek Parnell Melbourne, Australia 16/05/2005 11:01:22 PM |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Reimer | In article <d6a11p$1kpq$1@digitaldaemon.com>, John Reimer says... > >Perhaps some kind soul can help me here. I've spent many hours trying to make these procedures work to no avail. I imagine I could get bald soon. > [...] > >#leds\Scintilla.obj(Scintilla) ># Error 42: Symbol Undefined >#_D4dool9Character12CharacterT_a10CharacterT7toLowerFaZa Ah! CharacterT... I had the same problem. I just made CharacterT(T) into Character { alias char T; } and forget the others types. So I do have the same problem. Ant |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ant | On Mon, 16 May 2005 13:46:16 +0000, Ant wrote:
>>
>>#leds\Scintilla.obj(Scintilla)
>># Error 42: Symbol Undefined
>>#_D4dool9Character12CharacterT_a10CharacterT7toLowerFaZa
>
> Ah! CharacterT...
> I had the same problem.
> I just made CharacterT(T) into
> Character
> {
> alias char T;
> }
> and forget the others types.
>
> So I do have the same problem.
>
> Ant
The strange thing, Ant, is that it compiles if I don't use the library format. Build just pulls in all necessary objects and makes one large file. That's the only way I can get to work. And I don't want to have to continually pull in object files every time I use "build."
-JJR
|
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Thanks for taking the time to answer, Derek.
I need to get some sleep before I go at this again. I'll study your answer and keep you posted on further issues/questions. I'm going to try this on Linux and see if there's any difference. If linux works, I can imagine it might be a optlink problem.
I still think something is weird with the linker. :-( But I could be in over my head with build. :-P
-JJR
On Mon, 16 May 2005 23:20:15 +1000, Derek Parnell wrote:
> On Mon, 16 May 2005 04:43:05 -0700, John Reimer wrote:
>
>> Perhaps some kind soul can help me here. I've spent many hours trying to make these procedures work to no avail. I imagine I could get bald soon.
>
> [snip]
>
> I'm thinking about your issue now ... hang on, it might take awhile as you've got lots of things going on here...
>
> Firstly, the compiler needs .d files to *compile* applications. This means that if you import a file, its a ".d" file that is imported (used by the compiler) and not the .obj file or any library.
>
> Secondly, the linker uses .obj and .lib files and never used .d files.
>
> This means, from the point of view of the source file being compiled, that you source code *must* have all the imported ".d" source files available too. These can be either the full implementation of modules or just their stubs - it doesn't matter.
>
> So, if you are compiling a file called "xyzzy.d", and it imports "abc.d" and that imports "ghj.d", then at the time of compiling xyzzy.d, you must have both abc.d and ghj.d available and visible to the compiler. This will create an xyzzy.obj (only).
>
> To link this, with the modules 'abc' and 'ghj', which are stored in the library 'qwerty.lib', you only need to supply 'xyzzy.obj' and 'qwerty'.lib'.
>
> If you are using Build, and do not want to use any of the 'excess' object
> files, then place in those source files (eg. abc.d and ghj.d in this
> example), the Build pragma(nolink).
>
> eg.
>
> version(build) pragma(nolink);
>
> This will cause Build to make sure that their object files are not passed on to the linker. The net result is that 'dmd' will get the source file for 'xyzzy.d' and not get the 'abc.obj' and 'ghj.obj' files.
>
> You will most likely use the dmd lib pragma or the build link pragma ...
>
> eg.
>
> version(build) pragma(link, "dool.lib", "dui.lib", "dantfw.lib");
>
> The -X switch on Build command line will ensure that Build doesn't try to compile any files in these packages.
>
> Hope this helps. Let me know how it goes. Use DSource forum if you like.
|
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | On Mon, 16 May 2005 23:20:15 +1000, Derek Parnell wrote: > > Firstly, the compiler needs .d files to *compile* applications. This means that if you import a file, its a ".d" file that is imported (used by the compiler) and not the .obj file or any library. > Secondly, the linker uses .obj and .lib files and never used .d files. > This means, from the point of view of the source file being compiled, that you source code *must* have all the imported ".d" source files available too. These can be either the full implementation of modules or just their stubs - it doesn't matter. > > So, if you are compiling a file called "xyzzy.d", and it imports "abc.d" and that imports "ghj.d", then at the time of compiling xyzzy.d, you must have both abc.d and ghj.d available and visible to the compiler. This will create an xyzzy.obj (only). > > To link this, with the modules 'abc' and 'ghj', which are stored in the library 'qwerty.lib', you only need to supply 'xyzzy.obj' and 'qwerty'.lib'. Very Good explanations for what's going on. I understand all this. :-) > If you are using Build, and do not want to use any of the 'excess' object > files, then place in those source files (eg. abc.d and ghj.d in this > example), the Build pragma(nolink). > > eg. > > version(build) pragma(nolink); > > This will cause Build to make sure that their object files are not passed on to the linker. The net result is that 'dmd' will get the source file for 'xyzzy.d' and not get the 'abc.obj' and 'ghj.obj' files. > > You will most likely use the dmd lib pragma or the build link pragma ... > > eg. > > version(build) pragma(link, "dool.lib", "dui.lib", "dantfw.lib"); > > The -X switch on Build command line will ensure that Build doesn't try to compile any files in these packages. > > Hope this helps. Let me know how it goes. Use DSource forum if you like. Even more good descriptions. I think this might be my problem: I've been using switches on build with the assumption that I new what they were doing. If I re-attack the problem with these clarified workings of build, I think I still have a chance. I'll let you know how it goes. For some reason, I thought -X meant "don't include object files in the final executable/lib"; your explanation help clarify why I was having trouble with another issue. I thought build wasn't working right, but it was my misunderstanding of what build was doing. Thanks for the help, John |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Not too surprisingly, the issue turned out to be non existent on Linux. Performing the same steps results in a proper executable. Gentoo Linux 2.6 based kernel gcc 3.4.3 dmd 0.123 Thus, I had no trouble including just libdool.a, libdantfw.a, and libdui.a as I would have expected. The Build tool worked like a champ. I think I really don't like optlinker on windows. :-( -John |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Reimer | The problem is that when templates are instantiated, they are inserted into an object file record called a COMDAT. COMDATs have the necessary feature that if multiple object files have a COMDAT with the same name, the duplicates are discarded. This feature is necessary for template instantiations, since the compiler compiling one module doesn't know about the same templates being instantiated by another module. An unfortunate side effect is that the one cannot pull object files out of a library by referencing COMDATs alone, one must reference something else in that object file, too. The dmdscript.lib library has the same problem with protoerror.d. I solved it with the kludge of inserting: int foo; into the file, and then referencing it in dobject.d with: int* pfoo = &dmdscript.protoerror.foo; Not too pretty, but it works. |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Interesting. But would it be possible to make the compiler auto detect these cases and insert a hidden reference "behind the scenes"? It seems like a straight forward workaround, and straight forward workarounds like to be automated :) Nick In article <d6am2c$28v5$1@digitaldaemon.com>, Walter says... > >The problem is that when templates are instantiated, they are inserted into an object file record called a COMDAT. COMDATs have the necessary feature that if multiple object files have a COMDAT with the same name, the duplicates are discarded. > >This feature is necessary for template instantiations, since the compiler compiling one module doesn't know about the same templates being instantiated by another module. > >An unfortunate side effect is that the one cannot pull object files out of a library by referencing COMDATs alone, one must reference something else in that object file, too. > >The dmdscript.lib library has the same problem with protoerror.d. I solved it with the kludge of inserting: > > int foo; > >into the file, and then referencing it in dobject.d with: > > int* pfoo = &dmdscript.protoerror.foo; > >Not too pretty, but it works. > > |
May 16, 2005 Re: Hair-pulling, D, and Optlink | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick | I'm not sure how that could work. "Nick" <Nick_member@pathlink.com> wrote in message news:d6aq0f$2chg$1@digitaldaemon.com... > Interesting. But would it be possible to make the compiler auto detect these > cases and insert a hidden reference "behind the scenes"? It seems like a straight forward workaround, and straight forward workarounds like to be automated :) |
Copyright © 1999-2021 by the D Language Foundation