www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Newbie compilation/linking package problem

reply Jan Bendtsen <dimon controlREMOVEME.aau.dk> writes:
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
Jul 20 2004
next sibling parent "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
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
Jul 20 2004
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
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
Jul 20 2004
parent reply Jan Bendtsen <dimon controlREMOVEME.aau.dk> writes:
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
Jul 20 2004
parent Jan Bendtsen <dimon controlREMOVEME.aau.dk> writes:
[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)
Jul 20 2004