Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dub for openSUSE:Factory checked in 
at 2026-11-03 17:59:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dub (Old)
 and      /work/SRC/openSUSE:Factory/.dub.new.1257 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dub"

Tue Nov  3 17:59:17 2026 rev:30 rq:1394639 version:1.43.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/dub/dub.changes  2026-08-15 22:42:06.613720792 
+0200
+++ /work/SRC/openSUSE:Factory/.dub.new.1257/dub.changes        2026-11-03 
18:03:38.495683516 +0100
@@ -1,0 +2,12 @@
+Sun Nov  1 16:22:51 UTC 2026 - Andrea Manzini <[email protected]>
+
+- Update to 1.43.0:
+  * Added `dub generate ninja` command introducing Ninja build
+    backend.
+  * Fixed `--conf` options not being passed to LDC's linker
+    step.
+  * Fixed Windows response file quoting for paths with trailing
+    backslashes.
+  * Repacked source tarball to unbundle prebuilt Windows DLLs.
+
+-------------------------------------------------------------------

Old:
----
  dub-1.42.0.tar.gz

New:
----
  dub-1.43.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dub.spec ++++++
--- /var/tmp/diff_new_pack.T1eLvG/_old  2026-11-03 18:03:40.021747398 +0100
+++ /var/tmp/diff_new_pack.T1eLvG/_new  2026-11-03 18:03:40.025747566 +0100
@@ -23,13 +23,14 @@
 %bcond_with dcompiler_dmd
 %endif
 Name:           dub
-Version:        1.42.0
+Version:        1.43.0
 Release:        0
 Summary:        Package manager and meta build tool for the D programming 
language
 License:        MIT
-Group:          Development/Languages/Other
 URL:            https://code.dlang.org
-Source:         
https://github.com/dlang/dub/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+# Upstream tarball bundles Windows DLLs in bin/ (libcurl.dll, libeay32.dll, 
ssleay32.dll)
+# Repacked without bin/*.dll from 
https://github.com/dlang/dub/archive/v%%{version}.tar.gz
+Source:         %{name}-%{version}.tar.gz
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(libcurl)
 %if %{with dcompiler_dmd}

++++++ dub-1.42.0.tar.gz -> dub-1.43.0.tar.gz ++++++
Binary files old/dub-1.42.0/bin/libcurl.dll and new/dub-1.43.0/bin/libcurl.dll 
differ
Binary files old/dub-1.42.0/bin/libeay32.dll and 
new/dub-1.43.0/bin/libeay32.dll differ
Binary files old/dub-1.42.0/bin/ssleay32.dll and 
new/dub-1.43.0/bin/ssleay32.dll differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/build-files.txt 
new/dub-1.43.0/build-files.txt
--- old/dub-1.42.0/build-files.txt      2026-08-05 17:14:37.000000000 +0200
+++ new/dub-1.43.0/build-files.txt      2026-10-31 17:11:00.000000000 +0100
@@ -13,6 +13,7 @@
 source/dub/dub.d
 source/dub/generators/build.d
 source/dub/generators/cmake.d
+source/dub/generators/ninja.d
 source/dub/generators/generator.d
 source/dub/generators/sublimetext.d
 source/dub/generators/targetdescription.d
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/changelog/dustmite-timeout.dd 
new/dub-1.43.0/changelog/dustmite-timeout.dd
--- old/dub-1.42.0/changelog/dustmite-timeout.dd        2026-08-05 
17:14:37.000000000 +0200
+++ new/dub-1.43.0/changelog/dustmite-timeout.dd        1970-01-01 
01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-Added `--timeout` option to `dub dustmite` command.
-
-Adds a timeout (in seconds) for each oracle invocation, preventing
-the dustmite process from hanging indefinitely when the test command
-does not terminate. Requires the `timeout` command to be available
-(coreutils on Linux/macOS).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/changelog/ldc-conf.dd 
new/dub-1.43.0/changelog/ldc-conf.dd
--- old/dub-1.42.0/changelog/ldc-conf.dd        1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/changelog/ldc-conf.dd        2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,9 @@
+Fixed `--conf` options not being passed to LDC's linker step.
+
+Packages can now use `--conf` as a dflag to modify LDC's linker
+behavior for a package.
+
+Example:
+-------
+dflags "--conf=$KON_PACKAGE_DIR/55-wasm-wasi.conf" platform="wasm32"
+-------
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/changelog/ninja-generator.dd 
new/dub-1.43.0/changelog/ninja-generator.dd
--- old/dub-1.42.0/changelog/ninja-generator.dd 1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/changelog/ninja-generator.dd 2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,5 @@
+Added `dub generate ninja` command.
+
+Introduces a Ninja build backend for DUB. Running `dub generate ninja`
+produces a `build.ninja` file with compile and link rules for all source
+files in the project, using the correct flag syntax for DMD, LDC, and GDC.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/changelog/windows-response-file-escape.dd 
new/dub-1.43.0/changelog/windows-response-file-escape.dd
--- old/dub-1.42.0/changelog/windows-response-file-escape.dd    1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/changelog/windows-response-file-escape.dd    2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,8 @@
+Fix Windows response file quoting for paths with trailing backslashes
+
+When dub writes spaced compiler flags into `@` response files, a trailing
+directory separator before the closing quote could escape that quote under
+DMD/LDC response expansion. This broke ldc2 builds for users whose dub cache
+paths contain spaces (regression since import paths gained trailing slashes).
+
+Related: ldc-developers/ldc#5134
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/scripts/zsh-completion/_dub 
new/dub-1.43.0/scripts/zsh-completion/_dub
--- old/dub-1.42.0/scripts/zsh-completion/_dub  2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/scripts/zsh-completion/_dub  2026-10-31 17:11:00.000000000 
+0100
@@ -151,7 +151,7 @@
     '(-c --config)'{-c,--config=}'[Builds the specified configuration]:package 
