commit 84b4b6bffa126f1491f6029286ddecb5d6aec74b (tree)
parent 3dd439030ccc6cc9424ac03b70eab53b03f28356
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 18 Aug 2023 18:06:20 -0700
Merge pull request #16818 from ziglang/damn-sysroot
build: do not emit `-iwithsysroot`/`-iframeworkwithsysroot` implicitly
Diffstat:
9 files changed, 196 insertions(+), 43 deletions(-)
diff --git a/build.zig b/build.zig
@@ -128,7 +128,8 @@ pub fn build(b: *std.Build) !void {
"llvm-has-xtensa",
"Whether LLVM has the experimental target xtensa enabled",
) orelse false;
- const enable_macos_sdk = b.option(bool, "enable-macos-sdk", "Run tests requiring presence of macOS SDK and frameworks") orelse false;
+ const enable_ios_sdk = b.option(bool, "enable-ios-sdk", "Run tests requiring presence of iOS SDK and frameworks") orelse false;
+ const enable_macos_sdk = b.option(bool, "enable-macos-sdk", "Run tests requiring presence of macOS SDK and frameworks") orelse enable_ios_sdk;
const enable_symlinks_windows = b.option(bool, "enable-symlinks-windows", "Run tests requiring presence of symlinks on Windows") orelse false;
const config_h_path_option = b.option([]const u8, "config_h", "Path to the generated config.h");
@@ -485,11 +486,12 @@ pub fn build(b: *std.Build) !void {
b,
optimization_modes,
enable_macos_sdk,
+ enable_ios_sdk,
false,
enable_symlinks_windows,
));
test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
- test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, false, enable_symlinks_windows));
+ test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, false, enable_symlinks_windows));
test_step.dependOn(tests.addStackTraceTests(b, test_filter, optimization_modes));
test_step.dependOn(tests.addCliTests(b));
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, optimization_modes));
diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig
@@ -766,6 +766,60 @@ const MachODumper = struct {
});
},
+ .BUILD_VERSION => {
+ const blc = lc.cast(macho.build_version_command).?;
+ try writer.writeByte('\n');
+ try writer.print(
+ \\platform {s}
+ \\minos {d}.{d}.{d}
+ \\sdk {d}.{d}.{d}
+ \\ntools {d}
+ , .{
+ @tagName(blc.platform),
+ blc.minos >> 16,
+ @as(u8, @truncate(blc.minos >> 8)),
+ @as(u8, @truncate(blc.minos)),
+ blc.sdk >> 16,
+ @as(u8, @truncate(blc.sdk >> 8)),
+ @as(u8, @truncate(blc.sdk)),
+ blc.ntools,
+ });
+ for (lc.getBuildVersionTools()) |tool| {
+ try writer.writeByte('\n');
+ switch (tool.tool) {
+ .CLANG, .SWIFT, .LD, .LLD, .ZIG => try writer.print("tool {s}\n", .{@tagName(tool.tool)}),
+ else => |x| try writer.print("tool {d}\n", .{@intFromEnum(x)}),
+ }
+ try writer.print(
+ \\version {d}.{d}.{d}
+ , .{
+ tool.version >> 16,
+ @as(u8, @truncate(tool.version >> 8)),
+ @as(u8, @truncate(tool.version)),
+ });
+ }
+ },
+
+ .VERSION_MIN_MACOSX,
+ .VERSION_MIN_IPHONEOS,
+ .VERSION_MIN_WATCHOS,
+ .VERSION_MIN_TVOS,
+ => {
+ const vlc = lc.cast(macho.version_min_command).?;
+ try writer.writeByte('\n');
+ try writer.print(
+ \\version {d}.{d}.{d}
+ \\sdk {d}.{d}.{d}
+ , .{
+ vlc.version >> 16,
+ @as(u8, @truncate(vlc.version >> 8)),
+ @as(u8, @truncate(vlc.version)),
+ vlc.sdk >> 16,
+ @as(u8, @truncate(vlc.sdk >> 8)),
+ @as(u8, @truncate(vlc.sdk)),
+ });
+ },
+
else => {},
}
}
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
@@ -42,7 +42,6 @@ unwind_tables: ?bool,
compress_debug_sections: enum { none, zlib } = .none,
lib_paths: ArrayList(LazyPath),
rpaths: ArrayList(LazyPath),
-framework_dirs: ArrayList(LazyPath),
frameworks: StringHashMap(FrameworkLinkInfo),
verbose_link: bool,
verbose_cc: bool,
@@ -261,6 +260,8 @@ const FrameworkLinkInfo = struct {
pub const IncludeDir = union(enum) {
path: LazyPath,
path_system: LazyPath,
+ framework_path: LazyPath,
+ framework_path_system: LazyPath,
other_step: *Compile,
config_header_step: *Step.ConfigHeader,
};
@@ -442,7 +443,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
.c_macros = ArrayList([]const u8).init(owner.allocator),
.lib_paths = ArrayList(LazyPath).init(owner.allocator),
.rpaths = ArrayList(LazyPath).init(owner.allocator),
- .framework_dirs = ArrayList(LazyPath).init(owner.allocator),
.installed_headers = ArrayList(*Step).init(owner.allocator),
.c_std = std.Build.CStd.C99,
.zig_lib_dir = null,
@@ -1050,9 +1050,15 @@ pub fn addRPath(self: *Compile, directory_source: LazyPath) void {
directory_source.addStepDependencies(&self.step);
}
+pub fn addSystemFrameworkPath(self: *Compile, directory_source: LazyPath) void {
+ const b = self.step.owner;
+ self.include_dirs.append(IncludeDir{ .framework_path_system = directory_source.dupe(b) }) catch @panic("OOM");
+ directory_source.addStepDependencies(&self.step);
+}
+
pub fn addFrameworkPath(self: *Compile, directory_source: LazyPath) void {
const b = self.step.owner;
- self.framework_dirs.append(directory_source.dupe(b)) catch @panic("OOM");
+ self.include_dirs.append(IncludeDir{ .framework_path = directory_source.dupe(b) }) catch @panic("OOM");
directory_source.addStepDependencies(&self.step);
}
@@ -1772,27 +1778,16 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(include_path.getPath(b));
},
.path_system => |include_path| {
- if (b.sysroot != null) {
- try zig_args.append("-iwithsysroot");
- } else {
- try zig_args.append("-isystem");
- }
-
- const resolved_include_path = include_path.getPath(b);
-
- const common_include_path = if (builtin.os.tag == .windows and b.sysroot != null and fs.path.isAbsolute(resolved_include_path)) blk: {
- // We need to check for disk designator and strip it out from dir path so
- // that zig/clang can concat resolved_include_path with sysroot.
- const disk_designator = fs.path.diskDesignatorWindows(resolved_include_path);
-
- if (mem.indexOf(u8, resolved_include_path, disk_designator)) |where| {
- break :blk resolved_include_path[where + disk_designator.len ..];
- }
-
- break :blk resolved_include_path;
- } else resolved_include_path;
-
- try zig_args.append(common_include_path);
+ try zig_args.append("-isystem");
+ try zig_args.append(include_path.getPath(b));
+ },
+ .framework_path => |include_path| {
+ try zig_args.append("-F");
+ try zig_args.append(include_path.getPath2(b, step));
+ },
+ .framework_path_system => |include_path| {
+ try zig_args.append("-iframework");
+ try zig_args.append(include_path.getPath2(b, step));
},
.other_step => |other| {
if (other.generated_h) |header| {
@@ -1847,17 +1842,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
zig_args.appendAssumeCapacity(rpath.getPath2(b, step));
}
- for (self.framework_dirs.items) |directory_source| {
- if (b.sysroot != null) {
- try zig_args.append("-iframeworkwithsysroot");
- } else {
- try zig_args.append("-iframework");
- }
- try zig_args.append(directory_source.getPath2(b, step));
- try zig_args.append("-F");
- try zig_args.append(directory_source.getPath2(b, step));
- }
-
{
var it = self.frameworks.iterator();
while (it.next()) |entry| {
diff --git a/lib/std/macho.zig b/lib/std/macho.zig
@@ -1898,6 +1898,16 @@ pub const LoadCommandIterator = struct {
const data = lc.data[rpath_lc.path..];
return mem.sliceTo(data, 0);
}
+
+ /// Asserts LoadCommand is of type build_version_command.
+ pub fn getBuildVersionTools(lc: LoadCommand) []const build_tool_version {
+ const build_lc = lc.cast(build_version_command).?;
+ const ntools = build_lc.ntools;
+ if (ntools == 0) return &[0]build_tool_version{};
+ const data = lc.data[@sizeOf(build_version_command)..];
+ const tools = @as([*]const build_tool_version, @ptrCast(@alignCast(&data[0])))[0..ntools];
+ return tools;
+ }
};
pub fn next(it: *LoadCommandIterator) ?LoadCommand {
diff --git a/src/main.zig b/src/main.zig
@@ -1156,12 +1156,20 @@ fn buildOutputType(
try clang_argv.append(args_iter.nextOrFatal());
} else if (mem.eql(u8, arg, "-I")) {
try cssan.addIncludePath(.I, arg, args_iter.nextOrFatal(), false);
- } else if (mem.eql(u8, arg, "-isystem") or mem.eql(u8, arg, "-iwithsysroot")) {
+ } else if (mem.eql(u8, arg, "-isystem")) {
try cssan.addIncludePath(.isystem, arg, args_iter.nextOrFatal(), false);
+ } else if (mem.eql(u8, arg, "-iwithsysroot")) {
+ try cssan.addIncludePath(.iwithsysroot, arg, args_iter.nextOrFatal(), false);
} else if (mem.eql(u8, arg, "-idirafter")) {
try cssan.addIncludePath(.idirafter, arg, args_iter.nextOrFatal(), false);
- } else if (mem.eql(u8, arg, "-iframework") or mem.eql(u8, arg, "-iframeworkwithsysroot")) {
- try cssan.addIncludePath(.iframework, arg, args_iter.nextOrFatal(), false);
+ } else if (mem.eql(u8, arg, "-iframework")) {
+ const path = args_iter.nextOrFatal();
+ try cssan.addIncludePath(.iframework, arg, path, false);
+ try framework_dirs.append(path); // Forward to the backend as -F
+ } else if (mem.eql(u8, arg, "-iframeworkwithsysroot")) {
+ const path = args_iter.nextOrFatal();
+ try cssan.addIncludePath(.iframeworkwithsysroot, arg, path, false);
+ try framework_dirs.append(path); // Forward to the backend as -F
} else if (mem.eql(u8, arg, "--version")) {
const next_arg = args_iter.nextOrFatal();
version = std.SemanticVersion.parse(next_arg) catch |err| {
@@ -6191,6 +6199,11 @@ const ClangSearchSanitizer = struct {
if (m.idirafter) std.log.warn(wtxt, .{ dir, "isystem", "idirafter" });
if (m.iframework) std.log.warn(wtxt, .{ dir, "isystem", "iframework" });
},
+ .iwithsysroot => {
+ if (m.iwithsysroot) return;
+ m.iwithsysroot = true;
+ if (m.iframeworkwithsysroot) std.log.warn(wtxt, .{ dir, "iwithsysroot", "iframeworkwithsysroot" });
+ },
.idirafter => {
if (m.idirafter) return;
m.idirafter = true;
@@ -6205,18 +6218,25 @@ const ClangSearchSanitizer = struct {
if (m.isystem) std.log.warn(wtxt, .{ dir, "iframework", "isystem" });
if (m.idirafter) std.log.warn(wtxt, .{ dir, "iframework", "idirafter" });
},
+ .iframeworkwithsysroot => {
+ if (m.iframeworkwithsysroot) return;
+ m.iframeworkwithsysroot = true;
+ if (m.iwithsysroot) std.log.warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
+ },
}
try self.argv.append(arg);
if (!joined) try self.argv.append(dir);
}
- const Group = enum { I, isystem, idirafter, iframework };
+ const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot };
const Membership = packed struct {
I: bool = false,
isystem: bool = false,
+ iwithsysroot: bool = false,
idirafter: bool = false,
iframework: bool = false,
+ iframeworkwithsysroot: bool = false,
};
};
diff --git a/test/standalone.zig b/test/standalone.zig
@@ -245,6 +245,10 @@ pub const build_cases = [_]BuildCase{
.build_root = "test/standalone/compiler_rt_panic",
.import = @import("standalone/compiler_rt_panic/build.zig"),
},
+ .{
+ .build_root = "test/standalone/ios",
+ .import = @import("standalone/ios/build.zig"),
+ },
};
const std = @import("std");
diff --git a/test/standalone/ios/build.zig b/test/standalone/ios/build.zig
@@ -0,0 +1,37 @@
+const std = @import("std");
+
+pub const requires_symlinks = true;
+pub const requires_ios_sdk = true;
+
+pub fn build(b: *std.Build) void {
+ const test_step = b.step("test", "Test it");
+ b.default_step = test_step;
+
+ const optimize: std.builtin.OptimizeMode = .Debug;
+ const target: std.zig.CrossTarget = .{
+ .cpu_arch = .aarch64,
+ .os_tag = .ios,
+ };
+ const target_info = std.zig.system.NativeTargetInfo.detect(target) catch @panic("couldn't detect native target");
+ const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse @panic("no iOS SDK found");
+ b.sysroot = sdk.path;
+
+ const exe = b.addExecutable(.{
+ .name = "main",
+ .optimize = optimize,
+ .target = target,
+ });
+ exe.addCSourceFile(.{ .file = .{ .path = "main.m" }, .flags = &.{} });
+ exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk.path, "/usr/include" }) });
+ exe.addSystemFrameworkPath(.{ .path = b.pathJoin(&.{ sdk.path, "/System/Library/Frameworks" }) });
+ exe.addLibraryPath(.{ .path = b.pathJoin(&.{ sdk.path, "/usr/lib" }) });
+ exe.linkFramework("Foundation");
+ exe.linkFramework("UIKit");
+ exe.linkLibC();
+
+ const check = exe.checkObject();
+ check.checkStart();
+ check.checkExact("cmd BUILD_VERSION");
+ check.checkExact("platform IOS");
+ test_step.dependOn(&check.step);
+}
diff --git a/test/standalone/ios/main.m b/test/standalone/ios/main.m
@@ -0,0 +1,34 @@
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@end
+
+int main() {
+ @autoreleasepool {
+ return UIApplicationMain(0, nil, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(id)options {
+ CGRect mainScreenBounds = [[UIScreen mainScreen] bounds];
+ self.window = [[UIWindow alloc] initWithFrame:mainScreenBounds];
+ UIViewController *viewController = [[UIViewController alloc] init];
+ viewController.view.frame = mainScreenBounds;
+
+ NSString* msg = @"Hello world";
+
+ UILabel *label = [[UILabel alloc] initWithFrame:mainScreenBounds];
+ [label setText:msg];
+ [viewController.view addSubview: label];
+
+ self.window.rootViewController = viewController;
+
+ [self.window makeKeyAndVisible];
+
+ return YES;
+}
+
+@end
diff --git a/test/tests.zig b/test/tests.zig
@@ -566,6 +566,7 @@ pub fn addStandaloneTests(
b: *std.Build,
optimize_modes: []const OptimizeMode,
enable_macos_sdk: bool,
+ enable_ios_sdk: bool,
omit_stage2: bool,
enable_symlinks_windows: bool,
) *Step {
@@ -615,10 +616,13 @@ pub fn addStandaloneTests(
case.import.requires_symlinks;
const requires_macos_sdk = @hasDecl(case.import, "requires_macos_sdk") and
case.import.requires_macos_sdk;
+ const requires_ios_sdk = @hasDecl(case.import, "requires_ios_sdk") and
+ case.import.requires_ios_sdk;
const bad =
(requires_stage2 and omit_stage2) or
(requires_symlinks and omit_symlinks) or
- (requires_macos_sdk and !enable_macos_sdk);
+ (requires_macos_sdk and !enable_macos_sdk) or
+ (requires_ios_sdk and !enable_ios_sdk);
if (!bad) {
const dep = b.anonymousDependency(case.build_root, case.import, .{});
const dep_step = dep.builder.default_step;
@@ -635,6 +639,7 @@ pub fn addStandaloneTests(
pub fn addLinkTests(
b: *std.Build,
enable_macos_sdk: bool,
+ enable_ios_sdk: bool,
omit_stage2: bool,
enable_symlinks_windows: bool,
) *Step {
@@ -648,10 +653,13 @@ pub fn addLinkTests(
case.import.requires_symlinks;
const requires_macos_sdk = @hasDecl(case.import, "requires_macos_sdk") and
case.import.requires_macos_sdk;
+ const requires_ios_sdk = @hasDecl(case.import, "requires_ios_sdk") and
+ case.import.requires_ios_sdk;
const bad =
(requires_stage2 and omit_stage2) or
(requires_symlinks and omit_symlinks) or
- (requires_macos_sdk and !enable_macos_sdk);
+ (requires_macos_sdk and !enable_macos_sdk) or
+ (requires_ios_sdk and !enable_ios_sdk);
if (!bad) {
const dep = b.anonymousDependency(case.build_root, case.import, .{});
const dep_step = dep.builder.default_step;