Thread overview
Link errors with lib files
Nov 15, 2005
John C
Nov 15, 2005
Derek Parnell
Nov 15, 2005
John C
Nov 18, 2005
John C
Nov 19, 2005
Carlos Santander
Nov 25, 2005
Walter Bright
November 15, 2005
Normally I just compile all my source files on the command line, but I'm attempting to make a static library and am getting errors at link time. I've searched the archives to no avail. Can anyone help?

First, I have a source file called sample.d, as follows:

--------sample.d--------
module sample;

class Test {

    char[] getMessage() {
        return "Hello, World";
    }

}
-------------------------

Next, I generate an .obj file and a .lib file like so:

    dmd sample.d -c
    lib -c sample.lib sample.obj

Which gives me a static library called "sample.lib". Now I want to use it in a program, which is where things start going wrong.

Obviously I don't want sample.d to get compiled into my program, rather sample.lib, so (taking a leaf out of how phobos is built) I created a version of sample.d without definitions to use as an import module:

--------sample2.d--------
module sample;

class Test {

    char[] getMessage();

}
--------------------------

Then, my app's main source file, which imports the "sample" module:

--------program.d--------
module program;

import sample;

int main() {
    Test test = new Test;
    char[] msg = test.getMessage();

    return 0;
}
--------------------------

Finally, I put it all together on the command line:

    dmd program.d sample2.d sample.lib

This results in the following errors:

    Error1: Previous Definition Different : __init_6sample4Test
    Error1: Previous Definition Different : __Class_6sample4Test
    Error1: Previous Definition Different : __vtbl_6sample4Test

Of course, if I substitute "sample2.d" with "sample.d" on the cmd line the errors are eliminated, but the source is compiled into my program, which is not what I want.

So, what's going on? Does anyone have a solution?

Cheers, John.


November 15, 2005
"John C" <johnch_atms@hotmail.com> wrote in message news:dlceog$1gqq$1@digitaldaemon.com...
> So, what's going on? Does anyone have a solution?

Don't compile sample2.d.  Just import it from program.d.  ;)


November 15, 2005
On Tue, 15 Nov 2005 10:54:07 -0000, John C wrote:

> Normally I just compile all my source files on the command line, but I'm attempting to make a static library and am getting errors at link time. I've searched the archives to no avail. Can anyone help?
> 
> First, I have a source file called sample.d, as follows:
> 
> --------sample.d--------
> module sample;
> 
> class Test {
> 
>     char[] getMessage() {
>         return "Hello, World";
>     }
> 
> }
> -------------------------
> 
> Next, I generate an .obj file and a .lib file like so:
> 
>     dmd sample.d -c
>     lib -c sample.lib sample.obj
> 
> Which gives me a static library called "sample.lib". Now I want to use it in a program, which is where things start going wrong.
> 
> Obviously I don't want sample.d to get compiled into my program, rather sample.lib, so (taking a leaf out of how phobos is built) I created a version of sample.d without definitions to use as an import module:
> 
> --------sample2.d--------
> module sample;
> 
> class Test {
> 
>     char[] getMessage();
> 
> }
> --------------------------
> 
> Then, my app's main source file, which imports the "sample" module:
> 
> --------program.d--------
> module program;
> 
> import sample;
> 
> int main() {
>     Test test = new Test;
>     char[] msg = test.getMessage();
> 
>     return 0;
> }
> --------------------------
> 
> Finally, I put it all together on the command line:
> 
>     dmd program.d sample2.d sample.lib
> 
> This results in the following errors:
> 
>     Error1: Previous Definition Different : __init_6sample4Test
>     Error1: Previous Definition Different : __Class_6sample4Test
>     Error1: Previous Definition Different : __vtbl_6sample4Test
> 
> Of course, if I substitute "sample2.d" with "sample.d" on the cmd line the errors are eliminated, but the source is compiled into my program, which is not what I want.
> 
> So, what's going on? Does anyone have a solution?

You've almost got it right.

First, rename sample2.d to sample.d, obviously keeping the original sample.d (the one with the implementation code) in a separate directory for safe keeping.

Next, compile as

  dmd program.d sample.lib

