diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index 42e6cf9..f81d0cf 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -72,7 +72,7 @@ /// Replaces high level fields with low level fields and converts /// dmd flags to compiler-specific flags - void prepareBuildSettings(ref BuildSettings settings, BuildSetting supported_fields = BuildSetting.all) const; + void prepareBuildSettings(ref BuildSettings settings, in ref BuildPlatform platform, BuildSetting supported_fields = BuildSetting.all) const; /// Removes any dflags that match one of the BuildOptions values and populates the BuildSettings.options field. void extractBuildOptions(ref BuildSettings settings) const; diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index bf06e4c..3d695fb 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -132,7 +132,7 @@ ); } - void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) const + void prepareBuildSettings(ref BuildSettings settings, in ref BuildPlatform platform, BuildSetting fields = BuildSetting.all) const { enforceBuildRequirements(settings); @@ -163,9 +163,11 @@ } if (!(fields & BuildSetting.libs)) { - resolveLibs(settings); - version(Windows) settings.addSourceFiles(settings.libs.map!(l => l~".lib")().array()); - else settings.addLFlags(settings.libs.map!(l => "-l"~l)().array()); + resolveLibs(settings, platform); + if (platform.platform.canFind("windows")) + settings.addSourceFiles(settings.libs.map!(l => l~".lib")().array()); + else + settings.addLFlags(settings.libs.map!(l => "-l"~l)().array()); } if (!(fields & BuildSetting.sourceFiles)) { @@ -178,10 +180,8 @@ settings.lflags = null; } - version (Posix) { - if (settings.options & BuildOption.pic) - settings.addDFlags("-fPIC"); - } + if (platform.platform.canFind("posix") && (settings.options & BuildOption.pic)) + settings.addDFlags("-fPIC"); assert(fields & BuildSetting.dflags); assert(fields & BuildSetting.copyFiles); @@ -248,9 +248,10 @@ settings.addDFlags("-lib"); break; case TargetType.dynamicLibrary: - version (Windows) settings.addDFlags("-shared"); - else version (OSX) settings.addDFlags("-shared"); - else settings.prependDFlags("-shared", "-defaultlib=libphobos2.so"); + if (platform.platform.canFind("windows") || platform.platform.canFind("osx")) + settings.addDFlags("-shared"); + else + settings.prependDFlags("-shared", "-defaultlib=libphobos2.so"); break; case TargetType.object: settings.addDFlags("-c"); @@ -280,7 +281,8 @@ auto args = ["-of"~tpath.toNativeString()]; args ~= objects; args ~= settings.sourceFiles; - version(linux) args ~= "-L--no-as-needed"; // avoids linker errors due to libraries being specified in the wrong order by DMD + if (platform.platform.canFind("linux")) + args ~= "-L--no-as-needed"; // avoids linker errors due to libraries being specified in the wrong order by DMD args ~= lflagsToDFlags(settings.lflags); args ~= settings.dflags.filter!(f => isLinkerDFlag(f)).array; diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 4a9c0d2..eb753d8 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -85,7 +85,7 @@ ); } - void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) const + void prepareBuildSettings(ref BuildSettings settings, in ref BuildPlatform platform, BuildSetting fields = BuildSetting.all) const { enforceBuildRequirements(settings); @@ -121,7 +121,7 @@ } if (!(fields & BuildSetting.libs)) { - resolveLibs(settings); + resolveLibs(settings, platform); settings.addDFlags(settings.libs.map!(l => "-l"~l)().array()); } @@ -222,7 +222,8 @@ args = [ "ar", "rcs", tpath ] ~ objects; } else { args = platform.compilerBinary ~ objects ~ settings.sourceFiles ~ settings.lflags ~ settings.dflags.filter!(f => isLinkageFlag(f)).array; - version(linux) args ~= "-L--no-as-needed"; // avoids linker errors due to libraries being specified in the wrong order by DMD + if (platform.platform.canFind("linux")) + args ~= "-L--no-as-needed"; // avoids linker errors due to libraries being specified in the wrong order } logDiagnostic("%s", args.join(" ")); invokeTool(args, output_callback); diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 84e0a8e..7e77d0e 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -99,7 +99,7 @@ ); } - void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) const + void prepareBuildSettings(ref BuildSettings settings, in ref BuildPlatform platform, BuildSetting fields = BuildSetting.all) const { enforceBuildRequirements(settings); @@ -138,7 +138,7 @@ } if (!(fields & BuildSetting.libs)) { - resolveLibs(settings); + resolveLibs(settings, platform); settings.addLFlags(settings.libs.map!(l => "-l"~l)().array()); } diff --git a/source/dub/compilers/utils.d b/source/dub/compilers/utils.d index 03b3c33..da847bc 100644 --- a/source/dub/compilers/utils.d +++ b/source/dub/compilers/utils.d @@ -40,37 +40,36 @@ Linker files include static/dynamic libraries, resource files, object files and DLL definition files. */ -bool isLinkerFile(string f) +bool isLinkerFile(in ref BuildPlatform platform, string f) { import std.path; switch (extension(f)) { default: return false; - version (Windows) { - case ".lib", ".obj", ".res", ".def": - return true; - } else { - case ".a", ".o", ".so", ".dylib": - return true; - } + case ".lib", ".obj", ".res", ".def": + return platform.platform.canFind("windows"); + case ".a", ".o", ".so", ".dylib": + return !platform.platform.canFind("windows"); } } unittest { - version (Windows) { - assert(isLinkerFile("test.obj")); - assert(isLinkerFile("test.lib")); - assert(isLinkerFile("test.res")); - assert(!isLinkerFile("test.o")); - assert(!isLinkerFile("test.d")); - } else { - assert(isLinkerFile("test.o")); - assert(isLinkerFile("test.a")); - assert(isLinkerFile("test.so")); - assert(isLinkerFile("test.dylib")); - assert(!isLinkerFile("test.obj")); - assert(!isLinkerFile("test.d")); - } + BuildPlatform p; + + p.platform = ["windows"]; + assert(isLinkerFile(p, "test.obj")); + assert(isLinkerFile(p, "test.lib")); + assert(isLinkerFile(p, "test.res")); + assert(!isLinkerFile(p, "test.o")); + assert(!isLinkerFile(p, "test.d")); + + p.platform = ["something else"]; + assert(isLinkerFile(p, "test.o")); + assert(isLinkerFile(p, "test.a")); + assert(isLinkerFile(p, "test.so")); + assert(isLinkerFile(p, "test.dylib")); + assert(!isLinkerFile(p, "test.obj")); + assert(!isLinkerFile(p, "test.d")); } @@ -80,7 +79,7 @@ This function tries to invoke "pkg-config" if possible and falls back to direct flag translation if that fails. */ -void resolveLibs(ref BuildSettings settings) +void resolveLibs(ref BuildSettings settings, in ref BuildPlatform platform) { import std.string : format; import std.array : array; @@ -90,7 +89,8 @@ if (settings.targetType == TargetType.library || settings.targetType == TargetType.staticLibrary) { logDiagnostic("Ignoring all import libraries for static library build."); settings.libs = null; - version(Windows) settings.sourceFiles = settings.sourceFiles.filter!(f => !f.endsWith(".lib")).array; + if (platform.platform.canFind("windows")) + settings.sourceFiles = settings.sourceFiles.filter!(f => !f.endsWith(".lib")).array; } version (Posix) { diff --git a/source/dub/dub.d b/source/dub/dub.d index c8d4845..4e85269 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -32,9 +32,6 @@ import std.string; import std.encoding : sanitize; -// Workaround for libcurl liker errors when building with LDC -version (LDC) pragma(lib, "curl"); - // Set output path and options for coverage reports version (DigitalMars) version (D_Coverage) static if (__VERSION__ >= 2068) { diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index 5e5981a..47fcfee 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -27,8 +27,10 @@ import std.string; import std.encoding : sanitize; -version(Windows) enum objSuffix = ".obj"; -else enum objSuffix = ".o"; +string getObjSuffix(in ref BuildPlatform platform) +{ + return platform.platform.canFind("windows") ? ".obj" : ".o"; +} class BuildGenerator : ProjectGenerator { private { @@ -230,7 +232,7 @@ // do not pass all source files to RDMD, only the main source file buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(s => !s.endsWith(".d"))().array(); - settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine); + settings.compiler.prepareBuildSettings(buildsettings, settings.platform, BuildSetting.commandLine); auto generate_binary = !buildsettings.dflags.canFind("-o-"); @@ -416,13 +418,14 @@ /// Calls with path that resolve to the same file on the filesystem will return the same, /// unless they include different symbolic links (which are not resolved). - static string pathToObjName(string path) + static string pathToObjName(in ref BuildPlatform platform, string path) { import std.digest.crc : crc32Of; import std.path : buildNormalizedPath, dirSeparator, relativePath, stripDrive; if (path.endsWith(".d")) path = path[0 .. $-2]; auto ret = buildNormalizedPath(getcwd(), path).replace(dirSeparator, "."); auto idx = ret.lastIndexOf('.'); + const objSuffix = getObjSuffix(platform); return idx < 0 ? ret ~ objSuffix : format("%s_%(%02x%)%s", ret[idx+1 .. $], crc32Of(ret[0 .. idx]), objSuffix); } @@ -434,7 +437,7 @@ bs.lflags = null; bs.sourceFiles = [ srcFile ]; bs.targetType = TargetType.object; - gs.compiler.prepareBuildSettings(bs, BuildSetting.commandLine); + gs.compiler.prepareBuildSettings(bs, gs.platform, BuildSetting.commandLine); gs.compiler.setTarget(bs, gs.platform, objPath); gs.compiler.invoke(bs, gs.platform, gs.compileCallback); return objPath; @@ -456,12 +459,13 @@ import std.parallelism, std.range : walkLength; auto lbuildsettings = buildsettings; - auto srcs = buildsettings.sourceFiles.filter!(f => !isLinkerFile(f)); + auto srcs = buildsettings.sourceFiles.filter!(f => !isLinkerFile(settings.platform, f)); auto objs = new string[](srcs.walkLength); void compileSource(size_t i, string src) { logInfo("Compiling %s...", src); - objs[i] = compileUnit(src, pathToObjName(src), buildsettings, settings); + const objPath = pathToObjName(settings.platform, src); + objs[i] = compileUnit(src, objPath, buildsettings, settings); } if (settings.parallelBuild) { @@ -471,40 +475,40 @@ } logInfo("Linking..."); - lbuildsettings.sourceFiles = is_static_library ? [] : lbuildsettings.sourceFiles.filter!(f=> f.isLinkerFile()).array; + lbuildsettings.sourceFiles = is_static_library ? [] : lbuildsettings.sourceFiles.filter!(f => isLinkerFile(settings.platform, f)).array; settings.compiler.setTarget(lbuildsettings, settings.platform); - settings.compiler.prepareBuildSettings(lbuildsettings, BuildSetting.commandLineSeparate|BuildSetting.sourceFiles); + settings.compiler.prepareBuildSettings(lbuildsettings, settings.platform, BuildSetting.commandLineSeparate|BuildSetting.sourceFiles); settings.compiler.invokeLinker(lbuildsettings, settings.platform, objs, settings.linkCallback); // NOTE: separate compile/link is not yet enabled for GDC. } else if (generate_binary && (settings.buildMode == BuildMode.allAtOnce || settings.compiler.name == "gdc" || is_static_library)) { // don't include symbols of dependencies (will be included by the top level target) - if (is_static_library) buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(f => !f.isLinkerFile()).array; + if (is_static_library) buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(f => !isLinkerFile(settings.platform, f)).array; // setup for command line settings.compiler.setTarget(buildsettings, settings.platform); - settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine); + settings.compiler.prepareBuildSettings(buildsettings, settings.platform, BuildSetting.commandLine); // invoke the compiler settings.compiler.invoke(buildsettings, settings.platform, settings.compileCallback); } else { // determine path for the temporary object file - string tempobjname = buildsettings.targetName ~ objSuffix; + string tempobjname = buildsettings.targetName ~ getObjSuffix(settings.platform); NativePath tempobj = NativePath(buildsettings.targetPath) ~ tempobjname; // setup linker command line auto lbuildsettings = buildsettings; - lbuildsettings.sourceFiles = lbuildsettings.sourceFiles.filter!(f => isLinkerFile(f)).array; + lbuildsettings.sourceFiles = lbuildsettings.sourceFiles.filter!(f => isLinkerFile(settings.platform, f)).array; if (generate_binary) settings.compiler.setTarget(lbuildsettings, settings.platform); - settings.compiler.prepareBuildSettings(lbuildsettings, BuildSetting.commandLineSeparate|BuildSetting.sourceFiles); + settings.compiler.prepareBuildSettings(lbuildsettings, settings.platform, BuildSetting.commandLineSeparate|BuildSetting.sourceFiles); // setup compiler command line buildsettings.libs = null; buildsettings.lflags = null; if (generate_binary) buildsettings.addDFlags("-c", "-of"~tempobj.toNativeString()); - buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(f => !isLinkerFile(f)).array; + buildsettings.sourceFiles = buildsettings.sourceFiles.filter!(f => !isLinkerFile(settings.platform, f)).array; - settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine); + settings.compiler.prepareBuildSettings(buildsettings, settings.platform, BuildSetting.commandLine); settings.compiler.invoke(buildsettings, settings.platform, settings.compileCallback); diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index ddbbc33..1d8990f 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -353,7 +353,7 @@ { auto pdepti = &targets[depname]; configureDependents(*pdepti, targets, level + 1); - mergeFromDependency(pdepti.buildSettings, ti.buildSettings); + mergeFromDependency(pdepti.buildSettings, ti.buildSettings, genSettings.platform); } } @@ -519,7 +519,7 @@ child.addOptions(BuildOptions(parent.options & inheritedBuildOptions)); } - private static void mergeFromDependency(in ref BuildSettings child, ref BuildSettings parent) + private static void mergeFromDependency(in ref BuildSettings child, ref BuildSettings parent, in ref BuildPlatform platform) { import dub.compilers.utils : isLinkerFile; @@ -532,7 +532,7 @@ parent.addStringImportPaths(child.stringImportPaths); // linking of static libraries is done by parent if (child.targetType == TargetType.staticLibrary) { - parent.addSourceFiles(child.sourceFiles.filter!isLinkerFile.array); + parent.addSourceFiles(child.sourceFiles.filter!(f => isLinkerFile(platform, f)).array); parent.addLibs(child.libs); parent.addLFlags(child.lflags); } diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d index 87c8e51..df65729 100644 --- a/source/dub/generators/visuald.d +++ b/source/dub/generators/visuald.d @@ -194,7 +194,7 @@ addFile(p.recipePath.toNativeString(), false); if (files.targetType == TargetType.staticLibrary) - foreach(s; files.sourceFiles.filter!(s => !isLinkerFile(s))) addFile(s, true); + foreach(s; files.sourceFiles.filter!(s => !isLinkerFile(settings.platform, s))) addFile(s, true); else foreach(s; files.sourceFiles.filter!(s => !s.endsWith(".lib"))) addFile(s, true); diff --git a/source/dub/project.d b/source/dub/project.d index 48b6752..5f94b25 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -790,7 +790,7 @@ else static if (attributeName == "stringImportPaths") bs.stringImportPaths = bs.stringImportPaths.map!(ensureTrailingSlash).array(); - compiler.prepareBuildSettings(bs, BuildSetting.all & ~to!BuildSetting(attributeName)); + compiler.prepareBuildSettings(bs, platform, BuildSetting.all & ~to!BuildSetting(attributeName)); values = bs.dflags; break; @@ -801,7 +801,7 @@ bs.sourceFiles = null; bs.targetType = TargetType.none; // Force Compiler to NOT omit dependency libs when package is a library. - compiler.prepareBuildSettings(bs, BuildSetting.all & ~to!BuildSetting(attributeName)); + compiler.prepareBuildSettings(bs, platform, BuildSetting.all & ~to!BuildSetting(attributeName)); if (bs.lflags) values = compiler.lflagsToDFlags( bs.lflags ); @@ -1026,13 +1026,13 @@ if (projectDescription.rootPackage in projectDescription.targetLookup) { // Copy linker files from sourceFiles to linkerFiles auto target = projectDescription.lookupTarget(projectDescription.rootPackage); - foreach (file; target.buildSettings.sourceFiles.filter!(isLinkerFile)) + foreach (file; target.buildSettings.sourceFiles.filter!(f => isLinkerFile(settings.platform, f))) target.buildSettings.addLinkerFiles(file); // Remove linker files from sourceFiles target.buildSettings.sourceFiles = target.buildSettings.sourceFiles - .filter!(a => !isLinkerFile(a)) + .filter!(a => !isLinkerFile(settings.platform, a)) .array(); projectDescription.lookupTarget(projectDescription.rootPackage) = target; }