authorgravatar for vincent@rischmann.frVincent Rischmann <vincent@rischmann.fr> 2021-06-15 00:51:28+02:00
committergravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2021-06-17 17:32:17-04:00
log6f0cfdb8206026f239ca079a9f3eebae20bd5310
treecfae70fc577ac22c8e4d6558a1defa726a130acf
parente18ef71d989701833dc94d518e559817a781a7bf

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
...@@ -1179,6 +1179,16 @@ fn buildOutputType(...@@ -1179,6 +1179,16 @@ fn buildOutputType(
1179 .wl => {1179 .wl => {
1180 var split_it = mem.split(it.only_arg, ",");1180 var split_it = mem.split(it.only_arg, ",");
1181 while (split_it.next()) |linker_arg| {1181 while (split_it.next()) |linker_arg| {
1182 // Handle nested-joined args like `-Wl,-rpath=foo`.
1183 // Must be prefixed with 1 or 2 dashes.
1184 if (linker_arg.len >= 3 and linker_arg[0] == '-' and linker_arg[2] != '-') {
1185 if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
1186 try linker_args.append(linker_arg[0..equals_pos]);
1187 try linker_args.append(linker_arg[equals_pos + 1 ..]);
1188 continue;
1189 }
1190 }
1191
1182 try linker_args.append(linker_arg);1192 try linker_args.append(linker_arg);
1183 }1193 }
1184 },1194 },
...@@ -1394,7 +1404,7 @@ fn buildOutputType(...@@ -1394,7 +1404,7 @@ fn buildOutputType(
1394 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {1404 image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| {
1395 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1405 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1396 };1406 };
1397 } else if (mem.eql(u8, arg, "-T")) {1407 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
1398 i += 1;1408 i += 1;
1399 if (i >= linker_args.items.len) {1409 if (i >= linker_args.items.len) {
1400 fatal("expected linker arg after '{s}'", .{arg});1410 fatal("expected linker arg after '{s}'", .{arg});
...@@ -1420,30 +1430,40 @@ fn buildOutputType(...@@ -1420,30 +1430,40 @@ fn buildOutputType(
1420 // We don't need to care about these because these args are1430 // We don't need to care about these because these args are
1421 // for resolving circular dependencies but our linker takes1431 // for resolving circular dependencies but our linker takes
1422 // care of this without explicit args.1432 // care of this without explicit args.
1423 } else if (mem.startsWith(u8, arg, "--major-os-version") or1433 } else if (mem.eql(u8, arg, "--major-os-version") or
1424 mem.startsWith(u8, arg, "--minor-os-version"))1434 mem.eql(u8, arg, "--minor-os-version"))
1425 {1435 {
1436 i += 1;
1437 if (i >= linker_args.items.len) {
1438 fatal("expected linker arg after '{s}'", .{arg});
1439 }
1426 // This option does not do anything.1440 // This option does not do anything.
1427 } else if (mem.startsWith(u8, arg, "--major-subsystem-version=")) {1441 } else if (mem.eql(u8, arg, "--major-subsystem-version")) {
1442 i += 1;
1443 if (i >= linker_args.items.len) {
1444 fatal("expected linker arg after '{s}'", .{arg});
1445 }
1446
1428 major_subsystem_version = std.fmt.parseUnsigned(1447 major_subsystem_version = std.fmt.parseUnsigned(
1429 u32,1448 u32,
1430 arg["--major-subsystem-version=".len..],1449 linker_args.items[i],
1431 10,1450 10,
1432 ) catch |err| {1451 ) catch |err| {
1433 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1452 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1434 };1453 };
1435 } else if (mem.startsWith(u8, arg, "--minor-subsystem-version=")) {1454 } else if (mem.eql(u8, arg, "--minor-subsystem-version")) {
1455 i += 1;
1456 if (i >= linker_args.items.len) {
1457 fatal("expected linker arg after '{s}'", .{arg});
1458 }
1459
1436 minor_subsystem_version = std.fmt.parseUnsigned(1460 minor_subsystem_version = std.fmt.parseUnsigned(
1437 u32,1461 u32,
1438 arg["--minor-subsystem-version=".len..],1462 linker_args.items[i],
1439 10,1463 10,
1440 ) catch |err| {1464 ) catch |err| {
1441 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1465 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1442 };1466 };
1443 } else if (mem.startsWith(u8, arg, "--major-os-version=") or
1444 mem.startsWith(u8, arg, "--minor-os-version="))
1445 {
1446 // These args do nothing.
1447 } else {1467 } else {
1448 warn("unsupported linker arg: {s}", .{arg});1468 warn("unsupported linker arg: {s}", .{arg});
1449 }1469 }