mirror of
https://github.com/rui314/mold.git
synced 2024-09-11 21:17:28 +03:00
[Mach-O] Handle response files correctly
This commit is contained in:
parent
6087782660
commit
efb6e6729a
@ -5,7 +5,7 @@
|
||||
namespace mold {
|
||||
|
||||
template <typename C>
|
||||
static std::vector<std::string_view>
|
||||
std::vector<std::string_view>
|
||||
read_response_file(C &ctx, std::string_view path) {
|
||||
std::vector<std::string_view> vec;
|
||||
MappedFile<C> *mf = MappedFile<C>::must_open(ctx, std::string(path));
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "mold.h"
|
||||
#include "../cmdline.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
@ -78,35 +79,33 @@ static i64 parse_version(Context &ctx, std::string_view arg) {
|
||||
|
||||
void parse_nonpositional_args(Context &ctx,
|
||||
std::vector<std::string> &remaining) {
|
||||
std::span<std::string_view> args = ctx.cmdline_args;
|
||||
args = args.subspan(1);
|
||||
std::vector<std::string_view> &args = ctx.cmdline_args;
|
||||
i64 i = 1;
|
||||
|
||||
bool version_shown = false;
|
||||
|
||||
while (!args.empty()) {
|
||||
while (i < args.size()) {
|
||||
std::string_view arg;
|
||||
std::string_view arg2;
|
||||
std::string_view arg3;
|
||||
|
||||
auto read_arg = [&](std::string name) {
|
||||
if (args[0] == name) {
|
||||
if (args.size() == 1)
|
||||
if (args[i] == name) {
|
||||
if (args.size() <= i + 1)
|
||||
Fatal(ctx) << "option -" << name << ": argument missing";
|
||||
arg = args[1];
|
||||
args = args.subspan(2);
|
||||
arg = args[i + 1];
|
||||
i += 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto read_arg3 = [&](std::string name) {
|
||||
if (args[0] == name) {
|
||||
if (args.size() == 3)
|
||||
if (args[i] == name) {
|
||||
if (args.size() <= i + 3)
|
||||
Fatal(ctx) << "option -" << name << ": argument missing";
|
||||
arg = args[1];
|
||||
arg2 = args[2];
|
||||
arg3 = args[3];
|
||||
args = args.subspan(4);
|
||||
arg = args[i + 1];
|
||||
arg2 = args[i + 2];
|
||||
arg3 = args[i + 3];
|
||||
i += 4;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -115,24 +114,32 @@ void parse_nonpositional_args(Context &ctx,
|
||||
auto read_joined = [&](std::string name) {
|
||||
if (read_arg(name))
|
||||
return true;
|
||||
if (args[0].starts_with(name)) {
|
||||
arg = args[0].substr(2);
|
||||
args = args.subspan(1);
|
||||
if (args[i].starts_with(name)) {
|
||||
arg = args[i].substr(2);
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto read_flag = [&](std::string name) {
|
||||
if (args[0] == name) {
|
||||
args = args.subspan(1);
|
||||
if (args[i] == name) {
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (args[i].starts_with('@')) {
|
||||
std::vector<std::string_view> vec =
|
||||
read_response_file(ctx, args[i].substr(1));
|
||||
args.erase(args.begin() + i);
|
||||
args.insert(args.begin() + i, vec.begin(), vec.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (read_flag("-help") || read_flag("--help")) {
|
||||
SyncOut(ctx) << "Usage: " << ctx.cmdline_args[0]
|
||||
SyncOut(ctx) << "Usage: " << ctx.cmdline_args[i]
|
||||
<< " [options] file...\n" << helpmsg;
|
||||
exit(0);
|
||||
}
|
||||
@ -188,10 +195,10 @@ void parse_nonpositional_args(Context &ctx,
|
||||
} else if (read_flag("-v")) {
|
||||
SyncOut(ctx) << mold_version;
|
||||
} else {
|
||||
if (args[0][0] == '-')
|
||||
Fatal(ctx) << "unknown command line option: " << args[0];
|
||||
remaining.push_back(std::string(args[0]));
|
||||
args = args.subspan(1);
|
||||
if (args[i][i] == '-')
|
||||
Fatal(ctx) << "unknown command line option: " << args[i];
|
||||
remaining.push_back(std::string(args[i]));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,9 @@ int main(int argc, char **argv) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ctx.cmdline_args = expand_response_files(ctx, argv);
|
||||
for (i64 i = 0; i < argc; i++)
|
||||
ctx.cmdline_args.push_back(argv[i]);
|
||||
|
||||
std::vector<std::string> file_args;
|
||||
parse_nonpositional_args(ctx, file_args);
|
||||
|
||||
|
12
test/macho/response-file.sh
Executable file
12
test/macho/response-file.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd $(dirname $0)
|
||||
mold=`pwd`/../../ld64.mold
|
||||
echo -n "Testing $(basename -s .sh $0) ... "
|
||||
t=$(pwd)/../../out/test/macho/$(basename -s .sh $0)
|
||||
mkdir -p $t
|
||||
|
||||
echo ' -help' > $t/rsp
|
||||
$mold @$t/rsp | grep -q Usage
|
||||
|
||||
echo OK
|
@ -10,10 +10,10 @@ cat <<EOF | cc -o $t/a.o -c -xc -
|
||||
int main() {}
|
||||
EOF
|
||||
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o -Wl,-rpath,foo -Wl,-rpath,bar
|
||||
clang -fuse-ld=$mold -o $t/exe $t/a.o -Wl,-rpath,foo -Wl,-rpath,@bar
|
||||
otool -l $t/exe > $t/log
|
||||
|
||||
grep -A3 'cmd LC_RPATH' $t/log | grep -q 'path foo'
|
||||
grep -A3 'cmd LC_RPATH' $t/log | grep -q 'path bar'
|
||||
grep -A3 'cmd LC_RPATH' $t/log | grep -q 'path @bar'
|
||||
|
||||
echo OK
|
||||
|
Loading…
Reference in New Issue
Block a user