This will get the compiler to import sample.d (just declarations) but not compile it, and the linker will look into sample.lib to resolve reference to the implementation details.

-- 
Derek Parnell
Melbourne, Australia
16/11/2005 12:49:14 AM
November 15, 2005
"Derek Parnell" <derek@psych.ward> wrote in message news:1gx6rumzbj97o$.17079cha22x9a.dlg@40tude.net...
> On Tue, 15 Nov 2005 10:54:07 -0000, John C wrote:
>
>> Normally I just compile all my source files on the command line, but I'm
>> attempting to make a static library and am getting errors at link time.
>> I've
>> searched the archives to no avail. Can anyone help?
>>
>> First, I have a source file called sample.d, as follows:
>>
>> --------sample.d--------
>> module sample;
>>
>> class Test {
>>
>>     char[] getMessage() {
>>         return "Hello, World";
>>     }
>>
>> }
>> -------------------------
>>
>> Next, I generate an .obj file and a .lib file like so:
>>
>>     dmd sample.d -c
>>     lib -c sample.lib sample.obj
>>
>> Which gives me a static library called "sample.lib". Now I want to use it
>> in
>> a program, which is where things start going wrong.
>>
>> Obviously I don't want sample.d to get compiled into my program, rather sample.lib, so (taking a leaf out of how phobos is built) I created a version of sample.d without definitions to use as an import module:
>>
>> --------sample2.d--------
>> module sample;
>>
>> class Test {
>>
>>     char[] getMessage();
>>
>> }
>> --------------------------
>>
>> Then, my app's main source file, which imports the "sample" module:
>>
>> --------program.d--------
>> module program;
>>
>> import sample;
>>
>> int main() {
>>     Test test = new Test;
>>     char[] msg = test.getMessage();
>>
>>     return 0;
>> }
>> --------------------------
>>
>> Finally, I put it all together on the command line:
>>
>>     dmd program.d sample2.d sample.lib
>>
>> This results in the following errors:
>>
>>     Error1: Previous Definition Different : __init_6sample4Test
>>     Error1: Previous Definition Different : __Class_6sample4Test
>>     Error1: Previous Definition Different : __vtbl_6sample4Test
>>
>> Of course, if I substitute "sample2.d" with "sample.d" on the cmd line
>> the
>> errors are eliminated, but the source is compiled into my program, which
>> is
>> not what I want.
>>
>> So, what's going on? Does anyone have a solution?
>
> You've almost got it right.
>
> First, rename sample2.d to sample.d, obviously keeping the original
> sample.d (the one with the implementation code) in a separate directory
> for
> safe keeping.
>
> Next, compile as
>
>  dmd program.d sample.lib

Thanks Derek and Jarrett.

Now I also realise the usefulness of the -I import path.

>
> This will get the compiler to import sample.d (just declarations) but not compile it, and the linker will look into sample.lib to resolve reference to the implementation details.
>
> -- 
> Derek Parnell
> Melbourne, Australia
> 16/11/2005 12:49:14 AM


