Newer
Older
dub_jkp / source / dub / generators / build.d
  1. /**
  2. Generator for direct compiler builds.
  3. Copyright: © 2013 rejectedsoftware e.K.
  4. License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
  5. Authors: Sönke Ludwig
  6. */
  7. module dub.generators.build;
  8.  
  9. import dub.compilers.compiler;
  10. import dub.generators.generator;
  11. import dub.package_;
  12. import dub.packagemanager;
  13. import dub.project;
  14.  
  15. import std.algorithm;
  16. import std.array;
  17. import std.conv;
  18. import std.exception;
  19. import std.file;
  20. import std.string;
  21. import stdx.process;
  22.  
  23. import vibe.core.file;
  24. import vibe.core.log;
  25. import vibe.inet.path;
  26.  
  27.  
  28. class BuildGenerator : ProjectGenerator {
  29. private {
  30. Project m_project;
  31. PackageManager m_pkgMgr;
  32. }
  33. this(Project app, PackageManager mgr)
  34. {
  35. m_project = app;
  36. m_pkgMgr = mgr;
  37. }
  38. void generateProject(GeneratorSettings settings)
  39. {
  40.  
  41. //Added check for existance of [AppNameInPackagejson].d
  42. //If exists, use that as the starting file.
  43. auto outfile = getBinName(m_project);
  44. auto mainsrc = getMainSourceFile(m_project);
  45.  
  46. logDebug("Application output name is '%s'", outfile);
  47.  
  48. auto buildsettings = settings.buildSettings;
  49. m_project.addBuildSettings(buildsettings, settings.platform, settings.config);
  50. buildsettings.addDFlags(["-w"/*, "-property"*/]);
  51. string dflags = environment.get("DFLAGS");
  52. if( dflags.length ){
  53. settings.buildType = "$DFLAGS";
  54. buildsettings.addDFlags(dflags.split());
  55. } else {
  56. addBuildTypeFlags(buildsettings, settings.buildType);
  57. }
  58.  
  59. // add all .d files
  60. void addPackageFiles(in Package pack){
  61. foreach(s; pack.sources){
  62. if( pack !is m_project.mainPackage && s == Path("source/app.d") )
  63. continue;
  64. auto relpath = (pack.path ~ s).relativeTo(m_project.mainPackage.path);
  65. buildsettings.addFiles(relpath.toNativeString());
  66. }
  67. }
  68. addPackageFiles(m_project.mainPackage);
  69. foreach(dep; m_project.installedPackages)
  70. addPackageFiles(dep);
  71.  
  72. // setup for command line
  73. settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine);
  74.  
  75. Path run_exe_file;
  76. if( !settings.run ){
  77. settings.compiler.setTarget(buildsettings, m_project.binaryPath~outfile);
  78. } else {
  79. import std.random;
  80. auto rnd = to!string(uniform(uint.min, uint.max)) ~ "-";
  81. auto tmp = environment.get("TEMP");
  82. if( !tmp.length ) tmp = environment.get("TMP");
  83. if( !tmp.length ){
  84. version(Posix) tmp = "/tmp";
  85. else tmp = ".";
  86. }
  87. run_exe_file = Path(tmp~"/.rdmd/source/"~rnd~outfile);
  88. settings.compiler.setTarget(buildsettings, run_exe_file);
  89. }
  90.  
  91. string[] flags = buildsettings.dflags;
  92.  
  93. if( settings.config.length ) logInfo("Building configuration "~settings.config~", build type "~settings.buildType);
  94. else logInfo("Building default configuration, build type "~settings.buildType);
  95.  
  96. logInfo("Running %s", settings.compilerBinary ~ " " ~ join(flags, " "));
  97. auto compiler_pid = spawnProcess(settings.compilerBinary, flags);
  98. auto result = compiler_pid.wait();
  99. enforce(result == 0, "Build command failed with exit code "~to!string(result));
  100.  
  101. // TODO: move to a common place - this is not generator specific
  102. if( buildsettings.copyFiles.length ){
  103. logInfo("Copying files...");
  104. foreach( f; buildsettings.copyFiles ){
  105. auto src = Path(f);
  106. auto dst = (run_exe_file.empty ? m_project.binaryPath : run_exe_file.parentPath) ~ Path(f).head;
  107. logDebug(" %s to %s", src.toNativeString(), dst.toNativeString());
  108. try copyFile(src, dst, true);
  109. catch logWarn("Failed to copy to %s", dst.toNativeString());
  110. }
  111. }
  112.  
  113. if( settings.run ){
  114. auto prg_pid = spawnProcess(run_exe_file.toNativeString(), settings.runArgs);
  115. result = prg_pid.wait();
  116. remove(run_exe_file.toNativeString());
  117. foreach( f; buildsettings.copyFiles )
  118. remove((run_exe_file.parentPath ~ Path(f).head).toNativeString());
  119. enforce(result == 0, "Program exited with code "~to!string(result));
  120. }
  121. }
  122. }
  123.  
  124. private string getBinName(in Project prj)
  125. {
  126. // take the project name as the base or fall back to "app"
  127. string ret = prj.name;
  128. if( ret.length == 0 ) ret ="app";
  129. version(Windows) { ret ~= ".exe"; }
  130. return ret;
  131. }
  132.  
  133. private Path getMainSourceFile(in Project prj)
  134. {
  135. auto p = Path("source") ~ (prj.name ~ ".d");
  136. return existsFile(p) ? p : Path("source/app.d");
  137. }
  138.