Skip to content

Commit 062b399

Browse files
fpelliccionialandefreitas
authored andcommitted
cmake refactor fallback --system-information
1 parent bb927a6 commit 062b399

File tree

3 files changed

+96
-20
lines changed

3 files changed

+96
-20
lines changed

.github/workflows/ci.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
config_type="Release"
9696
filename="${{ runner.os }}-$config_type-29b20829.${{ ( runner.os == 'Windows' && '7z' ) || 'tar.xz' }}"
9797
url="https://mrdox.com/llvm+clang/$filename"
98-
98+
9999
# Download
100100
if command -v curl &> /dev/null
101101
then
@@ -107,7 +107,7 @@ jobs:
107107
echo "Neither curl nor wget are available"
108108
exit 1
109109
fi
110-
110+
111111
# Extract
112112
llvm_root="${{runner.tool_cache}}/llvm+clang"
113113
llvm_root=$(echo "$llvm_root" | sed 's/\\/\//g')
@@ -302,6 +302,9 @@ jobs:
302302

303303
- name: Generate demos
304304
run: |
305+
set -x
306+
cmake --help
307+
cmake --system-information
305308
config_template=$(printf '%s\n' \
306309
"verbose: true" \
307310
"source-root: ." \

src/lib/Lib/CMakeExecution.cpp

+90-17
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,13 @@ executeCmakeHelp(llvm::StringRef cmakePath)
4242
MRDOCS_CHECK(errOutputPath, "Failed to create temporary file");
4343
std::optional<llvm::StringRef> const redirects[] = {llvm::StringRef(), outputPath.path(), errOutputPath.path()};
4444
std::vector<llvm::StringRef> const args = {cmakePath, "--help"};
45-
llvm::ArrayRef<llvm::StringRef> emptyEnv;
46-
int const result = llvm::sys::ExecuteAndWait(cmakePath, args, emptyEnv, redirects);
45+
int const result = llvm::sys::ExecuteAndWait(cmakePath, args, std::nullopt, redirects);
4746
if (result != 0)
4847
{
4948
auto const bufferOrError = llvm::MemoryBuffer::getFile(errOutputPath.path());
50-
MRDOCS_CHECK(bufferOrError, "CMake execution failed (no error output available)");
49+
MRDOCS_CHECK(bufferOrError, "CMake --help execution failed (no error output available)");
5150
auto const bufferOrError2 = llvm::MemoryBuffer::getFile(errOutputPath.path());
52-
MRDOCS_CHECK(bufferOrError2, "CMake execution failed (no error output available)");
51+
MRDOCS_CHECK(bufferOrError2, "CMake --help execution failed (no error output available)");
5352
// Concatenate both outputs
5453
std::string output;
5554
if (bufferOrError.get()->getBuffer().str().empty())
@@ -67,35 +66,63 @@ executeCmakeHelp(llvm::StringRef cmakePath)
6766
return Unexpected(Error("CMake --help execution failed: \n" + output));
6867
}
6968
auto const bufferOrError = llvm::MemoryBuffer::getFile(outputPath.path());
70-
MRDOCS_CHECK(bufferOrError, "Failed to read CMake help output");
69+
MRDOCS_CHECK(bufferOrError, "Failed to read CMake --help output");
7170
return bufferOrError.get()->getBuffer().str();
7271
}
7372

