Skip to content

Commit e8c9414

Browse files
authored
[llvm-config] Quote and escape paths if necessary (#97305)
If any of the printed paths by `llvm-config` contains quotes, spaces, backslashes or dollar sign characters, these paths will be quoted and the corresponding characters will be escaped. Following discussion in #76304 Fixes #28117
1 parent 488fdb7 commit e8c9414

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

llvm/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ Changes to the LLVM tools
369369
jumping in reverse direction with shift+L/R/B). (`#95662
370370
<https://github.com/llvm/llvm-project/pull/95662>`).
371371

372+
* llvm-config now quotes and escapes paths emitted in stdout, to account for
373+
spaces or other special characters in path.
374+
(`#97305 <https://github.com/llvm/llvm-project/pull/97305>`).
375+
372376
Changes to LLDB
373377
---------------------------------
374378

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# Check directory options for obvious issues.
22

33
RUN: llvm-config --bindir 2>&1 | FileCheck --check-prefix=CHECK-BINDIR %s
4-
CHECK-BINDIR: {{.*}}{{/|\\}}bin
4+
CHECK-BINDIR: {{.*}}{{/|\\\\}}bin
55
CHECK-BINDIR-NOT: error:
66
CHECK-BINDIR-NOT: warning
77

88
RUN: llvm-config --includedir 2>&1 | FileCheck --check-prefix=CHECK-INCLUDEDIR %s
9-
CHECK-INCLUDEDIR: {{.*}}{{/|\\}}include
9+
CHECK-INCLUDEDIR: {{.*}}{{/|\\\\}}include
1010
CHECK-INCLUDEDIR-NOT: error:
1111
CHECK-INCLUDEDIR-NOT: warning
1212

1313
RUN: llvm-config --libdir 2>&1 | FileCheck --check-prefix=CHECK-LIBDIR %s
14-
CHECK-LIBDIR: {{.*}}{{/|\\}}lib{{.*}}
14+
CHECK-LIBDIR: {{.*}}{{/|\\\\}}lib{{.*}}
1515
CHECK-LIBDIR-NOT: error:
1616
CHECK-LIBDIR-NOT: warning
1717

1818
RUN: llvm-config --cmakedir 2>&1 | FileCheck --check-prefix=CHECK-CMAKEDIR %s
19-
CHECK-CMAKEDIR: {{.*}}{{/|\\}}cmake{{/|\\}}llvm
19+
CHECK-CMAKEDIR: {{.*}}{{/|\\\\}}cmake{{/|\\\\}}llvm
2020
CHECK-CMAKEDIR-NOT: error:
2121
CHECK-CMAKEDIR-NOT: warning

