Skip to content

Commit 9060f86

Browse files
committed
feat: support CMAKE_ROOT
1 parent c82e452 commit 9060f86

File tree

2 files changed

+59
-28
lines changed

2 files changed

+59
-28
lines changed

src/lib/Lib/CMakeExecution.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,16 @@ namespace {
2424
Expected<std::string>
2525
getCmakePath()
2626
{
27-
llvm::ErrorOr<std::string> const path = llvm::sys::findProgramByName("cmake");
27+
llvm::ErrorOr<std::string> path = llvm::sys::findProgramByName("cmake");
28+
if (!path)
29+
{
30+
char const* const cmakeRootPath = std::getenv("CMAKE_ROOT");
31+
if (cmakeRootPath != nullptr)
32+
{
33+
std::string cmakeBinPath = files::appendPath(cmakeRootPath, "bin");
34+
path = llvm::sys::findProgramByName("cmake", {cmakeBinPath, cmakeRootPath});
35+
}
36+
}
2837
MRDOCS_CHECK(path, "CMake executable not found");
2938
std::optional<llvm::StringRef> const redirects[] = {llvm::StringRef(), llvm::StringRef(), llvm::StringRef()};
3039
std::vector<llvm::StringRef> const args = {*path, "--version"};
@@ -452,20 +461,15 @@ executeCmakeExportCompileCommands(llvm::StringRef projectPath, llvm::StringRef c
452461
MRDOCS_CHECK(llvm::sys::fs::exists(projectPath), "Project path does not exist");
453462
MRDOCS_TRY(auto const cmakePath, getCmakePath());
454463

455-
ScopedTempFile const errorPath("cmake-error", "txt");
456-
MRDOCS_CHECK(errorPath, "Failed to create temporary file");
457-
458-
std::optional<llvm::StringRef> const redirects[] = {llvm::StringRef(), llvm::StringRef(), errorPath.path()};
464+
std::array<std::optional<llvm::StringRef>, 3> const redirects = {std::nullopt, std::nullopt, std::nullopt};
459465
std::vector<llvm::StringRef> args = {cmakePath, "-S", projectPath, "-B", buildDir, "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"};
460466

461467
auto const additionalArgs = parseBashArgs(cmakeArgs.str());
462468
MRDOCS_TRY(pushCMakeArgs(cmakePath, args, additionalArgs));
463469

464470
int const result = llvm::sys::ExecuteAndWait(cmakePath, args, std::nullopt, redirects);
465471
if (result != 0) {
466-
auto bufferOrError = llvm::MemoryBuffer::getFile(errorPath.path());
467-
MRDOCS_CHECK(bufferOrError, "CMake execution failed (no error output available)");
468-
return Unexpected(Error("CMake execution failed: \n" + bufferOrError.get()->getBuffer().str()));
472+
return Unexpected(Error("CMake execution failed"));
469473
}
470474

471475
llvm::SmallString<128> compileCommandsPath(buildDir);

src/tool/GenerateAction.cpp

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ generateCompileCommandsFile(llvm::StringRef inputPath, llvm::StringRef cmakeArgs
6767
auto const fileName = files::getFileName(inputPath);
6868
if (fileName == "CMakeLists.txt")
6969
{
70-
return executeCmakeExportCompileCommands(files::getParentDir(inputPath), cmakeArgs, buildDir);
70+
std::string cmakeSourceDir = files::getParentDir(inputPath);
71+
return executeCmakeExportCompileCommands(
72+
cmakeSourceDir, cmakeArgs, buildDir);
7173
}
7274

7375
// --------------------------------------------------------------
@@ -85,47 +87,59 @@ generateCompileCommandsFile(llvm::StringRef inputPath, llvm::StringRef cmakeArgs
8587

8688

8789
Expected<void>
88-
DoGenerateAction(std::string_view execPath, char const** argv)
90+
DoGenerateAction(
91+
std::string const& configPath,
92+
Config::Settings::ReferenceDirectories const& dirs,
93+
char const** argv)
8994
{
9095
// --------------------------------------------------------------
9196
//
9297
// Load configuration
9398
//
9499
// --------------------------------------------------------------
95100
Config::Settings publicSettings;
96-
MRDOCS_TRY(toolArgs.apply(publicSettings, execPath, argv));
97-
ThreadPool threadPool(toolArgs.concurrency);
101+
MRDOCS_TRY(Config::Settings::load_file(publicSettings, configPath, dirs));
102+
MRDOCS_TRY(toolArgs.apply(publicSettings, dirs, argv));
103+
MRDOCS_TRY(publicSettings.normalize(dirs));
104+
ThreadPool threadPool(publicSettings.concurrency);
98105
MRDOCS_TRY(
99106
std::shared_ptr<ConfigImpl const> config,
100-
loadConfigFile(publicSettings, nullptr, threadPool));
107+
ConfigImpl::load(publicSettings, dirs, threadPool));
101108

102109
// --------------------------------------------------------------
103110
//
104111
// Load generator
105112
//
106113
// --------------------------------------------------------------
107-
auto const& settings = config->settings();
114+
auto& settings = config->settings();
108115
MRDOCS_TRY(
109116
Generator const& generator,
110-
getGenerators().find(settings.generate),
117+
getGenerators().find(to_string(settings.generate)),
111118
formatError(
112119
"the Generator \"{}\" was not found",
113-
config->settings().generate));
120+
to_string(config->settings().generate)));
114121

115122
// --------------------------------------------------------------
116123
//
117124
// Find or generate the compile_commands.json
118125
//
119126
// --------------------------------------------------------------
127+
std::string compilationDatabasePath = settings.compilationDatabase;
128+
if (compilationDatabasePath.empty())
129+
{
130+
std::string c = files::appendPath(settings.sourceRoot, "CMakeLists.txt");
131+
if (files::exists(c)) {
132+
compilationDatabasePath = c;
133+
}
134+
}
120135
MRDOCS_CHECK(
121-
settings.compilationDatabase,
136+
compilationDatabasePath,
122137
"The compilation database path argument is missing");
123138
ScopedTempDirectory tempDir("mrdocs");
139+
std::string buildPath = files::appendPath(tempDir.path(), "build");
124140
Expected<std::string> const compileCommandsPathExp =
125141
generateCompileCommandsFile(
126-
settings.compilationDatabase,
127-
settings.cmake,
128-
files::appendPath(tempDir.path(), "build"));
142+
compilationDatabasePath, settings.cmake, buildPath);
129143
if (!compileCommandsPathExp)
130144
{
131145
report::error(
@@ -142,21 +156,27 @@ DoGenerateAction(std::string_view execPath, char const** argv)
142156
std::string compileCommandsPath = files::normalizePath(*compileCommandsPathExp);
143157
MRDOCS_TRY(compileCommandsPath, files::makeAbsolute(compileCommandsPath));
144158
std::string errorMessage;
145-
MRDOCS_TRY_MSG(
146-
auto& compileCommands,
159+
std::unique_ptr<clang::tooling::JSONCompilationDatabase>
160+
jsonDatabasePtr =
147161
tooling::JSONCompilationDatabase::loadFromFile(
148162
compileCommandsPath,
149163
errorMessage,
150-
tooling::JSONCommandLineSyntax::AutoDetect),
151-
std::move(errorMessage));
164+
tooling::JSONCommandLineSyntax::AutoDetect);
165+
if (!jsonDatabasePtr)
166+
{
167+
return Unexpected(formatError(
168+
"Failed to load compilation database: {}", errorMessage));
169+
}
170+
clang::tooling::JSONCompilationDatabase& jsonDatabase = *jsonDatabasePtr;
152171

153-
// Custom compilation database that converts relative paths to absolute
154-
auto const defaultIncludePaths = getCompilersDefaultIncludeDir(compileCommands);
172+
// Custom compilation database that applies settings from the configuration
173+
auto const defaultIncludePaths = getCompilersDefaultIncludeDir(
174+
jsonDatabase);
155175
auto compileCommandsDir = files::getParentDir(compileCommandsPath);
156-
MRDOCS_ASSERT(files::isDirsy(compileCommandsDir));
157176
MrDocsCompilationDatabase compilationDatabase(
158177
compileCommandsDir,
159-
compileCommands, config,
178+
jsonDatabase,
179+
config,
160180
defaultIncludePaths);
161181

162182
// --------------------------------------------------------------
@@ -187,6 +207,13 @@ DoGenerateAction(std::string_view execPath, char const** argv)
187207
(*config)->configDir));
188208
report::info("Generating docs\n");
189209
MRDOCS_TRY(generator.build(absOutput, *corpus));
210+
211+
// --------------------------------------------------------------
212+
//
213+
// Clean temp files
214+
//
215+
// --------------------------------------------------------------
216+
190217
return {};
191218
}
192219

0 commit comments

Comments
 (0)