diff options
| author | Alexey Panteleev <alpanteleev@nvidia.com> | 2022-03-16 08:28:01 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-16 08:28:01 -0700 |
| commit | 42ca6758046e11451b0788092f9c95fc7f788da6 (patch) | |
| tree | a377c6b9c7081230ac0385ad14b778b7f700a077 /source/slang/slang-compiler.cpp | |
| parent | 8533dd2344d8be040a992a86f23e7cf696d59c4a (diff) | |
Add -depfile option to save dependency info (#2161)
Diffstat (limited to 'source/slang/slang-compiler.cpp')
| -rw-r--r-- | source/slang/slang-compiler.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 65a18104e..39d558c01 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -2177,6 +2177,103 @@ namespace Slang return SLANG_OK; } + static void _writeString(Stream& stream, const char* string) + { + stream.write(string, strlen(string)); + } + + static void _escapeDependencyString(const char* string, StringBuilder& outBuilder) + { + // make has unusual escaping rules, but we only care about characters that are acceptable in a path + for (const char* p = string; *p; ++p) + { + char c = *p; + switch(c) + { + case ' ': + case ':': + case '#': + case '[': + case ']': + case '\\': + outBuilder.appendChar('\\'); + break; + + case '$': + outBuilder.appendChar('$'); + break; + } + + outBuilder.appendChar(c); + } + } + + // Writes a line to the file stream, formatted like this: + // <output-file>: <dependency-file> <dependency-file...> + static void _writeDependencyStatement(Stream& stream, EndToEndCompileRequest* compileRequest, const String& outputPath) + { + if (outputPath.getLength() == 0) + return; + + StringBuilder builder; + _escapeDependencyString(outputPath.begin(), builder); + _writeString(stream, builder.begin()); + _writeString(stream, ": "); + + int dependencyCount = compileRequest->getDependencyFileCount(); + for (int dependencyIndex = 0; dependencyIndex < dependencyCount; ++dependencyIndex) + { + builder.Clear(); + _escapeDependencyString(compileRequest->getDependencyFilePath(dependencyIndex), builder); + _writeString(stream, builder.begin()); + _writeString(stream, (dependencyIndex + 1 < dependencyCount) ? " " : "\n"); + } + } + + // Writes a file with dependency info, with one line in the output file per compile product. + static SlangResult _writeDependencyFile(EndToEndCompileRequest* compileRequest) + { + if (compileRequest->m_dependencyOutputPath.getLength() == 0) + return SLANG_OK; + + FileStream stream; + SLANG_RETURN_ON_FAIL(stream.init(compileRequest->m_dependencyOutputPath, FileMode::Create, FileAccess::Write, FileShare::ReadWrite)); + + auto linkage = compileRequest->getLinkage(); + auto program = compileRequest->getSpecializedGlobalAndEntryPointsComponentType(); + + // Iterate over all the targets and their outputs + for (const auto& targetReq : linkage->targets) + { + if (targetReq->isWholeProgramRequest()) + { + RefPtr<EndToEndCompileRequest::TargetInfo> targetInfo; + if (compileRequest->m_targetInfos.TryGetValue(targetReq, targetInfo)) + { + _writeDependencyStatement(stream, compileRequest, targetInfo->wholeTargetOutputPath); + } + } + else + { + Index entryPointCount = program->getEntryPointCount(); + for (Index entryPointIndex = 0; entryPointIndex < entryPointCount; ++entryPointIndex) + { + RefPtr<EndToEndCompileRequest::TargetInfo> targetInfo; + if (compileRequest->m_targetInfos.TryGetValue(targetReq, targetInfo)) + { + String outputPath; + if (targetInfo->entryPointOutputPaths.TryGetValue(entryPointIndex, outputPath)) + { + _writeDependencyStatement(stream, compileRequest, outputPath); + } + } + } + } + } + + return SLANG_OK; + } + static void _generateOutput( BackEndCompileRequest* compileRequest, @@ -2265,6 +2362,8 @@ namespace Slang compileRequest->maybeCreateContainer(); compileRequest->maybeWriteContainer(compileRequest->m_containerOutputPath); + + _writeDependencyFile(compileRequest); } } |
