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.begin (), ActiveIncludeDir.end (), ' /' , ' \\ ' );
405+ for (auto & Include : ActiveIncludeOptions)
406+ llvm::replace (Include.begin (), Include.end (), ' /' , ' \\ ' );
403407 }
404408 SharedDir = ActiveBinDir;
405409 StaticDir = ActiveLibDir;
@@ -501,6 +505,36 @@ 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 = false ;
511+ for (int i = 1 ; i != argc; ++i) {
512+ if (StringRef (argv[i]) == " --quote-paths" ) {
513+ QuotePaths = true ;
514+ break ;
515+ }
516+ }
517+
518+ auto MaybePrintQuoted = [&](StringRef Str) {
519+ if (QuotePaths)
520+ sys::printArg (OS, Str, /* Quote=*/ false ); // only add quotes if necessary
521+ else
522+ OS << Str;
523+ };
524+
525+ // Render include paths and associated flags
526+ auto RenderFlags = [&](StringRef Flags) {
527+ bool First = true ;
528+ for (auto &Include : ActiveIncludeOptions) {
529+ if (!First)
530+ OS << ' ' ;
531+ std::string FlagsStr = " -I" + Include;
532+ MaybePrintQuoted (FlagsStr);
533+ First = false ;
534+ }
535+ OS << ' ' << Flags << ' \n ' ;
536+ };
537+
504538 for (int i = 1 ; i != argc; ++i) {
505539 StringRef Arg = argv[i];
506540
@@ -509,24 +543,32 @@ int main(int argc, char **argv) {
509543 if (Arg == " --version" ) {
510544 OS << PACKAGE_VERSION << ' \n ' ;
511545 } else if (Arg == " --prefix" ) {
512- OS << ActivePrefix << ' \n ' ;
546+ MaybePrintQuoted (ActivePrefix);
547+ OS << ' \n ' ;
513548 } else if (Arg == " --bindir" ) {
514- OS << ActiveBinDir << ' \n ' ;
549+ MaybePrintQuoted (ActiveBinDir);
550+ OS << ' \n ' ;
515551 } else if (Arg == " --includedir" ) {
516- OS << ActiveIncludeDir << ' \n ' ;
552+ MaybePrintQuoted (ActiveIncludeDir);
553+ OS << ' \n ' ;
517554 } else if (Arg == " --libdir" ) {
518- OS << ActiveLibDir << ' \n ' ;
555+ MaybePrintQuoted (ActiveLibDir);
556+ OS << ' \n ' ;
519557 } else if (Arg == " --cmakedir" ) {
520- OS << ActiveCMakeDir << ' \n ' ;
558+ MaybePrintQuoted (ActiveCMakeDir);
559+ OS << ' \n ' ;
521560 } else if (Arg == " --cppflags" ) {
522- OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << ' \n ' ;
561+ RenderFlags ( LLVM_CPPFLAGS) ;
523562 } else if (Arg == " --cflags" ) {
524- OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << ' \n ' ;
563+ RenderFlags ( LLVM_CFLAGS) ;
525564 } else if (Arg == " --cxxflags" ) {
526- OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << ' \n ' ;
565+ RenderFlags ( LLVM_CXXFLAGS) ;
527566 } else if (Arg == " --ldflags" ) {
528- OS << ((HostTriple.isWindowsMSVCEnvironment ()) ? " -LIBPATH:" : " -L" )
529- << ActiveLibDir << ' ' << LLVM_LDFLAGS << ' \n ' ;
567+ std::string LDFlags =
568+ HostTriple.isWindowsMSVCEnvironment () ? " -LIBPATH:" : " -L" ;
569+ LDFlags += ActiveLibDir;
570+ MaybePrintQuoted (LDFlags);
571+ OS << ' ' << LLVM_LDFLAGS << ' \n ' ;
530572 } else if (Arg == " --system-libs" ) {
531573 PrintSystemLibs = true ;
532574 } else if (Arg == " --libs" ) {
@@ -580,7 +622,8 @@ int main(int argc, char **argv) {
580622 } else if (Arg == " --shared-mode" ) {
581623 PrintSharedMode = true ;
582624 } else if (Arg == " --obj-root" ) {
583- OS << ActivePrefix << ' \n ' ;
625+ MaybePrintQuoted (ActivePrefix);
626+ OS << ' \n ' ;
584627 } else if (Arg == " --ignore-libllvm" ) {
585628 LinkDyLib = false ;
586629 LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;
@@ -590,6 +633,8 @@ int main(int argc, char **argv) {
590633 LinkMode = LinkModeStatic;
591634 } else if (Arg == " --help" ) {
592635 usage (false );
636+ } else if (Arg == " --quote-paths" ) {
637+ // Was already handled above this loop.
593638 } else {
594639 usage ();
595640 }
@@ -682,26 +727,30 @@ int main(int argc, char **argv) {
682727
683728 auto PrintForLib = [&](const StringRef &Lib) {
684729 const bool Shared = LinkMode == LinkModeShared;
730+ std::string LibFileName;
685731 if (PrintLibNames) {
686- OS << GetComponentLibraryFileName (Lib, Shared);
732+ LibFileName = GetComponentLibraryFileName (Lib, Shared);
687733 } else if (PrintLibFiles) {
688- OS << GetComponentLibraryPath (Lib, Shared);
734+ LibFileName = GetComponentLibraryPath (Lib, Shared);
689735 } else if (PrintLibs) {
690736 // On Windows, output full path to library without parameters.
691737 // Elsewhere, if this is a typical library name, include it using -l.
692738 if (HostTriple.isWindowsMSVCEnvironment ()) {
693- OS << GetComponentLibraryPath (Lib, Shared);
739+ LibFileName = GetComponentLibraryPath (Lib, Shared);
694740 } else {
741+ LibFileName = " -l" ;
695742 StringRef LibName;
696743 if (GetComponentLibraryNameSlice (Lib, LibName)) {
697744 // Extract library name (remove prefix and suffix).
698- OS << " -l " << LibName;
745+ LibFileName += LibName;
699746 } else {
700747 // Lib is already a library name without prefix and suffix.
701- OS << " -l " << Lib;
748+ LibFileName += Lib;
702749 }
703750 }
704751 }
752+ if (!LibFileName.empty ())
753+ MaybePrintQuoted (LibFileName);
705754 };
706755
707756 if (LinkMode == LinkModeShared && LinkDyLib)
0 commit comments