Thread overview
Newbie compilation/linking package problem
Jul 20, 2004
Jan Bendtsen
Jul 20, 2004
Kris
Jul 20, 2004
Derek Parnell
Jul 20, 2004
Jan Bendtsen
Jul 20, 2004
Jan Bendtsen
July 20, 2004
Hello D people,

This is my first post to the newsgroup, and I'm a bit embarrassed that it is such a trivial question; but I don't know where else to find the solution, so please bear with me.

I basically come from a Java background, but I also have a little experience with plain old C. D appears to take the best from both worlds, with garbage collection and object-oriented syntax that reminds me of Java, combined with the ability to compile to a given architecture, which should solve Java's well-known performance problems.

So, ironically enough, my problem is related to compiling and linking... :-(

Say I write two modules called foo and bar and intend to put them in a package called pkg. The code is placed in two files called ./pkg/foo.d and ./pkg/bar.d (I use Mandrake Linux) and the outline looks roughly like this:


In ./pkg/foo.d:

module pkg.foo;

import std.math; // and other imports

public class Foo {
    // Foo fields
    // Foo methods
}

public class BadFooException : Exception {
    // Reason why Foo is bad
}

int main() {
    // A bit of code testing a couple of Foos
}


In ./pkg/bar.d:

module pkg.bar;

import pkg.foo;
import std.math; // and other imports

public class Bar {
    private:
    Foo myFoo;
    // Other Bar fields
    public:
    void setFoo(Foo f) {...}// register myFoo
    // Other Bar methods
}

public class UglyBarException : Exception {
    // Reason why Bar is ugly
}

int main() {
    Foo f = new Foo();
    Bar b = new Bar();
    b.setFoo(f);
    b.doSomethingCoolWithmyFoo();
    // ... and so forth
}


I happily compile ./pkg/foo.d to an executable and run it. But when I want to link it with ./pkg/bar.d I get into trouble:

[dimon@morpheus d]$ dmd -c ./pkg/foo.d
	(apparently a success; ./pkg/foo.o is created.)

[dimon@morpheus d]$ dmd -c ./pkg/bar.d
	(no error messages, but no object file is created)

And trying to compile them both together I get
[dimon@morpheus d]$ dmd ./pkg/bar.d ./pkg/foo.d
gcc bar.o foo.o -o bar -lphobos -lpthread -lm
foo.o(.deh_beg+0x0): multiple definition of `_deh_beg'
bar.o(.deh_beg+0x0): first defined here
foo.o(.deh_end+0x0): multiple definition of `_deh_end'
bar.o(.deh_end+0x0): first defined here
collect2: ld returned 1 exit status
--- errorlevel 256

So, I'm sure I'm doing something idiotic or, eqaully likely, completely missing something. Any help would be much appreciated!

Thanks in advance
Jan
July 20, 2004
I would imagine it's complaining (non-intuitively) about main() being
present in both files. Instead, you might consider renaming each main() to
be unittest, and just have one real main() function. Check out this page for
unittest specs: http://digitalmars.com/d/class.html

- Kris


"Jan Bendtsen" <dimon@controlREMOVEME.aau.dk> wrote in message news:cdikim$18li$2@digitaldaemon.com...
> Hello D people,
>
> This is my first post to the newsgroup, and I'm a bit embarrassed that it is such a trivial question; but I don't know where else to find the solution, so please bear with me.
>
> I basically come from a Java background, but I also have a little experience with plain old C. D appears to take the best from both worlds, with garbage collection and object-oriented syntax that reminds me of Java, combined with the ability to compile to a given architecture, which should solve Java's well-known performance problems.
>
> So, ironically enough, my problem is related to compiling and linking... :-(
>
> Say I write two modules called foo and bar and intend to put them in a package called pkg. The code is placed in two files called ./pkg/foo.d and ./pkg/bar.d (I use Mandrake Linux) and the outline looks roughly like this:
>
>
> In ./pkg/foo.d:
>
> module pkg.foo;
>
> import std.math; // and other imports
>
> public class Foo {
>      // Foo fields
>      // Foo methods
> }
>
> public class BadFooException : Exception {
>      // Reason why Foo is bad
> }
>
> int main() {
>      // A bit of code testing a couple of Foos
> }
>
>
> In ./pkg/bar.d:
>
> module pkg.bar;
>
> import pkg.foo;
> import std.math; // and other imports
>
> public class Bar {
>      private:
>      Foo myFoo;
>      // Other Bar fields
>      public:
>      void setFoo(Foo f) {...}// register myFoo
>      // Other Bar methods
> }
>
> public class UglyBarException : Exception {
>      // Reason why Bar is ugly
> }
>
> int main() {
>      Foo f = new Foo();
>      Bar b = new Bar();
>      b.setFoo(f);
>      b.doSomethingCoolWithmyFoo();
>      // ... and so forth
> }
>
>
> I happily compile ./pkg/foo.d to an executable and run it. But when I want to link it with ./pkg/bar.d I get into trouble:
>
> [dimon@morpheus d]$ dmd -c ./pkg/foo.d
> (apparently a success; ./pkg/foo.o is created.)
>
> [dimon@morpheus d]$ dmd -c ./pkg/bar.d
> (no error messages, but no object file is created)
>
> And trying to compile them both together I get
> [dimon@morpheus d]$ dmd ./pkg/bar.d ./pkg/foo.d
> gcc bar.o foo.o -o bar -lphobos -lpthread -lm
> foo.o(.deh_beg+0x0): multiple definition of `_deh_beg'
> bar.o(.deh_beg+0x0): first defined here
> foo.o(.deh_end+0x0): multiple definition of `_deh_end'
> bar.o(.deh_end+0x0): first defined here
> collect2: ld returned 1 exit status
> --- errorlevel 256
>
> So, I'm sure I'm doing something idiotic or, eqaully likely, completely missing something. Any help would be much appreciated!
>
> Thanks in advance
> Jan


July 20, 2004
On Tue, 20 Jul 2004 10:26:08 -0400, Jan Bendtsen wrote:

> Hello D people,
> 
> This is my first post to the newsgroup, and I'm a bit embarrassed that it is such a trivial question; but I don't know where else to find the solution, so please bear with me.
> 
> I basically come from a Java background, but I also have a little experience with plain old C. D appears to take the best from both worlds, with garbage collection and object-oriented syntax that reminds me of Java, combined with the ability to compile to a given architecture, which should solve Java's well-known performance problems.
> 
> So, ironically enough, my problem is related to compiling and linking... :-(
> 
> Say I write two modules called foo and bar and intend to put them in a package called pkg. The code is placed in two files called ./pkg/foo.d and ./pkg/bar.d (I use Mandrake Linux) and the outline looks roughly like this:
> 
> In ./pkg/foo.d:
> 
> module pkg.foo;
> 
> import std.math; // and other imports
> 
> public class Foo {
>      // Foo fields
>      // Foo methods
> }
> 
> public class BadFooException : Exception {
>      // Reason why Foo is bad
> }
> 
> int main() {
>      // A bit of code testing a couple of Foos
> }
> 
> In ./pkg/bar.d:
> 
> module pkg.bar;
> 
> import pkg.foo;
> import std.math; // and other imports
> 
> public class Bar {
>      private:
>      Foo myFoo;
>      // Other Bar fields
>      public:
>      void setFoo(Foo f) {...}// register myFoo
>      // Other Bar methods
> }
> 
> public class UglyBarException : Exception {
>      // Reason why Bar is ugly
> }
> 
> int main() {
>      Foo f = new Foo();
>      Bar b = new Bar();
>      b.setFoo(f);
>      b.doSomethingCoolWithmyFoo();
>      // ... and so forth
> }
> 
> I happily compile ./pkg/foo.d to an executable and run it. But when I want to link it with ./pkg/bar.d I get into trouble:
> 
> [dimon@morpheus d]$ dmd -c ./pkg/foo.d
> 	(apparently a success; ./pkg/foo.o is created.)
> 
> [dimon@morpheus d]$ dmd -c ./pkg/bar.d
> 	(no error messages, but no object file is created)
> 
> And trying to compile them both together I get
> [dimon@morpheus d]$ dmd ./pkg/bar.d ./pkg/foo.d
> gcc bar.o foo.o -o bar -lphobos -lpthread -lm
> foo.o(.deh_beg+0x0): multiple definition of `_deh_beg'
> bar.o(.deh_beg+0x0): first defined here
> foo.o(.deh_end+0x0): multiple definition of `_deh_end'
> bar.o(.deh_end+0x0): first defined here
> collect2: ld returned 1 exit status
> --- errorlevel 256
> 
> So, I'm sure I'm doing something idiotic or, eqaully likely, completely missing something. Any help would be much appreciated!
> 
> Thanks in advance
> Jan

I think its because you have two routines called 'main'.

If you are trying to get a stand-alone executable just by compiling foo.d then maybe if you did this to foo.d ...

version(TESTFOO)
{
void main() {
  Foo f = new Foo();
     // A bit of code testing a couple of Foos
}
}

and then compiled it alone with the -version=TESTFOO switch. This would give that effect. Then when compiling both together, leave out the swicth and only the 'main' in bar.d would get added to the object files.

-- 
Derek
Melbourne, Australia
20/Jul/04 6:38:32 PM
July 20, 2004
Hi again,

Derek Parnell wrote:
> On Tue, 20 Jul 2004 10:26:08 -0400, Jan Bendtsen wrote:
> 
> 
>>Hello D people,
>>
>>This is my first post to the newsgroup, and I'm a bit embarrassed that it is such a trivial question; but I don't know where else to find the solution, so please bear with me.
>>
>>I basically come from a Java background, but I also have a little 
[snip]

> I think its because you have two routines called 'main'. 
> 
> If you are trying to get a stand-alone executable just by compiling foo.d
> then maybe if you did this to foo.d ...
> 
> version(TESTFOO)
> {
> void main() {
>   Foo f = new Foo();
>      // A bit of code testing a couple of Foos
> }
> }
> 
> and then compiled it alone with the -version=TESTFOO switch. This would
> give that effect. Then when compiling both together, leave out the swicth
> and only the 'main' in bar.d would get added to the object files.


Yehah! That works like a charm :-) And of course it makes sense when I think about it from a more C-oriented perspective... Too much Java in my veins, I suppose ;-) Now I'm off to write a Makefile.

Thanks a lot, Derek and Chris.
Jan
July 20, 2004
[snip]
> Yehah! That works like a charm :-) And of course it makes sense when I think about it from a more C-oriented perspective... Too much Java in my veins, I suppose ;-) Now I'm off to write a Makefile.
> 
> Thanks a lot, Derek and Chris.

Er, sorry... Kris with a K ;-)

Cheers,
Jan (with a J)