diff --git a/source/app.d b/source/app.d index 9c16ef4..7eb0307 100644 --- a/source/app.d +++ b/source/app.d @@ -12,7 +12,6 @@ import dub.dub; import dub.generators.generator; import dub.package_; -import dub.platform; import dub.project; import dub.registry; @@ -48,6 +47,7 @@ LogLevel loglevel = LogLevel.Info; string build_type = "debug", build_config; string compiler_name = "dmd"; + string arch; bool rdmd = false; bool print_platform, print_builds, print_configs; bool install_system = false, install_local = false; @@ -62,6 +62,7 @@ "annotate", &annotate, "build", &build_type, "compiler", &compiler_name, + "arch", &arch, "rdmd", &rdmd, "config", &build_config, "print-builds", &print_builds, @@ -97,13 +98,9 @@ Url registryUrl = Url.parse("http://registry.vibed.org/"); logDebug("Using dub registry url '%s'", registryUrl); + BuildSettings build_settings; auto compiler = getCompiler(compiler_name); - - // FIXME: take into account command line flags - BuildPlatform build_platform; - build_platform.platform = determinePlatform(); - build_platform.architecture = determineArchitecture(); - build_platform.compiler = compiler.name; + auto build_platform = compiler.determinePlatform(build_settings, compiler_name, arch); if( print_platform ){ logInfo("Build platform:"); @@ -236,6 +233,7 @@ gensettings.buildType = build_type; gensettings.compiler = compiler; gensettings.compilerBinary = compiler_name; + gensettings.buildSettings = build_settings; gensettings.run = cmd == "run"; gensettings.runArgs = args[1 .. $]; @@ -296,6 +294,7 @@ be defined in package.json --compiler=NAME Uses one of the supported compilers: dmd (default), gcc, ldc, gdmd, ldmd + --arch=NAME Force a different architecture (e.g. x86 or x86_64) --nodeps Do not check dependencies for 'run' or 'build' --print-builds Prints the list of available build types --print-configs Prints the list of available configurations diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index 79b54eb..fe3846f 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -48,6 +48,8 @@ interface Compiler { @property string name() const; + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override = null); + /// 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); diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index 086e412..a3c95c3 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -8,6 +8,7 @@ module dub.compilers.dmd; import dub.compilers.compiler; +import dub.platform; import std.algorithm; import std.array; @@ -21,6 +22,29 @@ class DmdCompiler : Compiler { @property string name() const { return "dmd"; } + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) + { + // TODO: determine platform by invoking the compiler instead + BuildPlatform build_platform; + build_platform.platform = .determinePlatform(); + build_platform.architecture = .determineArchitecture(); + build_platform.compiler = this.name; + + switch(arch_override){ + default: throw new Exception("Unsupported architecture: "~arch_override); + case "": break; + case "x86": + build_platform.architecture = ["x86"]; + settings.addDFlags("-m32"); + break; + case "x86_64": + build_platform.architecture = ["x86_64"]; + settings.addDFlags("-m64"); + break; + } + return build_platform; + } + void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { if( !(fields & BuildSetting.libs) ){ diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 3c51ff5..76af13a 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -8,6 +8,7 @@ module dub.compilers.gdc; import dub.compilers.compiler; +import dub.platform; import std.algorithm; import std.array; @@ -21,6 +22,18 @@ class GdcCompiler : Compiler { @property string name() const { return "gdc"; } + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) + { + // TODO: determine platform by invoking the compiler instead + BuildPlatform build_platform; + build_platform.platform = .determinePlatform(); + build_platform.architecture = .determineArchitecture(); + build_platform.compiler = this.name; + + enforce(arch_override.length == 0, "Architecture override not implemented for GDC."); + return build_platform; + } + void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { // convert common DMD flags to the corresponding GDC flags diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 49f8973..655ce11 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -8,6 +8,7 @@ module dub.compilers.ldc; import dub.compilers.compiler; +import dub.platform; import std.algorithm; import std.array; @@ -21,6 +22,18 @@ class LdcCompiler : Compiler { @property string name() const { return "ldc"; } + BuildPlatform determinePlatform(ref BuildSettings settings, string compiler_binary, string arch_override) + { + // TODO: determine platform by invoking the compiler instead + BuildPlatform build_platform; + build_platform.platform = .determinePlatform(); + build_platform.architecture = .determineArchitecture(); + build_platform.compiler = this.name; + + enforce(arch_override.length == 0, "Architecture override not implemented for LDC."); + return build_platform; + } + void prepareBuildSettings(ref BuildSettings settings, BuildSetting fields = BuildSetting.all) { // convert common DMD flags to the corresponding GDC flags diff --git a/source/dub/dub.d b/source/dub/dub.d index ada3624..0763ad0 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -100,10 +100,6 @@ m_app = new Project(m_packageManager, m_root); } - /// Returns a list of flags which the application needs to be compiled - /// properly. - BuildSettings getBuildSettings(BuildPlatform platform, string config) { return m_app.getBuildSettings(platform, config); } - string getDefaultConfiguration(BuildPlatform platform) const { return m_app.getDefaultConfiguration(platform); } /// Lists all installed modules diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index ab1b2fe..cd1ffa2 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -28,13 +28,13 @@ class BuildGenerator : ProjectGenerator { private { - Project m_app; + Project m_project; PackageManager m_pkgMgr; } this(Project app, PackageManager mgr) { - m_app = app; + m_project = app; m_pkgMgr = mgr; } @@ -43,40 +43,33 @@ //Added check for existance of [AppNameInPackagejson].d //If exists, use that as the starting file. - auto outfile = getBinName(m_app); - auto mainsrc = getMainSourceFile(m_app); + auto outfile = getBinName(m_project); + auto mainsrc = getMainSourceFile(m_project); logDebug("Application output name is '%s'", outfile); - auto buildsettings = m_app.getBuildSettings(settings.platform, settings.config); + auto buildsettings = settings.buildSettings; + m_project.addBuildSettings(buildsettings, settings.platform, settings.config); buildsettings.addDFlags(["-w"/*, "-property"*/]); string dflags = environment.get("DFLAGS"); - if( dflags ){ + if( dflags.length ){ settings.buildType = "$DFLAGS"; + buildsettings.addDFlags(dflags.split()); } else { - switch(settings.buildType){ - default: throw new Exception("Unknown build configuration: "~settings.buildType); - case "plain": dflags = ""; break; - case "debug": dflags = "-g -debug"; break; - case "release": dflags = "-release -O -inline"; break; - case "unittest": dflags = "-g -unittest"; break; - case "profile": dflags = "-g -O -inline -profile"; break; - case "docs": assert(false, "docgen not implemented"); - } + addBuildTypeFlags(buildsettings, settings.buildType); } - buildsettings.addDFlags(dflags.split()); // add all .d files void addPackageFiles(in Package pack){ foreach(s; pack.sources){ - if( pack !is m_app.mainPackage && s == Path("source/app.d") ) + if( pack !is m_project.mainPackage && s == Path("source/app.d") ) continue; - auto relpath = (pack.path ~ s).relativeTo(m_app.mainPackage.path); + auto relpath = (pack.path ~ s).relativeTo(m_project.mainPackage.path); buildsettings.addFiles(relpath.toNativeString()); } } - addPackageFiles(m_app.mainPackage); - foreach(dep; m_app.installedPackages) + addPackageFiles(m_project.mainPackage); + foreach(dep; m_project.installedPackages) addPackageFiles(dep); // setup for command line @@ -84,7 +77,7 @@ Path run_exe_file; if( !settings.run ){ - settings.compiler.setTarget(buildsettings, m_app.binaryPath~outfile); + settings.compiler.setTarget(buildsettings, m_project.binaryPath~outfile); } else { import std.random; auto rnd = to!string(uniform(uint.min, uint.max)) ~ "-"; @@ -113,7 +106,7 @@ logInfo("Copying files..."); foreach( f; buildsettings.copyFiles ){ auto src = Path(f); - auto dst = (run_exe_file.empty ? m_app.binaryPath : run_exe_file.parentPath) ~ Path(f).head; + auto dst = (run_exe_file.empty ? m_project.binaryPath : run_exe_file.parentPath) ~ Path(f).head; logDebug(" %s to %s", src.toNativeString(), dst.toNativeString()); try copyFile(src, dst, true); catch logWarn("Failed to copy to %s", dst.toNativeString()); diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index 336fe92..3a238a6 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -34,6 +34,7 @@ string config; Compiler compiler; string compilerBinary; // compiler executable name + BuildSettings buildSettings; // only used for generator "rdmd" bool run; @@ -65,4 +66,17 @@ logTrace("Generating VisualD generator."); return new VisualDGenerator(app, mgr); } -} \ No newline at end of file +} + +void addBuildTypeFlags(ref BuildSettings dst, string build_type) +{ + switch(build_type){ + default: throw new Exception("Unknown build type: "~build_type); + case "plain": break; + case "debug": dst.addDFlags("-g", "-debug"); break; + case "release": dst.addDFlags("-release", "-O", "-inline"); break; + case "unittest": dst.addDFlags("-g", "-unittest"); break; + case "profile": dst.addDFlags("-g", "-O", "-inline", "-profile"); break; + case "docs": dst.addDFlags("-c", "-o-", "-D", "-Dfdocs", "-Xfdocs.json"); break; + } +} diff --git a/source/dub/generators/monod.d b/source/dub/generators/monod.d index 788abbf..ee48485 100644 --- a/source/dub/generators/monod.d +++ b/source/dub/generators/monod.d @@ -152,7 +152,8 @@ auto projName = pack.name; - auto buildsettings = m_app.getBuildSettings(settings.platform, m_app.getDefaultConfiguration(settings.platform)); + auto buildsettings = settings.buildSettings; + m_app.addBuildSettings(buildsettings, settings.platform, m_app.getDefaultConfiguration(settings.platform)); // Mono-D does not have a setting for string import paths settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.all & ~BuildSetting.stringImportPaths); diff --git a/source/dub/generators/rdmd.d b/source/dub/generators/rdmd.d index 322d872..900b601 100644 --- a/source/dub/generators/rdmd.d +++ b/source/dub/generators/rdmd.d @@ -27,13 +27,13 @@ class RdmdGenerator : ProjectGenerator { private { - Project m_app; + Project m_project; PackageManager m_pkgMgr; } this(Project app, PackageManager mgr) { - m_app = app; + m_project = app; m_pkgMgr = mgr; } @@ -42,8 +42,8 @@ //Added check for existance of [AppNameInPackagejson].d //If exists, use that as the starting file. - auto outfile = getBinName(m_app); - auto mainsrc = getMainSourceFile(m_app); + auto outfile = getBinName(m_project); + auto mainsrc = getMainSourceFile(m_project); logDebug("Application output name is '%s'", outfile); @@ -53,7 +53,7 @@ string[] flags = ["--force", "--build-only", "--compiler="~settings.compilerBinary]; Path run_exe_file; if( !settings.run ){ - flags ~= "-of"~(m_app.binaryPath~outfile).toNativeString(); + flags ~= "-of"~(m_project.binaryPath~outfile).toNativeString(); } else { import std.random; auto rnd = to!string(uniform(uint.min, uint.max)) ~ "-"; @@ -67,23 +67,16 @@ flags ~= "-of"~run_exe_file.toNativeString(); } - auto buildsettings = m_app.getBuildSettings(settings.platform, settings.config); + auto buildsettings = settings.buildSettings; + m_project.addBuildSettings(buildsettings, settings.platform, settings.config); buildsettings.addDFlags(["-w"/*, "-property"*/]); string dflags = environment.get("DFLAGS"); if( dflags ){ settings.buildType = "$DFLAGS"; + buildsettings.addDFlags(dflags.split()); } else { - switch(settings.buildType){ - default: throw new Exception("Unknown build configuration: "~settings.buildType); - case "plain": dflags = ""; break; - case "debug": dflags = "-g -debug"; break; - case "release": dflags = "-release -O -inline"; break; - case "unittest": dflags = "-g -unittest"; break; - case "profile": dflags = "-g -O -inline -profile"; break; - case "docs": assert(false, "docgen not implemented"); - } + addBuildTypeFlags(buildsettings, settings.buildType); } - buildsettings.addDFlags(dflags.split()); settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine); flags ~= buildsettings.dflags; @@ -102,7 +95,7 @@ logInfo("Copying files..."); foreach( f; buildsettings.copyFiles ){ auto src = Path(f); - auto dst = (run_exe_file.empty ? m_app.binaryPath : run_exe_file.parentPath) ~ Path(f).head; + auto dst = (run_exe_file.empty ? m_project.binaryPath : run_exe_file.parentPath) ~ Path(f).head; logDebug(" %s to %s", src.toNativeString(), dst.toNativeString()); try copyFile(src, dst, true); catch logWarn("Failed to copy to %s", dst.toNativeString()); diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d index df5b199..bd516e3 100644 --- a/source/dub/generators/visuald.d +++ b/source/dub/generators/visuald.d @@ -43,7 +43,7 @@ void generateProject(GeneratorSettings settings) { logTrace("About to generate projects for %s, with %s direct dependencies.", m_app.mainPackage().name, to!string(m_app.mainPackage().dependencies().length)); - generateProjects(m_app.mainPackage(), settings.platform); + generateProjects(m_app.mainPackage(), settings); generateSolution(); } @@ -136,11 +136,11 @@ formattedWrite(ret, "\n\t\t%s.%s.%s = %s", to!string(projectUuid), c, s, c); } - void generateProjects(const Package main, BuildPlatform buildPlatform) { + void generateProjects(const Package main, GeneratorSettings settings) { // TODO: cyclic check - generateProj(main, buildPlatform); + generateProj(main, settings); version(VISUALD_SEPERATE_PROJECT_FILES) { @@ -149,12 +149,13 @@ performOnDependencies(main, (const Package dependency) { if(dependency.name in generatedProjects) return; - generateProj(dependency, buildPlatform); + generateProj(dependency, settings); } ); } } - void generateProj(const Package pack, BuildPlatform buildPlatform) { + void generateProj(const Package pack, GeneratorSettings settings) + { int i = 0; auto ret = appender!(char[])(); @@ -164,9 +165,9 @@ %s", guid(projName)); // Several configurations (debug, release, unittest) - generateProjectConfiguration(ret, pack, Config.Debug, buildPlatform); - generateProjectConfiguration(ret, pack, Config.Release, buildPlatform); - generateProjectConfiguration(ret, pack, Config.Unittest, buildPlatform); + generateProjectConfiguration(ret, pack, Config.Debug, settings); + generateProjectConfiguration(ret, pack, Config.Release, settings); + generateProjectConfiguration(ret, pack, Config.Unittest, settings); // Add all files bool[SourceFile] sourceFiles; @@ -231,16 +232,18 @@ proj.flush(); } - void generateProjectConfiguration(Appender!(char[]) ret, const Package pack, Config type, BuildPlatform platform) { - auto settings = m_app.getBuildSettings(platform, m_app.getDefaultConfiguration(platform)); - string[] getSettings(string setting)(){ return __traits(getMember, settings, setting); } + void generateProjectConfiguration(Appender!(char[]) ret, const Package pack, Config type, GeneratorSettings settings) + { + auto buildsettings = settings.buildSettings; + m_app.addBuildSettings(buildsettings, settings.platform, m_app.getDefaultConfiguration(settings.platform)); + string[] getSettings(string setting)(){ return __traits(getMember, buildsettings, setting); } - foreach(architecture; platform.architecture) { + foreach(architecture; settings.platform.architecture) { string arch; switch(architecture) { default: logWarn("Unsupported platform('%s'), defaulting to x86", architecture); goto case; case "x86": arch = "Win32"; break; - case "x64": arch = "x64"; break; + case "x86_64": arch = "x64"; break; } ret.formattedWrite(" ", to!string(type), arch); diff --git a/source/dub/project.d b/source/dub/project.d index 8a5f0d7..e7a85ea 100644 --- a/source/dub/project.d +++ b/source/dub/project.d @@ -164,32 +164,28 @@ } /// Returns the DFLAGS - BuildSettings getBuildSettings(BuildPlatform platform, string config) + void addBuildSettings(ref BuildSettings dst, BuildPlatform platform, string config) const { - BuildSettings ret; - void addImportPath(string path, bool src) { if( !exists(path) ) return; - if( src ) ret.addImportDirs([path]); - else ret.addStringImportDirs([path]); + if( src ) dst.addImportDirs([path]); + else dst.addStringImportDirs([path]); } - if( m_main ) processVars(ret, ".", m_main.getBuildSettings(platform, config)); + if( m_main ) processVars(dst, ".", m_main.getBuildSettings(platform, config)); addImportPath("source", true); addImportPath("views", false); foreach( pkg; m_dependencies ){ - processVars(ret, pkg.path.toNativeString(), pkg.getBuildSettings(platform, config)); + processVars(dst, pkg.path.toNativeString(), pkg.getBuildSettings(platform, config)); addImportPath((pkg.path ~ "source").toNativeString(), true); addImportPath((pkg.path ~ "views").toNativeString(), false); } // add version identifiers for available packages foreach(pack; this.installedPackages) - ret.addVersions(["Have_" ~ stripDlangSpecialChars(pack.name)]); - - return ret; + dst.addVersions(["Have_" ~ stripDlangSpecialChars(pack.name)]); } /// Actions which can be performed to update the application.