Merge pull request #127 from keith:ks/apply-upstream-libtool_check_unique-fix
PiperOrigin-RevId: 485829598
Change-Id: Ifb0baed68f4a496c50989697f9d1a1cbc851b93e
diff --git a/cc/private/toolchain/libtool_check_unique.cc b/cc/private/toolchain/libtool_check_unique.cc
index b90aa59..340e9a3 100644
--- a/cc/private/toolchain/libtool_check_unique.cc
+++ b/cc/private/toolchain/libtool_check_unique.cc
@@ -22,6 +22,12 @@
using std::regex;
using std::string;
using std::unordered_set;
+using std::vector;
+
+const regex libRegex = regex(".*\\.a$");
+const regex noArgFlags =
+ regex("-static|-s|-a|-c|-L|-T|-D|-no_warning_for_no_symbols");
+const regex singleArgFlags = regex("-arch_only|-syslibroot|-o");
string getBasename(const string &path) {
// Assumes we're on an OS with "/" as the path separator
@@ -32,43 +38,72 @@
return path.substr(idx + 1);
}
-// Returns 0 if there are no duplicate basenames in the object files (both via
-// -filelist as well as shell args), 1 otherwise
-int main(int argc, const char *argv[]) {
+vector<string> readFile(const string path) {
+ vector<string> lines;
+ ifstream file(path);
+ string line;
+ while (std::getline(file, line)) {
+ if (!line.empty()) {
+ lines.push_back(line);
+ }
+ }
+
+ return lines;
+}
+
+unordered_set<string> parseArgs(vector<string> args) {
unordered_set<string> basenames;
- const regex libRegex = regex(".*\\.a$");
- const regex noArgFlags =
- regex("-static|-s|-a|-c|-L|-T|-D|-no_warning_for_no_symbols");
- const regex singleArgFlags = regex("-arch_only|-syslibroot|-o");
- // Set i to 1 to skip executable path
- for (int i = 1; argv[i] != nullptr; i++) {
- const string arg = argv[i];
+ for (auto it = args.begin(); it != args.end(); ++it) {
+ const string arg = *it;
if (arg == "-filelist") {
- ifstream list(argv[i + 1]);
+ ++it;
+ ifstream list(*it);
for (string line; getline(list, line);) {
const string basename = getBasename(line);
const auto pair = basenames.insert(basename);
if (!pair.second) {
- return EXIT_FAILURE;
+ exit(EXIT_FAILURE);
}
}
list.close();
- i++;
+ } else if (arg[0] == '@') {
+ string paramsFilePath(arg.substr(1));
+ auto newBasenames = parseArgs(readFile(paramsFilePath));
+ for (auto newBasename : newBasenames) {
+ const auto pair = basenames.insert(newBasename);
+ if (!pair.second) {
+ exit(EXIT_FAILURE);
+ }
+ }
} else if (regex_match(arg, noArgFlags)) {
} else if (regex_match(arg, singleArgFlags)) {
- i++;
+ ++it;
} else if (arg[0] == '-') {
- return EXIT_FAILURE;
- // Unrecognized flag, let the wrapper deal with it
+ exit(EXIT_FAILURE);
+ // Unrecognized flag, let the wrapper deal with it, any flags added to
+ // libtool.sh should also be added here.
} else if (regex_match(arg, libRegex)) {
// Archive inputs can remain untouched, as they come from other targets.
} else {
const string basename = getBasename(arg);
const auto pair = basenames.insert(basename);
if (!pair.second) {
- return EXIT_FAILURE;
+ exit(EXIT_FAILURE);
}
}
}
+
+ return basenames;
+}
+
+// Returns 0 if there are no duplicate basenames in the object files (via
+// -filelist, params files, and shell args), 1 otherwise
+int main(int argc, const char *argv[]) {
+ vector<string> args;
+ // Set i to 1 to skip executable path
+ for (int i = 1; argv[i] != nullptr; i++) {
+ args.push_back(argv[i]);
+ }
+ parseArgs(args);
return EXIT_SUCCESS;
}