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"
@@ -219,6 +220,7 @@ Options:\n\
219220 --components List of all possible components.\n \
220221 --cppflags C preprocessor flags for files that include LLVM headers.\n \
221222 --cxxflags C++ compiler flags for files that include LLVM headers.\n \
223+ --quote-paths Quote and escape paths when needed.\n \
222224 --has-rtti Print whether or not LLVM was built with rtti (YES or NO).\n \
223225 --help Print a summary of llvm-config arguments.\n \
224226 --host-target Target triple used to configure LLVM.\n \
@@ -326,7 +328,7 @@ int main(int argc, char **argv) {
326328 // information.
327329 std::string ActivePrefix, ActiveBinDir, ActiveIncludeDir, ActiveLibDir,
328330 ActiveCMakeDir;
329- std::string ActiveIncludeOption ;
331+ std::vector<std:: string> ActiveIncludeOptions ;
330332 if (IsInDevelopmentTree) {
331333 ActiveIncludeDir = std::string (LLVM_SRC_ROOT) + " /include" ;
332334 ActivePrefix = CurrentExecPrefix;
@@ -352,8 +354,8 @@ int main(int argc, char **argv) {
352354 }
353355
354356 // We need to include files from both the source and object trees.
355- ActiveIncludeOption =
356- ( " -I " + ActiveIncludeDir + " " + " -I " + ActiveObjRoot + " /include" );
357+ ActiveIncludeOptions. push_back (ActiveIncludeDir);
358+ ActiveIncludeOptions. push_back ( ActiveObjRoot + " /include" );
357359 } else {
358360 ActivePrefix = CurrentExecPrefix;
359361 {
@@ -372,7 +374,7 @@ int main(int argc, char **argv) {
372374 sys::fs::make_absolute (ActivePrefix, Path);
373375 ActiveCMakeDir = std::string (Path);
374376 }
375- ActiveIncludeOption = " -I " + ActiveIncludeDir;
377+ ActiveIncludeOptions. push_back ( ActiveIncludeDir) ;
376378 }
377379
378380 // / We only use `shared library` mode in cases where the static library form
@@ -401,8 +403,9 @@ int main(int argc, char **argv) {
401403 std::replace (ActiveBinDir.begin (), ActiveBinDir.end (), ' /' , ' \\ ' );
402404 std::replace (ActiveLibDir.begin (), ActiveLibDir.end (), ' /' , ' \\ ' );
403405 std::replace (ActiveCMakeDir.begin (), ActiveCMakeDir.end (), ' /' , ' \\ ' );
404- std::replace (ActiveIncludeOption.begin (), ActiveIncludeOption.end (), ' /' ,
405- ' \\ ' );
406+ std::replace (ActiveIncludeDir.begin (), ActiveIncludeDir.end (), ' /' , ' \\ ' );
407+ for (auto &Include : ActiveIncludeOptions)
408+ std::replace (Include.begin (), Include.end (), ' /' , ' \\ ' );
406409 }
407410 SharedDir = ActiveBinDir;
408411 StaticDir = ActiveLibDir;
@@ -504,6 +507,36 @@ int main(int argc, char **argv) {
504507 };
505508
506509 raw_ostream &OS = outs ();
510+
511+ // Check if we want quoting and escaping.
512+ bool QuotePaths = false ;
513+ for (int i = 1 ; i != argc; ++i) {
514+ if (StringRef (argv[i]) == " --quote-paths" ) {
515+ QuotePaths = true ;
516+ break ;
517+ }
518+ }
519+
520+ auto MaybePrintQuoted = [&](StringRef Str) {
521+ if (QuotePaths)
522+ sys::printArg (OS, Str, /* Quote=*/ false ); // only add quotes if necessary
523+ else
524+ OS << Str;
525+ };
526+
527+ // Render include paths and associated flags
528+ auto RenderFlags = [&](StringRef Flags) {
529+ bool First = true ;
530+ for (auto &Include : ActiveIncludeOptions) {
531+ if (!First)
532+ OS << ' ' ;
533+ std::string FlagsStr = " -I" + Include;
534+ MaybePrintQuoted (FlagsStr);
535+ First = false ;
536+ }
537+ OS << ' ' << Flags << ' \n ' ;
538+ };
539+
507540 for (int i = 1 ; i != argc; ++i) {
508541 StringRef Arg = argv[i];
509542
@@ -512,24 +545,32 @@ int main(int argc, char **argv) {
512545 if (Arg == " --version" ) {
513546 OS << PACKAGE_VERSION << ' \n ' ;
514547 } else if (Arg == " --prefix" ) {
515- OS << ActivePrefix << ' \n ' ;
548+ MaybePrintQuoted (ActivePrefix);
549+ OS << ' \n ' ;
516550 } else if (Arg == " --bindir" ) {
517- OS << ActiveBinDir << ' \n ' ;
551+ MaybePrintQuoted (ActiveBinDir);
552+ OS << ' \n ' ;
518553 } else if (Arg == " --includedir" ) {
519- OS << ActiveIncludeDir << ' \n ' ;
554+ MaybePrintQuoted (ActiveIncludeDir);
555+ OS << ' \n ' ;
520556 } else if (Arg == " --libdir" ) {
521- OS << ActiveLibDir << ' \n ' ;
557+ MaybePrintQuoted (ActiveLibDir);
558+ OS << ' \n ' ;
522559 } else if (Arg == " --cmakedir" ) {
523- OS << ActiveCMakeDir << ' \n ' ;
560+ MaybePrintQuoted (ActiveCMakeDir);
561+ OS << ' \n ' ;
524562 } else if (Arg == " --cppflags" ) {
525- OS << ActiveIncludeOption << ' ' << LLVM_CPPFLAGS << ' \n ' ;
563+ RenderFlags ( LLVM_CPPFLAGS) ;
526564 } else if (Arg == " --cflags" ) {
527- OS << ActiveIncludeOption << ' ' << LLVM_CFLAGS << ' \n ' ;
565+ RenderFlags ( LLVM_CFLAGS) ;
528566 } else if (Arg == " --cxxflags" ) {
529- OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << ' \n ' ;
567+ RenderFlags ( LLVM_CXXFLAGS) ;
530568 } else if (Arg == " --ldflags" ) {
531- OS << ((HostTriple.isWindowsMSVCEnvironment ()) ? " -LIBPATH:" : " -L" )
532- << ActiveLibDir << ' ' << LLVM_LDFLAGS << ' \n ' ;
569+ std::string LDFlags =
570+ HostTriple.isWindowsMSVCEnvironment () ? " -LIBPATH:" : " -L" ;
571+ LDFlags += ActiveLibDir;
572+ MaybePrintQuoted (LDFlags);
573+ OS << ' ' << LLVM_LDFLAGS << ' \n ' ;
533574 } else if (Arg == " --system-libs" ) {
534575 PrintSystemLibs = true ;
535576 } else if (Arg == " --libs" ) {
@@ -590,7 +631,8 @@ int main(int argc, char **argv) {
590631 } else if (Arg == " --shared-mode" ) {
591632 PrintSharedMode = true ;
592633 } else if (Arg == " --obj-root" ) {
593- OS << ActivePrefix << ' \n ' ;
634+ MaybePrintQuoted (ActivePrefix);
635+ OS << ' \n ' ;
594636 } else if (Arg == " --ignore-libllvm" ) {
595637 LinkDyLib = false ;
596638 LinkMode = BuiltSharedLibs ? LinkModeShared : LinkModeAuto;
@@ -600,6 +642,8 @@ int main(int argc, char **argv) {
600642 LinkMode = LinkModeStatic;
601643 } else if (Arg == " --help" ) {
602644 usage (false );
645+ } else if (Arg == " --quote-paths" ) {
646+ // Was already handled above this loop.
603647 } else {
604648 usage ();
605649 }
@@ -695,26 +739,30 @@ int main(int argc, char **argv) {
695739
696740 auto PrintForLib = [&](const StringRef &Lib) {
697741 const bool Shared = LinkMode == LinkModeShared;
742+ std::string LibFileName;
698743 if (PrintLibNames) {
699- OS << GetComponentLibraryFileName (Lib, Shared);
744+ LibFileName = GetComponentLibraryFileName (Lib, Shared);
700745 } else if (PrintLibFiles) {
701- OS << GetComponentLibraryPath (Lib, Shared);
746+ LibFileName = GetComponentLibraryPath (Lib, Shared);
702747 } else if (PrintLibs) {
703748 // On Windows, output full path to library without parameters.
704749 // Elsewhere, if this is a typical library name, include it using -l.
705750 if (HostTriple.isWindowsMSVCEnvironment ()) {
706- OS << GetComponentLibraryPath (Lib, Shared);
751+ LibFileName = GetComponentLibraryPath (Lib, Shared);
707752 } else {
753+ LibFileName = " -l" ;
708754 StringRef LibName;
709755 if (GetComponentLibraryNameSlice (Lib, LibName)) {
710756 // Extract library name (remove prefix and suffix).
711- OS << " -l " << LibName;
757+ LibFileName += LibName;
712758 } else {
713759 // Lib is already a library name without prefix and suffix.
714- OS << " -l " << Lib;
760+ LibFileName += Lib;
715761 }
716762 }
717763 }
764+ if (!LibFileName.empty ())
765+ MaybePrintQuoted (LibFileName);
718766 };
719767
720768 if (LinkMode == LinkModeShared && LinkDyLib) {
0 commit comments