llvm/tools/llvm-config/llvm-config.cpp

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/Config/config.h"
2525
#include "llvm/Support/FileSystem.h"
2626
#include "llvm/Support/Path.h"
27+
#include "llvm/Support/Program.h"
2728
#include "llvm/Support/WithColor.h"
2829
#include "llvm/Support/raw_ostream.h"
2930
#include "llvm/TargetParser/Triple.h"
@@ -326,7 +327,7 @@ int main(int argc, char **argv) {
326327
// information.
327328
std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
328329
ActiveCMakeDir;
329-
std::string ActiveIncludeOption;
330+
std::vector<std::string> ActiveIncludeOptions;
330331
if (IsInDevelopmentTree) {
331332
ActiveIncludeDir = std::string(LLVM_SRC_ROOT) + "/include";
332333
ActivePrefix = CurrentExecPrefix;
@@ -352,8 +353,8 @@ int main(int argc, char **argv) {
352353
}
353354

354355
// We need to include files from both the source and object trees.
355-
ActiveIncludeOption =
356-
("-I" + ActiveIncludeDir + " " + "-I" + ActiveObjRoot + "/include");
356+
ActiveIncludeOptions.push_back(ActiveIncludeDir);
357+
ActiveIncludeOptions.push_back(ActiveObjRoot + "/include");
357358
} else {
358359
ActivePrefix = CurrentExecPrefix;
359360
{
@@ -372,7 +373,7 @@ int main(int argc, char **argv) {
372373
sys::fs::make_absolute(ActivePrefix, Path);
373374
ActiveCMakeDir = std::string(Path);
374375
}
375-
ActiveIncludeOption = "-I" + ActiveIncludeDir;
376+
ActiveIncludeOptions.push_back(ActiveIncludeDir);
376377
}
377378

378379
/// We only use `shared library` mode in cases where the static library form
@@ -401,8 +402,8 @@ int main(int argc, char **argv) {
401402
std::replace(ActiveBinDir.begin(), ActiveBinDir.end(), '/', '\\');
402403
std::replace(ActiveLibDir.begin(), ActiveLibDir.end(), '/', '\\');
403404
std::replace(ActiveCMakeDir.begin(), ActiveCMakeDir.end(), '/', '\\');
404-
std::replace(ActiveIncludeOption.begin(), ActiveIncludeOption.end(), '/',
405-
'\\');
405+
for (auto &Include : ActiveIncludeOptions)
406+
std::replace(Include.begin(), Include.end(), '/', '\\');
406407
}
407408
SharedDir = ActiveBinDir;
408409
StaticDir = ActiveLibDir;
@@ -504,6 +505,20 @@ int main(int argc, char **argv) {
504505
};
505506

506507
raw_ostream &OS = outs();
508+
509+
// Render include paths and associated flags
510+
auto RenderFlags = [&](StringRef Flags) {
511+
bool First = true;
512+
for (auto &Include : ActiveIncludeOptions) {
513+
if (!First)
514+
OS << ' ';
515+
OS << "-I";
516+
sys::printArg(OS, Include, /*Quote=*/true);
517+
First = false;
518+
}
519+
OS << ' ' << Flags << '\n';
520+
};
521+
507522
for (int i = 1; i != argc; ++i) {
508523
StringRef Arg = argv[i];
509524

@@ -512,24 +527,30 @@ int main(int argc, char **argv) {
512527
if (Arg == "--version") {
513528
OS << PACKAGE_VERSION << '\n';
514529
} else if (Arg == "--prefix") {
515-
OS << ActivePrefix << '\n';
530+
sys::printArg(OS, ActivePrefix, /*Quote=*/true);
531+
OS << '\n';
516532
} else if (Arg == "--bindir") {
517-
OS << ActiveBinDir << '\n';
533+
sys::printArg(OS, ActiveBinDir, /*Quote=*/true);
534+
OS << '\n';
518535
} else if (Arg == "--includedir") {
519-
OS << ActiveIncludeDir << '\n';
536+
sys::printArg(OS, ActiveIncludeDir, /*Quote=*/true);
537+
OS << '\n';
520538
} else if (Arg == "--libdir") {
521-
OS << ActiveLibDir << '\n';
539+
sys::printArg(OS, ActiveLibDir, /*Quote=*/true);
540+
OS << '\n';
522541
} else if (Arg == "--cmakedir") {
523-
OS << ActiveCMakeDir << '\n';
542+
sys::printArg(OS, ActiveCMakeDir, /*Quote=*/true);
543+
OS << '\n';
524544
} else if (Arg == "--cppflags") {
525-
OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << '\n';
545+
RenderFlags(LLVM_CPPFLAGS);
526546
} else if (Arg == "--cflags") {
527-
OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << '\n';
547+
RenderFlags(LLVM_CFLAGS);
528548
} else if (Arg == "--cxxflags") {
529-
OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
549+
RenderFlags(LLVM_CXXFLAGS);
530550
} else if (Arg == "--ldflags") {
531-
OS << ((HostTriple.isWindowsMSVCEnvironment()) ? "-LIBPATH:" : "-L")
532-
<< ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n';
551+
OS << ((HostTriple.isWindowsMSVCEnvironment()) ? "-LIBPATH:" : "-L");
552+
sys::printArg(OS, ActiveLibDir, /*Quote=*/true);
553+
OS << ' ' << LLVM_LDFLAGS << '\n';
533554
} else if (Arg == "--system-libs") {
534555
PrintSystemLibs = true;
535556
} else if (Arg == "--libs") {
@@ -590,7 +611,8 @@ int main(int argc, char **argv) {
590611
} else if (Arg == "--shared-mode") {
591612
PrintSharedMode = true;
592613
} else if (Arg == "--obj-root") {
593-
OS << ActivePrefix << '\n';
614+
sys::printArg(OS, ActivePrefix, /*Quote=*/true);
615+
OS << '\n';
594616
} else if (Arg == "--ignore-libllvm") {
595617
LinkDyLib = false;
596618
LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;
@@ -695,26 +717,30 @@ int main(int argc, char **argv) {
695717

696718
auto PrintForLib = [&](const StringRef &Lib) {
697719
const bool Shared = LinkMode == LinkModeShared;
720+
std::string LibFileName;
698721
if (PrintLibNames) {
699-
OS << GetComponentLibraryFileName(Lib, Shared);
722+
LibFileName = GetComponentLibraryFileName(Lib, Shared);
700723
} else if (PrintLibFiles) {
701-
OS << GetComponentLibraryPath(Lib, Shared);
724+
LibFileName = GetComponentLibraryPath(Lib, Shared);
702725
} else if (PrintLibs) {
703726
// On Windows, output full path to library without parameters.
704727
// Elsewhere, if this is a typical library name, include it using -l.
705728
if (HostTriple.isWindowsMSVCEnvironment()) {
706-
OS << GetComponentLibraryPath(Lib, Shared);
729+
LibFileName = GetComponentLibraryPath(Lib, Shared);
707730
} else {
731+
OS << "-l";
708732
StringRef LibName;
709733
if (GetComponentLibraryNameSlice(Lib, LibName)) {
710734
// Extract library name (remove prefix and suffix).
711-
OS << "-l" << LibName;
735+
LibFileName = LibName;
712736
} else {
713737
// Lib is already a library name without prefix and suffix.
714-
OS << "-l" << Lib;
738+
LibFileName = Lib;
715739
}
716740
}
717741
}
742+
if (!LibFileName.empty())
743+
sys::printArg(OS, LibFileName, /*Quote=*/true);
718744
};
719745

720746
if (LinkMode == LinkModeShared && LinkDyLib) {

0 commit comments

Comments
 (0)