diff --git a/source/dub/dub.d b/source/dub/dub.d
index 1083905..90bec38 100644
--- a/source/dub/dub.d
+++ b/source/dub/dub.d
@@ -169,9 +169,6 @@
logError("Unsupported IDE, there is no generator available for '"~ide~"'");
throw new Exception("Unsupported IDE, there is no generator available for '"~ide~"'");
}
-
- // Q: update before generating?
-
generator.generateProject(build_platform);
}
diff --git a/source/dub/generators/visuald.d b/source/dub/generators/visuald.d
index 3355c3e..75b393e 100644
--- a/source/dub/generators/visuald.d
+++ b/source/dub/generators/visuald.d
@@ -25,6 +25,9 @@
// version = VISUALD_SEPERATE_PROJECT_FILES;
version = VISUALD_SINGLE_PROJECT_FILE;
+// Dubbing is developing dub...
+//version = DUBBING;
+
class VisualDGenerator : ProjectGenerator {
private {
Project m_app;
@@ -83,7 +86,7 @@
// Writing solution file
logTrace("About to write to .sln file with %s bytes", to!string(ret.data().length));
- auto sln = openFile(m_app.mainPackage().name ~ ".sln", FileMode.CreateTrunc);
+ auto sln = openFile(solutionFileName(), FileMode.CreateTrunc);
scope(exit) sln.close();
sln.write(ret.data());
sln.flush();
@@ -102,7 +105,7 @@
void generateSolutionEntry(Appender!(char[]) ret, const Package pack) {
auto projUuid = generateUUID();
auto projName = pack.name;
- auto projPath = pack.name ~ ".visualdproj";
+ auto projPath = projFileName(pack);
auto projectUuid = guid(projName);
// Write project header, like so
@@ -169,19 +172,12 @@
// generateProjectConfiguration(ret, pack, Config.Unittest);
// Add all files
- // TODO: nice folders
- 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);
+ void gatherSources(const(Package) pack, string prefix) {
+ logDebug("Gather sources for %s", pack.name);
if(prefix != "") prefix = "|" ~ prefix ~ "|";
- foreach(source; package_.sources) {
- SourceFile f = { package_.name, source, source };
+ foreach(source; pack.sources) {
+ SourceFile f = { pack.name, Path(pack.name)~source, pack.path ~ source };
sourceFiles[f] = true;
logDebug("pkg file: %s", source);
}
@@ -207,34 +203,37 @@
}
// Create folders and files
- // TODO: nice foldering
ret.formattedWrite("\n ", pack.name);
- version(VISUALD_SINGLE_PROJECT_FILE) {
- SourceFile[] files = sourceFiles.keys;
- sort!("a.pkg > b.pkg")(files);
- string last = "";
- foreach(source; files) {
- if(last != source.pkg) {
- if(!last.empty)
- ret.put("\n ");
- ret.formattedWrite("\n ", source.pkg);
- last = source.pkg;
- }
- ret.formattedWrite("\n ", source.filePath.toNativeString());
+ Path lastFolder;
+ foreach(source; sortedSources(sourceFiles.keys)) {
+ auto cur = source.structurePath[0..$-1];
+ if(lastFolder != cur) {
+ int same = 0;
+ foreach(int idx; 0..min(lastFolder.length, cur.length))
+ if(lastFolder[idx] != cur[idx]) break;
+ else same = idx+1;
+
+ const int decrease = max(0, lastFolder.length - same);
+ const int increase = max(0, cur.length - same);
+
+ foreach(unused; 0..decrease)
+ ret.put("\n ");
+ foreach(idx; 0..increase)
+ ret.formattedWrite("\n ", cur[same + idx].toString());
+ lastFolder = cur;
}
+ ret.formattedWrite("\n ", source.filePath.toNativeString());
+ }
+ // Finalize all open folders
+ foreach(unused; 0..lastFolder.length)
ret.put("\n ");
- }
- version(VISUALD_SEPERATE_PROJECT_FILES) {
- foreach(source, dummy; sourceFiles)
- ret.formattedWrite("\n ", source.filePath.toNativeString());
- }
ret.put("\n \n");
logTrace("About to write to '%s.visualdproj' file %s bytes", pack.name, ret.data().length);
- auto sln = openFile(pack.name ~ ".visualdproj", FileMode.CreateTrunc);
- scope(exit) sln.close();
- sln.write(ret.data());
- sln.flush();
+ auto proj = openFile(projFileName(pack), FileMode.CreateTrunc);
+ scope(exit) proj.close();
+ proj.write(ret.data());
+ proj.flush();
}
void generateProjectConfiguration(Appender!(char[]) ret, const Package pack, Config type, BuildPlatform platform) {
@@ -297,15 +296,20 @@
0");
// include paths and string imports
- string imports;
- string stringImports;
+ string imports = join(getSettings!"importPaths"(), " ");
+ string stringImports = join(getSettings!"stringImportPaths"(), " ");
ret.formattedWrite("
%s
%s", imports, stringImports);
// Compiler?
+ string compiler = "$(DMDInstallDir)windows\\bin\\dmd.exe";
+ string dflags = join(getSettings!"dflags"(), " ");
ret.formattedWrite("
- $(DMDInstallDir)windows\\bin\\dmd.exe
+ %s
+ %s", compiler, dflags);
+
+ ret.formattedWrite("
$(ConfigurationName)
$(OutDir)
@@ -351,7 +355,7 @@
");
// Add libraries, system libs need to be suffixed by ".lib".
- string linkLibs = join(map!("a~\".lib\"")(getSettings!"libs"()), " ");
+ string linkLibs = join(map!(a => a~".lib")(getSettings!"libs"()), " ");
string addLinkFiles = join(getSettings!"files"(), " ");
ret.formattedWrite("
%s", linkLibs ~ " " ~ addLinkFiles);
@@ -362,7 +366,6 @@
bin\\$(ProjectName)_d.exe
-
");
// Add a post build command to copy files
@@ -398,9 +401,74 @@
m_projectUuids[projectName] = generateUUID();
return m_projectUuids[projectName];
}
-
- string libfiles(const Package pack) {
- return "";
+
+ auto solutionFileName() const {
+ version(DUBBING) return m_app.mainPackage().name ~ ".dubbed.sln";
+ else return m_app.mainPackage().name ~ ".sln";
}
+
+ auto projFileName(ref const Package pack) const {
+ version(DUBBING) return pack.name ~ ".dubbed.visualdproj";
+ else return pack.name ~ ".visualdproj";
+ }
+ }
+
+ // TODO: nice folders
+ struct SourceFile {
+ string pkg;
+ Path structurePath;
+ Path filePath;
+
+ int opCmp(ref const SourceFile rhs) const { return sortOrder(this, rhs); }
+ // "a < b" for folder structures (deepest folder first, else lexical)
+ private final static int sortOrder(ref const SourceFile a, ref const SourceFile b) {
+ enforce(!a.structurePath.empty());
+ enforce(!b.structurePath.empty());
+ auto as = a.structurePath;
+ auto bs = b.structurePath;
+
+ // Check for different folders, compare folders only (omit last one).
+ for(uint idx=0; idx bs.length? -1 : 1;
+ }
+ else {
+ // Both paths indicate files in the same directory, use lexical
+ // ordering for those.
+ return as.head.opCmp(bs.head);
+ }
+ }
+ }
+
+ auto sortedSources(SourceFile[] sources) {
+ return sort(sources);
+ }
+
+ unittest {
+ SourceFile[] sfs = [
+ { "", Path("b/file.d"), Path("") },
+ { "", Path("b/b/fileA.d"), Path("") },
+ { "", Path("a/file.d"), Path("") },
+ { "", Path("b/b/fileB.d"), Path("") },
+ { "", Path("b/b/b/fileA.d"), Path("") },
+ { "", Path("b/c/fileA.d"), Path("") },
+ ];
+ auto sorted = sort(sfs);
+ SourceFile[] sortedSfs;
+ foreach(sr; sorted) {
+ logInfo("%s", sr.structurePath.toNativeString());
+ sortedSfs ~= sr;
+ }
+ assert(sortedSfs[0].structurePath == Path("a/file.d"), "1");
+ assert(sortedSfs[1].structurePath == Path("b/b/b/fileA.d"), "2");
+ assert(sortedSfs[2].structurePath == Path("b/b/fileA.d"), "3");
+ assert(sortedSfs[3].structurePath == Path("b/b/fileB.d"), "4");
+ assert(sortedSfs[4].structurePath == Path("b/c/fileA.d"), "5");
+ assert(sortedSfs[5].structurePath == Path("b/file.d"), "6");
}
}
\ No newline at end of file
diff --git a/source/dub/package_.d b/source/dub/package_.d
index c2d83b1..828703a 100644
--- a/source/dub/package_.d
+++ b/source/dub/package_.d
@@ -244,15 +244,20 @@
return ret;
}
- /// Returns all sources as absolute paths.
+ /// Returns all sources as relative paths, prepend each with
+ /// path() to get the absolute one.
@property const(Path[]) sources() const {
Path[] allSources;
auto sourcePath = Path("source");
auto customSourcePath = "sourcePath" in m_meta;
if(customSourcePath)
sourcePath = Path(customSourcePath.get!string());
- foreach(d; dirEntries((m_path ~ sourcePath).toNativeString(), "*.d", SpanMode.depth))
- allSources ~= Path(d.name);
+ foreach(d; dirEntries((m_path ~ sourcePath).toNativeString(), "*.d", SpanMode.depth)) {
+ // direct assignment allSources ~= Path(d.name)[...] spawns internal compiler/linker error
+ if(isDir(d.name)) continue;
+ auto p = Path(d.name);
+ allSources ~= p[m_path.length..$];
+ }
return allSources;
}
@@ -288,4 +293,4 @@
toPrettyJson(js, m_meta);
dstFile.write( js.data );
}
-}
+}
\ No newline at end of file