1 /** 2 Generator for project files 3 4 Copyright: © 2012-2013 Matthias Dondorff 5 License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 6 Authors: Matthias Dondorff 7 */ 8 module dub.generators.generator; 9 10 import dub.compilers.compiler; 11 import dub.generators.build; 12 import dub.generators.monod; 13 import dub.generators.rdmd; 14 import dub.generators.visuald; 15 import dub.internal.vibecompat.core.file; 16 import dub.internal.vibecompat.core.log; 17 import dub.internal.vibecompat.inet.path; 18 import dub.package_; 19 import dub.packagemanager; 20 import dub.project; 21 22 import std.exception; 23 import std.file; 24 import std.string; 25 26 27 /** 28 Common interface for project generators/builders. 29 */ 30 interface ProjectGenerator 31 { 32 void generateProject(GeneratorSettings settings); 33 } 34 35 36 struct GeneratorSettings { 37 BuildPlatform platform; 38 string config; 39 Compiler compiler; 40 BuildSettings buildSettings; 41 42 // only used for generator "rdmd" 43 bool run; 44 string[] runArgs; 45 string buildType; 46 } 47 48 49 /** 50 Creates a project generator of the given type for the specified project. 51 */ 52 ProjectGenerator createProjectGenerator(string generator_type, Project app, PackageManager mgr) 53 { 54 assert(app !is null && mgr !is null, "Project and package manager needed to create a generator."); 55 56 generator_type = generator_type.toLower(); 57 switch(generator_type) { 58 default: 59 throw new Exception("Unknown project generator: "~generator_type); 60 case "build": 61 logDebug("Creating build generator."); 62 return new BuildGenerator(app, mgr); 63 case "rdmd": 64 logDebug("Creating rdmd generator."); 65 return new RdmdGenerator(app, mgr); 66 case "mono-d": 67 logDebug("Creating MonoD generator."); 68 return new MonoDGenerator(app, mgr); 69 case "visuald": 70 logDebug("Creating VisualD generator."); 71 return new VisualDGenerator(app, mgr, false); 72 case "visuald-combined": 73 logDebug("Creating VisualD generator (combined project)."); 74 return new VisualDGenerator(app, mgr, true); 75 } 76 } 77 78 79 /** 80 Runs pre-build commands and performs other required setup before project files are generated. 81 */ 82 void prepareGeneration(BuildSettings buildsettings) 83 { 84 if( buildsettings.preGenerateCommands.length ){ 85 logInfo("Running pre-generate commands..."); 86 runBuildCommands(buildsettings.preGenerateCommands, buildsettings); 87 } 88 } 89 90 /** 91 Runs post-build commands and copies required files to the binary directory. 92 */ 93 void finalizeGeneration(BuildSettings buildsettings, bool generate_binary) 94 { 95 if (buildsettings.postGenerateCommands.length) { 96 logInfo("Running post-generate commands..."); 97 runBuildCommands(buildsettings.postGenerateCommands, buildsettings); 98 } 99 100 if (generate_binary) { 101 if (!exists(buildsettings.targetPath)) 102 mkdirRecurse(buildsettings.targetPath); 103 104 if (buildsettings.copyFiles.length) { 105 logInfo("Copying files..."); 106 foreach (f; buildsettings.copyFiles) { 107 auto src = Path(f); 108 auto dst = Path(buildsettings.targetPath) ~ Path(f).head; 109 logDiagnostic(" %s to %s", src.toNativeString(), dst.toNativeString()); 110 try { 111 copyFile(src, dst, true); 112 } catch logWarn("Failed to copy to %s", dst.toNativeString()); 113 } 114 } 115 } 116 } 117 118 void runBuildCommands(string[] commands, in BuildSettings build_settings) 119 { 120 import dub.internal.std.process; 121 import dub.internal.utils; 122 123 string[string] env = environment.toAA(); 124 // TODO: do more elaborate things here 125 // TODO: escape/quote individual items appropriately 126 env["DFLAGS"] = join(cast(string[])build_settings.dflags, " "); 127 env["LFLAGS"] = join(cast(string[])build_settings.lflags," "); 128 env["VERSIONS"] = join(cast(string[])build_settings.versions," "); 129 env["LIBS"] = join(cast(string[])build_settings.libs," "); 130 env["IMPORT_PATHS"] = join(cast(string[])build_settings.importPaths," "); 131 env["STRING_IMPORT_PATHS"] = join(cast(string[])build_settings.stringImportPaths," "); 132 runCommands(commands, env); 133 }