1 /** 2 Generator for direct compiler builds. 3 4 Copyright: © 2013-2013 rejectedsoftware e.K. 5 License: Subject to the terms of the MIT license. 6 Authors: Sönke Ludwig, Jan Jurzitza 7 */ 8 module workspaced.dub.lintgenerator; 9 10 // TODO: this sucks, this is copy pasted from build.d in dub and only removed binary output here 11 12 import dub.compilers.compiler; 13 import dub.compilers.utils; 14 import dub.generators.generator; 15 import dub.internal.utils; 16 import dub.internal.vibecompat.core.file; 17 import dub.internal.vibecompat.core.log; 18 import dub.internal.vibecompat.inet.path; 19 import dub.package_; 20 import dub.packagemanager; 21 import dub.project; 22 23 import std.algorithm; 24 import std.array; 25 import std.conv; 26 import std.exception; 27 import std.file; 28 import std.process; 29 import std.string; 30 import std.encoding : sanitize; 31 32 version (Windows) 33 enum objSuffix = ".obj"; 34 else 35 enum objSuffix = ".o"; 36 37 class DubLintGenerator : ProjectGenerator 38 { 39 this(Project project) 40 { 41 super(project); 42 } 43 44 override void generateTargets(GeneratorSettings settings, in TargetInfo[string] targets) 45 { 46 auto dcl = settings.compiler; 47 48 auto root_ti = targets[m_project.rootPackage.name]; 49 50 logInfo("Performing \"%s\" build using %s for %-(%s, %).", settings.buildType, 51 settings.platform.compilerBinary, settings.platform.architecture); 52 53 buildTarget(settings, root_ti.buildSettings.dup, m_project.rootPackage, root_ti.config); 54 } 55 56 private void buildTarget(GeneratorSettings settings, 57 BuildSettings buildsettings, in Package pack, string config) 58 { 59 auto cwd = NativePath(getcwd()); 60 61 // make all paths relative to shrink the command line 62 string makeRelative(string path) 63 { 64 return shrinkPath(NativePath(path), cwd); 65 } 66 67 foreach (ref f; buildsettings.sourceFiles) 68 f = makeRelative(f); 69 foreach (ref p; buildsettings.importPaths) 70 p = makeRelative(p); 71 foreach (ref p; buildsettings.stringImportPaths) 72 p = makeRelative(p); 73 74 // perform the actual build 75 performDirectBuild(settings, buildsettings, pack, config); 76 } 77 78 private void performDirectBuild(GeneratorSettings settings, 79 ref BuildSettings buildsettings, in Package pack, string config) 80 { 81 auto cwd = NativePath(getcwd()); 82 83 // make file paths relative to shrink the command line 84 foreach (ref f; buildsettings.sourceFiles) 85 { 86 auto fp = NativePath(f); 87 if (fp.absolute) 88 fp = fp.relativeTo(cwd); 89 f = fp.toNativeString(); 90 } 91 92 logInfo("%s %s: building configuration \"%s\"...", pack.name, pack.version_, config); 93 94 // make all target/import paths relative 95 string makeRelative(string path) 96 { 97 auto p = NativePath(path); 98 // storing in a separate temprary to work around #601 99 auto prel = p.absolute ? p.relativeTo(cwd) : p; 100 return prel.toNativeString(); 101 } 102 103 buildsettings.targetPath = makeRelative(buildsettings.targetPath); 104 foreach (ref p; buildsettings.importPaths) 105 p = makeRelative(p); 106 foreach (ref p; buildsettings.stringImportPaths) 107 p = makeRelative(p); 108 109 buildWithCompiler(settings, buildsettings); 110 } 111 112 private void buildWithCompiler(GeneratorSettings settings, BuildSettings buildsettings) 113 { 114 scope (failure) 115 { 116 logDiagnostic("FAIL %s %s %s", buildsettings.targetPath, 117 buildsettings.targetName, buildsettings.targetType); 118 } 119 120 buildsettings.libs = null; 121 buildsettings.lflags = null; 122 buildsettings.addOptions(BuildOption.syntaxOnly); 123 buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(f => !isLinkerFile(settings.platform, f)).array; 124 125 settings.compiler.prepareBuildSettings(buildsettings, settings.platform, BuildSetting.commandLine); 126 127 settings.compiler.invoke(buildsettings, settings.platform, settings.compileCallback); 128 } 129 } 130 131 private string shrinkPath(NativePath path, NativePath base) 132 { 133 auto orig = path.toNativeString(); 134 if (!path.absolute) 135 return orig; 136 auto ret = path.relativeTo(base).toNativeString(); 137 return ret.length < orig.length ? ret : orig; 138 }