2012-06-20 43 views
6

我正尝试在D(语言版本2)中使用基本模块导入。作为指南,我在dlang.org上使用了示例,但我的简单程序不能编译。这些文件位于相同的目录中。在D中导入模块

这里是我的main.d文件的内容:

import std.stdio; 
import mymodule; 

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

这里是我的模块文件的内容(mymodule.d):

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

} 

编译通过我的bash执行

dmd main.d 

而错误输出是:

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

试试'dmd mymodule.d main.d' –

+0

这很奏效。发布它作为一个适当的答案,所以我可以给你的认可。你应得的!即使你不关心这些问题,至少我可以将问题标记为答案。 – RedMage

+1

只需使用rdmd --build-only main.d. – Trass3r

回答

9
  1. 您需要列出您在命令行上编译的所有模块。如果你没有列出一个模块,那么它将不会被编译。编译器的模块将能够使用未编译的模块,因为编译器会引入它们的声明,但编译器不会为它们生成目标文件。所以,当链接器链接时,它会抱怨缺少定义。在这种情况下,它抱怨mymodule.sayHello尚未定义。

    如果您希望编译器自动搜索第一个模块导入的所有模块并为您编译所有这些模块,那么您将需要使用rdmd,它是dmd的包装器,它随附DMD。 dmd本身并不这样做。它只编译你告诉它的模块。

  2. 您还没有在mymodule中导入std.stdio。所以,即使你做的dmd main.d mymodule.d像你应该(或更好,dmd -w main.d mymodule.ddmd -wi main.d mymodule.d),它将无法编译mymodule,因为writeln还没有被声明。 main.d导入它的事实对mymodule没有影响。

  3. 虽然在这种情况下这不是什么大问题,但是您应该在模块的顶部放置一个module modulename;声明。编译器会从文件名中推断出模块名称,但一旦你有子包,你需要来做这件事,否则你会导入问题,因为只推荐文件名,而不是包名。因此,如果您有foo/bar/mod.d,并且您在mod.d中没有module声明,则它将被推断为mod,而不是foo.bar.mod

4

dmd mymodule.d main.d

我知道的唯一语言是足够聪明,对自己的工作了依赖是围棋和Haskell。

+2

'rdmd'将解决依赖关系。 'rdmd main.d'将构建文件和所有依赖项并执行结果。如果你只想为命令添加'--build-only'。 – eco

+0

我喜欢Haskell的这个特性。我希望D也有。 – Arlen

+2

要迂腐,我不认为Go或Haskell都有这个特性,而是他们的编译器。一致的D编译器也可以拥有它。 – BCS