configuration: ' \
     '*--override-config=[ Uses the specified configuration for a certain 
dependency]:dependency/config: ' \
     '--compiler=[Specifies the compiler binary to use (can be a 
path)]:compiler:(dmd gdc ldc gdmd ldmd)' \
-    '(-a --arch)'{-a,--arch=}'[Force a different architecture (e.g. x86 or 
x86_64)]:architecture: ' \
+    '(-a --arch)'{-a,--arch=}'[Force a different architecture (e.g. x86, 
x86_64 or aarch64)]:architecture: ' \
     '(-d --debug)*'{-d,--debug=}'[Define the specified debug version 
identifier when building]:Debug version: ' \
     '--d-version=[Define the specified version identifier when 
building]:Version identifier: ' \
     '--nodeps[Do not resolve missing dependencies before building]' \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/commandline.d 
new/dub-1.43.0/source/dub/commandline.d
--- old/dub-1.42.0/source/dub/commandline.d     2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/commandline.d     2026-10-31 17:11:00.000000000 
+0100
@@ -11,15 +11,15 @@
 import dub.dependency;
 import dub.dub;
 import dub.generators.generator;
+import dub.internal.logging;
+import dub.internal.utils : getClosestMatch, getDUBVersion, getTempFile;
 import dub.internal.vibecompat.core.file;
 import dub.internal.vibecompat.data.json;
 import dub.internal.vibecompat.inet.path;
-import dub.internal.logging;
 import dub.package_;
 import dub.packagemanager;
 import dub.packagesuppliers;
 import dub.project;
-import dub.internal.utils : getDUBVersion, getClosestMatch, getTempFile;
 
 import dub.internal.dyaml.stdsumtype;
 
