www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Importing problems

reply "Korey Peters" <koreypeters gmail.com> writes:
Hi everyone.

I'm new to D, coming from a Java/Python background. I've been 
reading the excellent "The D Programming Language" book, and want 
to now start playing around with D.

I'm having an issue with importing. When I have the following 
file:

file ~/src/sample.d: =====================

import std.stdio;

class A{
	int a = 1;
}

class B{
	A a;
	int b = 2;
	this(A a){
		this.a = a;
	}
}

void main(){
	auto a = new A;
	auto b = new B(a);
	writeln(b.b);
	writeln(b.a.a);
}

...and then at the terminal window:

me ubuntu:~/src$ rdmd sample.d
1
2

However, if I create a second file to import A from like so:

file ~/src/sample.d: =====================

import std.stdio;
import sample_a;


class B{
	A a;
	int b = 2;
	this(A a){
		this.a = a;
	}
}

void main(){
	auto a = new A;
	auto b = new B(a);
	writeln(b.b);
	writeln(b.a.a);
}

file ~/src/sample_a.d: =====================
class A{
	int a = 1;
}

...and at the terminal:
me ubuntu:~/src$ rdmd sample.d
/tmp/.rdmd-1000/rdmd-sample.d-94E53075E2E84D963426A11F2B81FDED/objs/sample.o: 
In function `_Dmain':
sample.d:(.text._Dmain+0xa): undefined reference to 
`_D8sample_a1A7__ClassZ'
collect2: error: ld returned 1 exit status
--- errorlevel 1

I feel like I'm missing something fundamental (and I'm guessing 
it's because I don't have any experience in "compiled" languages. 
Can anyone help? It sucks to have everything in one file! :)

Ubuntu 12.10 64bit with the latest D packages (downloaded a few 
days ago).

I get the same problems in Win7.

Kind regards,
Korey
Feb 13 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Feb 13, 2013 at 06:17:51PM +0100, Korey Peters wrote:
[...]
 ...and at the terminal:
 me ubuntu:~/src$ rdmd sample.d
 /tmp/.rdmd-1000/rdmd-sample.d-94E53075E2E84D963426A11F2B81FDED/objs/sample.o:
 In function `_Dmain':
 sample.d:(.text._Dmain+0xa): undefined reference to
 `_D8sample_a1A7__ClassZ'
 collect2: error: ld returned 1 exit status
 --- errorlevel 1
 
 I feel like I'm missing something fundamental (and I'm guessing it's
 because I don't have any experience in "compiled" languages. Can
 anyone help? It sucks to have everything in one file! :)
