diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 24d2b1b..cee924a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -48,7 +48,7 @@ # Compiler to test with - name: Prepare compiler - uses: mihails-strasuns/setup-dlang@v1 + uses: dlang-community/setup-dlang@v1 with: compiler: ${{ matrix.dc }} diff --git a/changelog/pdb.dd b/changelog/pdb.dd new file mode 100644 index 0000000..c16cabb --- /dev/null +++ b/changelog/pdb.dd @@ -0,0 +1,5 @@ +Windows: Copy PDB files to `targetPath`, alongside executable/DLL + +If the default PDB file is generated when linking an executable or DLL +(e.g., no `/PDB:my\path.pdb` lflag), it is now copied to the target +directory too. diff --git a/source/dub/commandline.d b/source/dub/commandline.d index 5b62fe6..6d0bc45 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -28,7 +28,7 @@ import std.exception; import std.file; import std.getopt; -import std.path : absolutePath, buildNormalizedPath; +import std.path : expandTilde, absolutePath, buildNormalizedPath; import std.process; import std.stdio; import std.string; @@ -161,7 +161,7 @@ } else { - options.root_path = options.root_path.absolutePath.buildNormalizedPath; + options.root_path = options.root_path.expandTilde.absolutePath.buildNormalizedPath; } } @@ -950,7 +950,7 @@ args.getopt("b|build", &m_buildType, [ "Specifies the type of build to perform. Note that setting the DFLAGS environment variable will override the build type with custom flags.", "Possible names:", - " debug (default), plain, release, release-debug, release-nobounds, unittest, profile, profile-gc, docs, ddox, cov, unittest-cov, syntax and custom types" + " "~builtinBuildTypes.join(", ")~" and custom types" ]); args.getopt("c|config", &m_buildConfig, [ "Builds the specified configuration. Configurations can be defined in dub.json" @@ -1148,10 +1148,10 @@ setupVersionPackage(dub, str_package_info, "debug"); - if (m_printBuilds) { // FIXME: use actual package data + if (m_printBuilds) { logInfo("Available build types:"); - foreach (tp; ["debug", "release", "unittest", "profile"]) - logInfo(" %s", tp); + foreach (i, tp; dub.project.builds) + logInfo(" %s%s", tp, i == 0 ? " [default]" : null); logInfo(""); } @@ -2280,6 +2280,9 @@ string m_testPackage; bool m_combined; bool m_noRedirect; + string m_strategy; + uint m_jobCount; // zero means not specified + bool m_trace; } this() @safe pure nothrow @@ -2308,6 +2311,9 @@ args.getopt("test-package", &m_testPackage, ["Perform a test run - usually only used internally"]); args.getopt("combined", &m_combined, ["Builds multiple packages with one compiler run"]); args.getopt("no-redirect", &m_noRedirect, ["Don't redirect stdout/stderr streams of the test command"]); + args.getopt("strategy", &m_strategy, ["Set strategy (careful/lookback/pingpong/indepth/inbreadth)"]); + args.getopt("j", &m_jobCount, ["Set number of look-ahead processes"]); + args.getopt("trace", &m_trace, ["Save all attempted reductions to DIR.trace"]); super.prepare(args); // speed up loading when in test mode @@ -2445,6 +2451,10 @@ string[] extraArgs; if (m_noRedirect) extraArgs ~= "--no-redirect"; + if (m_strategy.length) extraArgs ~= "--strategy=" ~ m_strategy; + if (m_jobCount) extraArgs ~= "-j" ~ m_jobCount.to!string; + if (m_trace) extraArgs ~= "--trace"; + const cmd = "dustmite" ~ extraArgs ~ [path.toNativeString(), testcmd.data]; auto dmpid = spawnProcess(cmd); return dmpid.wait(); diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index 72e0aeb..bb62e16 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -19,13 +19,31 @@ import std.exception; import std.process; +/// Exception thrown in Compiler.determinePlatform if the given architecture is +/// not supported. +class UnsupportedArchitectureException : Exception +{ + this(string architecture, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null) pure nothrow @safe + { + super("Unsupported architecture: "~architecture, file, line, nextInChain); + } +} + +/// Exception thrown in getCompiler if no compiler matches the given name. +class UnknownCompilerException : Exception +{ + this(string compilerName, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null) pure nothrow @safe + { + super("Unknown compiler: "~compilerName, file, line, nextInChain); + } +} /** Returns a compiler handler for a given binary name. The name will be compared against the canonical name of each registered compiler handler. If no match is found, the sub strings "dmd", "gdc" and "ldc", in this order, will be searched within the name. If this doesn't - yield a match either, an exception will be thrown. + yield a match either, an $(LREF UnknownCompilerException) will be thrown. */ Compiler getCompiler(string name) { @@ -38,7 +56,7 @@ if (name.canFind("gdc")) return getCompiler("gdc"); if (name.canFind("ldc")) return getCompiler("ldc"); - throw new Exception("Unknown compiler: "~name); + throw new UnknownCompilerException(name); } /** Registers a new compiler handler. diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index 1263f13..d92d045 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -108,7 +108,7 @@ { string[] arch_flags; switch (arch_override) { - default: throw new Exception("Unsupported architecture: "~arch_override); + default: throw new UnsupportedArchitectureException(arch_override); case "": // Don't use Optlink by default on Windows version (Windows) { diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 4f2afcd..f0fd762 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -67,7 +67,7 @@ { string[] arch_flags; switch (arch_override) { - default: throw new Exception("Unsupported architecture: "~arch_override); + default: throw new UnsupportedArchitectureException(arch_override); case "": break; case "arm": arch_flags = ["-marm"]; break; case "arm_thumb": arch_flags = ["-mthumb"]; break; diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 5ddabe7..1ab5019 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -88,7 +88,7 @@ if (arch_override.canFind('-')) arch_flags = ["-mtriple="~arch_override]; else - throw new Exception("Unsupported architecture: "~arch_override); + throw new UnsupportedArchitectureException(arch_override); break; } settings.addDFlags(arch_flags); diff --git a/source/dub/dependency.d b/source/dub/dependency.d index f41c458..52dc3ee 100644 --- a/source/dub/dependency.d +++ b/source/dub/dependency.d @@ -776,7 +776,7 @@ */ @property string remote() @nogc nothrow pure @safe in { assert(m_remote !is null); } - body + do { return m_remote; } diff --git a/source/dub/dub.d b/source/dub/dub.d index 4b8711a..1b71bd7 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -142,7 +142,7 @@ string[string] m_defaultPostBuildEnvironments; string[string] m_defaultPreRunEnvironments; string[string] m_defaultPostRunEnvironments; - + } /** The default placement location of fetched packages. @@ -359,7 +359,7 @@ configuration file will be used. Otherwise false will be returned. */ @property bool defaultLowMemory() const { return m_defaultLowMemory; } - + @property const(string[string]) defaultEnvironments() const { return m_defaultEnvironments; } @property const(string[string]) defaultBuildEnvironments() const { return m_defaultBuildEnvironments; } @property const(string[string]) defaultRunEnvironments() const { return m_defaultRunEnvironments; } @@ -663,6 +663,7 @@ BuildSettings lbuildsettings = settings.buildSettings; m_project.addBuildSettings(lbuildsettings, settings, config, null, true); + if (lbuildsettings.targetType == TargetType.none) { logInfo(`Configuration '%s' has target type "none". Skipping test.`, config); return; @@ -1514,7 +1515,7 @@ } m_defaultCompiler = compilers[0]; } - + unittest { import std.path: buildPath, absolutePath; @@ -1532,10 +1533,10 @@ scope (exit) repairenv("DC", olddc); scope (exit) repairenv("PATH", oldpath); scope (exit) rmdirRecurse(testdir); - + version (Windows) enum sep = ";", exe = ".exe"; version (Posix) enum sep = ":", exe = ""; - + immutable dmdpath = testdir.buildPath("dmd", "bin"); immutable ldcpath = testdir.buildPath("ldc", "bin"); mkdirRecurse(dmdpath); @@ -1544,21 +1545,21 @@ immutable ldcbin = ldcpath.buildPath("ldc2"~exe); std.file.write(dmdbin, null); std.file.write(ldcbin, null); - + environment["DC"] = dmdbin.absolutePath(); dub.determineDefaultCompiler(); assert(dub.m_defaultCompiler == dmdbin.absolutePath()); - + environment["DC"] = "dmd"; environment["PATH"] = dmdpath ~ sep ~ ldcpath; dub.determineDefaultCompiler(); assert(dub.m_defaultCompiler == "dmd"); - + environment["DC"] = "ldc2"; environment["PATH"] = dmdpath ~ sep ~ ldcpath; dub.determineDefaultCompiler(); assert(dub.m_defaultCompiler == "ldc2"); - + environment.remove("DC"); environment["PATH"] = ldcpath ~ sep ~ dmdpath; dub.determineDefaultCompiler(); @@ -1970,7 +1971,7 @@ if (m_parentConfig) return m_parentConfig.defaultLowMemory; return false; } - + @property string[string] defaultEnvironments() const { if (auto pv = "defaultEnvironments" in m_data) @@ -1978,7 +1979,7 @@ if (m_parentConfig) return m_parentConfig.defaultEnvironments; return null; } - + @property string[string] defaultBuildEnvironments() const { if (auto pv = "defaultBuildEnvironments" in m_data) @@ -1986,7 +1987,7 @@ if (m_parentConfig) return m_parentConfig.defaultBuildEnvironments; return null; } - + @property string[string] defaultRunEnvironments() const { if (auto pv = "defaultRunEnvironments" in m_data) @@ -1994,7 +1995,7 @@ if (m_parentConfig) return m_parentConfig.defaultRunEnvironments; return null; } - + @property string[string] defaultPreGenerateEnvironments() const { if (auto pv = "defaultPreGenerateEnvironments" in m_data) @@ -2002,7 +2003,7 @@ if (m_parentConfig) return m_parentConfig.defaultPreGenerateEnvironments; return null; } - + @property string[string] defaultPostGenerateEnvironments() const { if (auto pv = "defaultPostGenerateEnvironments" in m_data) @@ -2010,7 +2011,7 @@ if (m_parentConfig) return m_parentConfig.defaultPostGenerateEnvironments; return null; } - + @property string[string] defaultPreBuildEnvironments() const { if (auto pv = "defaultPreBuildEnvironments" in m_data) @@ -2018,7 +2019,7 @@ if (m_parentConfig) return m_parentConfig.defaultPreBuildEnvironments; return null; } - + @property string[string] defaultPostBuildEnvironments() const { if (auto pv = "defaultPostBuildEnvironments" in m_data) @@ -2026,7 +2027,7 @@ if (m_parentConfig) return m_parentConfig.defaultPostBuildEnvironments; return null; } - + @property string[string] defaultPreRunEnvironments() const { if (auto pv = "defaultPreRunEnvironments" in m_data) @@ -2034,7 +2035,7 @@ if (m_parentConfig) return m_parentConfig.defaultPreRunEnvironments; return null; } - + @property string[string] defaultPostRunEnvironments() const { if (auto pv = "defaultPostRunEnvironments" in m_data) diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index 2f6f611..4251789 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -371,12 +371,30 @@ private void copyTargetFile(NativePath build_path, BuildSettings buildsettings, GeneratorSettings settings) { - auto filename = settings.compiler.getTargetFileName(buildsettings, settings.platform); - auto src = build_path ~ filename; - logDiagnostic("Copying target from %s to %s", src.toNativeString(), buildsettings.targetPath); if (!existsFile(NativePath(buildsettings.targetPath))) mkdirRecurse(buildsettings.targetPath); - hardLinkFile(src, NativePath(buildsettings.targetPath) ~ filename, true); + + string[] filenames = [ + settings.compiler.getTargetFileName(buildsettings, settings.platform) + ]; + + // Windows: add .pdb if found + const tt = buildsettings.targetType; + if ((tt == TargetType.executable || tt == TargetType.dynamicLibrary) && + settings.platform.platform.canFind("windows")) + { + import std.path : setExtension; + const pdbFilename = filenames[0].setExtension(".pdb"); + if (existsFile(build_path ~ pdbFilename)) + filenames ~= pdbFilename; + } + + foreach (filename; filenames) + { + auto src = build_path ~ filename; + logDiagnostic("Copying target from %s to %s", src.toNativeString(), buildsettings.targetPath); + hardLinkFile(src, NativePath(buildsettings.targetPath) ~ filename, true); + } } private bool isUpToDate(NativePath target_path, BuildSettings buildsettings, GeneratorSettings settings, in Package main_pack, in Package[] packages, in NativePath[] additional_dep_files) diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index cba8f09..2c87ee9 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -383,45 +383,21 @@ visited.clear(); // 1. downwards inherits versions, debugVersions, and inheritable build settings - static void configureDependencies(const scope ref TargetInfo ti, TargetInfo[string] targets, - BuildSettings[string] dependBS, size_t level = 0) + static void configureDependencies(const scope ref TargetInfo ti, TargetInfo[string] targets, size_t level = 0) { - static void applyForcedSettings(const scope ref BuildSettings forced, ref BuildSettings child) { - child.addDFlags(forced.dflags); - } - // do not use `visited` here as dependencies must inherit // configurations from *all* of their parents logDebug("%sConfigure dependencies of %s, deps:%(%s, %)", ' '.repeat(2 * level), ti.pack.name, ti.dependencies); foreach (depname; ti.dependencies) { - BuildSettings forcedSettings; auto pti = &targets[depname]; mergeFromDependent(ti.buildSettings, pti.buildSettings); - - if (auto matchedSettings = depname in dependBS) - forcedSettings = *matchedSettings; - else if (auto matchedSettings = "*" in dependBS) - forcedSettings = *matchedSettings; - - applyForcedSettings(forcedSettings, pti.buildSettings); - configureDependencies(*pti, targets, ["*" : forcedSettings], level + 1); + configureDependencies(*pti, targets, level + 1); } } - BuildSettings[string] dependencyBuildSettings; - foreach (key, value; rootPackage.recipe.buildSettings.dependencyBuildSettings) - { - BuildSettings buildSettings; - if (auto target = key in targets) - { - value.getPlatformSettings(buildSettings, genSettings.platform, target.pack.path); - buildSettings.processVars(m_project, target.pack, buildSettings, genSettings, true); - dependencyBuildSettings[key] = buildSettings; - } - } - configureDependencies(*roottarget, targets, dependencyBuildSettings); + configureDependencies(*roottarget, targets); // 2. add Have_dependency_xyz for all direct dependencies of a target // (includes incorporated non-target dependencies and their dependencies) @@ -529,6 +505,54 @@ overrideStringImports(targets[depname], *roottarget, targets, roottarget.buildSettings.stringImportFiles); + // 6. downwards inherits dependency build settings + static void applyForcedSettings(const scope ref TargetInfo ti, TargetInfo[string] targets, + BuildSettings[string] dependBS, size_t level = 0) + { + + static void apply(const scope ref BuildSettings forced, ref BuildSettings child) { + child.addDFlags(forced.dflags); + } + + // apply to all dependencies + foreach (depname; ti.dependencies) + { + BuildSettings forcedSettings; + auto pti = &targets[depname]; + + // fetch the forced dependency build settings + if (auto matchedSettings = depname in dependBS) + forcedSettings = *matchedSettings; + else if (auto matchedSettings = "*" in dependBS) + forcedSettings = *matchedSettings; + + apply(forcedSettings, pti.buildSettings); + + // recursively apply forced settings to all dependencies of his dependency + applyForcedSettings(*pti, targets, ["*" : forcedSettings], level + 1); + } + } + + // apply both top level and configuration level forced dependency build settings + foreach (configured_dbs; [ + cast(const(BuildSettingsTemplate[string])) rootPackage.recipe.buildSettings.dependencyBuildSettings, + rootPackage.getBuildSettings(genSettings.config).dependencyBuildSettings]) + { + BuildSettings[string] dependencyBuildSettings; + foreach (key, value; configured_dbs) + { + BuildSettings buildSettings; + if (auto target = key in targets) + { + // get platform specific build settings and process dub variables (BuildSettingsTemplate => BuildSettings) + value.getPlatformSettings(buildSettings, genSettings.platform, target.pack.path); + buildSettings.processVars(m_project, target.pack, buildSettings, genSettings, true); + dependencyBuildSettings[key] = buildSettings; + } + } + applyForcedSettings(*roottarget, targets, dependencyBuildSettings); + } + // remove targets without output foreach (name; targets.keys) { diff --git a/source/dub/internal/undead/xml.d b/source/dub/internal/undead/xml.d index 368aed5..4c11a47 100644 --- a/source/dub/internal/undead/xml.d +++ b/source/dub/internal/undead/xml.d @@ -591,7 +591,7 @@ */ override bool opEquals(scope const Object o) const { - const doc = toType!(const Document)(o); + const scope doc = toType!(const Document)(o); return prolog == doc.prolog && (cast(const) this).Element.opEquals(cast(const) doc) && epilog == doc.epilog; @@ -611,7 +611,7 @@ */ override int opCmp(scope const Object o) scope const { - const doc = toType!(const Document)(o); + const scope doc = toType!(const Document)(o); if (prolog != doc.prolog) return prolog < doc.prolog ? -1 : 1; if (int cmp = this.Element.opCmp(doc)) @@ -842,7 +842,7 @@ */ override bool opEquals(scope const Object o) const { - const element = toType!(const Element)(o); + const scope element = toType!(const Element)(o); immutable len = items.length; if (len != element.items.length) return false; foreach (i; 0 .. len) @@ -866,7 +866,7 @@ */ override int opCmp(scope const Object o) @safe const { - const element = toType!(const Element)(o); + const scope element = toType!(const Element)(o); for (uint i=0; ; ++i) { if (i == items.length && i == element.items.length) return 0; @@ -1277,7 +1277,7 @@ */ override bool opEquals(scope const Object o) const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const Comment) item; return t !is null && content == t.content; } @@ -1296,7 +1296,7 @@ */ override int opCmp(scope const Object o) scope const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const Comment) item; return t !is null && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 ); @@ -1365,7 +1365,7 @@ */ override bool opEquals(scope const Object o) const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const CData) item; return t !is null && content == t.content; } @@ -1384,7 +1384,7 @@ */ override int opCmp(scope const Object o) scope const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const CData) item; return t !is null && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 ); @@ -1442,7 +1442,7 @@ */ override bool opEquals(scope const Object o) const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const Text) item; return t !is null && content == t.content; } @@ -1461,7 +1461,7 @@ */ override int opCmp(scope const Object o) scope const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const Text) item; return t !is null && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 ); @@ -1525,7 +1525,7 @@ */ override bool opEquals(scope const Object o) const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const XMLInstruction) item; return t !is null && content == t.content; } @@ -1544,7 +1544,7 @@ */ override int opCmp(scope const Object o) scope const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const XMLInstruction) item; return t !is null && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 ); @@ -1605,7 +1605,7 @@ */ override bool opEquals(scope const Object o) const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const ProcessingInstruction) item; return t !is null && content == t.content; } @@ -1624,7 +1624,7 @@ */ override int opCmp(scope const Object o) scope const { - const item = toType!(const Item)(o); + const scope item = toType!(const Item)(o); const t = cast(const ProcessingInstruction) item; return t !is null && (content != t.content ? (content < t.content ? -1 : 1 ) : 0 ); @@ -2955,7 +2955,7 @@ private { - inout(T) toType(T)(inout Object o) + inout(T) toType(T)(scope return inout Object o) { T t = cast(T)(o); if (t is null) diff --git a/source/dub/internal/utils.d b/source/dub/internal/utils.d index 30f637e..345385b 100644 --- a/source/dub/internal/utils.d +++ b/source/dub/internal/utils.d @@ -610,18 +610,22 @@ //search for module keyword in file string moduleName = getModuleNameFromFile(file.to!string); - if(moduleName.length) return moduleName; + if(moduleName.length) { + assert(moduleName.length > 0, "Wasn't this module name already checked? what"); + return moduleName; + } //create module name from path foreach (i; 0 .. mpath.length) { import std.path; auto p = mpath[i].name; - if (p == "package.d") break; - if (i > 0) ret ~= "."; + if (p == "package.d") break ; + if (ret.data.length > 0) ret ~= "."; if (i+1 < mpath.length) ret ~= p; else ret ~= p.baseName(".d"); } + assert(ret.data.length > 0, "A module name was expected to be computed, and none was."); return ret.data; } diff --git a/source/dub/package_.d b/source/dub/package_.d index 45efe6e..cf49f92 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -55,6 +55,23 @@ /// Returns the default package recile file name. @property string defaultPackageFilename() { return packageInfoFiles[0].filename; } +/// All built-in build type names except for the special `$DFLAGS` build type. +/// Has the default build type (`debug`) as first index. +static immutable string[] builtinBuildTypes = [ + "debug", + "plain", + "release", + "release-debug", + "release-nobounds", + "unittest", + "profile", + "profile-gc", + "docs", + "ddox", + "cov", + "unittest-cov", + "syntax" +]; /** Represents a package, including its sub packages. */ @@ -256,6 +273,18 @@ return ret.data; } + /** Returns the list of all custom build type names. + + Build type contents can be accessed using `this.recipe.buildTypes`. + */ + @property string[] customBuildTypes() + const { + auto ret = appender!(string[])(); + foreach (name; m_info.buildTypes.byKey) + ret.put(name); + return ret.data; + } + /** Writes the current recipe contents to a recipe file. The parameter-less overload writes to `this.path`, which must not be @@ -402,12 +431,9 @@ */ void addBuildTypeSettings(ref BuildSettings settings, in BuildPlatform platform, string build_type) const { - if (build_type == "$DFLAGS") { - import std.process; - string dflags = environment.get("DFLAGS"); - settings.addDFlags(dflags.split()); - return; - } + import std.process; + string dflags = environment.get("DFLAGS", ""); + settings.addDFlags(dflags.split()); if (auto pbt = build_type in m_info.buildTypes) { logDiagnostic("Using custom build type '%s'.", build_type); @@ -415,6 +441,7 @@ } else { with(BuildOption) switch (build_type) { default: throw new Exception(format("Unknown build type for %s: '%s'", this.name, build_type)); + case "$DFLAGS": break; case "plain": break; case "debug": settings.addOptions(debugMode, debugInfo); break; case "release": settings.addOptions(releaseMode, optimize, inline); break; diff --git a/source/dub/packagemanager.d b/source/dub/packagemanager.d index be15f15..cb637bd 100644 --- a/source/dub/packagemanager.d +++ b/source/dub/packagemanager.d @@ -272,7 +272,7 @@ */ Package loadSCMPackage(string name, Dependency dependency) in { assert(!dependency.repository.empty); } - body { + do { Package pack; with (dependency.repository) final switch (kind) diff --git a/source/dub/project.d b/source/dub/project.d index 5b9bcd4..026697d 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -427,6 +427,10 @@ /// Returns the names of all configurations of the root package. @property string[] configurations() const { return m_rootPackage.configurations; } + /// Returns the names of all built-in and custom build types of the root package. + /// The default built-in build type is the first item in the list. + @property string[] builds() const { return builtinBuildTypes ~ m_rootPackage.customBuildTypes; } + /// Returns a map with the configuration for all packages in the dependency tree. string[string] getPackageConfigs(in BuildPlatform platform, string config, bool allow_non_library = true) const { @@ -983,11 +987,11 @@ case "post-build-environments": case "pre-run-environments": case "post-run-environments": - enforce(false, "--data="~requestedData~" can only be used with --data-list or --data-0."); + enforce(false, "--data="~requestedData~" can only be used with `--data-list` or `--data-list --data-0`."); break; case "requirements": - enforce(false, "--data=requirements can only be used with --data-list or --data-0. Use --data=options instead."); + enforce(false, "--data=requirements can only be used with `--data-list` or `--data-list --data-0`. Use --data=options instead."); break; default: break; @@ -1200,7 +1204,7 @@ dst.addPostBuildEnvironments(processVerEnvs(settings.postBuildEnvironments, gsettings.buildSettings.postBuildEnvironments)); dst.addPreRunEnvironments(processVerEnvs(settings.preRunEnvironments, gsettings.buildSettings.preRunEnvironments)); dst.addPostRunEnvironments(processVerEnvs(settings.postRunEnvironments, gsettings.buildSettings.postRunEnvironments)); - + auto buildEnvs = [dst.environments, dst.buildEnvironments]; auto runEnvs = [dst.environments, dst.runEnvironments]; auto preGenEnvs = [dst.environments, dst.preGenerateEnvironments]; @@ -1209,7 +1213,7 @@ auto postBuildEnvs = buildEnvs ~ [dst.postBuildEnvironments]; auto preRunEnvs = runEnvs ~ [dst.preRunEnvironments]; auto postRunEnvs = runEnvs ~ [dst.postRunEnvironments]; - + dst.addDFlags(processVars(project, pack, gsettings, settings.dflags, false, buildEnvs)); dst.addLFlags(processVars(project, pack, gsettings, settings.lflags, false, buildEnvs)); dst.addLibs(processVars(project, pack, gsettings, settings.libs, false, buildEnvs)); @@ -1469,7 +1473,7 @@ else if (name == "LFLAGS") return join(buildSettings.lflags," "); } - + import std.range; foreach (aa; retro(extraVars)) if (auto exvar = name in aa) diff --git a/source/dub/semver.d b/source/dub/semver.d index 68978d8..c04a9c5 100644 --- a/source/dub/semver.d +++ b/source/dub/semver.d @@ -103,7 +103,7 @@ */ bool isPreReleaseVersion(string ver) pure @nogc in { assert(isValidVersion(ver)); } -body { +do { foreach (i; 0 .. 2) { auto di = ver.indexOf('.'); assert(di > 0); diff --git a/test/depen-build-settings/.no_build_dmd b/test/depen-build-settings/.no_build_dmd new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/depen-build-settings/.no_build_dmd diff --git a/test/depen-build-settings/.no_build_gdc b/test/depen-build-settings/.no_build_gdc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/depen-build-settings/.no_build_gdc diff --git a/test/depen-build-settings/depend/depend2/source/depend2.d b/test/depen-build-settings/depend/depend2/source/depend2.d index 31b6367..3fff78b 100644 --- a/test/depen-build-settings/depend/depend2/source/depend2.d +++ b/test/depen-build-settings/depend/depend2/source/depend2.d @@ -1,5 +1,7 @@ import std.stdio; +version (must_be_defined) {} else static assert(0, "Expected must_be_defined to be set"); + extern (C) void depend2_func() { writeln("depend2_func"); diff --git a/test/depen-build-settings/depend/source/depend.d b/test/depen-build-settings/depend/source/depend.d index d9bb981..2db3cac 100644 --- a/test/depen-build-settings/depend/source/depend.d +++ b/test/depen-build-settings/depend/source/depend.d @@ -1,5 +1,7 @@ import std.stdio; +version (must_be_defined) {} else static assert(0, "Expected must_be_defined to be set"); + extern (C) void depend2_func(); extern (C) void depend1_func() diff --git a/test/depen-build-settings/dub.json b/test/depen-build-settings/dub.json index 1769ac1..4e8ccfd 100644 --- a/test/depen-build-settings/dub.json +++ b/test/depen-build-settings/dub.json @@ -4,5 +4,15 @@ "dependencies": { "depend1": { "version" : "*", "dflags" : ["-X"] } - } + }, + + "configurations": [ + { + "name" : "defaultconfig", + "targetType": "executable", + "dependencies": { + "depend1": { "version" : "*", "dflags" : ["--d-version=must_be_defined"] } + } + } + ] } diff --git a/test/depen-build-settings/source/app.d b/test/depen-build-settings/source/app.d index 8893119..dbba31e 100644 --- a/test/depen-build-settings/source/app.d +++ b/test/depen-build-settings/source/app.d @@ -3,10 +3,13 @@ extern (C) void depend1_func(); +version (must_be_defined) static assert(0, "Expected must_be_defined not to be set"); + void main() { writeln("Edit source/app.d to start your project."); depend1_func(); + assert(!exists("depen-build-settings.json")); assert(exists("depend2.json")); assert(exists("depend.json")); } diff --git a/test/issue1645-dflags-build.sh b/test/issue1645-dflags-build.sh new file mode 100755 index 0000000..5fbcb1e --- /dev/null +++ b/test/issue1645-dflags-build.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +# If DFLAGS are not processed, dub for library would fail +DFLAGS="-w" $DUB build --root="$CURR_DIR"/1-staticLib-simple --build=plain +if DFLAGS="-asfdsf" $DUB build --root="$CURR_DIR"/1-staticLib-simple --build=plain 2>/dev/null; then + echo "Should not accept this DFLAGS"; + false # fail +fi +$DUB build --root="$CURR_DIR"/1-staticLib-simple --build=plain --build=plain diff --git a/test/issue2051_running_unittests_from_dub_single_file_packages_fails.d b/test/issue2051_running_unittests_from_dub_single_file_packages_fails.d index 2327db3..b7e5fbf 100644 --- a/test/issue2051_running_unittests_from_dub_single_file_packages_fails.d +++ b/test/issue2051_running_unittests_from_dub_single_file_packages_fails.d @@ -7,7 +7,7 @@ import std.file : tempDir; import std.stdio : File, writeln; import std.string : lineSplitter; -import std.path : buildPath; +import std.path : buildPath, buildNormalizedPath; import std.process : environment, executeShell; auto executeCommand(string command) @@ -28,11 +28,15 @@ auto dub = environment.get("DUB"); if (!dub.length) dub = buildPath(".", "bin", "dub"); - + + string destinationDirectory = tempDir; + // remove any ending slahes (which can for some reason be added at the end by tempDir, which fails on OSX) https://issues.dlang.org/show_bug.cgi?id=22738 + destinationDirectory = buildNormalizedPath(destinationDirectory); + string filename; // check if the single file package with dependency compiles and runs { - filename = tempDir.buildPath("issue2051_success.d"); + filename = destinationDirectory.buildPath("issue2051_success.d"); auto f = File(filename, "w"); f.write( `#!/usr/bin/env dub @@ -61,7 +65,7 @@ ` ); } - const rc1 = text(dub, " test --single ", filename).executeCommand; + const rc1 = text(dub, " test --single \"", filename, "\"").executeCommand; if (rc1) writeln("\nError. Unittests failed."); else @@ -69,7 +73,7 @@ // Check if dub `test` command runs unittests for single file package { - filename = tempDir.buildPath("issue2051_fail.d"); + filename = destinationDirectory.buildPath("issue2051_fail.d"); auto f = File(filename, "w"); f.write( `#!/usr/bin/env dub @@ -89,7 +93,7 @@ ` ); } - const rc2 = text(dub, " test --single ", filename).executeCommand; + const rc2 = text(dub, " test --single \"", filename, "\"").executeCommand; if (rc2) writeln("\nOk. Unittests failed."); else