@@ -1308,7 +1308,7 @@
                        "  "~["dmd", "gdc", "ldc", "gdmd", "ldmd"].join(", ")
                ]);
                args.getopt("a|arch", &m_arch, [
-                       "Force a different architecture (e.g. x86 or x86_64)"
+                       "Force a different architecture (e.g. x86, x86_64 or 
aarch64)"
                ]);
                args.getopt("d|debug", &m_debugVersions, [
                        "Define the specified `debug` version identifier when 
building - can be used multiple times"
@@ -1453,6 +1453,7 @@
                        "visuald - VisualD project files",
                        "sublimetext - SublimeText project file",
                        "cmake - CMake build scripts",
+                       "ninja - Ninja build files",
                        "build - Builds the package directly",
                        "",
                        "An optional package name can be given to generate a 
different package than the root/CWD package."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/compilers/buildsettings.d 
new/dub-1.43.0/source/dub/compilers/buildsettings.d
--- old/dub-1.42.0/source/dub/compilers/buildsettings.d 2026-08-05 
17:14:37.000000000 +0200
+++ new/dub-1.43.0/source/dub/compilers/buildsettings.d 2026-10-31 
17:11:00.000000000 +0100
@@ -649,6 +649,74 @@
 }
 
 /**
+       ABI-critical dflags that must be propagated downwards to all 
dependencies.
+
+       These are raw compiler flags (not covered by `BuildOption`) that affect
+       calling conventions, instruction-set selection, or runtime behaviour in
+       ways that must be consistent across every compilation unit in the
+       dependency graph; otherwise the resulting binaries suffer from silent 
ABI
+       mismatches or linker errors.
+
+       See_Also: $(LINK2 https://github.com/dlang/dub/issues/3080)
+*/
+private immutable abiCriticalPrefixes = [
+       // LDC
+       "-mattr=",
+       "-mcpu=",
+       "-mtriple=",
+       "-checkaction=",
+       // DMD / LDC (-boundscheck=off is also extracted as a BuildOption,
+       // but -boundscheck=safeonly and -boundscheck=on stay as raw dflags)
+       "-boundscheck=",
+       // LDC – sanitizer instrumentation must be consistent
+       "-fsanitize=",
+       // GDC (GCC-style)
+       "-march=",
+       "-mfpu=",
+       "-mfloat-abi=",
+];
+
+/// Returns only the ABI-critical flags from `dflags`.
+const(string)[] filterABICriticalFlags(const string[] dflags)
+{
+       import std.algorithm.iteration : filter;
+       import std.algorithm.searching : startsWith;
+
+       return dflags.filter!(f => abiCriticalPrefixes.any!(p => 
f.startsWith(p))).array;
+}
+
+unittest
+{
+       auto flags = ["-mattr=+avx", "-w", "-g", "-mcpu=haswell", "-O2",
+               "-checkaction=halt", "-mtriple=x86_64-linux-gnu"];
+       auto critical = filterABICriticalFlags(flags);
+       assert(critical == ["-mattr=+avx", "-mcpu=haswell",
+               "-checkaction=halt", "-mtriple=x86_64-linux-gnu"]);
+}
+
+unittest
+{
+       // No ABI-critical flags → empty result
+       assert(filterABICriticalFlags(["-w", "-g", "-O2"]).length == 0);
+}
+
+unittest
+{
+       // GDC flags
+       auto flags = ["-march=native", "-mfpu=neon", "-mfloat-abi=hard", "-v"];
+       auto critical = filterABICriticalFlags(flags);
+       assert(critical == ["-march=native", "-mfpu=neon", "-mfloat-abi=hard"]);
+}
+
+unittest
+{
+       // -boundscheck= variants and -fsanitize=
+       auto flags = ["-boundscheck=safeonly", "-O2", "-fsanitize=address", 
"-w"];
+       auto critical = filterABICriticalFlags(flags);
+       assert(critical == ["-boundscheck=safeonly", "-fsanitize=address"]);
+}
+
+/**
        All build options that will be inherited upwards in the dependency graph
 
        Build options in this category fulfill one of the following properties:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/compilers/dmd.d 
new/dub-1.43.0/source/dub/compilers/dmd.d
--- old/dub-1.42.0/source/dub/compilers/dmd.d   2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/compilers/dmd.d   2026-10-31 17:11:00.000000000 
+0100
@@ -9,10 +9,10 @@
 
 import dub.compilers.compiler;
 import dub.compilers.utils;
+import dub.internal.logging;
 import dub.internal.utils;
 import dub.internal.vibecompat.core.file;
 import dub.internal.vibecompat.inet.path;
-import dub.internal.logging;
 
 import std.algorithm;
 import std.array;
@@ -23,7 +23,7 @@
 version (Windows)
 private Nullable!bool isWow64() {
        // See also: 
https://docs.microsoft.com/de-de/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
-       import core.sys.windows.windows : GetNativeSystemInfo, SYSTEM_INFO, 
PROCESSOR_ARCHITECTURE_AMD64;
+       import core.sys.windows.windows : GetNativeSystemInfo, 
PROCESSOR_ARCHITECTURE_AMD64, SYSTEM_INFO;
 
        static Nullable!bool result;
 
@@ -128,6 +128,7 @@
        {
                // Set basic arch flags for the probe - might be revised based 
on the exact value + compiler version
                string[] arch_flags;
+               // keep the platform arguments below updated with dub-docs! 
(docs/dub-reference/platform_specifications.md)
                switch (arch_override) {
                        default: throw new 
UnsupportedArchitectureException(arch_override);
                        case "":
@@ -420,7 +421,7 @@
 
        private auto escapeArgs(in string[] args)
        {
-               return args.map!(s => s.canFind(' ') ? "\""~s~"\"" : s);
+               return args.map!(escapeResponseFileArg);
        }
 
        static bool isLinkerDFlag(string arg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/compilers/gdc.d 
new/dub-1.43.0/source/dub/compilers/gdc.d
--- old/dub-1.42.0/source/dub/compilers/gdc.d   2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/compilers/gdc.d   2026-10-31 17:11:00.000000000 
+0100
@@ -9,10 +9,10 @@
 
 import dub.compilers.compiler;
 import dub.compilers.utils;
+import dub.internal.logging;
 import dub.internal.utils;
 import dub.internal.vibecompat.core.file;
 import dub.internal.vibecompat.inet.path;
-import dub.internal.logging;
 
 import std.algorithm;
 import std.array;
@@ -68,6 +68,7 @@
        BuildPlatform determinePlatform(ref BuildSettings settings, string 
compiler_binary, string arch_override)
        {
                string[] arch_flags;
+               // keep the platform arguments below updated with dub-docs! 
(docs/dub-reference/platform_specifications.md)
                switch (arch_override) {
                        default: throw new 
UnsupportedArchitectureException(arch_override);
                        case "": break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/compilers/ldc.d 
new/dub-1.43.0/source/dub/compilers/ldc.d
--- old/dub-1.42.0/source/dub/compilers/ldc.d   2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/compilers/ldc.d   2026-10-31 17:11:00.000000000 
+0100
@@ -9,10 +9,10 @@
 
 import dub.compilers.compiler;
 import dub.compilers.utils;
+import dub.internal.logging;
 import dub.internal.utils;
 import dub.internal.vibecompat.core.file;
 import dub.internal.vibecompat.inet.path;
-import dub.internal.logging;
 
 import std.algorithm;
 import std.array;
@@ -80,6 +80,7 @@
        {
                string[] arch_flags;
                bool arch_override_is_triple = false;
+               // keep the platform arguments below updated with dub-docs! 
(docs/dub-reference/platform_specifications.md)
                switch (arch_override) {
                        case "": break;
                        case "x86": arch_flags = ["-march=x86"]; break;
@@ -335,7 +336,7 @@
 
        private auto escapeArgs(in string[] args)
        {
-               return args.map!(s => s.canFind(' ') ? "\""~s~"\"" : s);
+               return args.map!(escapeResponseFileArg);
        }
 
        static bool isLinkerDFlag(string arg)
@@ -359,7 +360,8 @@
                                    || arg.startsWith("-linker=")
                                    || arg.startsWith("-march=")
                                    || arg.startsWith("-mscrtlib=")
-                                   || arg.startsWith("-mtriple=");
+                                   || arg.startsWith("-mtriple=")
+                                   || arg.startsWith("-conf=");
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/compilers/utils.d 
new/dub-1.43.0/source/dub/compilers/utils.d
--- old/dub-1.42.0/source/dub/compilers/utils.d 2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/compilers/utils.d 2026-10-31 17:11:00.000000000 
+0100
@@ -13,6 +13,8 @@
 import dub.internal.logging;
 
 import std.algorithm : canFind, endsWith, filter;
+import std.array : array;
+import std.range : repeat;
 
 /**
        Alters the build options to comply with the specified build 
requirements.
@@ -72,6 +74,46 @@
        assert(!isLinkerFile(p, "test.d"));
 }
 
+/**
+       Formats one command-line argument for a compiler response file.
+
+       DMD and LDC treat a backslash immediately before a closing double quote 
as
+       escaping that quote when expanding `@` files. Spaced arguments are 
wrapped in
+       quotes; trailing backslashes in the payload must be doubled so the 
closing
+       quote ends the argument (see Phobos `responseExpandFrom`, LDC
+       `driver/response.cpp`).
+*/
+string escapeResponseFileArg(string s)
+{
+       if (!s.canFind(' '))
+               return s;
+
+       size_t trailingBackslashes;
+       for (trailingBackslashes = 0;
+            trailingBackslashes < s.length && s[$ - 1 - trailingBackslashes] 
== '\\';
+            trailingBackslashes++) { }
+
+       if (trailingBackslashes)
+               s ~= '\\'.repeat(trailingBackslashes).array;
+
+       return '"' ~ s ~ '"';
+}
+
+unittest {
+       // No spaces: leave the argument untouched (including trailing 
backslashes).
+       assert(escapeResponseFileArg(`C:\nospace`) == `C:\nospace`);
+       assert(escapeResponseFileArg(`C:\trail\\`) == `C:\trail\\`);
+
+       enum spaced = `C:\dir with spaces\file.d`;
+       assert(escapeResponseFileArg(spaced) == `"` ~ spaced ~ `"`);
+
+       // Trailing directory separators must be doubled inside the quotes so 
the
+       // closing quote is not escaped by response-file expansion.
+       assert(escapeResponseFileArg(`-IC:\Users\Has Space\src\`) ==
+               `"-IC:\Users\Has Space\src\\"`);
+       assert(escapeResponseFileArg(`C:\dir with spaces\trail\\`) ==
+               `"C:\dir with spaces\trail\\\\"`);
+}
 
 /**
        Adds a default DT_SONAME (ELF) / 'install name' (Mach-O) when linking a 
dynamic library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/generators/generator.d 
new/dub-1.43.0/source/dub/generators/generator.d
--- old/dub-1.42.0/source/dub/generators/generator.d    2026-08-05 
17:14:37.000000000 +0200
+++ new/dub-1.43.0/source/dub/generators/generator.d    2026-10-31 
17:11:00.000000000 +0100
@@ -9,6 +9,7 @@
 
 import dub.compilers.compiler;
 import dub.generators.cmake;
+import dub.generators.ninja;
 import dub.generators.build;
 import dub.generators.sublimetext;
 import dub.generators.visuald;
@@ -742,6 +743,10 @@
                child.addVersions(parent.versions);
                child.addDebugVersions(parent.debugVersions);
                child.addOptions(Flags!BuildOption(parent.options & 
inheritedBuildOptions));
+               // Propagate ABI-critical dflags (e.g. -mattr=+avx) so that all
+               // dependencies are compiled with a consistent instruction set /
+               // calling convention.  See 
https://github.com/dlang/dub/issues/3080
+               child.addDFlags(filterABICriticalFlags(parent.dflags));
        }
 
        private static void mergeFromDependency(const scope ref BuildSettings 
child, ref BuildSettings parent, const scope ref BuildPlatform platform)
@@ -950,6 +955,9 @@
                case "cmake":
                        logDebug("Creating CMake generator.");
                        return new CMakeGenerator(project);
+               case "ninja":
+                       logDebug("Creating Ninja generator.");
+                       return new NinjaGenerator(project);
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/generators/ninja.d 
new/dub-1.43.0/source/dub/generators/ninja.d
--- old/dub-1.42.0/source/dub/generators/ninja.d        1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/source/dub/generators/ninja.d        2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,165 @@
+/**
+    Generator for Ninja build scripts
+
+    License: Subject to the terms of the MIT license
+    Authors: Hariprakash V
+*/
+module dub.generators.ninja;
+
+import dub.compilers.compiler;
+import dub.generators.generator;
+import dub.project;
+import dub.internal.vibecompat.inet.path;
+
+import std.algorithm : map, startsWith;
+import std.array : join, replace;
+import std.path : stripExtension;
+import std.stdio : File;
+import std.file : exists, thisExePath;
+
+class NinjaGenerator : ProjectGenerator
+{
+    this(Project project)
+    {
+        super(project);
+    }
+
+    override void generateTargets(GeneratorSettings settings, in 
TargetInfo[string] targets)
+    {
+        auto f = File("build.ninja", "w");
+        scope(exit) f.close();
+
+        immutable compiler = settings.platform.compilerBinary;
+        immutable cname    = settings.platform.compiler;
+
+        f.writeln("# Generated by DUB ninja generator");
+        f.writeln();
+        f.writeln("ar = ar");
+        f.writeln();
+        f.writeln("rule dc");
+        f.writeln("  command = ", compiler, " $flags -c $in -of=$out 
-makedeps=$out.dep");
+        f.writeln("  depfile = $out.dep");
+        f.writeln("  deps = gcc");
+        f.writeln("  description = Compiling $in");
+        f.writeln();
+        f.writeln("rule link");
+        f.writeln("  command = ", compiler, " $in $lflags -of=$out");
+        f.writeln("  description = Linking $out");
+        f.writeln();
+        f.writeln("rule ar");
+        f.writeln("  command = $ar rcs $out $in");
+        f.writeln("  description = Archiving $out");
+        f.writeln();
+
+        const recipePath     = 
m_project.rootPackage.recipePath.toNativeString();
+        auto selectionsPath = (m_project.rootPackage.path ~ 
"dub.selections.json").toNativeString();
+
+        f.writeln("rule regen");
+        f.writeln("  command = ", thisExePath(), " generate ninja");
+        f.writeln("  generator = 1");
+        f.writeln("  description = Regenerating build.ninja");
+        f.writeln();
+
+        string[] regenInputs = [recipePath];
+        if (exists(selectionsPath))
+            regenInputs ~= selectionsPath;
+
+        f.writeln("build build.ninja: regen ", regenInputs.map!(p => 
escapeNinjaPath(p)).join(" "));
+        f.writeln();
+
+        foreach (name, info; targets)
+        {
+            auto bs = info.buildSettings;
+
+            auto importFlags  = bs.importPaths.map!(p => "-I" ~ 
escapeNinjaPath(p)).join(" ");
+            auto strImportFlags = bs.stringImportPaths.map!(p => "-J" ~ 
escapeNinjaPath(p)).join(" ");
+            auto versionFlags = bs.versions.map!(v => versionFlag(cname) ~ 
v).join(" ");
+            auto debugFlags   = bs.debugVersions.map!(v => debugFlag(cname) ~ 
v).join(" ");
+            auto extraFlags   = bs.dflags.join(" ");
+
+            string[] parts;
+            if (importFlags.length)  parts ~= importFlags;
+            if (strImportFlags.length) parts ~= strImportFlags;
+            if (versionFlags.length) parts ~= versionFlags;
+            if (debugFlags.length)   parts ~= debugFlags;
+            if (extraFlags.length)   parts ~= extraFlags;
+            auto flags = parts.join(" ");
+
+            auto lflags = bs.lflags.map!(f => escapeNinjaPath(f)).join(" ");
+
+            string[] objs;
+            foreach (src; bs.sourceFiles)
+            {
+                auto obj = objName(src);
+                f.writeln("build ", obj, ": dc ", escapeNinjaPath(src));
+                if (flags.length)
+                    f.writeln("  flags = ", flags);
+                objs ~= obj;
+            }
+            f.writeln();
+
+            string[] depLibs;
+            foreach (dep; info.linkDependencies)
+            {
+                if (dep in targets)
+                    depLibs ~= libName(targets[dep].buildSettings.targetName, 
sanitizeName(dep));
+            }
+
+            auto outBin = bs.targetName.length ? bs.targetName : 
sanitizeName(name);
+
+            if (bs.targetType == TargetType.staticLibrary ||
+                bs.targetType == TargetType.library)
+            {
+                f.writeln("build ", outBin ~ ".a", ": ar ", objs.join(" "));
+            }
+            else
+            {
+                auto linkInputs = (objs ~ depLibs).join(" ");
+                f.writeln("build ", outBin, ": link ", linkInputs);
+                if (lflags.length)
+                    f.writeln("  lflags = ", lflags);
+                f.writeln();
+                f.writeln("default ", outBin);
+            }
+            f.writeln();
+        }
+    }
+
+    private static string escapeNinjaPath(string path)
+    {
+        return path.replace(":", "$:").replace(" ", "$ ");
+    }
+
+    private static string objName(string src)
+    {
+        return stripExtension(src)
+            .replace("/", "_")
+            .replace("\\", "_")
+            .replace(":", "_") ~ ".o";
+    }
+
+    private static string libName(string targetName, string fallback)
+    {
+        auto base = targetName.length ? targetName : fallback;
+        return base ~ ".a";
+    }
+
+    private static string versionFlag(string cname)
+    {
+        if (cname.startsWith("ldc")) return "--d-version=";
+        if (cname.startsWith("gdc")) return "-fversion=";
+        return "-version=";
+    }
+
+    private static string debugFlag(string cname)
+    {
+        if (cname.startsWith("ldc")) return "--d-debug=";
+        if (cname.startsWith("gdc")) return "-fdebug=";
+        return "-debug=";
+    }
+    private static string sanitizeName(string name)
+    {
+        return name.replace(":", "_").replace("/", "_");
+    }
+
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/generators/visuald.d 
new/dub-1.43.0/source/dub/generators/visuald.d
--- old/dub-1.42.0/source/dub/generators/visuald.d      2026-08-05 
17:14:37.000000000 +0200
+++ new/dub-1.43.0/source/dub/generators/visuald.d      2026-10-31 
17:11:00.000000000 +0100
@@ -307,7 +307,26 @@
                                ret.formattedWrite("    
<imppath>%s</imppath>\n", combinedImports);
                                ret.formattedWrite("    
<fileImppath>%s</fileImppath>\n", stringImports);
 
-                               ret.formattedWrite("    
<program>%s</program>\n", "$(DMDInstallDir)windows\\bin\\dmd.exe"); // FIXME: 
use the actually selected compiler!
+                               ret.formattedWrite("    
<program>%s</program>\n", settings.compiler.name);
+                               string program;
+
+                               final switch (settings.compiler.name)
+                               {
+                               case "ldc":
+                               case "ldc2":
+                                       program = 
"$(LDCInstallDir)bin\\ldc2.exe";
+                                       break;
+
+                               case "gdc":
+                                       program = 
"$(GDCInstallDir)bin\\gdc.exe";
+                                       break;
+
+                               case "dmd":
+                                       program = 
"$(DMDInstallDir)windows\\bin\\dmd.exe";
+                                       break;
+                               }
+
+                               ret.formattedWrite("    
<program>%s</program>\n", program);
                                ret.formattedWrite("    
<additionalOptions>%s</additionalOptions>\n", getSettings!"dflags"().join(" "));
 
                                // Add version identifiers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/internal/utils.d 
new/dub-1.43.0/source/dub/internal/utils.d
--- old/dub-1.42.0/source/dub/internal/utils.d  2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/internal/utils.d  2026-10-31 17:11:00.000000000 
+0100
@@ -138,7 +138,7 @@
 void atomicWriteJsonFile(NativePath path, Json json)
 {
        import std.random : uniform;
-       auto tmppath = path.parentPath ~ format("%s.%s.tmp", path.head, 
uniform(0, int.max));
+       auto tmppath = path.parentPath ~ format("%s.%s.tmp", path.head.name, 
uniform(0, int.max));
        auto app = appender!string();
        app.writePrettyJsonString(json);
        writeFile(tmppath, app.data);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/source/dub/version_.d 
new/dub-1.43.0/source/dub/version_.d
--- old/dub-1.42.0/source/dub/version_.d        2026-08-05 17:14:37.000000000 
+0200
+++ new/dub-1.43.0/source/dub/version_.d        2026-10-31 17:11:00.000000000 
+0100
@@ -1,2 +1,2 @@
 module dub.version_;
-enum dubVersion = "v1.42.0";
+enum dubVersion = "v1.43.0";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/issue3080-abi-dflags/.gitignore 
new/dub-1.43.0/test/issue3080-abi-dflags/.gitignore
--- old/dub-1.42.0/test/issue3080-abi-dflags/.gitignore 1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags/.gitignore 2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,2 @@
+issue3080
+libdep.a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/issue3080-abi-dflags/dep/dub.json 
new/dub-1.43.0/test/issue3080-abi-dflags/dep/dub.json
--- old/dub-1.42.0/test/issue3080-abi-dflags/dep/dub.json       1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags/dep/dub.json       2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,4 @@
+{
+       "name": "dep",
+       "targetType": "library"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/dub-1.42.0/test/issue3080-abi-dflags/dep/source/dep.d 
new/dub-1.43.0/test/issue3080-abi-dflags/dep/source/dep.d
--- old/dub-1.42.0/test/issue3080-abi-dflags/dep/source/dep.d   1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags/dep/source/dep.d   2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,5 @@
+module dep;
+
+void greet()
+{
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/issue3080-abi-dflags/dub.json 
new/dub-1.43.0/test/issue3080-abi-dflags/dub.json
--- old/dub-1.42.0/test/issue3080-abi-dflags/dub.json   1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags/dub.json   2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,8 @@
+{
+       "name": "issue3080",
+       "targetType": "executable",
+       "dependencies": {
+               "dep": { "path": "dep" }
+       },
+       "dflags": ["-checkaction=halt"]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/issue3080-abi-dflags/source/app.d 
new/dub-1.43.0/test/issue3080-abi-dflags/source/app.d
--- old/dub-1.42.0/test/issue3080-abi-dflags/source/app.d       1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags/source/app.d       2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,6 @@
+import dep;
+
+void main()
+{
+       greet();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/issue3080-abi-dflags.sh 
new/dub-1.43.0/test/issue3080-abi-dflags.sh
--- old/dub-1.42.0/test/issue3080-abi-dflags.sh 1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/test/issue3080-abi-dflags.sh 2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+
+# Test for https://github.com/dlang/dub/issues/3080
+# Verify that ABI-critical dflags from the root package are propagated
+# to dependency compilations.
+
+set -e
+
+. $(dirname "${BASH_SOURCE[0]}")/common.sh
+
+cd ${CURR_DIR}/issue3080-abi-dflags
+
+# -checkaction is supported by DMD and LDC but not GDC
+DC_BIN=$(basename "$DC")
+if [ "$DC_BIN" = "gdc" ]; then
+    echo "Skipping -checkaction propagation test for GDC."
+    exit 0
+fi
+
+# Build with verbose output so we can see the compiler invocations
+OUTPUT=$($DUB build --force --compiler=${DC} -v 2>&1)
+
+# The root dub.json sets dflags: ["-checkaction=halt"].
+# Verify that the dependency "dep" is also compiled with this flag.
+# In verbose output, the dep compilation line looks like:
+#   ldc2 ... dep/source/dep.d -checkaction=halt ...
+# Count how many compiler invocation lines contain -checkaction=halt.
+COUNT=$(echo "$OUTPUT" | grep -c '\-checkaction=halt' || true)
+if [ "$COUNT" -ge 2 ]; then
+    echo "PASS: -checkaction=halt propagated to dependency ($COUNT 
occurrences)."
+else
+    echo "FAIL: -checkaction=halt was not propagated to dependency (found 
$COUNT times)."
+    echo "Verbose output:"
+    echo "$OUTPUT"
+    exit 1
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-ar.sh 
new/dub-1.43.0/test/ninja-ar.sh
--- old/dub-1.42.0/test/ninja-ar.sh     1970-01-01 01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-ar.sh     2026-10-31 17:11:00.000000000 +0100
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+. $(dirname "${BASH_SOURCE[0]}")/common.sh
+
+cd "$CURR_DIR"/ninja-static-lib
+
+if ! $DUB generate ninja --compiler=$DC 2>&1; then
+    die $LINENO 'dub generate ninja failed!'
+fi
+
+ninja -t clean
+if ! ninja 2>&1; then
+    die $LINENO 'ninja build failed!'
+fi
+
+if [ ! -f ninja-static-lib.a ]; then
+    die $LINENO 'static library was not produced!'
+fi
+
+$DC -c consumer.d -of=consumer.o
+$DC consumer.o ninja-static-lib.a -of=consumer_test
+
+output=$(./consumer_test)
+if [ "$output" != "5" ]; then
+    die $LINENO "expected 5 from linked archive, got '$output'"
+fi
+
+rm -f consumer.o consumer_test
+ninja -t clean
+rm -f build.ninja
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator/dub.json 
new/dub-1.43.0/test/ninja-generator/dub.json
--- old/dub-1.42.0/test/ninja-generator/dub.json        1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-generator/dub.json        2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,4 @@
+{
+    "name": "ninja-generator",
+    "targetType": "executable"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator/source/app.d 
new/dub-1.43.0/test/ninja-generator/source/app.d
--- old/dub-1.42.0/test/ninja-generator/source/app.d    1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-generator/source/app.d    2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1 @@
+void main() {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator-sdl/dub.sdl 
new/dub-1.43.0/test/ninja-generator-sdl/dub.sdl
--- old/dub-1.42.0/test/ninja-generator-sdl/dub.sdl     1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-generator-sdl/dub.sdl     2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,2 @@
+name "ninja-generator-sdl"
+targetType "executable"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator-sdl/source/app.d 
new/dub-1.43.0/test/ninja-generator-sdl/source/app.d
--- old/dub-1.42.0/test/ninja-generator-sdl/source/app.d        1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-generator-sdl/source/app.d        2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1 @@
+void main() {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator.script.d 
new/dub-1.43.0/test/ninja-generator.script.d
--- old/dub-1.42.0/test/ninja-generator.script.d        1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-generator.script.d        2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,86 @@
+/+ dub.sdl:
+   name "ninja-generator-regen"
+   dependency "common" path="./common"
+ +/
+
+module ninja_generator_regen;
+
+import std.process : environment, execute, Config;
+import std.path : buildPath, dirName;
+import std.file : readText, remove, mkdirRecurse, rmdirRecurse, write;
+import std.algorithm : canFind;
+import core.thread : Thread;
+import core.time : seconds;
+
+import common;
+
+bool regenUpdatesImportPath(string projDir, string recipePath, string 
origRecipe, string newRecipe)
+{
+       const buildNinjaPath = buildPath(projDir, "build.ninja");
+       const importDir = buildPath(projDir, "extra-imports");
+
+       mkdirRecurse(importDir);
+       scope(exit) rmdirRecurse(importDir);
+
+       Thread.sleep(1.seconds);
+       write(recipePath, newRecipe);
+       scope(exit) write(recipePath, origRecipe);
+
+       const result = execute(["ninja"], null, Config.none, size_t.max, 
projDir);
+       if (result.status != 0 || !result.output.canFind("Regenerating 
build.ninja"))
+               return false;
+
+       return readText(buildNinjaPath).canFind("extra-imports");
+}
+
+int main()
+{
+       const dub = environment.get("DUB", 
buildPath(__FILE_FULL_PATH__.dirName.dirName, "bin", "dub"));
+       const dc = environment.get("DC", "dmd");
+       const curr_dir = environment.get("CURR_DIR", 
buildPath(__FILE_FULL_PATH__.dirName));
+       const projDir = buildPath(curr_dir, "ninja-generator");
+
+       if (execute([dub, "generate", "ninja", "--compiler", dc], null, 
Config.none, size_t.max, projDir).status)
+               die("dub generate ninja failed");
+
+       execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, 
projDir);
+       if (execute(["ninja"], null, Config.none, size_t.max, projDir).status)
+               die("initial ninja build failed");
+
+       const jsonRecipePath = buildPath(projDir, "dub.json");
+       const origJson = readText(jsonRecipePath);
+       const newJson = `{
+    "name": "ninja-generator",
+    "targetType": "executable",
+    "importPaths": ["extra-imports"]
+}`;
+
+       if (!regenUpdatesImportPath(projDir, jsonRecipePath, origJson, newJson))
+               die("build.ninja was not actually regenerated with the new 
import path after touching dub.json");
+
+       const sdlProjDir = buildPath(curr_dir, "ninja-generator-sdl");
+
+       if (execute([dub, "generate", "ninja", "--compiler", dc], null, 
Config.none, size_t.max, sdlProjDir).status)
+               die("dub generate ninja failed for dub.sdl project");
+
+       const sdlBuildNinja = buildPath(sdlProjDir, "build.ninja");
+       if (!readText(sdlBuildNinja).canFind("regen") || 
!readText(sdlBuildNinja).canFind("dub.sdl"))
+               die("build.ninja regen edge missing dub.sdl dependency");
+
+       execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, 
sdlProjDir);
+       if (execute(["ninja"], null, Config.none, size_t.max, 
sdlProjDir).status)
+               die("initial ninja build failed for dub.sdl project");
+
+       const sdlRecipePath = buildPath(sdlProjDir, "dub.sdl");
+       const origSdl = readText(sdlRecipePath);
+       const newSdl = "name \"ninja-generator-sdl\"\ntargetType 
\"executable\"\nimportPaths \"extra-imports\"\n";
+
+       if (!regenUpdatesImportPath(sdlProjDir, sdlRecipePath, origSdl, newSdl))
+               die("build.ninja was not actually regenerated with the new 
import path after touching dub.sdl");
+
+       execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, 
sdlProjDir);
+       remove(sdlBuildNinja);
+
+       log("PASS");
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-generator.sh 
new/dub-1.43.0/test/ninja-generator.sh
--- old/dub-1.42.0/test/ninja-generator.sh      1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/test/ninja-generator.sh      2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+. $(dirname "${BASH_SOURCE[0]}")/common.sh
+
+cd "$CURR_DIR"/ninja-generator
+
+if ! $DUB generate ninja --compiler=$DC 2>&1; then
+    die $LINENO 'dub generate ninja failed!'
+fi
+
+if [ ! -f build.ninja ]; then
+    die $LINENO 'build.ninja was not generated!'
+fi
+
+if ! grep -q "rule dc" build.ninja; then
+    die $LINENO 'build.ninja missing dc rule!'
+fi
+
+if ! grep -q "rule link" build.ninja; then
+    die $LINENO 'build.ninja missing link rule!'
+fi
+
+rm -f build.ninja
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-makedeps/dub.json 
new/dub-1.43.0/test/ninja-makedeps/dub.json
--- old/dub-1.42.0/test/ninja-makedeps/dub.json 1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/test/ninja-makedeps/dub.json 2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,4 @@
+{
+    "name": "ninja-makedeps",
+    "targetType": "executable"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-makedeps/source/app.d 
new/dub-1.43.0/test/ninja-makedeps/source/app.d
--- old/dub-1.42.0/test/ninja-makedeps/source/app.d     1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-makedeps/source/app.d     2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,2 @@
+import helper;
+void main() { helperFunc(); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-makedeps/source/helper.d 
new/dub-1.43.0/test/ninja-makedeps/source/helper.d
--- old/dub-1.42.0/test/ninja-makedeps/source/helper.d  1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-makedeps/source/helper.d  2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1 @@
+void helperFunc() {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-makedeps.script.d 
new/dub-1.43.0/test/ninja-makedeps.script.d
--- old/dub-1.42.0/test/ninja-makedeps.script.d 1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/test/ninja-makedeps.script.d 2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,73 @@
+/+ dub.sdl:
+   name "ninja-makedeps-regen"
+   dependency "common" path="./common"
+ +/
+
+module ninja_makedeps_regen;
+
+import std.process : environment, execute, Config;
+import std.path : buildPath, dirName;
+import std.file : readText, write, timeLastModified, exists;
+import std.algorithm : canFind;
+import core.thread : Thread;
+import core.time : seconds;
+
+import common;
+
+int main()
+{
+       const dub = environment.get("DUB", 
buildPath(__FILE_FULL_PATH__.dirName.dirName, "bin", "dub"));
+       const dc = environment.get("DC", "dmd");
+       const curr_dir = environment.get("CURR_DIR", 
buildPath(__FILE_FULL_PATH__.dirName));
+       const projDir = buildPath(curr_dir, "ninja-makedeps");
+
+       if (execute([dub, "generate", "ninja", "--compiler", dc], null, 
Config.none, size_t.max, projDir).status)
+               die("dub generate ninja failed");
+
+       const buildNinjaPath = buildPath(projDir, "build.ninja");
+       if (!readText(buildNinjaPath).canFind("-makedeps"))
+               die("build.ninja missing -makedeps flag on dc rule");
+       if (!readText(buildNinjaPath).canFind("depfile ="))
+               die("build.ninja missing depfile directive on dc rule");
+
+       execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, 
projDir);
+       if (execute(["ninja"], null, Config.none, size_t.max, projDir).status)
+               die("initial ninja build failed");
+
+       // Locate the actual app.o produced, since the generator encodes the 
full
+       // source path into the object filename.
+       import std.file : dirEntries, SpanMode;
+       string findObj(string moduleName)
+       {
+               foreach (entry; dirEntries(projDir, SpanMode.shallow))
+                       if (entry.name.canFind("_" ~ moduleName ~ ".o"))
+                               return entry.name;
+               return "";
+       }
+
+       const objPath = findObj("app");
+       if (!objPath.length || !exists(objPath))
+               die("could not locate app.o after initial build");
+
+       const mtimeBefore = timeLastModified(objPath);
+
+       const helperPath = buildPath(projDir, "source", "helper.d");
+       const origHelper = readText(helperPath);
+
+       Thread.sleep(1.seconds);
+       write(helperPath, origHelper ~ "\n// touched\n");
+       scope(exit) write(helperPath, origHelper);
+
+       if (execute(["ninja"], null, Config.none, size_t.max, projDir).status)
+               die("rebuild after touching helper.d failed");
+
+       const mtimeAfter = timeLastModified(objPath);
+
+       if (mtimeAfter <= mtimeBefore)
+               die("app.o was not recompiled after helper.d changed -- depfile 
is not tracking transitive imports");
+
+       execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, 
projDir);
+
+       log("PASS");
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-static-lib/consumer.d 
new/dub-1.43.0/test/ninja-static-lib/consumer.d
--- old/dub-1.42.0/test/ninja-static-lib/consumer.d     1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-static-lib/consumer.d     2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,3 @@
+import std.stdio;
+extern(C) int add(int a, int b);
+void main() { write(add(2, 3)); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-static-lib/dub.json 
new/dub-1.43.0/test/ninja-static-lib/dub.json
--- old/dub-1.42.0/test/ninja-static-lib/dub.json       1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-static-lib/dub.json       2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,4 @@
+{
+    "name": "ninja-static-lib",
+    "targetType": "staticLibrary"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-static-lib/source/lib.d 
new/dub-1.43.0/test/ninja-static-lib/source/lib.d
--- old/dub-1.42.0/test/ninja-static-lib/source/lib.d   1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-static-lib/source/lib.d   2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1 @@
+extern(C) int add(int a, int b) { return a + b; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-subpackage/dub.json 
new/dub-1.43.0/test/ninja-subpackage/dub.json
--- old/dub-1.42.0/test/ninja-subpackage/dub.json       1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-subpackage/dub.json       2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,14 @@
+{
+    "name": "ninja-subpackage",
+    "targetType": "executable",
+    "dependencies": {
+        "ninja-subpackage:mylib": "*"
+    },
+    "subPackages": [
+        {
+            "name": "mylib",
+            "targetType": "staticLibrary",
+            "sourcePaths": ["lib/source"]
+        }
+    ]
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-subpackage/lib/source/lib.d 
new/dub-1.43.0/test/ninja-subpackage/lib/source/lib.d
--- old/dub-1.42.0/test/ninja-subpackage/lib/source/lib.d       1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-subpackage/lib/source/lib.d       2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1 @@
+extern(C) int add(int a, int b) { return a + b; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-subpackage/source/app.d 
new/dub-1.43.0/test/ninja-subpackage/source/app.d
--- old/dub-1.42.0/test/ninja-subpackage/source/app.d   1970-01-01 
01:00:00.000000000 +0100
+++ new/dub-1.43.0/test/ninja-subpackage/source/app.d   2026-10-31 
17:11:00.000000000 +0100
@@ -0,0 +1,2 @@
+extern(C) int add(int a, int b);
+void main() { assert(add(1, 2) == 3); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dub-1.42.0/test/ninja-subpackage.sh 
new/dub-1.43.0/test/ninja-subpackage.sh
--- old/dub-1.42.0/test/ninja-subpackage.sh     1970-01-01 01:00:00.000000000 
+0100
+++ new/dub-1.43.0/test/ninja-subpackage.sh     2026-10-31 17:11:00.000000000 
+0100
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+. $(dirname "${BASH_SOURCE[0]}")/common.sh
+
+cd "$CURR_DIR"/ninja-subpackage
+
+if ! $DUB generate ninja --compiler=$DC 2>&1; then
+    die $LINENO 'dub generate ninja failed!'
+fi
+
+if ! grep -q "rule ar" build.ninja; then
+    die $LINENO 'build.ninja missing ar rule!'
+fi
+
+if ! grep -q "\.a" build.ninja; then
+    die $LINENO 'build.ninja missing static library build edge!'
+fi
+
+ninja -t clean
+if ! ninja 2>&1; then
+    die $LINENO 'ninja build failed!'
+fi
+
+if ! ./ninja-subpackage 2>&1; then
+    die $LINENO 'linked executable failed to run!'
+fi
+
+ninja -t clean
+rm -f build.ninja

Reply via email to