dubのcopyFiles
Contents
- 背景
 - ファイルがコピーされるタイミング
 - ディレクトリをコピーする
 - 他の言語のソースをビルドした結果のオブジェクトファイルをリンクする
 - さいごに
 
背景
dubでは、dub.jsonに記述した"copyFiles"というプロパティにファイル名を設定することで、
ビルド時にファイルをコピーするように設定できます。
これはWindowsでDLLを実行ファイルと同じディレクトリに置くために存在します。
今回はこのcopyFilesを使い倒します。
ファイルがコピーされるタイミング
"copyFiles"に設定したファイルは、プロジェクトのビルドが完全に終わってからコピーされます。
そのため、プロジェクトのビルド前にファイルをコピーしてほしい場合には、"preGenerateCommands"や"preBuildCommands"にコピーするコマンドを書くしかありません。
"preGenerateCommands": ["cp fromFile toFile"]
もし、あなたが作っているプロジェクトがライブラリとして、他のプロジェクトから使用されるのであればこの方法は使用できません。
なぜなら、"preGenerateCommands"や"preBuildCommands"は、あなたのライブラリのディレクトリで実行されるわけではなく、そのライブラリを使用するプロジェクトのディレクトリで実行されるためです。
そこで、あなたのライブラリのdub.jsonの"configurations"を次のように編集します。
"configurations":[
  {
    "name": "library",
  },
  {
    "name": "preBuildCopyCommand",
    "copyFiles": ["Build前にコピーしたいファイル"],
  }
]
そして、このライブラリ使用者は次のようなconfigurationsをdub.jsonに書くように心がけます。
"configurations": [
  {
    "name": "application",
    "targetType": "executable",
    "preGenerateCommands":[
      "dub generate --config=preBuildCopyCommand visuald",
    ],
  },
  {
    "name": "preBuildCopyCommand",
    "subConfigurations": {
      "myLibrary": "preBuildCopyCommand"
    }
  },
],
このconfigurationsは、まず"application"の"preGenerateCommands"が実行されます。
つまり、dub generate --config=preBuildCopyCommand visualdが実行されるため、ライブラリmyLibraryの"preBuildCopyCommand"のcopyFilesがビルド前に実行されるのです。
このとき、VisualD用の.slnファイル等ができてしまうため、邪魔に思った場合は"application"の"postBuildCommands"や"postGenerateCommands"でそれらのファイルを削除してしまいましょう。
ディレクトリをコピーする
ディレクトリをコピーするには、事前にディレクトリをzip等で圧縮しておき、先ほど述べたBuild前コピーのテクニックで先にコピーしておき、unzipしてしまいましょう。
"configurations":[
  {
    "name": "library",
  },
  {
    "name": "preBuildCopyCommand",
    "copyFiles": ["zipFile.zip"],
  }
  {
    "name": "preBuildPostCopyCommand",
    "preGenerateCommands": ["unzip zipFile.zip"]
  }
]
"configurations": [
  {
    "name": "application",
    "targetType": "executable",
    "preGenerateCommands":[
      "dub generate --config=preBuildCopyCommand visuald",
      "dub generate --config=preBuildPostCopyCommand visuald"
    ],
  },
  {
    "name": "preBuildCopyCommand",
    "subConfigurations": {
      "myLibrary": "preBuildCopyCommand"
    }
  },
  {
    "name": "preBuildPostCopyCommand",
    "subConfigurations": {
      "myLibrary": "preBuildCopyCommand"
    }
  }
],
他の言語のソースをビルドした結果のオブジェクトファイルをリンクする
Build前コピーのテクニックで先にそのコードをコピーしておき、その直後にその言語でビルドしオブジェクトファイルを生成します。
"configurations":[
  {
    "name": "library",
  },
  {
    "name": "preBuildCopyCommand",
    "copyFiles": ["c/src/src.cpp"],
  }
  {
    "name": "preBuildPostCopyCommand",
    "preGenerateCommands": ["g++ -c src.cpp"]
  }
]
"configurations": [
  {
    "name": "application",
    "targetType": "executable",
    "preGenerateCommands":[
      "dub generate --config=preBuildCopyCommand visuald",
      "dub generate --config=preBuildPostCopyCommand visuald"
    ],
  },
  {
    "name": "preBuildCopyCommand",
    "subConfigurations": {
      "myLibrary": "preBuildCopyCommand"
    }
  },
  {
    "name": "preBuildPostCopyCommand",
    "subConfigurations": {
      "myLibrary": "preBuildPostCopyCommand"
    }
  }
],
さいごに
そもそも、copyFilesに書いたファイルのコピーが"preGenerateCommands"よりも先に実行されていれば、このような労力はいらなかったのです。
この方法はかなりのバッドノウハウですが、使えるとかなり融通がきくため知っていると良いと思います。 使うかどうかは別として。