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"
@@ -218,6 +219,7 @@ Options:\n\
218219 --components List of all possible components.\n \
219220 --cppflags C preprocessor flags for files that include LLVM headers.\n \
220221 --cxxflags C++ compiler flags for files that include LLVM headers.\n \
222+ --quote-paths Quote and escape paths when needed.\n \
221223 --has-rtti Print whether or not LLVM was built with rtti (YES or NO).\n \
222224 --help Print a summary of llvm-config arguments.\n \
223225 --host-target Target triple used to configure LLVM.\n \
@@ -324,7 +326,7 @@ int main(int argc, char **argv) {
324326 // information.
325327 std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
326328 ActiveCMakeDir;
327- std::string ActiveIncludeOption ;
329+ std::vector<std:: string> ActiveIncludeOptions ;
328330 if (IsInDevelopmentTree) {
329331 ActiveIncludeDir = std::string (LLVM_SRC_ROOT) + " /include" ;
330332 ActivePrefix = CurrentExecPrefix;
@@ -350,8 +352,8 @@ int main(int argc, char **argv) {
350352 }
351353
352354 // We need to include files from both the source and object trees.
353- ActiveIncludeOption =
354- ( " -I " + ActiveIncludeDir + " " + " -I " + ActiveObjRoot + " /include" );
355+ ActiveIncludeOptions. push_back (ActiveIncludeDir);
356+ ActiveIncludeOptions. push_back ( ActiveObjRoot + " /include" );
355357 } else {
356358 ActivePrefix = CurrentExecPrefix;
357359 {
@@ -370,7 +372,7 @@ int main(int argc, char **argv) {
370372 sys::path::make_absolute (ActivePrefix, Path);
371373 ActiveCMakeDir = std::string (Path);
372374 }
373- ActiveIncludeOption = " -I " + ActiveIncludeDir;
375+ ActiveIncludeOptions. push_back ( ActiveIncludeDir) ;
374376 }
375377
376378 // / We only use `shared library` mode in cases where the static library form
@@ -399,7 +401,9 @@ int main(int argc, char **argv) {
399401 llvm::replace (ActiveBinDir, ' /' , ' \\ ' );
400402 llvm::replace (ActiveLibDir, ' /' , ' \\ ' );
401403 llvm::replace (ActiveCMakeDir, ' /' , ' \\ ' );
402- llvm::replace (ActiveIncludeOption, ' /' , ' \\ ' );
404+ llvm::replace (ActiveIncludeDir, ' /' , ' \\ ' );
405+ for (auto &Include : ActiveIncludeOptions)
406+ llvm::replace (Include, ' /' , ' \\ ' );
403407 }
404408 SharedDir = ActiveBinDir;
405409 StaticDir = ActiveLibDir;
@@ -501,6 +505,32 @@ int main(int argc, char **argv) {
501505 };
502506
503507 raw_ostream &OS = outs ();
508+
509+ // Check if we want quoting and escaping.
510+ bool QuotePaths = std::any_of (&argv[0 ], &argv[argc], [](const char *Arg) {
511+ return StringRef (Arg) == " --quote-paths" ;
512+ });
513+
514+ auto MaybePrintQuoted = [&](StringRef Str) {
515+ if (QuotePaths)
516+ sys::printArg (OS, Str, /* Quote=*/ false ); // only add quotes if necessary
517+ else
518+ OS << Str;
519+ };
520+
521+ // Render include paths and associated flags
522+ auto RenderFlags = [&](StringRef Flags) {
523+ bool First = true ;
524+ for (auto &Include : ActiveIncludeOptions) {
525+ if (!First)
526+ OS << ' ' ;
527+ std::string FlagsStr = " -I" + Include;
528+ MaybePrintQuoted (FlagsStr);
529+ First = false ;
530+ }
531+ OS << ' ' << Flags << ' \n ' ;
532+ };
533+
504534 for (int i = 1 ; i != argc; ++i) {
505535 StringRef Arg = argv[i];
506536
@@ -509,24 +539,32 @@ int main(int argc, char **argv) {
509539 if (Arg == " --version" ) {
510540 OS << PACKAGE_VERSION << ' \n ' ;
511541 } else if (Arg == " --prefix" ) {
512- OS << ActivePrefix << ' \n ' ;
542+ MaybePrintQuoted (ActivePrefix);
543+ OS << ' \n ' ;
513544 } else if (Arg == " --bindir" ) {
514- OS << ActiveBinDir << ' \n ' ;
545+ MaybePrintQuoted (ActiveBinDir);
546+ OS << ' \n ' ;
515547 } else if (Arg == " --includedir" ) {
516- OS << ActiveIncludeDir << ' \n ' ;
548+ MaybePrintQuoted (ActiveIncludeDir);
549+ OS << ' \n ' ;
517550 } else if (Arg == " --libdir" ) {
518- OS << ActiveLibDir << ' \n ' ;
551+ MaybePrintQuoted (ActiveLibDir);
552+ OS << ' \n ' ;
519553 } else if (Arg == " --cmakedir" ) {
520- OS << ActiveCMakeDir << ' \n ' ;
554+ MaybePrintQuoted (ActiveCMakeDir);
555+ OS << ' \n ' ;
521556 } else if (Arg == " --cppflags" ) {
522- OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << ' \n ' ;
557+ RenderFlags ( LLVM_CPPFLAGS) ;
523558 } else if (Arg == " --cflags" ) {
524- OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << ' \n ' ;
559+ RenderFlags ( LLVM_CFLAGS) ;
525560 } else if (Arg == " --cxxflags" ) {
526- OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << ' \n ' ;
561+ RenderFlags ( LLVM_CXXFLAGS) ;
527562 } else if (Arg == " --ldflags" ) {
528- OS << ((HostTriple.isWindowsMSVCEnvironment ()) ? " -LIBPATH:" : " -L" )
529- << ActiveLibDir << ' ' << LLVM_LDFLAGS << ' \n ' ;
563+ std::string LDFlags =
564+ HostTriple.isWindowsMSVCEnvironment () ? " -LIBPATH:" : " -L" ;
565+ LDFlags += ActiveLibDir;
566+ MaybePrintQuoted (LDFlags);
567+ OS << ' ' << LLVM_LDFLAGS << ' \n ' ;
530568 } else if (Arg == " --system-libs" ) {
531569 PrintSystemLibs = true ;
532570 } else if (Arg == " --libs" ) {
@@ -580,7 +618,8 @@ int main(int argc, char **argv) {
580618 } else if (Arg == " --shared-mode" ) {
581619 PrintSharedMode = true ;
582620 } else if (Arg == " --obj-root" ) {
583- OS << ActivePrefix << ' \n ' ;
621+ MaybePrintQuoted (ActivePrefix);
622+ OS << ' \n ' ;
584623 } else if (Arg == " --ignore-libllvm" ) {
585624 LinkDyLib = false ;
586625 LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;
@@ -590,6 +629,8 @@ int main(int argc, char **argv) {
590629 LinkMode = LinkModeStatic;
591630 } else if (Arg == " --help" ) {
592631 usage (false );
632+ } else if (Arg == " --quote-paths" ) {
633+ // Was already handled above this loop.
593634 } else {
594635 usage ();
595636 }
@@ -682,26 +723,30 @@ int main(int argc, char **argv) {
682723
683724 auto PrintForLib = [&](const StringRef &Lib) {
684725 const bool Shared = LinkMode == LinkModeShared;
726+ std::string LibFileName;
685727 if (PrintLibNames) {
686- OS << GetComponentLibraryFileName (Lib, Shared);
728+ LibFileName = GetComponentLibraryFileName (Lib, Shared);
687729 } else if (PrintLibFiles) {
688- OS << GetComponentLibraryPath (Lib, Shared);
730+ LibFileName = GetComponentLibraryPath (Lib, Shared);
689731 } else if (PrintLibs) {
690732 // On Windows, output full path to library without parameters.
691733 // Elsewhere, if this is a typical library name, include it using -l.
692734 if (HostTriple.isWindowsMSVCEnvironment ()) {
693- OS << GetComponentLibraryPath (Lib, Shared);
735+ LibFileName = GetComponentLibraryPath (Lib, Shared);
694736 } else {
737+ LibFileName = " -l" ;
695738 StringRef LibName;
696739 if (GetComponentLibraryNameSlice (Lib, LibName)) {
697740 // Extract library name (remove prefix and suffix).
698- OS << " -l " << LibName;
741+ LibFileName += LibName;
699742 } else {
700743 // Lib is already a library name without prefix and suffix.
701- OS << " -l " << Lib;
744+ LibFileName += Lib;
702745 }
703746 }
704747 }
748+ if (!LibFileName.empty ())
749+ MaybePrintQuoted (LibFileName);
705750 };
706751
707752 if (LinkMode == LinkModeShared && LinkDyLib)
0 commit comments