How does import work?

Jens Mueller jens.k.mueller at gmx.de
Tue Oct 19 05:57:03 PDT 2010


Steven Schveighoffer wrote:
> On Tue, 19 Oct 2010 05:04:03 -0400, Jens Mueller <jens.k.mueller at gmx.de>  
> wrote:
>
>> Hi,
>>
>> I have a simply example using imports that confuses me. Unfortunately I
>> cannot find explanation on the web site.
>> File a.d:
>> module a;
>>
>> // some import here
>> //import std.conv;
>>
>> File b.d:
>> module b;
>> import a;
>>
>> void main() {
>> }
>>
>> I do a
>> $ dmd -run b.d
>> and that works as expected.
>> If I commented in 'import std.conv;' in file a.d and do
>> $ dmd -run b.d
>> linking fails with
>> "b.o:(.data+0xc): undefined reference to `_D1a12__ModuleInfoZ'"
>>
>> I figured out that I need to add a.d like this
>> $ dmd a.d -run b.d
>> Because the ModuleInfo for a.d needs to be generated.
>>
>> So much for my limited understanding.
>> In my use case I want to do unit testing like this
>> $ dmd -unittest -run b.d
>>
>> It seems that I always have to built a library to make sure that an
>> import works. Can somebody explain the rational behind that? What is
>> ModuleInfo? And why is it needed? How can I make the unit testing work
>> per module? How do you do it?
>> I think I missed something essential about imports.
>
> ModuleInfo is the runtime representation of the module.  Modules can have 
> their own constructors and destructors to initialize global and  
> thread-local data.  You can also get the name of the module from the  
> module info.  They are stored by the compiler in an array that is  
> accessible at runtime.  A module's unit tests are also stored in the  
> module info.
>
> To answer your other questions, just unit test everything at once.  There 
> is no need to run each individual file.  In other words, just do:
>
> dmd -unittest -run b.d a.d
>
> And that will test all unittests in b and a.
>
> If you insist on only testing unittests in b, you still need a complete  
> program.  So a's module info must be included.  Therefore you need to do 
> a partial compilation:
>
> dmd -c a.d
>
> this creates a.o (or a.obj depending on your platform).  If a has  
> unittests they are *not* included in the object file.
>
> dmd -unittest -run b.d a.o
>
> Note that I'm passing the already-compiled version of a, this means it  
> will not be recompiled to add a's unit tests.  Why you'd want to do it  
> this way, I have no idea.

Thanks very much for your explanation. It just seemed natural to me to
test them separately. Often I do not know even which modules a module
depends on. And assuming there are many tests that might take long,
picking a specific one seemed the better option to me. In general if the
test suite is large and something fails then after the problem is fixed
or while fixing I want to run only the depended tests.
But admittedly this does not come up in practice, does it? I mean phobos
does not need it. Testing everything is fast.
So then I'll just test all.

Jens


More information about the Digitalmars-d mailing list