authorgravatar for vincent@rischmann.frVincent Rischmann <vincent@rischmann.fr> 2021-06-15 00:51:28+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-17 20:28:37-07:00
log721ec8fa5305c0c4724acde16fa601356930f603
tree3ff03e7005d2973e7d5ecc1945cd3e109fb59cf5
parentdc392f49f8dc8815ba47aae236bb65f14ebf4b86

zig cc: improve linker args parsing

Handle linker args joined with a = like -Wl,-rpath=foo Update existing args --major-os-version, --minor-os-version, --major-subsystem-version and --minor-subsytem-version to work with the new parsing. Also handle -Wl,--script in addition to -Wl,-T

1 files changed, 31 insertions(+), 11 deletions(-)

src/main.zig+31-11
...@@ -1174,6 +1174,16 @@ fn buildOutputType(...@@ -1174,6 +1174,16 @@ fn buildOutputType(
1174 .wl => {1174 .wl => {
1175 var split_it = mem.split(it.only_arg, ",");1175 var split_it = mem.split(it.only_arg, ",");
1176 while (split_it.next()) |linker_arg| {1176 while (split_it.next()) |linker_arg| {
1177 // Handle nested-joined args like `-Wl,-rpath=foo`.
1178 // Must be prefixed with 1 or 2 dashes.
1179 if (linker_arg.len >= 3 and linker_arg[0] == '-' and linker_arg[2] != '-') {
1180 if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
1181 try linker_args.append(linker_arg[0..equals_pos]);
1182 try linker_args.append(linker_arg[equals_pos + 1 ..]);
1183 continue;
1184 }
1185 }
1186
1177 try linker_args.append(linker_arg);1187 try linker_args.append(linker_arg);
1178 }1188 }
1179 },1189 },
...@@ -1382,7 +1392,7 @@ fn buildOutputType(...@@ -1382,7 +1392,7 @@ fn buildOutputType(
1382 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {1392 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {
1383 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1393 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1384 };1394 };
1385 } else if (mem.eql(u8, arg, "-T")) {1395 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
1386 i += 1;1396 i += 1;
1387 if (i >= linker_args.items.len) {1397 if (i >= linker_args.items.len) {
1388 fatal("expected linker arg after '{s}'", .{arg});1398 fatal("expected linker arg after '{s}'", .{arg});
...@@ -1408,30 +1418,40 @@ fn buildOutputType(...@@ -1408,30 +1418,40 @@ fn buildOutputType(
1408 // We don't need to care about these because these args are1418 // We don't need to care about these because these args are
1409 // for resolving circular dependencies but our linker takes1419 // for resolving circular dependencies but our linker takes
1410 // care of this without explicit args.1420 // care of this without explicit args.
1411 } else if (mem.startsWith(u8, arg, "--major-os-version") or1421 } else if (mem.eql(u8, arg, "--major-os-version") or
1412 mem.startsWith(u8, arg, "--minor-os-version"))1422 mem.eql(u8, arg, "--minor-os-version"))
1413 {1423 {
1424 i += 1;
1425 if (i >= linker_args.items.len) {
1426 fatal("expected linker arg after '{s}'", .{arg});
1427 }
1414 // This option does not do anything.1428 // This option does not do anything.
1415 } else if (mem.startsWith(u8, arg, "--major-subsystem-version=")) {1429 } else if (mem.eql(u8, arg, "--major-subsystem-version")) {
1430 i += 1;
1431 if (i >= linker_args.items.len) {
1432 fatal("expected linker arg after '{s}'", .{arg});
1433 }
1434
1416 major_subsystem_version = std.fmt.parseUnsigned(1435 major_subsystem_version = std.fmt.parseUnsigned(
1417 u32,1436 u32,
1418 arg["--major-subsystem-version=".len..],1437 linker_args.items[i],
1419 10,1438 10,
1420 ) catch |err| {1439 ) catch |err| {
1421 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1440 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1422 };1441 };
1423 } else if (mem.startsWith(u8, arg, "--minor-subsystem-version=")) {1442 } else if (mem.eql(u8, arg, "--minor-subsystem-version")) {
1443 i += 1;
1444 if (i >= linker_args.items.len) {
1445 fatal("expected linker arg after '{s}'", .{arg});
1446 }
1447
1424 minor_subsystem_version = std.fmt.parseUnsigned(1448 minor_subsystem_version = std.fmt.parseUnsigned(
1425 u32,1449 u32,
1426 arg["--minor-subsystem-version=".len..],1450 linker_args.items[i],
1427 10,1451 10,
1428 ) catch |err| {1452 ) catch |err| {
1429 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1453 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1430 };1454 };
1431 } else if (mem.startsWith(u8, arg, "--major-os-version=") or
1432 mem.startsWith(u8, arg, "--minor-os-version="))
1433 {
1434 // These args do nothing.
1435 } else {1455 } else {
1436 warn("unsupported linker arg: {s}", .{arg});1456 warn("unsupported linker arg: {s}", .{arg});
1437 }1457 }