jackoalan updated this revision to Diff 393777.
jackoalan added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Add entry to user manual explaining the `<@>` token.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D115604/new/
https://reviews.llvm.org/D115604
Files:
clang/docs/UsersManual.rst
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp
Index: llvm/unittests/Support/CommandLineTest.cpp
===================================================================
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -796,8 +796,10 @@
llvm::MemoryBuffer::getMemBuffer("-option_1 -option_2\n"
"@incdir/resp2\n"
"-option_3=abcd\n"
- "@incdir/resp3\n"
- "-option_4=efjk\n"));
+ "@<@>/incdir/resp3\n"
+ "-option_4=efjk\n"
+ "-option_5=<@>\n"
+ "-option_6=<@>/sub\n"));
// Directory for included file.
llvm::StringRef IncDir = "incdir";
@@ -807,14 +809,16 @@
llvm::sys::path::append(IncludedFileName2, IncDir, "resp2");
FS.addFile(IncludedFileName2, 0,
MemoryBuffer::getMemBuffer("-option_21 -option_22\n"
- "-option_23=abcd\n"));
+ "-option_23=abcd\n"
+ "-option_24=<@>\n"));
// Create second included response file of second level.
llvm::SmallString<128> IncludedFileName3;
llvm::sys::path::append(IncludedFileName3, IncDir, "resp3");
FS.addFile(IncludedFileName3, 0,
MemoryBuffer::getMemBuffer("-option_31 -option_32\n"
- "-option_33=abcd\n"));
+ "-option_33=abcd\n"
+ "-option_34=<@>\n"));
// Prepare 'file' with reference to response file.
SmallString<128> IncRef;
@@ -829,12 +833,14 @@
ASSERT_TRUE(llvm::cl::ExpandResponseFiles(
Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true,
/*CurrentDir=*/StringRef(TestRoot), FS));
- EXPECT_THAT(Argv, testing::Pointwise(
- StringEquality(),
- {"test/test", "-flag_1", "-option_1", "-option_2",
- "-option_21", "-option_22", "-option_23=abcd",
- "-option_3=abcd", "-option_31", "-option_32",
- "-option_33=abcd", "-option_4=efjk", "-flag_2"}));
+ EXPECT_THAT(
+ Argv, testing::Pointwise(
+ StringEquality(),
+ {"test/test", "-flag_1", "-option_1", "-option_2", "-option_21",
+ "-option_22", "-option_23=abcd", "-option_24=/incdir",
+ "-option_3=abcd", "-option_31", "-option_32",
+ "-option_33=abcd", "-option_34=/incdir", "-option_4=efjk",
+ "-option_5=/", "-option_6=/sub", "-flag_2"}));
}
TEST(CommandLineTest, RecursiveResponseFiles) {
@@ -1045,15 +1051,17 @@
TempFile ConfigFile(TestCfg, "",
"# Comment\n"
"-option_1\n"
+ "-option_2=<@>/dir1\n"
"@subconfig\n"
- "-option_3=abcd\n"
- "-option_4=\\\n"
+ "-option_5=abcd\n"
+ "-option_6=\\\n"
"cdef\n");
llvm::SmallString<128> TestCfg2;
llvm::sys::path::append(TestCfg2, TestDir.path(), "subconfig");
TempFile ConfigFile2(TestCfg2, "",
- "-option_2\n"
+ "-option_3\n"
+ "-option_4=<@>/dir2\n"
"\n"
" # comment\n");
@@ -1071,11 +1079,15 @@
bool Result = llvm::cl::readConfigFile(ConfigFile.path(), Saver, Argv);
EXPECT_TRUE(Result);
- EXPECT_EQ(Argv.size(), 4U);
+ EXPECT_EQ(Argv.size(), 6U);
EXPECT_STREQ(Argv[0], "-option_1");
- EXPECT_STREQ(Argv[1], "-option_2");
- EXPECT_STREQ(Argv[2], "-option_3=abcd");
- EXPECT_STREQ(Argv[3], "-option_4=cdef");
+ EXPECT_STREQ(Argv[1],
+ ("-option_2=" + TestDir.path() + "/dir1").str().c_str());
+ EXPECT_STREQ(Argv[2], "-option_3");
+ EXPECT_STREQ(Argv[3],
+ ("-option_4=" + TestDir.path() + "/dir2").str().c_str());
+ EXPECT_STREQ(Argv[4], "-option_5=abcd");
+ EXPECT_STREQ(Argv[5], "-option_6=cdef");
}
TEST(CommandLineTest, PositionalEatArgsError) {
Index: llvm/lib/Support/CommandLine.cpp
===================================================================
--- llvm/lib/Support/CommandLine.cpp
+++ llvm/lib/Support/CommandLine.cpp
@@ -1078,6 +1078,38 @@
return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
}
+// Substitute <@> with the response file base path.
+static void ExpandResponseDirTokens(StringRef BasePath, StringSaver &Saver,
+ const char *&Arg) {
+ assert(sys::path::is_absolute(BasePath));
+ constexpr StringLiteral Token("<@>");
+ const StringRef ArgString(Arg);
+
+ SmallString<128> ResponseFile;
+ StringRef::size_type StartPos = 0;
+ for (StringRef::size_type TokenPos = ArgString.find(Token);
+ TokenPos != StringRef::npos;
+ TokenPos = ArgString.find(Token, StartPos)) {
+ // Although it typically does not make sense to use <@> more than once per
+ // arg, support it by using path-append on any subsequent appearances.
+ const StringRef LHS = ArgString.substr(StartPos, TokenPos - StartPos);
+ if (ResponseFile.empty())
+ ResponseFile = LHS;
+ else
+ llvm::sys::path::append(ResponseFile, LHS);
+ ResponseFile.append(BasePath);
+ StartPos = TokenPos + Token.size();
+ }
+
+ if (!ResponseFile.empty()) {
+ // Path-append the remaining arg substring if at least one <@> appeared.
+ const StringRef Remaining = ArgString.substr(StartPos);
+ if (!Remaining.empty())
+ llvm::sys::path::append(ResponseFile, Remaining);
+ Arg = Saver.save(ResponseFile.str()).data();
+ }
+}
+
// FName must be an absolute path.
static llvm::Error ExpandResponseFile(
StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer,
@@ -1116,8 +1148,14 @@
// file, replace the included response file names with their full paths
// obtained by required resolution.
for (auto &Arg : NewArgv) {
+ if (!Arg)
+ continue;
+
+ // Substitute <@> with the response file base path.
+ ExpandResponseDirTokens(BasePath, Saver, Arg);
+
// Skip non-rsp file arguments.
- if (!Arg || Arg[0] != '@')
+ if (Arg[0] != '@')
continue;
StringRef FileName(Arg + 1);
@@ -1129,7 +1167,7 @@
ResponseFile.push_back('@');
ResponseFile.append(BasePath);
llvm::sys::path::append(ResponseFile, FileName);
- Arg = Saver.save(ResponseFile.c_str()).data();
+ Arg = Saver.save(ResponseFile.str()).data();
}
return Error::success();
}
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -917,6 +917,18 @@
`~/.llvm/target.cfg` contains the directive `@os/linux.opts`, the file
`linux.opts` is searched for in the directory `~/.llvm/os`.
+To generate paths relative to the configuration file, the `<@>` token may be
+used. This will expand to the absolute path of the directory containing the
+configuration file. A typical use-case may be a portable, potentially
+not-installed cross-compilation SDK directory:
+
+::
+
+ --target=sample
+ -isystem <@>/include
+ -L <@>/lib
+ -T <@>/ldscripts/link.ld
+
Language and Target-Independent Features
========================================
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits