diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index bd86769..0a47c15 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -134,8 +134,10 @@ string[] postGenerateCommands; string[] preBuildCommands; string[] postBuildCommands; + BuildRequirements requirements; void addDFlags(in string[] value...) { add(dflags, value); } + void removeDFlags(in string[] value...) { remove(dflags, value); } void addLFlags(in string[] value...) { add(lflags, value); } void addLibs(in string[] value...) { add(libs, value); } void addSourceFiles(in string[] value...) { add(sourceFiles, value); } @@ -148,31 +150,45 @@ void addPostGenerateCommands(in string[] value...) { add(postGenerateCommands, value, false); } 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; } // Adds vals to arr without adding duplicates. private void add(ref string[] arr, in string[] vals, bool no_duplicates = true) { - if( !no_duplicates ){ + if (!no_duplicates) { arr ~= vals; return; } - foreach( v; vals ){ + foreach (v; vals) { bool found = false; - foreach( i; 0 .. arr.length ) - if( arr[i] == v ){ + foreach (i; 0 .. arr.length) + if (arr[i] == v) { found = true; break; } - if( !found ) arr ~= v; + if (!found) arr ~= v; } } private void removePaths(ref string[] arr, in string[] vals) { - bool matches(string s){ - foreach( p; vals ) - if( Path(s) == Path(p) ) + bool matches(string s) + { + foreach (p; vals) + if (Path(s) == Path(p)) + return true; + return false; + } + arr = arr.filter!(s => !matches(s))().array(); + } + + private void remove(ref string[] arr, in string[] vals) + { + bool matches(string s) + { + foreach (p; vals) + if (s == p) return true; return false; } @@ -269,6 +285,19 @@ staticLibrary } +enum BuildRequirements { + none = 0, /// No special requirements + allowWarnings = 1<<0, /// Warnings do not abort compilation + silenceWarnings = 1<<1, /// Don't show warnings + disallowDeprecations = 1<<2, /// Using deprecated features aborts compilation + silenceDeprecations = 1<<3, /// Don't show deprecation warnings + disallowInlining = 1<<4, /// Avoid function inlining, even in release builds + disallowOptimization = 1<<5, /// Avoid optimizations, even in release builds + requireBoundsCheck = 1<<6, /// Always perform bounds checks + requireContracts = 1<<7, /// Leave assertions and contracts enabled in release builds + relaxProperties = 1<<8, /// Do not enforce strict property handling (-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 aeafb46..1379cd1 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -87,6 +87,16 @@ 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); } diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 1afbd2f..5a71515 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -128,6 +128,16 @@ 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); } diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 9aff585..3fecfa8 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -84,6 +84,16 @@ 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); } diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index be1ee4e..64b639a 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -45,7 +45,7 @@ auto buildsettings = settings.buildSettings; m_project.addBuildSettings(buildsettings, settings.platform, settings.config); - buildsettings.addDFlags(["-w"/*, "-property"*/]); + buildsettings.addDFlags(["-w", "-property"]); string dflags = environment.get("DFLAGS"); if( dflags.length ){ settings.buildType = "$DFLAGS"; diff --git a/source/dub/package_.d b/source/dub/package_.d index e1ceda8..32d72c5 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -18,6 +18,7 @@ import std.file; import std.range; import std.string; +import std.traits : EnumMembers; import vibecompat.core.log; import vibecompat.core.file; import vibecompat.data.json; @@ -411,6 +412,7 @@ string[][string] postGenerateCommands; string[][string] preBuildCommands; string[][string] postBuildCommands; + BuildRequirements[string] buildRequirements; void parseJson(Json json) { @@ -454,6 +456,12 @@ case "postGenerateCommands": this.postGenerateCommands[suffix] = deserializeJson!(string[])(value); break; case "preBuildCommands": this.preBuildCommands[suffix] = deserializeJson!(string[])(value); break; case "postBuildCommands": this.postBuildCommands[suffix] = deserializeJson!(string[])(value); break; + case "buildRequirements": + BuildRequirements reqs; + foreach (req; deserializeJson!(string[])(value)) + reqs |= to!BuildRequirements(req); + this.buildRequirements[suffix] = reqs; + break; } } } @@ -461,23 +469,29 @@ Json toJson() const { auto ret = Json.EmptyObject; - if( targetType != TargetType.autodetect ) ret["targetType"] = targetType.to!string(); - if( !targetPath.empty ) ret["targetPath"] = targetPath; - if( !targetName.empty ) ret["targetName"] = targetPath; - foreach(suffix, arr; dflags) ret["dflags"~suffix] = serializeToJson(arr); - foreach(suffix, arr; lflags) ret["lflags"~suffix] = serializeToJson(arr); - foreach(suffix, arr; libs) ret["libs"~suffix] = serializeToJson(arr); - foreach(suffix, arr; sourceFiles) ret["sourceFiles"~suffix] = serializeToJson(arr); - foreach(suffix, arr; sourcePaths) ret["sourcePaths"~suffix] = serializeToJson(arr); - 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; importPaths) ret["importPaths"~suffix] = serializeToJson(arr); - foreach(suffix, arr; stringImportPaths) ret["stringImportPaths"~suffix] = serializeToJson(arr); - foreach(suffix, arr; preGenerateCommands) ret["preGenerateCommands"~suffix] = serializeToJson(arr); - foreach(suffix, arr; postGenerateCommands) ret["postGenerateCommands"~suffix] = serializeToJson(arr); - foreach(suffix, arr; preBuildCommands) ret["preBuildCommands"~suffix] = serializeToJson(arr); - foreach(suffix, arr; postBuildCommands) ret["postBuildCommands"~suffix] = serializeToJson(arr); + if (targetType != TargetType.autodetect) ret["targetType"] = targetType.to!string(); + if (!targetPath.empty) ret["targetPath"] = targetPath; + if (!targetName.empty) ret["targetName"] = targetPath; + foreach (suffix, arr; dflags) ret["dflags"~suffix] = serializeToJson(arr); + foreach (suffix, arr; lflags) ret["lflags"~suffix] = serializeToJson(arr); + foreach (suffix, arr; libs) ret["libs"~suffix] = serializeToJson(arr); + foreach (suffix, arr; sourceFiles) ret["sourceFiles"~suffix] = serializeToJson(arr); + foreach (suffix, arr; sourcePaths) ret["sourcePaths"~suffix] = serializeToJson(arr); + 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; importPaths) ret["importPaths"~suffix] = serializeToJson(arr); + foreach (suffix, arr; stringImportPaths) ret["stringImportPaths"~suffix] = serializeToJson(arr); + foreach (suffix, arr; preGenerateCommands) ret["preGenerateCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; postGenerateCommands) ret["postGenerateCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; preBuildCommands) ret["preBuildCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; postBuildCommands) ret["postBuildCommands"~suffix] = serializeToJson(arr); + foreach (suffix, arr; buildRequirements) { + string[] val; + foreach (i; [EnumMembers!BuildRequirements]) + if (arr & i) val ~= to!string(i); + ret["buildRequirements"~suffix] = serializeToJson(val); + } return ret; } @@ -520,6 +534,7 @@ getPlatformSetting!("postGenerateCommands", "addPostGenerateCommands")(dst, platform); getPlatformSetting!("preBuildCommands", "addPreBuildCommands")(dst, platform); getPlatformSetting!("postBuildCommands", "addPostBuildCommands")(dst, platform); + getPlatformSetting!("buildRequirements", "addRequirements")(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 6c9a6de..d9e22be 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -592,6 +592,7 @@ dst.addPostGenerateCommands(processVars(project_path, settings.postGenerateCommands)); dst.addPreBuildCommands(processVars(project_path, settings.preBuildCommands)); dst.addPostBuildCommands(processVars(project_path, settings.postBuildCommands)); + dst.addRequirements(settings.requirements); } private string[] processVars(string project_path, string[] vars, bool are_paths = false)