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