diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index 2ae3a9a..950f29a 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -182,7 +182,9 @@ // cmdline option does not lead to the same string being found among // `build_platform.architecture`, as it's brittle and doesn't work with triples. if (build_platform.compiler != "ldc") { - if (arch_override.length && !build_platform.architecture.canFind(arch_override)) { + if (arch_override.length && !build_platform.architecture.canFind(arch_override) && + !(build_platform.compiler == "dmd" && arch_override.among("x86_omf", "x86_mscoff")) // Will be fixed in determinePlatform + ) { logWarn(`Failed to apply the selected architecture %s. Got %s.`, arch_override, build_platform.architecture); } diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index f8f9f7b..65ee2f4 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -106,29 +106,70 @@ BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) { + // Set basic arch flags for the probe - might be revised based on the exact value + compiler version string[] arch_flags; - switch (arch_override) { - default: throw new UnsupportedArchitectureException(arch_override); - case "": - // Don't use Optlink by default on Windows - version (Windows) { - const is64bit = isWow64(); - if (!is64bit.isNull) - arch_flags = [is64bit.get ? "-m64" : "-m32mscoff"]; - } - break; - case "x86": arch_flags = ["-m32"]; break; - case "x86_omf": arch_flags = ["-m32"]; break; - case "x86_64": arch_flags = ["-m64"]; break; - case "x86_mscoff": arch_flags = ["-m32mscoff"]; break; + if (arch_override.length) + arch_flags = [ arch_override != "x86_64" ? "-m32" : "-m64" ]; + else + { + // Don't use Optlink by default on Windows + version (Windows) { + const is64bit = isWow64(); + if (!is64bit.isNull) + arch_flags = [ is64bit.get ? "-m64" : "-m32" ]; + } } - settings.addDFlags(arch_flags); - return probePlatform( + BuildPlatform bp = probePlatform( compiler_binary, arch_flags ~ ["-quiet", "-c", "-o-", "-v"], arch_override ); + + /// Replace archticture string in `bp.archtiecture` + void replaceArch(const string from, const string to) + { + const idx = bp.architecture.countUntil(from); + if (idx != -1) + bp.architecture[idx] = to; + } + + // DMD 2.099 changed the default for -m32 from OMF to MsCOFF + const m32IsCoff = bp.frontendVersion >= 2_099; + + switch (arch_override) { + default: throw new UnsupportedArchitectureException(arch_override); + case "": break; + case "x86": arch_flags = ["-m32"]; break; + case "x86_64": arch_flags = ["-m64"]; break; + + case "x86_omf": + if (m32IsCoff) + { + arch_flags = [ "-m32omf" ]; + replaceArch("x86_mscoff", "x86_omf"); // Probe used the wrong default + } + else // -m32 is OMF + { + arch_flags = [ "-m32" ]; + } + break; + + case "x86_mscoff": + if (m32IsCoff) + { + arch_flags = [ "-m32" ]; + } + else // -m32 is OMF + { + arch_flags = [ "-m32mscoff" ]; + replaceArch("x86_omf", "x86_mscoff"); // Probe used the wrong default + } + break; + } + settings.addDFlags(arch_flags); + + return bp; } version (Windows) version (DigitalMars) unittest { diff --git a/test/win32_default.d b/test/win32_default.d new file mode 100644 index 0000000..fcbfe5a --- /dev/null +++ b/test/win32_default.d @@ -0,0 +1,54 @@ +/+ dub.json: { + "name": "win32_default", + "configurations": [ + { + "name": "Default", + "versions": [ "Default" ] + }, + { + "name": "OMF", + "versions": [ "OMF" ] + }, + { + "name": "MsCoff", + "versions": [ "MsCoff" ] + }, + { + "name": "MsCoff64", + "versions": [ "MsCoff", "Is64" ] + } + ] +} +/ + +module dynlib.app; + +pragma(msg, "Frontend: ", __VERSION__); + +// Object format should match the expectation +version (OMF) +{ + enum expSize = 4; + enum expFormat = "omf"; +} +else version (MsCoff) +{ + // Should be a 32 bit build + version (Is64) enum expSize = 8; + else enum expSize = 4; + + enum expFormat = "coff"; +} +else version (Default) +{ + enum expSize = 4; + enum expFormat = __VERSION__ >= 2099 ? "coff" : "omf"; +} +else +{ + static assert(false, "Missing version flag!"); +} + +enum actFormat = __traits(getTargetInfo, "objectFormat"); + +static assert(actFormat == expFormat); +static assert((int*).sizeof == expSize); diff --git a/test/win32_default.script.d b/test/win32_default.script.d new file mode 100644 index 0000000..de0356e --- /dev/null +++ b/test/win32_default.script.d @@ -0,0 +1,89 @@ +/+ dub.json: { + "name": "win32_default_test" +} +/ + +module win32_default.script; + +int main() +{ + import std.stdio; + + version (Windows) + { + version (DigitalMars) + enum disabled = null; + else + enum disabled = "DMD as the host compiler"; + } + else + enum disabled = "Windows"; + + static if (disabled) + { + writeln("Test `win32_default` requires " ~ disabled); + return 0; + } + else + { + import std.algorithm; + import std.path; + import std.process; + + const dir = __FILE_FULL_PATH__.dirName(); + const file = buildPath(dir, "win32_default.d"); + + const dub = environment.get("DUB", buildPath(dirName(dir), "bin", "dub.exe")); + const dmd = environment.get("DMD", "dmd"); + + int exitCode; + + void runTest(scope const string[] cmd) + { + const result = execute(cmd); + + if (result.status || result.output.canFind("Failed")) + { + writefln("\n> %-(%s %)", cmd); + writeln("==========================================================="); + writeln(result.output); + writeln("==========================================================="); + writeln("Last command failed with exit code ", result.status, '\n'); + exitCode = 1; + } + } + + // Test without --arch + runTest([ + dub, "build", + "--compiler", dmd, + "--config", "MsCoff64", + "--single", file, + ]); + + // Test with different --arch + const string[2][] tests = [ + [ "x86", "Default" ], + [ "x86_omf", "OMF" ], + [ "x86_mscoff", "MsCoff" ], + [ "x86_64", "MsCoff64" ], + ]; + + foreach (string[2] test; tests) + { + const arch = test[0]; + const config = test[1]; + + runTest([ + dub, "build", + "--compiler", dmd, + "--arch", arch, + "--config", config, + "--single", file, + ]); + } + + + + return exitCode; + } +}