73+
7474
Expected<std::string>
75-
getCmakeDefaultGenerator(llvm::StringRef cmakePath)
75+
executeCmakeSystemInformation(llvm::StringRef cmakePath)
7676
{
77-
Expected<std::string> const cmakeHelpExp = executeCmakeHelp(cmakePath);
78-
if (!cmakeHelpExp) {
79-
if (llvm::sys::path::extension(cmakePath) == ".exe")
77+
ScopedTempFile const outputPath("cmake-system-information-out", "txt");
78+
MRDOCS_CHECK(outputPath, "Failed to create temporary file");
79+
ScopedTempFile const errOutputPath("cmake-system-information-err", "txt");
80+
MRDOCS_CHECK(errOutputPath, "Failed to create temporary file");
81+
std::optional<llvm::StringRef> const redirects[] = {llvm::StringRef(), outputPath.path(), errOutputPath.path()};
82+
std::vector<llvm::StringRef> const args = {cmakePath, "--system-information"};
83+
int const result = llvm::sys::ExecuteAndWait(cmakePath, args, std::nullopt, redirects);
84+
if (result != 0)
85+
{
86+
auto const bufferOrError = llvm::MemoryBuffer::getFile(errOutputPath.path());
87+
MRDOCS_CHECK(bufferOrError, "CMake --system-information execution failed (no error output available)");
88+
auto const bufferOrError2 = llvm::MemoryBuffer::getFile(errOutputPath.path());
89+
MRDOCS_CHECK(bufferOrError2, "CMake --system-information execution failed (no error output available)");
90+
// Concatenate both outputs
91+
std::string output;
92+
if (bufferOrError.get()->getBuffer().str().empty())
8093
{
81-
return "Visual Studio 17 2022";
94+
output = bufferOrError2.get()->getBuffer().str();
95+
}
96+
else if (bufferOrError2.get()->getBuffer().str().empty())
97+
{
98+
output = bufferOrError.get()->getBuffer().str();
8299
}
83100
else
84101
{
85-
return "Unix Makefiles";
102+
output = bufferOrError.get()->getBuffer().str() + "\n" + bufferOrError2.get()->getBuffer().str();
86103
}
104+
return Unexpected(Error("CMake --help execution failed: \n" + output));
87105
}
106+
auto const bufferOrError = llvm::MemoryBuffer::getFile(outputPath.path());
107+
MRDOCS_CHECK(bufferOrError, "Failed to read CMake --system-information output");
108+
return bufferOrError.get()->getBuffer().str();
109+
}
88110

89-
std::string const cmakeHelp = *std::move(cmakeHelpExp);
111+
Expected<std::string>
112+
parseCmakeHelpOutput(std::string const& cmakeHelp)
113+
{
90114
std::istringstream stream(cmakeHelp);
91115
std::string line;
92116
std::string defaultGenerator;
93117

94-
while (std::getline(stream, line)) {
95-
if (line[0] == '*' && line[1] == ' ') {
118+
while (std::getline(stream, line))
119+
{
120+
if (line[0] == '*' && line[1] == ' ')
121+
{
96122
size_t const start = 2;
97123
size_t const end = line.find("=", start);
98-
if (end == std::string::npos) {
124+
if (end == std::string::npos)
125+
{
99126
continue;
100127
}
101128
return line.substr(start, end - start);
@@ -104,8 +131,54 @@ getCmakeDefaultGenerator(llvm::StringRef cmakePath)
104131
return Unexpected(Error("Default CMake generator not found"));
105132
}
106133

134+
Expected<std::string>
135+
parseCmakeSystemInformationOutput(std::string const& cmakeSystemInformation)
136+
{
137+
std::istringstream stream(cmakeSystemInformation);
138+
std::string line;
139+
std::string defaultGenerator;
140+
141+
while (std::getline(stream, line))
142+
{
143+
if (line.starts_with("CMAKE_GENERATOR \""))
144+
{
145+
size_t const start = 17;
146+
size_t const end = line.find("\"", start);
147+
if (end == std::string::npos)
148+
{
149+
continue;
150+
}
151+
return line.substr(start, end - start);
152+
}
153+
}
154+
return Unexpected(Error("Default CMake generator not found"));
155+
}
156+
157+
Expected<std::string>
158+
getCmakeDefaultGenerator(llvm::StringRef cmakePath)
159+
{
160+
Expected<std::string> const cmakeHelpExp = executeCmakeHelp(cmakePath);
161+
if (!cmakeHelpExp)
162+
{
163+
Expected<std::string> const cmakeSystemInformationExp = executeCmakeSystemInformation(cmakePath);
164+
if (!cmakeSystemInformationExp)
165+
{
166+
if (llvm::sys::path::extension(cmakePath) == ".exe")
167+
{
168+
return "Visual Studio 17 2022";
169+
}
170+
return "Unix Makefiles";
171+
}
172+
std::string const cmakeSystemInformation = *std::move(cmakeSystemInformationExp);
173+
return parseCmakeSystemInformationOutput(cmakeSystemInformation);
174+
}
175+
176+
std::string const cmakeHelp = *std::move(cmakeHelpExp);
177+
return parseCmakeHelpOutput(cmakeHelp);
178+
}
179+
107180
Expected<bool>
108-
cmakeDefaultGeneratorIsVisualStudio(llvm::StringRef cmakePath)
181+
cmakeDefaultGeneratorIsVisualStudio(llvm::StringRef cmakePath)
109182
{
110183
MRDOCS_TRY(auto const defaultGenerator, getCmakeDefaultGenerator(cmakePath));
111184
return defaultGenerator.starts_with("Visual Studio");
@@ -145,7 +218,7 @@ parseBashIdentifier(std::string_view str)
145218
return identifier;
146219
}
147220

148-
std::vector<std::string>
221+
std::vector<std::string>
149222
parseBashArgs(std::string_view str)
150223
{
151224
std::vector<std::string> args;

src/lib/Support/Path.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ ScopedTempFile(
419419
ok_ = !llvm::sys::fs::createTemporaryFile(prefix, ext, tempPath);
420420
if (ok_)
421421
{
422-
path_ = files::makeDirsy(path_.str());
422+
path_ = tempPath;
423423
}
424424
}
425425

0 commit comments

Comments
 (0)