Search code examples
moduled

Importing Modules in D


I am trying to use basic module importing in D (language release 2). As a guide I used example on dlang.org but my simple program will not compile. The files are in the same directory.

Here is my main.d file's contents:

import std.stdio;
import mymodule;

void main(string[] args){
  sayHello();
  writeln("Executing Main");
}

And here is my module file's contents (mymodule.d):

void sayHello(){
  writeln("hello");

}

To compile I execute via bash:

dmd main.d

And the error output is:

main.o: In function `_Dmain':
main.d:(.text._Dmain+0x5): undefined reference to `_D8mymodule8sayHelloFZv'
collect2: ld returned 1 exit status
--- errorlevel 1

Solution

    1. You need to list all of the modules that you're compiling on the command line. If you don't list a module, then it won't be compiled. The modules that are compiled will be able to use the uncompiled modules, since the compiler pulls in their declarations, but the compiler generates no object files for them. So, when the linker goes to link, it will complain that that there are definitions missing. In this case, it complains about the fact that mymodule.sayHello hasn't been defined.

      If you want the compiler to automatically search for all of the modules that the first module imports and compile them all for you, then you're going to need to use rdmd, which is a wrapper for dmd, which comes with dmd. dmd itself doesn't do that. It only compiles the modules that you tell it to.

    2. You haven't imported std.stdio in mymodule. So, even if you do dmd main.d mymodule.d like you should be (or even better, dmd -w main.d mymodule.d or dmd -wi main.d mymodule.d), it'll fail to compile mymodule, because writeln hasn't been declared. The fact that main.d imported it has no effect on mymodule.

    3. While it's not a big deal in this case, you really should put a module modulename; declaration at the top of your modules. The compiler will infer the module name from the filename, but once you have subpackages, you need to do it, or you'll have importing problems, because only the filename is inferred, not the package names. So, if you have foo/bar/mod.d, and you don't have a module declaration in mod.d, it'll be inferred as mod, not foo.bar.mod.