diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a5b705f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository + +open_collective: dlang +custom: https://dlang.org/foundation/donate.html diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index b6a96cc..42e6cf9 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -92,6 +92,9 @@ /// Convert linker flags to compiler format string[] lflagsToDFlags(in string[] lflags) const; + /// Determines compiler version + string determineVersion(string compiler_binary, string verboseOutput); + /** Runs a tool and provides common boilerplate code. This method should be used by `Compiler` implementations to invoke the @@ -123,19 +126,12 @@ compiler_binary = binary to invoke compiler with args = arguments for the probe compilation arch_override = special handler for x86_mscoff - versionRes = array of regular expressions to scan the output - and find the compiler version. For each, the - version must be in capture index 1. The output - is scanned in multi-line mode (i.e. ^ will match any line start) */ protected final BuildPlatform probePlatform(string compiler_binary, string[] args, - string arch_override, string[] versionRes) + string arch_override) { import dub.compilers.utils : generatePlatformProbeFile, readPlatformJsonProbe; - import std.algorithm : filter, map; - import std.range : takeOne; - import std.regex : matchFirst, regex; - import std.string : format; + import std.string : format, strip; auto fil = generatePlatformProbeFile(); @@ -151,17 +147,14 @@ `This will probably result in build errors.`, build_platform.compiler, this.name); } - auto ver = versionRes - .map!(re => matchFirst(result.output, regex(re, "m"))) - .filter!(c => c.length > 1) - .map!(c => c[1]) - .takeOne(); + auto ver = determineVersion(compiler_binary, result.output) + .strip; if (ver.empty) { logWarn(`Could not probe the compiler version for "%s". ` ~ `Toolchain requirements might be ineffective`, build_platform.compiler); } else { - build_platform.compilerVersion = ver.front; + build_platform.compilerVersion = ver; } // Hack: see #1059 diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index a628076..bf06e4c 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -99,6 +99,13 @@ assert(c && c.length > 1 && c[1] == "2.084.0-beta.1"); } + string determineVersion(string compiler_binary, string verboseOutput) + { + import std.regex : matchFirst, regex; + auto ver = matchFirst(verboseOutput, regex(dmdVersionRe, "m")); + return ver && ver.length > 1 ? ver[1] : null; + } + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) { string[] arch_flags; @@ -109,7 +116,7 @@ version (Windows) { const is64bit = isWow64(); if (!is64bit.isNull) - arch_flags = [is64bit ? "-m64" : "-m32mscoff"]; + arch_flags = [is64bit.get ? "-m64" : "-m32mscoff"]; } break; case "x86": arch_flags = ["-m32"]; break; @@ -121,8 +128,7 @@ return probePlatform( compiler_binary, arch_flags ~ ["-quiet", "-c", "-o-", "-v"], - arch_override, - [ dmdVersionRe ] + arch_override ); } @@ -287,7 +293,7 @@ string[] lflagsToDFlags(in string[] lflags) const { - return lflags.map!(f => "-L"~f)().array(); + return map!(f => "-L"~f)(lflags.filter!(f => f != "")()).array(); } private auto escapeArgs(in string[] args) diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 53225e3..4a9c0d2 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -54,31 +54,15 @@ @property string name() const { return "gdc"; } - enum gdcVersionRe1 = `GDC\s+(\d+\.\d+\.\d+[A-Za-z0-9.+-]*)`; - enum gdcVersionRe2 = `^GNU D \(.*?\) version (\d+\.\d+\.\d+[A-Za-z0-9.+-]*)`; - enum gdcVersionRe3 = `^gcc version (\d+\.\d+\.\d+[A-Za-z0-9.+-]*)`; + string determineVersion(string compiler_binary, string verboseOutput) + { + const result = execute([ + compiler_binary, + "-dumpfullversion", + "-dumpversion" + ]); - unittest { - import std.algorithm : equal, map; - import std.range : only; - import std.regex : matchFirst, regex; - auto probe = ` -Target: x86_64-pc-linux-gnu -Thread model: posix -gcc version 8.2.1 20180831 (GDC 8.2.1 based on D v2.068.2 built with ISL 0.20 for Arch Linux) -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -GNU D (GDC 8.2.1 based on D v2.068.2 built with ISL 0.20 for Arch Linux) version 8.2.1 20180831 (x86_64-pc-linux-gnu) -GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 -binary /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/cc1d -version v2.068.2 -predefs GNU D_Version2 LittleEndian GNU_DWARF2_Exceptions GNU_StackGrowsDown GNU_InlineAsm D_LP64 D_PIC assert all X86_64 D_HardFloat Posix linux CRuntime_Glibc -`; - auto vers = only(gdcVersionRe1, gdcVersionRe2, gdcVersionRe3) - .map!(re => matchFirst(probe, regex(re, "m"))) - .filter!(c => c && c.length > 1) - .map!(c => c[1]); - - assert(vers.equal([ "8.2.1", "8.2.1", "8.2.1" ])); + return result.status == 0 ? result.output : null; } BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) @@ -97,8 +81,7 @@ return probePlatform( compiler_binary, arch_flags ~ ["-S", "-v"], - arch_override, - [ gdcVersionRe1, gdcVersionRe2, gdcVersionRe3 ] + arch_override ); } @@ -250,6 +233,9 @@ string[] dflags; foreach( f; lflags ) { + if ( f == "") { + continue; + } dflags ~= "-Xlinker"; dflags ~= f; } diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 4522825..11c2872 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -69,6 +69,13 @@ assert(c && c.length > 1 && c[1] == "1.11.0"); } + string determineVersion(string compiler_binary, string verboseOutput) + { + import std.regex : matchFirst, regex; + auto ver = matchFirst(verboseOutput, regex(ldcVersionRe, "m")); + return ver && ver.length > 1 ? ver[1] : null; + } + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) { string[] arch_flags; @@ -83,8 +90,7 @@ return probePlatform( compiler_binary, arch_flags ~ ["-c", "-o-", "-v"], - arch_override, - [ ldcVersionRe ] + arch_override ); } @@ -230,7 +236,7 @@ string[] lflagsToDFlags(in string[] lflags) const { - return lflags.map!(s => "-L="~s)().array(); + return map!(f => "-L"~f)(lflags.filter!(f => f != "")()).array(); } private auto escapeArgs(in string[] args) diff --git a/source/dub/dub.d b/source/dub/dub.d index 33f99cc..d1b6d4c 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -1630,7 +1630,7 @@ // note: external sub packages are handled further below auto spr = basepack.getInternalSubPackage(subname); if (!spr.isNull) { - auto sp = new Package(spr, basepack.path, basepack); + auto sp = new Package(spr.get, basepack.path, basepack); m_remotePackages[sp.name] = sp; return sp; } else { diff --git a/source/dub/internal/utils.d b/source/dub/internal/utils.d index 6466e5b..6380791 100644 --- a/source/dub/internal/utils.d +++ b/source/dub/internal/utils.d @@ -366,13 +366,20 @@ on "unrecoverable failures" such as 404 not found Otherwise might throw anything else that `download` throws. See_Also: download + + The download times out if a connection cannot be established within + `timeout` ms, or if the average transfer rate drops below 10 bytes / s for + more than `timeout` seconds. Pass `0` as `timeout` to disable both timeout + mechanisms. + + Note: Timeouts are only implemented when curl is used (DubUseCurl). **/ -void retryDownload(URL url, NativePath filename, size_t retryCount = 3) +void retryDownload(URL url, NativePath filename, size_t retryCount = 3, uint timeout = 8) { foreach(i; 0..retryCount) { version(DubUseCurl) { try { - download(url, filename); + download(url, filename, timeout); return; } catch(HTTPStatusException e) { @@ -408,12 +415,12 @@ } ///ditto -ubyte[] retryDownload(URL url, size_t retryCount = 3) +ubyte[] retryDownload(URL url, size_t retryCount = 3, uint timeout = 8) { foreach(i; 0..retryCount) { version(DubUseCurl) { try { - return download(url); + return download(url, timeout); } catch(HTTPStatusException e) { if (e.status == 404) throw e; diff --git a/source/dub/packagesuppliers/maven.d b/source/dub/packagesuppliers/maven.d index 372851d..eaee689 100644 --- a/source/dub/packagesuppliers/maven.d +++ b/source/dub/packagesuppliers/maven.d @@ -17,6 +17,7 @@ import std.datetime : Clock, Duration, hours, SysTime, UTC; private { + enum httpTimeout = 16; URL m_mavenUrl; struct CacheEntry { Json data; SysTime cacheTime; } CacheEntry[string] m_metadataCache; @@ -57,7 +58,7 @@ auto url = m_mavenUrl~NativePath("%s/%s/%s-%s.zip".format(packageId, vers, packageId, vers)); try { - retryDownload(url, path); + retryDownload(url, path, 3, httpTimeout); return; } catch(HTTPStatusException e) { @@ -93,7 +94,7 @@ string xmlData; try - xmlData = cast(string)retryDownload(url); + xmlData = cast(string)retryDownload(url, 3, httpTimeout); catch(HTTPStatusException e) { if (e.status == 404) { logDebug("Maven metadata %s not found at %s (404): %s", packageId, description, e.msg); diff --git a/test/issue1003-check-empty-ld-flags.sh b/test/issue1003-check-empty-ld-flags.sh new file mode 100755 index 0000000..61678f7 --- /dev/null +++ b/test/issue1003-check-empty-ld-flags.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +. $(dirname "${BASH_SOURCE[0]}")/common.sh + +cd ${CURR_DIR}/issue1003-check-empty-ld-flags + +${DUB} build --compiler=${DC} --force diff --git a/test/issue1003-check-empty-ld-flags/dub.json b/test/issue1003-check-empty-ld-flags/dub.json new file mode 100644 index 0000000..7c4c251 --- /dev/null +++ b/test/issue1003-check-empty-ld-flags/dub.json @@ -0,0 +1,10 @@ +{ + "authors": [ + "--" + ], + "copyright": "Copyright © 2019, --", + "description": "--", + "license": "--", + "name": "issue1003-empty-ld-flags", + "lflags": [""] +} diff --git a/test/issue1003-check-empty-ld-flags/source/app.d b/test/issue1003-check-empty-ld-flags/source/app.d new file mode 100644 index 0000000..c3eec7f --- /dev/null +++ b/test/issue1003-check-empty-ld-flags/source/app.d @@ -0,0 +1,6 @@ +import std.stdio; + +void main() +{ + writeln("Edit source/app.d to start your project."); +} diff --git a/test/issue1037-better-dependency-messages.sh b/test/issue1037-better-dependency-messages.sh index c06bdc4..4c5c87a 100755 --- a/test/issue1037-better-dependency-messages.sh +++ b/test/issue1037-better-dependency-messages.sh @@ -9,7 +9,7 @@ function cleanup { rm -f $temp_file - rm -f $temp_file + rm -f $temp_file2 } trap cleanup EXIT @@ -22,4 +22,4 @@ die 'output not containing conflict information' fi -exit 0 \ No newline at end of file +exit 0