November 18, 2005
"Derek Parnell" <derek@psych.ward> wrote in message news:1gx6rumzbj97o$.17079cha22x9a.dlg@40tude.net...
> On Tue, 15 Nov 2005 10:54:07 -0000, John C wrote:
>
>> Normally I just compile all my source files on the command line, but I'm
>> attempting to make a static library and am getting errors at link time.
>> I've
>> searched the archives to no avail. Can anyone help?
>>
>> First, I have a source file called sample.d, as follows:
>>
>> --------sample.d--------
>> module sample;
>>
>> class Test {
>>
>>     char[] getMessage() {
>>         return "Hello, World";
>>     }
>>
>> }
>> -------------------------
>>
>> Next, I generate an .obj file and a .lib file like so:
>>
>>     dmd sample.d -c
>>     lib -c sample.lib sample.obj
>>
>> Which gives me a static library called "sample.lib". Now I want to use it
>> in
>> a program, which is where things start going wrong.
>>
>> Obviously I don't want sample.d to get compiled into my program, rather sample.lib, so (taking a leaf out of how phobos is built) I created a version of sample.d without definitions to use as an import module:
>>
>> --------sample2.d--------
>> module sample;
>>
>> class Test {
>>
>>     char[] getMessage();
>>
>> }
>> --------------------------
>>
>> Then, my app's main source file, which imports the "sample" module:
>>
>> --------program.d--------
>> module program;
>>
>> import sample;
>>
>> int main() {
>>     Test test = new Test;
>>     char[] msg = test.getMessage();
>>
>>     return 0;
>> }
>> --------------------------
>>
>> Finally, I put it all together on the command line:
>>
>>     dmd program.d sample2.d sample.lib
>>
>> This results in the following errors:
>>
>>     Error1: Previous Definition Different : __init_6sample4Test
>>     Error1: Previous Definition Different : __Class_6sample4Test
>>     Error1: Previous Definition Different : __vtbl_6sample4Test
>>
>> Of course, if I substitute "sample2.d" with "sample.d" on the cmd line
>> the
>> errors are eliminated, but the source is compiled into my program, which
>> is
>> not what I want.
>>
>> So, what's going on? Does anyone have a solution?
>
> You've almost got it right.
>
> First, rename sample2.d to sample.d, obviously keeping the original
> sample.d (the one with the implementation code) in a separate directory
> for
> safe keeping.
>
> Next, compile as
>
>  dmd program.d sample.lib
>
> This will get the compiler to import sample.d (just declarations) but not compile it, and the linker will look into sample.lib to resolve reference to the implementation details.

Now I'm running into all sorts of problems with templates not getting compiled properly into my lib file. I've read around the issue, tried to apply the kludge from http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23701 but that had no effect.

In "collections.d" I have a couple of classes:

    interface IComparer(T) { ... }
    class Comparer(T) : IComparer!(T) { ... } // a default implementation of
IComparer(T)

    interface IDictionary(TKey, TValue) { ... }
    class Dictionary(TKey, TValue) : IDictionary!(TKey, TValue) {
        this(IComparer comparer = null) { // null by default, so users can
supply their own specialised comparer
            if (comparer is null) comparer = new Comparer!(TKey);
            ...
        }
    }

In "dom.d" I have a specialisation of IComparer(T) and a class that instantiates it.

    import collections, msxml;
    class InterfaceComparer(T) : IComparer!(T) { ... }

    class XmlNode { ... }
    class XmlNodeFactory {
        static IDictionary!(IXMLDOMNode, XmlNode) nodeTable_;
        // msxml defines interface IXMLDOMNode.
        static this() {
            nodeTable_ = new Dictionary!(IXMLDOMNode, XmlNode)(new
InterfaceComparer!(IXMLDOMNode));
        }
        ...
    }

These then are compiled to msxml.obj, collections.obj and dom.obj, which are in turn compiled into dom.lib, without errors. But when I link with dom.lib I'm told:

    Symbol Undefined
__Class_11collections29Comparer_C5msxml11IXMLDOMNode8Comparer

I've narrowed the issue down to collections.d, and this line:

    if (comparer is null) comparer = new Comparer!(TKey);

which translates to

    if (comparer is null) comparer = new Comparer!(IXMLDOMNode);

If I comment out the above line, everything links fine. But my Dictionary class relies on it (unless the user passes their own specialised comparer). I thought perhaps it needed a definition of IXMLDOMNode, but importing the appropriate module didn't help.

The suggested workaround is to add something like "int foo;" to one file, and "int* pfoo = &foo;" to another. Which should go where? msxml.d, collections.d or dom.d? I've tried all variations, without success.

>
> -- 
> Derek Parnell
> Melbourne, Australia
> 16/11/2005 12:49:14 AM


November 19, 2005
John C escribió:
> 
> Now I'm running into all sorts of problems with templates not getting compiled properly into my lib file. I've read around the issue, tried to apply the kludge from http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23701 but that had no effect.
> 
> ...
> 
> The suggested workaround is to add something like "int foo;" to one file, and "int* pfoo = &foo;" to another. Which should go where? msxml.d, collections.d or dom.d? I've tried all variations, without success.
> 

Same here with dcouple 0.2 on Windows. I don't know where to put what. Any help?

-- 
Carlos Santander Bernal
November 25, 2005
My first suggestion is you have too many files and too much code in the files to figure out what's going wrong. Try to cut things down as far as possible.