Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions source/dub/generators/ninja.d
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class NinjaGenerator : ProjectGenerator
f.writeln("ar = ar");
f.writeln();
f.writeln("rule dc");
f.writeln(" command = ", compiler, " $flags -c $in -of=$out");
f.writeln(" command = ", compiler, " $flags -c $in -of=$out -makedeps=$out.dep");
f.writeln(" depfile = $out.dep");
f.writeln(" deps = gcc");
f.writeln(" description = Compiling $in");
f.writeln();
f.writeln("rule link");
Expand Down Expand Up @@ -69,13 +71,15 @@ class NinjaGenerator : ProjectGenerator
{
auto bs = info.buildSettings;

auto importFlags = bs.importPaths.map!(p => "-I" ~ p).join(" ");
auto importFlags = bs.importPaths.map!(p => "-I" ~ escapeNinjaPath(p)).join(" ");
auto strImportFlags = bs.stringImportPaths.map!(p => "-J" ~ escapeNinjaPath(p)).join(" ");
auto versionFlags = bs.versions.map!(v => versionFlag(cname) ~ v).join(" ");
auto debugFlags = bs.debugVersions.map!(v => debugFlag(cname) ~ v).join(" ");
auto extraFlags = bs.dflags.join(" ");

string[] parts;
if (importFlags.length) parts ~= importFlags;
if (strImportFlags.length) parts ~= strImportFlags;
if (versionFlags.length) parts ~= versionFlags;
if (debugFlags.length) parts ~= debugFlags;
if (extraFlags.length) parts ~= extraFlags;
Expand Down
73 changes: 73 additions & 0 deletions test/ninja-makedeps.script.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/+ dub.sdl:
name "ninja-makedeps-regen"
dependency "common" path="./common"
+/

module ninja_makedeps_regen;

import std.process : environment, execute, Config;
import std.path : buildPath, dirName;
import std.file : readText, write, timeLastModified, exists;
import std.algorithm : canFind;
import core.thread : Thread;
import core.time : seconds;

import common;

int main()
{
const dub = environment.get("DUB", buildPath(__FILE_FULL_PATH__.dirName.dirName, "bin", "dub"));
const dc = environment.get("DC", "dmd");
const curr_dir = environment.get("CURR_DIR", buildPath(__FILE_FULL_PATH__.dirName));
const projDir = buildPath(curr_dir, "ninja-makedeps");

if (execute([dub, "generate", "ninja", "--compiler", dc], null, Config.none, size_t.max, projDir).status)
die("dub generate ninja failed");

const buildNinjaPath = buildPath(projDir, "build.ninja");
if (!readText(buildNinjaPath).canFind("-makedeps"))
die("build.ninja missing -makedeps flag on dc rule");
if (!readText(buildNinjaPath).canFind("depfile ="))
die("build.ninja missing depfile directive on dc rule");

execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, projDir);
if (execute(["ninja"], null, Config.none, size_t.max, projDir).status)
die("initial ninja build failed");

// Locate the actual app.o produced, since the generator encodes the full
// source path into the object filename.
import std.file : dirEntries, SpanMode;
string findObj(string moduleName)
{
foreach (entry; dirEntries(projDir, SpanMode.shallow))
if (entry.name.canFind("_" ~ moduleName ~ ".o"))
return entry.name;
return "";
}

const objPath = findObj("app");
if (!objPath.length || !exists(objPath))
die("could not locate app.o after initial build");

const mtimeBefore = timeLastModified(objPath);

const helperPath = buildPath(projDir, "source", "helper.d");
const origHelper = readText(helperPath);

Thread.sleep(1.seconds);
write(helperPath, origHelper ~ "\n// touched\n");
scope(exit) write(helperPath, origHelper);

if (execute(["ninja"], null, Config.none, size_t.max, projDir).status)
die("rebuild after touching helper.d failed");

const mtimeAfter = timeLastModified(objPath);

if (mtimeAfter <= mtimeBefore)
die("app.o was not recompiled after helper.d changed -- depfile is not tracking transitive imports");

execute(["ninja", "-t", "clean"], null, Config.none, size_t.max, projDir);

log("PASS");
return 0;
}
4 changes: 4 additions & 0 deletions test/ninja-makedeps/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "ninja-makedeps",
"targetType": "executable"
}
2 changes: 2 additions & 0 deletions test/ninja-makedeps/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import helper;
void main() { helperFunc(); }
1 change: 1 addition & 0 deletions test/ninja-makedeps/source/helper.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
void helperFunc() {}
Loading