diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d index fc510e4..cf53c04 100644 --- a/source/dub/generators/visuald.d +++ b/source/dub/generators/visuald.d @@ -7,10 +7,12 @@ */ module dub.generators.visuald; +import std.algorithm; import std.array; import std.conv; import std.format; import std.uuid; +import std.exception; import vibe.core.file; import vibe.core.log; @@ -20,6 +22,9 @@ import dub.packagestore; import dub.generators.generator; +// version = VISUALD_SEPERATE_PROJECT_FILES; +version = VISUALD_SINGLE_PROJECT_FILE; + class VisualDGenerator : ProjectGenerator { private { Application m_app; @@ -50,28 +55,30 @@ auto ret = appender!(char[])(); // Solution header - ret.formattedWrite("Microsoft Visual Studio Solution File, Format Version 11.00 + ret.formattedWrite(" +Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010"); generateSolutionEntries(ret, m_app.mainPackage()); // Global section contains configurations - ret.formattedWrite("Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - Unittest|Win32 = Unittest|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution"); + ret.formattedWrite(" +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Unittest|Win32 = Unittest|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution"); generateSolutionConfig(ret, m_app.mainPackage()); // TODO: for all dependencies ret.formattedWrite(" - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal"); // Writing solution file @@ -84,7 +91,12 @@ void generateSolutionEntries(Appender!(char[]) ret, const Package main) { generateSolutionEntry(ret, main); - performOnDependencies(main, (const Package pack) { generateSolutionEntries(ret, pack); } ); + version(VISUALD_SEPERATE_PROJECT_FILES) { + performOnDependencies(main, (const Package pack) { generateSolutionEntries(ret, pack); } ); + } + version(VISUALD_SINGLE_PROJECT_FILE) { + enforce(main == m_app.mainPackage()); + } } void generateSolutionEntry(Appender!(char[]) ret, const Package pack) { @@ -98,18 +110,19 @@ ret.formattedWrite("\nProject(\"%s\") = \"%s\", \"%s\", \"%s\"", projUuid, projName, projPath, projectUuid); - // TODO: add dependency references - if(pack.dependencies.length > 0) { - ret.formattedWrite(" - ProjectSection(ProjectDependencies) = postProject"); - foreach(id, dependency; pack.dependencies) { - // TODO: clarify what "uuid = uuid" should mean - auto uuid = guid(id); + version(VISUALD_SEPERATE_PROJECT_FILES) { + if(pack.dependencies.length > 0) { ret.formattedWrite(" - %s = %s", uuid, uuid); + ProjectSection(ProjectDependencies) = postProject"); + foreach(id, dependency; pack.dependencies) { + // TODO: clarify what "uuid = uuid" should mean + auto uuid = guid(id); + ret.formattedWrite(" + %s = %s", uuid, uuid); + } + ret.formattedWrite(" + EndProjectSection"); } - ret.formattedWrite(" - EndProjectSection"); } ret.formattedWrite("\nEndProject"); @@ -117,7 +130,7 @@ void generateSolutionConfig(Appender!(char[]) ret, const Package pack) { const string[] sub = [ "ActiveCfg", "Build.0" ]; - const string[] conf = [ "Debug|Win32", "Release|Win32", "Unittest|Win32" ]; + const string[] conf = [ "Debug|Win32", "Release|Win32" /*, "Unittest|Win32" */]; auto projectUuid = guid(pack.name()); foreach(c; conf) foreach(s; sub) @@ -129,12 +142,16 @@ // TODO: cyclic check generateProj(main); - m_generatedProjects[main.name] = true; - performOnDependencies(main, (const Package dependency) { - if(dependency.name in m_generatedProjects) - return; - generateProjects(dependency); - } ); + + version(VISUALD_SEPERATE_PROJECT_FILES) + { + m_generatedProjects[main.name] = true; + performOnDependencies(main, (const Package dependency) { + if(dependency.name in m_generatedProjects) + return; + generateProjects(dependency); + } ); + } } void generateProj(const Package pack) { @@ -144,22 +161,83 @@ auto projName = pack.name; ret.formattedWrite( " - %s", guid(projName)); + %s", guid(projName)); // Several configurations (debug, release, unittest) - generateProjectConfiguration(ret, pack, Config.Release); generateProjectConfiguration(ret, pack, Config.Debug); - generateProjectConfiguration(ret, pack, Config.Unittest); + generateProjectConfiguration(ret, pack, Config.Release); + // generateProjectConfiguration(ret, pack, Config.Unittest); // Add all files // TODO: nice folders - formattedWrite(ret, " - ", projName); - foreach(source; pack.sources) { - ret.formattedWrite("\n ", source.toString()); + struct SourceFile { + string pkg; + Path structurePath; + Path filePath; + int opCmp(ref const SourceFile rhs) const { return filePath.opCmp(rhs.filePath); } + } + bool[SourceFile] sourceFiles; + void gatherSources(const(Package) package_, string prefix) { + logDebug("Gather sources for %s", package_.name); + if(prefix != "") prefix = "|" ~ prefix ~ "|"; + foreach(source; package_.sources) { + SourceFile f = { package_.name, source, source }; + sourceFiles[f] = true; + logDebug("pkg file: %s", source); + } + } + version(VISUALD_SINGLE_PROJECT_FILE) { + // gather all sources + enforce(pack == m_app.mainPackage(), "Some setup has gone wrong in VisualD.generateProj()"); + bool[string] gathered; + void gatherAll(const Package package_) { + logDebug("Looking at %s", package_.name); + if(package_.name in gathered) + return; + gathered[package_.name] = true; + gatherSources(package_, ""/*package_.name*/); + performOnDependencies(package_, (const Package dependency) { gatherAll(dependency); }); + } + gatherAll(pack); + } + version(VISUALD_SEPERATE_PROJECT_FILES) { + // gather sources for this package only + gatherSources(pack, ""); + } + + // Create folders and files + // TODO: nice foldering + version(VISUALD_SINGLE_PROJECT_FILE) { + SourceFile[] files = sourceFiles.keys; + sort!("a.pkg > b.pkg")(files); + string last = ""; + ret.formattedWrite(" + "); + foreach(source; files) { + if(last != source.pkg) { + if(!last.empty) + ret.formattedWrite(" + "); + ret.formattedWrite(" + ", source.pkg); + last = source.pkg; + } + ret.formattedWrite(" + ", source.filePath.toString()); + } + ret.formattedWrite(" + + "); + } + version(VISUALD_SEPERATE_PROJECT_FILES) { + formattedWrite(ret, " + ", projName); + foreach(source, dummy; sourceFiles) + ret.formattedWrite("\n ", source.filePath.toString()); + ret.formattedWrite(" + "); } ret.formattedWrite(" - "); logTrace("About to write to '%s.visualdproj' file %s bytes", pack.name, to!string(ret.data().length)); @@ -171,111 +249,111 @@ void generateProjectConfiguration(Appender!(char[]) ret, const Package pack, Config type) { ret.formattedWrite( -"\n - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - 2 - 0 - 0 - 0 - $(DMDInstallDir)windows\\bin\\dmd.exe - source; ..\\vibe.d\\source - - $(ConfigurationName) - obj\\$(ConfigurationName) - - - 0 - - - - - 0 - - - 1 - $(IntDir)\\$(TargetName).json - 0 - - 0 - DerelictGL_ALL HostWin32 - 0 - 0 - 0 - - - - 0 - - 1 - $(VisualDInstallDir)cv2pdb\\cv2pdb.exe - 0 - 0 - 0 - - - - ws2_32.lib gdi32.lib winmm.lib ..\\vibe.d\\lib\\win-i386\\event2.lib ..\\vibe.d\\lib\\win-i386\\eay.lib ..\\vibe.d\\lib\\win-i386\\ssl.lib - - - - bin\\$(ProjectName)_d.exe - -L/PAGESIZE:1024 - - - *.obj;*.cmd;*.build;*.json;*.dep - ", to!string(type)); +"\n + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + $(DMDInstallDir)windows\\bin\\dmd.exe + + + $(ConfigurationName) + $(OutDir) + + + 0 + + + + + 0 + + + 1 + $(IntDir)\\$(TargetName).json + 0 + + 0 + DerelictGL_ALL HostWin32 + 0 + 0 + 0 + + + + 0 + + 1 + $(VisualDInstallDir)cv2pdb\\cv2pdb.exe + 0 + 0 + 0 + + + + ws2_32.lib gdi32.lib winmm.lib ..\\vibe.d\\lib\\win-i386\\event2.lib ..\\vibe.d\\lib\\win-i386\\eay.lib ..\\vibe.d\\lib\\win-i386\\ssl.lib + + + + bin\\$(ProjectName)_d.exe + + + + *.obj;*.cmd;*.build;*.json;*.dep + ", to!string(type)); } void performOnDependencies(const Package main, void delegate(const Package pack) op) { // TODO: cyclic check foreach(id, dependency; main.dependencies) { - logWarn("Retrieving package %s from store.", id); - logWarn("dudb"); + logDebug("Retrieving package %s from store.", id); auto pack = m_store.package_(id, dependency); if(pack is null) { logWarn("Package %s (%s) could not be retrieved continuing...", id, to!string(dependency)); continue; } + logDebug("Performing on retrieved package %s", pack.name); op(pack); } }