You need to specify both files on the command line, so that the linker knows where to find everything: rdmd sample.d sample_a.d As to the 'why': compiled languages generally are compiled in two steps: first the compiler parses the source file(s) and generates executable code for each file (this is generally called 'object code'), then a second stage, calling 'linking', is used to link these object files together into the final executable. The 'import' statement only relates to the first stage, that is, to use declarations in another source file. But before you can actually use the stuff in the other file, that other file needs to be compiled as well (the 'import' only imports declarations; it doesn't actually compile the declared code), and it needs to be included in the linking stage so that all references between the source files can be linked properly. Hope this helps. T -- English is useful because it is a mess. Since English is a mess, it maps well onto the problem space, which is also a mess, which we call reality. Similarly, Perl was designed to be a mess, though in the nicests of all possible ways. -- Larry Wall
Feb 13 2013
parent reply "Korey Peters" <koreypeters gmail.com> writes:
Thanks for your response, H.S.Teoh.

On Wednesday, 13 February 2013 at 17:47:09 UTC, H. S. Teoh wrote:
 You need to specify both files on the command line, so that the 
 linker
 knows where to find everything:

 	rdmd sample.d sample_a.d
Running this from the command line produces (exactly?) the same error... me ubuntu:~/src$ rdmd sample.d sample_a.d /tmp/.rdmd-1000/rdmd-sample.d-94E53075E2E84D963426A11F2B81FDED/objs/sample.o: In function `_Dmain': sample.d:(.text._Dmain+0xa): undefined reference to `_D8sample_a1A7__ClassZ' collect2: error: ld returned 1 exit status --- errorlevel 1 I tried swapping the order of the file names, but that didn't help.
 But before you can actually use the stuff in the other file, 
 that other
 file needs to be compiled as well (the 'import' only imports
 declarations; it doesn't actually compile the declared code), 
 and it
 needs to be included in the linking stage so that all 
 references between
 the source files can be linked properly.
Ah. I thought that the purpose of "rdmd" (as opposed to "dmd") was to link the files automatically. Thanks.
Feb 13 2013
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Feb 13, 2013 at 06:57:52PM +0100, Korey Peters wrote:
 Thanks for your response, H.S.Teoh.
 
 On Wednesday, 13 February 2013 at 17:47:09 UTC, H. S. Teoh wrote:
You need to specify both files on the command line, so that the
linker
knows where to find everything:

	rdmd sample.d sample_a.d
Running this from the command line produces (exactly?) the same error... me ubuntu:~/src$ rdmd sample.d sample_a.d /tmp/.rdmd-1000/rdmd-sample.d-94E53075E2E84D963426A11F2B81FDED/objs/sample.o: In function `_Dmain': sample.d:(.text._Dmain+0xa): undefined reference to `_D8sample_a1A7__ClassZ' collect2: error: ld returned 1 exit status --- errorlevel 1 I tried swapping the order of the file names, but that didn't help.
But before you can actually use the stuff in the other file, that
other file needs to be compiled as well (the 'import' only imports
declarations; it doesn't actually compile the declared code), and it
needs to be included in the linking stage so that all references
between the source files can be linked properly.
Ah. I thought that the purpose of "rdmd" (as opposed to "dmd") was to link the files automatically. Thanks.
Actually, you're right, rdmd is supposed to automatically link all dependent files. I just tried your code in my environment (Linux 64-bit, git HEAD) and I didn't see this problem. I wonder if it's a bug that has since been fixed? Maybe you can try inserting this line into sample_a.d: module sample_a; I'm not sure if that will help, but just trying to narrow down the problem a bit. T -- Give me some fresh salted fish, please.
Feb 13 2013
next sibling parent "Korey Peters" <koreypeters gmail.com> writes:
Hmm.

I moved my two sample files from "~/path/to/where/I/was/working" 
to "~/" and the import worked.

This makes me suspect a permissions issue. I'll carry on working 
in ~/ for now, until I sort my stupidity out!

Thanks for your help.
Feb 13 2013
prev sibling parent reply "jerro" <a a.com> writes:
On Wednesday, 13 February 2013 at 18:42:51 UTC, H. S. Teoh wrote:
 On Wed, Feb 13, 2013 at 06:57:52PM +0100, Korey Peters wrote:
 Thanks for your response, H.S.Teoh.
 
 On Wednesday, 13 February 2013 at 17:47:09 UTC, H. S. Teoh 
 wrote:
You need to specify both files on the command line, so that 
the
linker
knows where to find everything:

	rdmd sample.d sample_a.d
Running this from the command line produces (exactly?) the same error... me ubuntu:~/src$ rdmd sample.d sample_a.d /tmp/.rdmd-1000/rdmd-sample.d-94E53075E2E84D963426A11F2B81FDED/objs/sample.o: In function `_Dmain': sample.d:(.text._Dmain+0xa): undefined reference to `_D8sample_a1A7__ClassZ' collect2: error: ld returned 1 exit status --- errorlevel 1 I tried swapping the order of the file names, but that didn't help.
But before you can actually use the stuff in the other file, 
that
other file needs to be compiled as well (the 'import' only 
imports
declarations; it doesn't actually compile the declared code), 
and it
needs to be included in the linking stage so that all 
references
between the source files can be linked properly.
Ah. I thought that the purpose of "rdmd" (as opposed to "dmd") was to link the files automatically. Thanks.
Actually, you're right, rdmd is supposed to automatically link all dependent files. I just tried your code in my environment (Linux 64-bit, git HEAD) and I didn't see this problem. I wonder if it's a bug that has since been fixed? Maybe you can try inserting this line into sample_a.d: module sample_a; I'm not sure if that will help, but just trying to narrow down the problem a bit. T
I created self-contained sample.d, ran it with rdmd, then moved class A to sample_a.d and tried to run it with rdmd again. I could reproduce the issue that way. It seems that rdmd caches the dependency list. Using --chatty flag confirms that rdmd does not run dmd to get the dependency list the second time. This solves the issue: rdmd --force sample
Feb 13 2013
next sibling parent "Korey Peters" <koreypeters gmail.com> writes:
On Wednesday, 13 February 2013 at 19:33:00 UTC, jerro wrote:
 This solves the issue:

 rdmd --force sample
Hi jerro, That definitely helped. There's still some things I haven't figured out yet about D's importing, but this has got me going. Thank you.
Feb 13 2013
prev sibling parent reply Brad Roberts <braddr slice-2.puremagic.com> writes:
On Wed, 13 Feb 2013, jerro wrote:

 I created self-contained sample.d, ran it with rdmd, then moved class A to
 sample_a.d and tried to run it with rdmd again. I could reproduce the issue
 that way. It seems that rdmd caches the dependency list. Using --chatty flag
 confirms that rdmd does not run dmd to get the dependency list the second
 time.
 
 This solves the issue:
 
 rdmd --force sample
Please file a bug report on this.
Feb 13 2013
next sibling parent "jerro" <a a.com> writes:
 Please file a bug report on this.
Done.
Feb 13 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Feb 13, 2013 at 03:53:51PM -0800, Brad Roberts wrote:
 On Wed, 13 Feb 2013, jerro wrote:
 
 I created self-contained sample.d, ran it with rdmd, then moved
 class A to sample_a.d and tried to run it with rdmd again. I could
 reproduce the issue that way. It seems that rdmd caches the
 dependency list. Using --chatty flag confirms that rdmd does not run
 dmd to get the dependency list the second time.
 
 This solves the issue:
 
 rdmd --force sample
Please file a bug report on this.
I just glanced over the code, it seems to be using timestamps to check whether or not to update the dependencies. Which *should* work in general, though there may be problems if you're on NFS and the system clock is out of sync. T -- Let's call it an accidental feature. -- Larry Wall
Feb 13 2013