2012-06-20 214 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