mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
test/link/macho: test force-loading objects containing ObjC from archives
This commit is contained in:
parent
7c65f0be37
commit
abeb0e3ea4
@ -116,6 +116,9 @@ platform: Platform,
|
||||
sdk_version: ?std.SemanticVersion,
|
||||
/// When set to true, the linker will hoist all dylibs including system dependent dylibs.
|
||||
no_implicit_dylibs: bool = false,
|
||||
/// Whether the linker should parse and always force load objects containing ObjC in archives.
|
||||
// TODO: in Zig we currently take -ObjC as always on
|
||||
force_load_objc: bool = true,
|
||||
|
||||
/// Hot-code swapping state.
|
||||
hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
|
||||
@ -998,7 +1001,7 @@ fn parseArchive(self: *MachO, lib: SystemLib, must_link: bool, fat_arch: ?fat.Ar
|
||||
|
||||
// Finally, we do a post-parse check for -ObjC to see if we need to force load this member
|
||||
// anyhow.
|
||||
// TODO: object.alive = object.alive or (self.options.force_load_objc and object.hasObjc());
|
||||
object.alive = object.alive or (self.force_load_objc and object.hasObjc());
|
||||
}
|
||||
if (has_parse_error) return error.MalformedArchive;
|
||||
}
|
||||
|
||||
@ -46,121 +46,66 @@ const OverlayOptions = struct {
|
||||
c_source_flags: []const []const u8 = &.{},
|
||||
cpp_source_bytes: ?[]const u8 = null,
|
||||
cpp_source_flags: []const []const u8 = &.{},
|
||||
objc_source_bytes: ?[]const u8 = null,
|
||||
objc_source_flags: []const []const u8 = &.{},
|
||||
zig_source_bytes: ?[]const u8 = null,
|
||||
pic: ?bool = null,
|
||||
strip: ?bool = null,
|
||||
};
|
||||
|
||||
pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Step.Compile {
|
||||
const compile_step = b.addExecutable(.{
|
||||
.name = overlay.name,
|
||||
.root_source_file = rsf: {
|
||||
const bytes = overlay.zig_source_bytes orelse break :rsf null;
|
||||
break :rsf b.addWriteFiles().add("a.zig", bytes);
|
||||
},
|
||||
.target = base.target,
|
||||
.optimize = base.optimize,
|
||||
.use_llvm = base.use_llvm,
|
||||
.use_lld = base.use_lld,
|
||||
.pic = overlay.pic,
|
||||
.strip = overlay.strip,
|
||||
});
|
||||
if (overlay.cpp_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.cpp", bytes),
|
||||
.flags = overlay.cpp_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.c_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.c", bytes),
|
||||
.flags = overlay.c_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.asm_source_bytes) |bytes| {
|
||||
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
|
||||
}
|
||||
return compile_step;
|
||||
pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Compile {
|
||||
return addCompileStep(b, base, overlay, .exe);
|
||||
}
|
||||
|
||||
pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Step.Compile {
|
||||
const compile_step = b.addObject(.{
|
||||
.name = overlay.name,
|
||||
.root_source_file = rsf: {
|
||||
const bytes = overlay.zig_source_bytes orelse break :rsf null;
|
||||
break :rsf b.addWriteFiles().add("a.zig", bytes);
|
||||
},
|
||||
.target = base.target,
|
||||
.optimize = base.optimize,
|
||||
.use_llvm = base.use_llvm,
|
||||
.use_lld = base.use_lld,
|
||||
.pic = overlay.pic,
|
||||
.strip = overlay.strip,
|
||||
});
|
||||
if (overlay.cpp_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.cpp", bytes),
|
||||
.flags = overlay.cpp_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.c_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.c", bytes),
|
||||
.flags = overlay.c_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.asm_source_bytes) |bytes| {
|
||||
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
|
||||
}
|
||||
return compile_step;
|
||||
pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
|
||||
return addCompileStep(b, base, overlay, .obj);
|
||||
}
|
||||
|
||||
pub fn addStaticLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
|
||||
const compile_step = b.addStaticLibrary(.{
|
||||
.name = overlay.name,
|
||||
.root_source_file = rsf: {
|
||||
const bytes = overlay.zig_source_bytes orelse break :rsf null;
|
||||
break :rsf b.addWriteFiles().add("a.zig", bytes);
|
||||
},
|
||||
.target = base.target,
|
||||
.optimize = base.optimize,
|
||||
.use_llvm = base.use_llvm,
|
||||
.use_lld = base.use_lld,
|
||||
.pic = overlay.pic,
|
||||
.strip = overlay.strip,
|
||||
});
|
||||
if (overlay.cpp_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.cpp", bytes),
|
||||
.flags = overlay.cpp_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.c_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.c", bytes),
|
||||
.flags = overlay.c_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.asm_source_bytes) |bytes| {
|
||||
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
|
||||
}
|
||||
return compile_step;
|
||||
return addCompileStep(b, base, overlay, .static_lib);
|
||||
}
|
||||
|
||||
pub fn addSharedLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
|
||||
const compile_step = b.addSharedLibrary(.{
|
||||
return addCompileStep(b, base, overlay, .shared_lib);
|
||||
}
|
||||
|
||||
fn addCompileStep(
|
||||
b: *Build,
|
||||
base: Options,
|
||||
overlay: OverlayOptions,
|
||||
kind: enum { exe, obj, shared_lib, static_lib },
|
||||
) *Compile {
|
||||
const compile_step = Compile.create(b, .{
|
||||
.name = overlay.name,
|
||||
.root_source_file = rsf: {
|
||||
const bytes = overlay.zig_source_bytes orelse break :rsf null;
|
||||
break :rsf b.addWriteFiles().add("a.zig", bytes);
|
||||
.root_module = .{
|
||||
.target = base.target,
|
||||
.optimize = base.optimize,
|
||||
.root_source_file = rsf: {
|
||||
const bytes = overlay.zig_source_bytes orelse break :rsf null;
|
||||
break :rsf b.addWriteFiles().add("a.zig", bytes);
|
||||
},
|
||||
.pic = overlay.pic,
|
||||
.strip = overlay.strip,
|
||||
},
|
||||
.target = base.target,
|
||||
.optimize = base.optimize,
|
||||
.use_llvm = base.use_llvm,
|
||||
.use_lld = base.use_lld,
|
||||
.pic = overlay.pic,
|
||||
.strip = overlay.strip,
|
||||
.kind = switch (kind) {
|
||||
.exe => .exe,
|
||||
.obj => .obj,
|
||||
.shared_lib, .static_lib => .lib,
|
||||
},
|
||||
.linkage = switch (kind) {
|
||||
.exe, .obj => null,
|
||||
.shared_lib => .dynamic,
|
||||
.static_lib => .static,
|
||||
},
|
||||
});
|
||||
if (overlay.objc_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.m", bytes),
|
||||
.flags = overlay.objc_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.cpp_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.cpp", bytes),
|
||||
|
||||
@ -52,6 +52,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
||||
macho_step.dependOn(testDeadStripDylibs(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testObjc(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testWeakFramework(b, .{ .target = b.host }));
|
||||
}
|
||||
}
|
||||
@ -830,6 +831,34 @@ fn testNeededLibrary(b: *Build, opts: Options) *Step {
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testObjc(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-objc", opts);
|
||||
|
||||
const lib = addStaticLibrary(b, opts, .{ .name = "a", .objc_source_bytes =
|
||||
\\#import <Foundation/Foundation.h>
|
||||
\\@interface Foo : NSObject
|
||||
\\@end
|
||||
\\@implementation Foo
|
||||
\\@end
|
||||
});
|
||||
|
||||
const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = "int main() { return 0; }" });
|
||||
exe.root_module.linkSystemLibrary("a", .{});
|
||||
exe.root_module.linkFramework("Foundation", .{});
|
||||
exe.addLibraryPath(lib.getEmittedBinDirectory());
|
||||
|
||||
const check = exe.checkObject();
|
||||
check.checkInSymtab();
|
||||
check.checkContains("_OBJC_");
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
const run = addRunArtifact(exe);
|
||||
run.expectExitCode(0);
|
||||
test_step.dependOn(&run.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testRelocatable(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-relocatable", opts);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user