blob: 340e9a3cac6110ab76e0383186dc02ac0155102a [file] [log] [blame]
Michael Eiseld8723b42020-08-24 12:08:16 -07001// Copyright 2020 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <cstdlib>
16#include <fstream>
17#include <iostream>
18#include <regex> // NOLINT
19#include <unordered_set>
20
21using std::ifstream;
22using std::regex;
23using std::string;
24using std::unordered_set;
Keith Smiley48dd1592021-09-09 11:46:47 -070025using std::vector;
26
27const regex libRegex = regex(".*\\.a$");
28const regex noArgFlags =
29 regex("-static|-s|-a|-c|-L|-T|-D|-no_warning_for_no_symbols");
30const regex singleArgFlags = regex("-arch_only|-syslibroot|-o");
Michael Eiseld8723b42020-08-24 12:08:16 -070031
32string getBasename(const string &path) {
33 // Assumes we're on an OS with "/" as the path separator
34 auto idx = path.find_last_of("/");
35 if (idx == string::npos) {
36 return path;
37 }
38 return path.substr(idx + 1);
39}
40
Keith Smiley48dd1592021-09-09 11:46:47 -070041vector<string> readFile(const string path) {
42 vector<string> lines;
43 ifstream file(path);
44 string line;
45 while (std::getline(file, line)) {
46 if (!line.empty()) {
47 lines.push_back(line);
48 }
49 }
50
51 return lines;
52}
53
54unordered_set<string> parseArgs(vector<string> args) {
Michael Eiseld8723b42020-08-24 12:08:16 -070055 unordered_set<string> basenames;
Keith Smiley48dd1592021-09-09 11:46:47 -070056 for (auto it = args.begin(); it != args.end(); ++it) {
57 const string arg = *it;
Michael Eiseld8723b42020-08-24 12:08:16 -070058 if (arg == "-filelist") {
Keith Smiley48dd1592021-09-09 11:46:47 -070059 ++it;
60 ifstream list(*it);
Michael Eiseld8723b42020-08-24 12:08:16 -070061 for (string line; getline(list, line);) {
62 const string basename = getBasename(line);
63 const auto pair = basenames.insert(basename);
64 if (!pair.second) {
Keith Smiley48dd1592021-09-09 11:46:47 -070065 exit(EXIT_FAILURE);
Michael Eiseld8723b42020-08-24 12:08:16 -070066 }
67 }
68 list.close();
Keith Smiley48dd1592021-09-09 11:46:47 -070069 } else if (arg[0] == '@') {
70 string paramsFilePath(arg.substr(1));
71 auto newBasenames = parseArgs(readFile(paramsFilePath));
72 for (auto newBasename : newBasenames) {
73 const auto pair = basenames.insert(newBasename);
74 if (!pair.second) {
75 exit(EXIT_FAILURE);
76 }
77 }
Michael Eiseld8723b42020-08-24 12:08:16 -070078 } else if (regex_match(arg, noArgFlags)) {
79 } else if (regex_match(arg, singleArgFlags)) {
Keith Smiley48dd1592021-09-09 11:46:47 -070080 ++it;
Michael Eiseld8723b42020-08-24 12:08:16 -070081 } else if (arg[0] == '-') {
Keith Smiley48dd1592021-09-09 11:46:47 -070082 exit(EXIT_FAILURE);
83 // Unrecognized flag, let the wrapper deal with it, any flags added to
84 // libtool.sh should also be added here.
Michael Eiseld8723b42020-08-24 12:08:16 -070085 } else if (regex_match(arg, libRegex)) {
86 // Archive inputs can remain untouched, as they come from other targets.
87 } else {
88 const string basename = getBasename(arg);
89 const auto pair = basenames.insert(basename);
90 if (!pair.second) {
Keith Smiley48dd1592021-09-09 11:46:47 -070091 exit(EXIT_FAILURE);
Michael Eiseld8723b42020-08-24 12:08:16 -070092 }
93 }
94 }
Keith Smiley48dd1592021-09-09 11:46:47 -070095
96 return basenames;
97}
98
99// Returns 0 if there are no duplicate basenames in the object files (via
100// -filelist, params files, and shell args), 1 otherwise
101int main(int argc, const char *argv[]) {
102 vector<string> args;
103 // Set i to 1 to skip executable path
104 for (int i = 1; argv[i] != nullptr; i++) {
105 args.push_back(argv[i]);
106 }
107 parseArgs(args);
Michael Eiseld8723b42020-08-24 12:08:16 -0700108 return EXIT_SUCCESS;
109}