diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index 9e15d09..7aff632 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -148,11 +148,28 @@ /// dmd flags to compiler-specific flags void prepareBuildSettings(ref BuildSettings settings, BuildSetting supported_fields = BuildSetting.all); + /// Removes any dflags that match one of the BuildOptions values and populates the BuildSettings.options field. + void extractBuildOptions(ref BuildSettings settings); + /// Adds the appropriate flag to set a target path void setTarget(ref BuildSettings settings, in BuildPlatform platform); /// Invokes the underlying linker directly void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects); + + final protected void enforceBuildRequirements(ref BuildSettings settings) + { + settings.addOptions(BuildOptions.warnings); + if (settings.requirements & BuildRequirements.allowWarnings) settings.options &= ~BuildOptions.warningsAsErrors; + if (settings.requirements & BuildRequirements.silenceWarnings) settings.options &= ~(BuildOptions.warningsAsErrors|BuildOptions.warnings); + if (settings.requirements & BuildRequirements.disallowDeprecations) { settings.options &= ~(BuildOptions.ignoreDeprecations|BuildOptions.deprecationWarnings); settings.options |= BuildOptions.deprecationErrors; } + if (settings.requirements & BuildRequirements.silenceDeprecations) { settings.options &= ~(BuildOptions.deprecationErrors|BuildOptions.deprecationWarnings); settings.options |= BuildOptions.ignoreDeprecations; } + if (settings.requirements & BuildRequirements.disallowInlining) settings.options &= BuildOptions.inline; + if (settings.requirements & BuildRequirements.disallowOptimization) settings.options &= ~BuildOptions.optimize; + if (settings.requirements & BuildRequirements.requireBoundsCheck) settings.options &= ~BuildOptions.noBoundsChecks; + if (settings.requirements & BuildRequirements.requireContracts) settings.options &= ~BuildOptions.release; + if (settings.requirements & BuildRequirements.relaxProperties) settings.options &= ~BuildOptions.property; + } } @@ -169,6 +186,7 @@ string[] sourceFiles; string[] copyFiles; string[] versions; + string[] debugVersions; string[] importPaths; string[] stringImportPaths; string[] preGenerateCommands; @@ -176,6 +194,7 @@ string[] preBuildCommands; string[] postBuildCommands; BuildRequirements requirements; + BuildOptions options; void addDFlags(in string[] value...) { dflags ~= value; } void removeDFlags(in string[] value...) { remove(dflags, value); } @@ -185,6 +204,7 @@ void removeSourceFiles(in string[] value...) { removePaths(sourceFiles, value); } void addCopyFiles(in string[] value...) { add(copyFiles, value); } void addVersions(in string[] value...) { add(versions, value); } + void addDebugVersions(in string[] value...) { add(debugVersions, value); } void addImportPaths(in string[] value...) { add(importPaths, value); } void addStringImportPaths(in string[] value...) { add(stringImportPaths, value); } void addPreGenerateCommands(in string[] value...) { add(preGenerateCommands, value, false); } @@ -192,6 +212,8 @@ void addPreBuildCommands(in string[] value...) { add(preBuildCommands, value, false); } void addPostBuildCommands(in string[] value...) { add(postBuildCommands, value, false); } void addRequirements(in BuildRequirements[] value...) { foreach (v; value) this.requirements |= v; } + void addOptions(in BuildOptions[] value...) { foreach (v; value) this.options |= v; } + void removeOptions(in BuildOptions[] value...) { foreach (v; value) this.options &= ~v; } // Adds vals to arr without adding duplicates. private void add(ref string[] arr, in string[] vals, bool no_duplicates = true) @@ -309,12 +331,15 @@ sourceFiles = 1<<3, copyFiles = 1<<4, versions = 1<<5, - importPaths = 1<<6, - stringImportPaths = 1<<7, + debugVersions = 1<<6, + importPaths = 1<<7, + stringImportPaths = 1<<8, + options = 1<<9, none = 0, commandLine = dflags|copyFiles, commandLineSeparate = commandLine|lflags, - all = dflags|lflags|libs|sourceFiles|copyFiles|versions|importPaths|stringImportPaths + all = dflags|lflags|libs|sourceFiles|copyFiles|versions|debugVersions|importPaths|stringImportPaths|options, + noOptions = all & ~options } enum TargetType { @@ -341,6 +366,30 @@ noDefaultFlags = 1<<9, /// Do not issue any of the default build flags (e.g. -debug, -w, -property etc.) - use only for development purposes } +enum BuildOptions { + debug_ = 1<<0, /// Compile in debug mode (enables contracts, -debug) + release = 1<<1, /// Compile in release mode (disables assertions and bounds checks, -release) + coverage = 1<<2, /// Enable code coverage analysis (-cov) + debugInfo = 1<<3, /// Enable symbolic debug information (-g) + debugInfoC = 1<<4, /// Enable symbolic debug information in C compatible form (-gc) + alwaysStackFrame = 1<<5, /// Always generate a stack frame (-gs) + stackStomping = 1<<6, /// Perform stack stomping (-gx) + inline = 1<<7, /// Perform function inlining (-inline) + noBoundsChecks = 1<<8, /// Disable all bounds checking (-noboundscheck) + optimize = 1<<9, /// Enable optimizations (-O) + profile = 1<<10, /// Emit profiling code (-profile) + unittests = 1<<11, /// Compile unit tests (-unittest) + verbose = 1<<12, /// Verbose compiler output (-v) + ignoreUnknownPragmas = 1<<13, /// Ignores unknown pragmas during compilation (-ignore) + syntaxOnly = 1<<14, /// Don't generate object files (-o-) + warnings = 1<<15, /// Enable warnings (-wi) + warningsAsErrors = 1<<16, /// Treat warnings as errors (-w) + ignoreDeprecations = 1<<17, /// Do not warn about using deprecated features (-d) + deprecationWarnings = 1<<18, /// Warn about using deprecated features (-dw) + deprecationErrors = 1<<19, /// Stop compilation upon usage of deprecated features (-de) + property = 1<<20, /// DEPRECATED: Enforce property syntax (-property) +} + string getTargetFileName(in BuildSettings settings, in BuildPlatform platform) { assert(settings.targetName.length > 0, "No target name set."); diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index c098dc7..786c8b6 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -17,9 +17,34 @@ import std.array; import std.conv; import std.exception; +import std.typecons; class DmdCompiler : Compiler { + private static immutable s_options = [ + tuple(BuildOptions.debug_, ["-debug"]), + tuple(BuildOptions.release, ["-release"]), + tuple(BuildOptions.coverage, ["-cov"]), + tuple(BuildOptions.debugInfo, ["-g"]), + tuple(BuildOptions.debugInfoC, ["-gc"]), + tuple(BuildOptions.alwaysStackFrame, ["-gs"]), + tuple(BuildOptions.stackStomping, ["-gx"]), + tuple(BuildOptions.inline, ["-inline"]), + tuple(BuildOptions.noBoundsChecks, ["-noboundscheck"]), + tuple(BuildOptions.optimize, ["-O"]), + tuple(BuildOptions.profile, ["-profile"]), + tuple(BuildOptions.unittests, ["-unittest"]), + tuple(BuildOptions.verbose, ["-v"]), + tuple(BuildOptions.ignoreUnknownPragmas, ["-ignore"]), + tuple(BuildOptions.syntaxOnly, ["-o-"]), + tuple(BuildOptions.warnings, ["-wi"]), + tuple(BuildOptions.warningsAsErrors, ["-w"]), + tuple(BuildOptions.ignoreDeprecations, ["-d"]), + tuple(BuildOptions.deprecationWarnings, ["-dw"]), + tuple(BuildOptions.deprecationErrors, ["-de"]), + tuple(BuildOptions.property, ["-property"]), + ]; + @property string name() const { return "dmd"; } BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) @@ -47,6 +72,14 @@ void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { + enforceBuildRequirements(settings); + + if (!(fields & BuildSetting.options)) { + foreach (t; s_options) + if (settings.options & t[0]) + settings.addDFlags(t[1]); + } + if (!(fields & BuildSetting.libs)) resolveLibs(settings); @@ -55,6 +88,11 @@ settings.versions = null; } + if (!(fields & BuildSetting.debugVersions)) { + settings.addDFlags(settings.debugVersions.map!(s => "-debug="~s)().array()); + settings.debugVersions = null; + } + if (!(fields & BuildSetting.importPaths)) { settings.addDFlags(settings.importPaths.map!(s => "-I"~s)().array()); settings.importPaths = null; @@ -75,20 +113,26 @@ settings.lflags = null; } - if (settings.requirements & BuildRequirements.allowWarnings) { settings.removeDFlags("-w"); settings.addDFlags("-wi"); } - if (settings.requirements & BuildRequirements.silenceWarnings) { settings.removeDFlags("-w", "-wi"); } - if (settings.requirements & BuildRequirements.disallowDeprecations) { settings.removeDFlags("-dw", "-d"); settings.addDFlags("-de"); } - if (settings.requirements & BuildRequirements.silenceDeprecations) { settings.removeDFlags("-dw", "-de"); settings.addDFlags("-d"); } - if (settings.requirements & BuildRequirements.disallowInlining) { settings.removeDFlags("-inline"); } - if (settings.requirements & BuildRequirements.disallowOptimization) { settings.removeDFlags("-O"); } - if (settings.requirements & BuildRequirements.requireBoundsCheck) { settings.removeDFlags("-noboundscheck"); } - if (settings.requirements & BuildRequirements.requireContracts) { settings.removeDFlags("-release"); } - if (settings.requirements & BuildRequirements.relaxProperties) { settings.removeDFlags("-property"); } - assert(fields & BuildSetting.dflags); assert(fields & BuildSetting.copyFiles); } + void extractBuildOptions(ref BuildSettings settings) + { + Appender!(string[]) newflags; + next_flag: foreach (f; settings.dflags) { + foreach (t; s_options) + if (t[1].canFind(f)) { + settings.options |= t[0]; + continue next_flag; + } + if (f.startsWith("-version=")) settings.addVersions(f[9 .. $]); + else if (f.startsWith("-debug=")) settings.addDebugVersions(f[7 .. $]); + else newflags ~= f; + } + settings.dflags = newflags.data; + } + void setTarget(ref BuildSettings settings, in BuildPlatform platform) { final switch (settings.targetType) { diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 870a18d..a56ff83 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -17,9 +17,34 @@ import std.array; import std.conv; import std.exception; +import std.typecons; class GdcCompiler : Compiler { + private static immutable s_options = [ + tuple(BuildOptions.debug_, ["-fdebug"]), + tuple(BuildOptions.release, ["-frelease"]), + tuple(BuildOptions.coverage, ["-fprofile-arcs", "-ftest-coverage"]), + tuple(BuildOptions.debugInfo, ["-g"]), + tuple(BuildOptions.debugInfoC, ["-g", "-fdebug-c"]), + //tuple(BuildOptions.alwaysStackFrame, ["-X"]), + //tuple(BuildOptions.stackStomping, ["-X"]), + tuple(BuildOptions.inline, ["-finline-functions"]), + tuple(BuildOptions.noBoundsChecks, ["-fno-bounds-check"]), + tuple(BuildOptions.optimize, ["-O3"]), + //tuple(BuildOptions.profile, ["-X"]), + tuple(BuildOptions.unittests, ["-funittest"]), + tuple(BuildOptions.verbose, ["-fd-verbose"]), + tuple(BuildOptions.ignoreUnknownPragmas, ["-fignore-unknown-pragmas"]), + tuple(BuildOptions.syntaxOnly, ["-fsyntax-only"]), + tuple(BuildOptions.warnings, ["-Wall"]), + tuple(BuildOptions.warningsAsErrors, ["-Werror", "-Wall"]), + //tuple(BuildOptions.ignoreDeprecations, ["-?"]), + //tuple(BuildOptions.deprecationWarnings, ["-?"]), + //tuple(BuildOptions.deprecationErrors, ["-?"]), + tuple(BuildOptions.property, ["-fproperty"]), + ]; + @property string name() const { return "gdc"; } BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) @@ -36,58 +61,14 @@ void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { - // convert common DMD flags to the corresponding GDC flags - string[] newdflags; - foreach (f; settings.dflags) { - switch (f) { - default: newdflags ~= f; break; - case "-cov": newdflags ~= ["-fprofile-arcs", "-ftest-coverage"]; break; - case "-D": newdflags ~= "-fdoc"; break; - //case "-Dd[dir]": newdflags ~= ""; break; - //case "-Df[file]": newdflags ~= ""; break; - case "-d": newdflags ~= "-fdeprecated"; break; - case "-dw": break; - case "-de": break; - case "-debug": newdflags ~= "-fdebug"; break; - //case "-debug=[level/ident]": newdflags ~= ""; break; - //case "-debuglib=[ident]": newdflags ~= ""; break; - //case "-defaultlib=[ident]": newdflags ~= ""; break; - //case "-deps=[file]": newdflags ~= ""; break; - case "-fPIC": newdflags ~= ""; break; - case "-g": newdflags ~= "-g"; break; - case "-gc": newdflags ~= ["-g" ~ "-fdebug-c"]; break; - case "-gs": break; - case "-H": newdflags ~= "-fintfc"; break; - //case "-Hd[dir]": newdflags ~= ""; break; - //case "-Hf[file]": newdflags ~= ""; break; - case "-ignore": newdflags ~= "-fignore-unknown-pragmas"; break; - case "-inline": newdflags ~= "-finline-functions"; break; - //case "-lib": newdflags ~= ""; break; - //case "-m32": newdflags ~= ""; break; - //case "-m64": newdflags ~= ""; break; - case "-noboundscheck": newdflags ~= "-fno-bounds-check"; break; - case "-O": newdflags ~= "-O3"; break; - case "-o-": newdflags ~= "-fsyntax-only"; break; - //case "-od[dir]": newdflags ~= ""; break; - //case "-of[file]": newdflags ~= ""; break; - //case "-op": newdflags ~= ""; break; - //case "-profile": newdflags ~= "-pg"; break; - case "-property": newdflags ~= "-fproperty"; break; - //case "-quiet": newdflags ~= ""; break; - case "-release": newdflags ~= "-frelease"; break; - case "-shared": newdflags ~= "-shared"; break; - case "-unittest": newdflags ~= "-funittest"; break; - case "-v": newdflags ~= "-fd-verbose"; break; - //case "-version=[level/ident]": newdflags ~= ""; break; - case "-vtls": newdflags ~= "-fd-vtls"; break; - case "-w": newdflags ~= "-Werror"; break; - case "-wi": newdflags ~= "-Wall"; break; - //case "-X": newdflags ~= ""; break; - //case "-Xf[file]": newdflags ~= ""; break; - } + enforceBuildRequirements(settings); + + if (!fields & BuildSetting.options) { + foreach (t; s_options) + if (settings.options & t[0]) + settings.addDFlags(t[1]); } - settings.dflags = newdflags; - + if (!(fields & BuildSetting.libs)) resolveLibs(settings); @@ -96,6 +77,11 @@ settings.versions = null; } + if (!(fields & BuildSetting.debugVersions)) { + settings.addDFlags(settings.debugVersions.map!(s => "-fdebug="~s)().array()); + settings.debugVersions = null; + } + if (!(fields & BuildSetting.importPaths)) { settings.addDFlags(settings.importPaths.map!(s => "-I"~s)().array()); settings.importPaths = null; @@ -117,20 +103,26 @@ settings.lflags = null; } - if (settings.requirements & BuildRequirements.allowWarnings) { settings.removeDFlags("-Werror"); settings.addDFlags("-Wall"); } - if (settings.requirements & BuildRequirements.silenceWarnings) { settings.removeDFlags("-Werror", "-Wall"); } - if (settings.requirements & BuildRequirements.disallowDeprecations) { settings.addDFlags("-fdeprecated"); } - if (settings.requirements & BuildRequirements.silenceDeprecations) { settings.addDFlags("-fdeprecated"); } - if (settings.requirements & BuildRequirements.disallowInlining) { settings.removeDFlags("-finline-functions"); } - if (settings.requirements & BuildRequirements.disallowOptimization) { settings.removeDFlags("-O3"); } - if (settings.requirements & BuildRequirements.requireBoundsCheck) { settings.removeDFlags("-fno-bounds-check"); } - if (settings.requirements & BuildRequirements.requireContracts) { settings.removeDFlags("-frelease"); } - if (settings.requirements & BuildRequirements.relaxProperties) { settings.removeDFlags("-fproperty"); } - assert(fields & BuildSetting.dflags); assert(fields & BuildSetting.copyFiles); } + void extractBuildOptions(ref BuildSettings settings) + { + Appender!(string[]) newflags; + next_flag: foreach (f; settings.dflags) { + foreach (t; s_options) + if (t[1].canFind(f)) { + settings.options |= t[0]; + continue next_flag; + } + if (f.startsWith("-fversion=")) settings.addVersions(f[10 .. $]); + else if (f.startsWith("-fdebug=")) settings.addDebugVersions(f[8 .. $]); + else newflags ~= f; + } + settings.dflags = newflags.data; + } + void setTarget(ref BuildSettings settings, in BuildPlatform platform) { final switch (settings.targetType) { diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 3477fd4..57def93 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -17,9 +17,34 @@ import std.array; import std.conv; import std.exception; +import std.typecons; class LdcCompiler : Compiler { + private static immutable s_options = [ + tuple(BuildOptions.debug_, ["-d-debug"]), + tuple(BuildOptions.release, ["-release"]), + //tuple(BuildOptions.coverage, ["-?"]), + tuple(BuildOptions.debugInfo, ["-g"]), + tuple(BuildOptions.debugInfoC, ["-gc"]), + //tuple(BuildOptions.alwaysStackFrame, ["-?"]), + //tuple(BuildOptions.stackStomping, ["-?"]), + tuple(BuildOptions.inline, ["-enable-inlining"]), + tuple(BuildOptions.noBoundsChecks, ["-disable-boundscheck"]), + tuple(BuildOptions.optimize, ["-O"]), + //tuple(BuildOptions.profile, ["-?"]), + tuple(BuildOptions.unittests, ["-unittest"]), + tuple(BuildOptions.verbose, ["-v"]), + tuple(BuildOptions.ignoreUnknownPragmas, ["-ignore"]), + tuple(BuildOptions.syntaxOnly, ["-o-"]), + tuple(BuildOptions.warnings, ["-wi"]), + tuple(BuildOptions.warningsAsErrors, ["-w"]), + tuple(BuildOptions.ignoreDeprecations, ["-d"]), + tuple(BuildOptions.deprecationWarnings, ["-dw"]), + tuple(BuildOptions.deprecationErrors, ["-de"]), + tuple(BuildOptions.property, ["-property"]), + ]; + @property string name() const { return "ldc"; } BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) @@ -36,21 +61,13 @@ void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { - // convert common DMD flags to the corresponding GDC flags - string[] newdflags; - foreach (f; settings.dflags) { - switch (f) { - default: - if (f.startsWith("-debug=")) newdflags ~= "-d-debug="~f[7 .. $]; - else if (f.startsWith("-version=")) newdflags ~= "-d-version="~f[9 .. $]; - else newdflags ~= f; - break; - case "-debug": newdflags ~= "-d-debug"; break; - case "-inline": newdflags ~= "-enable-inlining"; break; - case "-noboundscheck": newdflags ~= "-disable-boundscheck"; break; - } + enforceBuildRequirements(settings); + + if (!fields & BuildSetting.options) { + foreach (t; s_options) + if (settings.options & t[0]) + settings.addDFlags(t[1]); } - settings.dflags = newdflags; // since LDC always outputs multiple object files, avoid conflicts by default settings.addDFlags("-oq", "-od=.dub/obj"); @@ -63,6 +80,11 @@ settings.versions = null; } + if (!(fields & BuildSetting.debugVersions)) { + settings.addDFlags(settings.debugVersions.map!(s => "-d-debug="~s)().array()); + settings.debugVersions = null; + } + if (!(fields & BuildSetting.importPaths)) { settings.addDFlags(settings.importPaths.map!(s => "-I"~s)().array()); settings.importPaths = null; @@ -83,20 +105,26 @@ settings.lflags = null; } - if (settings.requirements & BuildRequirements.allowWarnings) { settings.removeDFlags("-w"); settings.addDFlags("-wi"); } - if (settings.requirements & BuildRequirements.silenceWarnings) { settings.removeDFlags("-w", "-wi"); } - if (settings.requirements & BuildRequirements.disallowDeprecations) { settings.removeDFlags("-dw", "-d"); settings.addDFlags("-de"); } - if (settings.requirements & BuildRequirements.silenceDeprecations) { settings.removeDFlags("-dw", "-de"); settings.addDFlags("-d"); } - if (settings.requirements & BuildRequirements.disallowInlining) { settings.removeDFlags("-enable-inlining"); } - if (settings.requirements & BuildRequirements.disallowOptimization) { settings.removeDFlags("-O"); } - if (settings.requirements & BuildRequirements.requireBoundsCheck) { settings.removeDFlags("-disable-boundscheck"); } - if (settings.requirements & BuildRequirements.requireContracts) { settings.removeDFlags("-release"); } - if (settings.requirements & BuildRequirements.relaxProperties) { settings.removeDFlags("-property"); } - assert(fields & BuildSetting.dflags); assert(fields & BuildSetting.copyFiles); } + void extractBuildOptions(ref BuildSettings settings) + { + Appender!(string[]) newflags; + next_flag: foreach (f; settings.dflags) { + foreach (t; s_options) + if (t[1].canFind(f)) { + settings.options |= t[0]; + continue next_flag; + } + if (f.startsWith("-d-version=")) settings.addVersions(f[11 .. $]); + else if (f.startsWith("-d-debug=")) settings.addDebugVersions(f[9 .. $]); + else newflags ~= f; + } + settings.dflags = newflags.data; + } + void setTarget(ref BuildSettings settings, in BuildPlatform platform) { final switch (settings.targetType) { diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index c12215d..0581c73 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -46,7 +46,7 @@ m_project.addBuildSettings(buildsettings, settings.platform, settings.config); m_project.addBuildTypeSettings(buildsettings, settings.platform, settings.buildType); - auto generate_binary = !buildsettings.dflags.canFind("-o-"); + auto generate_binary = !(buildsettings.options & BuildOptions.syntaxOnly); auto is_static_library = buildsettings.targetType == TargetType.staticLibrary || buildsettings.targetType == TargetType.library; // make paths relative to shrink the command line diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d index 579dde2..1e72ba8 100644 --- a/source/dub/generators/visuald.d +++ b/source/dub/generators/visuald.d @@ -189,9 +189,8 @@ auto projName = pack.name; auto project_file_dir = m_app.mainPackage.path ~ projFileName(pack).parentPath; - ret.formattedWrite( -" - %s", guid(projName)); + ret.put("\n"); + ret.formattedWrite(" %s\n", guid(projName)); // Several configurations (debug, release, unittest) generateProjectConfiguration(ret, pack, "debug", settings); @@ -234,7 +233,7 @@ } // Create folders and files - ret.formattedWrite("\n ", getPackageFileName(pack)); + ret.formattedWrite(" ", getPackageFileName(pack)); Path lastFolder; foreach(source; sortedSources(sourceFiles.keys)) { logDebug("source looking at %s", source.structurePath); @@ -275,9 +274,8 @@ auto buildsettings = settings.buildSettings; auto pbuildsettings = pack.getBuildSettings(settings.platform, configs[pack.name]); m_app.addBuildSettings(buildsettings, settings.platform, settings.config, pack); - - BuildSettings btsettings; m_app.addBuildTypeSettings(buildsettings, settings.platform, type); + settings.compiler.extractBuildOptions(buildsettings); string[] getSettings(string setting)(){ return __traits(getMember, buildsettings, setting); } string[] getPathSettings(string setting)() @@ -295,17 +293,15 @@ case "x86": arch = "Win32"; break; case "x86_64": arch = "x64"; break; } - ret.formattedWrite(" - \n", to!string(type), arch); + ret.formattedWrite(" \n", to!string(type), arch); // FIXME: handle compiler options in an abstract way instead of searching for DMD specific flags // debug and optimize setting - string[] special_flags = ["-w", "-debug", "-g", "-O", "-inline", "-release", "-unittest"]; - ret.formattedWrite(" %s\n", btsettings.dflags.canFind("-g") ? "1" : "0"); - ret.formattedWrite(" %s\n", btsettings.dflags.canFind("-O") ? "1" : "0"); - ret.formattedWrite(" %s\n", btsettings.dflags.canFind("-inline") ? "1" : "0"); - ret.formattedWrite(" %s\n", btsettings.dflags.canFind("-release") ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.debugInfo ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.optimize ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.inline ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.release ? "1" : "0"); // Lib or exe? bool is_lib = pbuildsettings.targetType != TargetType.executable; @@ -318,30 +314,23 @@ // include paths and string imports string imports = join(getPathSettings!"importPaths"(), " "); string stringImports = join(getPathSettings!"stringImportPaths"(), " "); - ret.formattedWrite(" %s - %s", imports, stringImports); + ret.formattedWrite(" %s\n", imports); + ret.formattedWrite(" %s\n", stringImports); - // Compiler? - string compiler = "$(DMDInstallDir)windows\\bin\\dmd.exe"; - string dflags = getSettings!"dflags"().filter!(f => !special_flags.canFind(f)).join(" "); - ret.formattedWrite(" - %s - %s", compiler, dflags); + ret.formattedWrite(" %s\n", "$(DMDInstallDir)windows\\bin\\dmd.exe"); // FIXME: use the actually selected compiler! + ret.formattedWrite(" %s\n", getSettings!"dflags"().join(" ")); // Add version identifiers string versions = join(getSettings!"versions"(), " "); - ret.formattedWrite(" - %s", versions); + ret.formattedWrite(" %s\n", versions); // Add libraries, system libs need to be suffixed by ".lib". string linkLibs = join(map!(a => a~".lib")(getSettings!"libs"()), " "); string addLinkFiles = join(getSettings!"sourceFiles"().filter!(s => s.endsWith(".lib"))(), " "); - ret.formattedWrite(" - %s %s phobos.lib", linkLibs, addLinkFiles); + ret.formattedWrite(" %s %s phobos.lib\n", linkLibs, addLinkFiles); // Unittests - ret.formattedWrite(" - %s", btsettings.dflags.canFind("-unittest") ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.unittests ? "1" : "0"); // compute directory for intermediate files (need dummy/ because of how -op determines the resulting path) auto relpackpath = pack.path.relativeTo(project_file_dir); @@ -350,89 +339,84 @@ if (relpackpath[i] == "..") ndummy++; string intersubdir = (ndummy*2 > relpackpath.length ? replicate("dummy/", ndummy*2-relpackpath.length) : "") ~ getPackageFileName(pack); - // Not yet dynamic stuff - ret.formattedWrite(" - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - 0 - 0 - 0 -"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 2\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.verbose ? "1" : "0"); + ret.put(" 0\n"); + ret.put(" 0\n"); ret.formattedWrite(" %s\n", arch == "x64" ? 1 : 0); -ret.formattedWrite( -" 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 2 - 0\n"); - ret.formattedWrite(" %s\n", settings.compiler.name == "ldc" ? 2 : settings.compiler.name == "gdc" ? 1 : 0); - ret.formattedWrite(" 0\n"); - ret.formattedWrite(" %s\n", bin_path.toNativeString()); - ret.formattedWrite(" .dub/obj/%s/%s\n", to!string(type), intersubdir); - ret.formattedWrite("%s", -" - - 0 - - - - - 0 - - - 1 - $(IntDir)\\$(TargetName).json - 0 - 0 - - 0 - 0 - 0 - - - - 0 - - 1 - $(VisualDInstallDir)cv2pdb\\cv2pdb.exe - 0 - 0 - 0 - - - - - - - - - *.obj;*.cmd;*.build;*.dep - "); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.noBoundsChecks ? "1" : "0"); + ret.put(" 0\n"); + ret.put(" 1\n"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.warningsAsErrors ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.warnings ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.property ? "1" : "0"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.alwaysStackFrame ? "1" : "0"); + ret.put(" 0\n"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.coverage ? "1" : "0"); + ret.put(" 0\n"); + ret.put(" 2\n"); + ret.formattedWrite(" %s\n", buildsettings.options & BuildOptions.ignoreUnknownPragmas ? "1" : "0"); + ret.formattedWrite(" %s\n", settings.compiler.name == "ldc" ? 2 : settings.compiler.name == "gdc" ? 1 : 0); + ret.formattedWrite(" 0\n"); + ret.formattedWrite(" %s\n", bin_path.toNativeString()); + ret.formattedWrite(" .dub/obj/%s/%s\n", to!string(type), intersubdir); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" 1\n"); + ret.put(" $(IntDir)\\$(TargetName).json\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" 1\n"); + ret.put(" $(VisualDInstallDir)cv2pdb\\cv2pdb.exe\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" 0\n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" \n"); + ret.put(" *.obj;*.cmd;*.build;*.dep\n"); + ret.put(" \n"); } // foreach(architecture) } @@ -471,6 +455,7 @@ string pkg; Path structurePath; Path filePath; + bool build = true; int opCmp(ref const SourceFile rhs) const { return sortOrder(this, rhs); } // "a < b" for folder structures (deepest folder first, else lexical) diff --git a/source/dub/package_.d b/source/dub/package_.d index ee64a5a..8717773 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -186,7 +186,13 @@ if( conf.name != config ) continue; m_info.buildSettings.getPlatformSettings(ret, platform, this.path); conf.buildSettings.getPlatformSettings(ret, platform, this.path); + + // construct default target name based on package name if( ret.targetName.empty ) ret.targetName = this.name.replace(":", "_"); + + // special support for DMD style flags + getCompiler("dmd").extractBuildOptions(ret); + return ret; } assert(config is null, "Unknown configuration for "~m_info.name~": "~config); @@ -205,17 +211,17 @@ if (auto pbt = build_type in m_info.buildTypes) { pbt.getPlatformSettings(settings, platform, this.path); } else { - switch (build_type) { + with(BuildOptions) switch (build_type) { default: throw new Exception(format("Unknown build type for %s: %s", this.name, build_type)); case "plain": break; - case "debug": settings.addDFlags("-g", "-debug"); break; - case "release": settings.addDFlags("-release", "-O", "-inline"); break; - case "unittest": settings.addDFlags("-g", "-debug", "-unittest"); break; - case "docs": settings.addDFlags("-c", "-o-", "-D", "-Dddocs"); break; - case "ddox": settings.addDFlags("-c", "-o-", "-D", "-Df__dummy.html", "-Xfdocs.json"); break; - case "profile": settings.addDFlags("-g", "-O", "-inline", "-profile"); break; - case "cov": settings.addDFlags("-g", "-cov"); break; - case "unittest-cov": settings.addDFlags("-g", "-debug", "-unittest", "-cov"); break; + case "debug": settings.addOptions(debug_, debugInfo); break; + case "release": settings.addOptions(release, optimize, inline); break; + case "unittest": settings.addOptions(unittests, debug_, debugInfo); break; + case "docs": settings.addOptions(BuildOptions.syntaxOnly); settings.addDFlags("-c", "-Dddocs"); break; + case "ddox": settings.addOptions(BuildOptions.syntaxOnly); settings.addDFlags("-c", "-Df__dummy.html", "-Xfdocs.json"); break; + case "profile": settings.addOptions(profile, optimize, inline, debugInfo); break; + case "cov": settings.addOptions(coverage, debugInfo); break; + case "unittest-cov": settings.addOptions(unittests, coverage, debug_, debugInfo); break; } } } @@ -469,6 +475,7 @@ string[][string] excludedSourceFiles; string[][string] copyFiles; string[][string] versions; + string[][string] debugVersions; string[][string] importPaths; string[][string] stringImportPaths; string[][string] preGenerateCommands; @@ -476,6 +483,7 @@ string[][string] preBuildCommands; string[][string] postBuildCommands; BuildRequirements[string] buildRequirements; + BuildOptions[string] buildOptions; void parseJson(Json json) { @@ -544,6 +552,7 @@ case "excludedSourceFiles": this.excludedSourceFiles[suffix] = deserializeJson!(string[])(value); break; case "copyFiles": this.copyFiles[suffix] = deserializeJson!(string[])(value); break; case "versions": this.versions[suffix] = deserializeJson!(string[])(value); break; + case "debugVersions": this.debugVersions[suffix] = deserializeJson!(string[])(value); break; case "importPaths": this.importPaths[suffix] = deserializeJson!(string[])(value); break; case "stringImportPaths": this.stringImportPaths[suffix] = deserializeJson!(string[])(value); break; case "preGenerateCommands": this.preGenerateCommands[suffix] = deserializeJson!(string[])(value); break; @@ -556,6 +565,12 @@ reqs |= to!BuildRequirements(req); this.buildRequirements[suffix] = reqs; break; + case "buildOptions": + BuildOptions options; + foreach (opt; deserializeJson!(string[])(value)) + options |= to!BuildOptions(opt); + this.buildOptions[suffix] = options; + break; } } } @@ -590,6 +605,7 @@ foreach (suffix, arr; excludedSourceFiles) ret["excludedSourceFiles"~suffix] = serializeToJson(arr); foreach (suffix, arr; copyFiles) ret["copyFiles"~suffix] = serializeToJson(arr); foreach (suffix, arr; versions) ret["versions"~suffix] = serializeToJson(arr); + foreach (suffix, arr; debugVersions) ret["debugVersions"~suffix] = serializeToJson(arr); foreach (suffix, arr; importPaths) ret["importPaths"~suffix] = serializeToJson(arr); foreach (suffix, arr; stringImportPaths) ret["stringImportPaths"~suffix] = serializeToJson(arr); foreach (suffix, arr; preGenerateCommands) ret["preGenerateCommands"~suffix] = serializeToJson(arr); @@ -602,6 +618,12 @@ if (arr & i) val ~= to!string(i); ret["buildRequirements"~suffix] = serializeToJson(val); } + foreach (suffix, arr; buildOptions) { + string[] val; + foreach (i; [EnumMembers!BuildOptions]) + if (arr & i) val ~= to!string(i); + ret["buildOptions"~suffix] = serializeToJson(val); + } return ret; } @@ -640,6 +662,7 @@ getPlatformSetting!("excludedSourceFiles", "removeSourceFiles")(dst, platform); getPlatformSetting!("copyFiles", "addCopyFiles")(dst, platform); getPlatformSetting!("versions", "addVersions")(dst, platform); + getPlatformSetting!("debugVersions", "addDebugVersions")(dst, platform); getPlatformSetting!("importPaths", "addImportPaths")(dst, platform); getPlatformSetting!("stringImportPaths", "addStringImportPaths")(dst, platform); getPlatformSetting!("preGenerateCommands", "addPreGenerateCommands")(dst, platform); @@ -647,6 +670,7 @@ getPlatformSetting!("preBuildCommands", "addPreBuildCommands")(dst, platform); getPlatformSetting!("postBuildCommands", "addPostBuildCommands")(dst, platform); getPlatformSetting!("buildRequirements", "addRequirements")(dst, platform); + getPlatformSetting!("buildOptions", "addOptions")(dst, platform); } void getPlatformSetting(string name, string addname)(ref BuildSettings dst, in BuildPlatform platform) diff --git a/source/dub/project.d b/source/dub/project.d index 4c31e27..54e967c 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -277,7 +277,6 @@ { bool usedefflags = !(dst.requirements & BuildRequirements.noDefaultFlags); if (usedefflags) { - dst.addDFlags(["-w"]); BuildSettings btsettings; m_main.addBuildTypeSettings(btsettings, platform, build_type); processVars(dst, m_main.path.toNativeString(), btsettings); @@ -581,6 +580,7 @@ dst.addSourceFiles(processVars(project_path, settings.sourceFiles, true)); dst.addCopyFiles(processVars(project_path, settings.copyFiles, true)); dst.addVersions(processVars(project_path, settings.versions)); + dst.addDebugVersions(processVars(project_path, settings.debugVersions)); dst.addImportPaths(processVars(project_path, settings.importPaths, true)); dst.addStringImportPaths(processVars(project_path, settings.stringImportPaths, true)); dst.addPreGenerateCommands(processVars(project_path, settings.preGenerateCommands)); @@ -588,6 +588,7 @@ dst.addPreBuildCommands(processVars(project_path, settings.preBuildCommands)); dst.addPostBuildCommands(processVars(project_path, settings.postBuildCommands)); dst.addRequirements(settings.requirements); + dst.addOptions(settings.options); } private string[] processVars(string project_path, string[] vars, bool are_paths = false)