Skip to content

Commit 8568c82

Browse files
carson-katrikrichprollsch
authored andcommitted
Add support for building on iOS
1 parent 3f2f56d commit 8568c82

File tree

5 files changed

+128
-65
lines changed

5 files changed

+128
-65
lines changed

Makefile

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,29 @@ F=
99
# OS and ARCH
1010
kernel = $(shell uname -ms)
1111
ifeq ($(kernel), Darwin arm64)
12-
OS := macos
13-
ARCH := aarch64
12+
OS ?= macos
13+
ARCH ?= aarch64
1414
else ifeq ($(kernel), Darwin x86_64)
15-
OS := macos
16-
ARCH := x86_64
15+
OS ?= macos
16+
ARCH ?= x86_64
1717
else ifeq ($(kernel), Linux aarch64)
18-
OS := linux
19-
ARCH := aarch64
18+
OS ?= linux
19+
ARCH ?= aarch64
2020
else ifeq ($(kernel), Linux arm64)
21-
OS := linux
22-
ARCH := aarch64
21+
OS ?= linux
22+
ARCH ?= aarch64
2323
else ifeq ($(kernel), Linux x86_64)
24-
OS := linux
25-
ARCH := x86_64
24+
OS ?= linux
25+
ARCH ?= x86_64
2626
else
2727
$(error "Unhandled kernel: $(kernel)")
2828
endif
2929

30+
MAKE ?= make
31+
CMAKE ?= cmake
32+
AUTOCONF_FLAGS ?=
33+
CFLAGS ?=
34+
LDFLAGS ?=
3035

3136
# Infos
3237
# -----
@@ -156,38 +161,40 @@ _install-netsurf: clean-netsurf
156161
mkdir -p $(BC_NS) && \
157162
cp -R vendor/netsurf/share $(BC_NS) && \
158163
export PREFIX=$(BC_NS) && \
159-
export OPTLDFLAGS="-L$(ICONV)/lib" && \
160-
export OPTCFLAGS="$(OPTCFLAGS) -I$(ICONV)/include" && \
164+
export OPTLDFLAGS="$(LDFLAGS) -L$(ICONV)/lib" && \
165+
export OPTCFLAGS="$(CFLAGS) $(OPTCFLAGS) -I$(ICONV)/include" && \
161166
printf "\e[33mInstalling libwapcaplet...\e[0m\n" && \
162167
cd vendor/netsurf/libwapcaplet && \
163-
BUILDDIR=$(BC_NS)/build/libwapcaplet make install && \
168+
BUILDDIR=$(BC_NS)/build/libwapcaplet $(MAKE) install && \
164169
cd ../libparserutils && \
165170
printf "\e[33mInstalling libparserutils...\e[0m\n" && \
166-
BUILDDIR=$(BC_NS)/build/libparserutils make install && \
171+
BUILDDIR=$(BC_NS)/build/libparserutils $(MAKE) install && \
167172
cd ../libhubbub && \
168173
printf "\e[33mInstalling libhubbub...\e[0m\n" && \
169-
BUILDDIR=$(BC_NS)/build/libhubbub make install && \
174+
BUILDDIR=$(BC_NS)/build/libhubbub $(MAKE) install && \
170175
rm src/treebuilder/autogenerated-element-type.c && \
171176
cd ../libdom && \
172177
printf "\e[33mInstalling libdom...\e[0m\n" && \
173-
BUILDDIR=$(BC_NS)/build/libdom make install && \
174-
printf "\e[33mRunning libdom example...\e[0m\n" && \
175-
cd examples && \
176-
$(ZIG) cc \
177-
-I$(ICONV)/include \
178-
-I$(BC_NS)/include \
179-
-L$(ICONV)/lib \
180-
-L$(BC_NS)/lib \
181-
-liconv \
182-
-ldom \
183-
-lhubbub \
184-
-lparserutils \
185-
-lwapcaplet \
186-
-o a.out \
187-
dom-structure-dump.c \
188-
$(ICONV)/lib/libiconv.a && \
189-
./a.out > /dev/null && \
190-
rm a.out && \
178+
BUILDDIR=$(BC_NS)/build/libdom $(MAKE) install && \
179+
if [ -z "$${SKIP_EXAMPLES}" ]; then \
180+
printf "\e[33mRunning libdom example...\e[0m\n" && \
181+
cd examples && \
182+
$(ZIG) cc \
183+
-I$(ICONV)/include \
184+
-I$(BC_NS)/include \
185+
-L$(ICONV)/lib \
186+
-L$(BC_NS)/lib \
187+
-liconv \
188+
-ldom \
189+
-lhubbub \
190+
-lparserutils \
191+
-lwapcaplet \
192+
-o a.out \
193+
dom-structure-dump.c \
194+
$(ICONV)/lib/libiconv.a && \
195+
./a.out > /dev/null && \
196+
rm a.out; \
197+
fi && \
191198
printf "\e[36mDone NetSurf $(OS)\e[0m\n"
192199

193200
clean-netsurf:
@@ -211,7 +218,7 @@ endif
211218

212219
build-libiconv: clean-libiconv
213220
@cd vendor/libiconv/libiconv-1.17 && \
214-
./configure --prefix=$(ICONV) --enable-static && \
221+
./configure --prefix=$(ICONV) --enable-static $(AUTOCONF_FLAGS) && \
215222
make && make install
216223

217224
install-libiconv: download-libiconv build-libiconv
@@ -231,7 +238,7 @@ MIMALLOC := $(BC)vendor/mimalloc/out/$(OS)-$(ARCH)
231238
_build_mimalloc: clean-mimalloc
232239
@mkdir -p $(MIMALLOC)/build && \
233240
cd $(MIMALLOC)/build && \
234-
cmake -DMI_BUILD_SHARED=OFF -DMI_BUILD_OBJECT=OFF -DMI_BUILD_TESTS=OFF -DMI_OVERRIDE=OFF $(OPTS) ../../.. && \
241+
$(CMAKE) -DMI_BUILD_SHARED=OFF -DMI_BUILD_OBJECT=OFF -DMI_BUILD_TESTS=OFF -DMI_OVERRIDE=OFF $(OPTS) ../../.. && \
235242
make && \
236243
mkdir -p $(MIMALLOC)/lib
237244

build.zig

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,36 @@ pub fn build(b: *Build) !void {
6262
try addDependencies(b, lightpanda_module, opts);
6363

6464
{
65-
// browser
66-
// -------
67-
68-
// compile and install
69-
const exe = b.addExecutable(.{
70-
.name = "lightpanda",
71-
.use_llvm = true,
72-
.root_module = lightpanda_module,
73-
});
74-
b.installArtifact(exe);
65+
// static lib
66+
// ----------
7567

76-
// run
77-
const run_cmd = b.addRunArtifact(exe);
78-
if (b.args) |args| {
79-
run_cmd.addArgs(args);
80-
}
81-
82-
// step
83-
const run_step = b.step("run", "Run the app");
84-
run_step.dependOn(&run_cmd.step);
68+
const lib = b.addLibrary(.{ .name = "lightpanda", .root_module = lightpanda_module, .use_llvm = true, .linkage = .static });
69+
b.installArtifact(lib);
8570
}
8671

72+
// {
73+
// // browser
74+
// // -------
75+
76+
// // compile and install
77+
// const exe = b.addExecutable(.{
78+
// .name = "lightpanda",
79+
// .use_llvm = true,
80+
// .root_module = lightpanda_module,
81+
// });
82+
// b.installArtifact(exe);
83+
84+
// // run
85+
// const run_cmd = b.addRunArtifact(exe);
86+
// if (b.args) |args| {
87+
// run_cmd.addArgs(args);
88+
// }
89+
90+
// // step
91+
// const run_step = b.step("run", "Run the app");
92+
// run_step.dependOn(&run_cmd.step);
93+
// }
94+
8795
{
8896
// tests
8997
// ----
@@ -176,6 +184,7 @@ fn addDependencies(b: *Build, mod: *Build.Module, opts: *Build.Step.Options) !vo
176184
const os = switch (target.result.os.tag) {
177185
.linux => "linux",
178186
.macos => "macos",
187+
.ios => "ios",
179188
else => return error.UnsupportedPlatform,
180189
};
181190
var lib_path = try std.fmt.allocPrint(
@@ -199,6 +208,12 @@ fn addDependencies(b: *Build, mod: *Build.Module, opts: *Build.Step.Options) !vo
199208
mod.addSystemFrameworkPath(.{ .cwd_relative = "/System/Library/Frameworks" });
200209
mod.linkFramework("CoreFoundation", .{});
201210
},
211+
.ios => {
212+
const sdk_path = try std.process.getEnvVarOwned(mod.owner.allocator, "SDK");
213+
const framework_path = try std.fmt.allocPrint(mod.owner.allocator, "{s}/System/Library/Frameworks", .{sdk_path});
214+
mod.addSystemFrameworkPath(.{ .cwd_relative = framework_path });
215+
mod.linkFramework("CoreFoundation", .{});
216+
},
202217
else => {},
203218
}
204219
}
@@ -393,26 +408,47 @@ fn addDependencies(b: *Build, mod: *Build.Module, opts: *Build.Step.Options) !vo
393408
mod.linkFramework("CoreFoundation", .{});
394409
mod.linkFramework("SystemConfiguration", .{});
395410
},
411+
.ios => {
412+
const sdk_path = try std.process.getEnvVarOwned(mod.owner.allocator, "SDK");
413+
const framework_path = try std.fmt.allocPrint(mod.owner.allocator, "{s}/System/Library/Frameworks", .{sdk_path});
414+
mod.addSystemFrameworkPath(.{ .cwd_relative = framework_path });
415+
mod.linkFramework("CoreFoundation", .{});
416+
mod.linkFramework("SystemConfiguration", .{});
417+
},
396418
else => {},
397419
}
398420
}
399421
}
400422

401423
fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
402424
const target = mod.resolved_target.?;
403-
const os = target.result.os.tag;
404-
const arch = target.result.cpu.arch;
425+
const os = switch (target.result.os.tag) {
426+
.linux => "linux",
427+
.macos => "macos",
428+
.ios => switch (target.result.abi) {
429+
.simulator => "iphonesimulator",
430+
else => return error.UnsupportedPlatform,
431+
},
432+
else => return error.UnsupportedPlatform,
433+
};
434+
const arch = switch (target.result.os.tag) {
435+
.ios => switch (target.result.cpu.arch) {
436+
.aarch64 => "arm64",
437+
else => @tagName(target.result.cpu.arch),
438+
},
439+
else => @tagName(target.result.cpu.arch),
440+
};
405441

406442
// iconv
407443
const libiconv_lib_path = try std.fmt.allocPrint(
408444
b.allocator,
409445
"vendor/libiconv/out/{s}-{s}/lib/libiconv.a",
410-
.{ @tagName(os), @tagName(arch) },
446+
.{ os, arch },
411447
);
412448
const libiconv_include_path = try std.fmt.allocPrint(
413449
b.allocator,
414450
"vendor/libiconv/out/{s}-{s}/lib/libiconv.a",
415-
.{ @tagName(os), @tagName(arch) },
451+
.{ os, arch },
416452
);
417453
mod.addObjectFile(b.path(libiconv_lib_path));
418454
mod.addIncludePath(b.path(libiconv_include_path));
@@ -423,7 +459,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
423459
const lib_path = try std.fmt.allocPrint(
424460
b.allocator,
425461
mimalloc ++ "/out/{s}-{s}/lib/libmimalloc.a",
426-
.{ @tagName(os), @tagName(arch) },
462+
.{ os, arch },
427463
);
428464
mod.addObjectFile(b.path(lib_path));
429465
mod.addIncludePath(b.path(mimalloc ++ "/include"));
@@ -434,7 +470,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
434470
const ns_include_path = try std.fmt.allocPrint(
435471
b.allocator,
436472
ns ++ "/out/{s}-{s}/include",
437-
.{ @tagName(os), @tagName(arch) },
473+
.{ os, arch },
438474
);
439475
mod.addIncludePath(b.path(ns_include_path));
440476

@@ -448,7 +484,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
448484
const ns_lib_path = try std.fmt.allocPrint(
449485
b.allocator,
450486
ns ++ "/out/{s}-{s}/lib/" ++ lib ++ ".a",
451-
.{ @tagName(os), @tagName(arch) },
487+
.{ os, arch },
452488
);
453489
mod.addObjectFile(b.path(ns_lib_path));
454490
mod.addIncludePath(b.path(ns ++ "/" ++ lib ++ "/src"));
@@ -521,7 +557,7 @@ fn buildMbedtls(b: *Build, m: *Build.Module) !void {
521557
mbedtls.addIncludePath(b.path(root ++ "include"));
522558
mbedtls.addIncludePath(b.path(root ++ "library"));
523559

524-
mbedtls.addCSourceFiles(.{ .flags = &.{}, .files = &.{
560+
mbedtls.addCSourceFiles(.{ .flags = &.{"-Wno-nullability-completeness"}, .files = &.{
525561
root ++ "library/aes.c",
526562
root ++ "library/aesni.c",
527563
root ++ "library/aesce.c",
@@ -675,6 +711,12 @@ fn buildNghttp2(b: *Build, m: *Build.Module) !void {
675711
}
676712

677713
fn buildCurl(b: *Build, m: *Build.Module) !void {
714+
if (m.resolved_target.?.result.os.tag == .ios) {
715+
const sdk_path = try std.process.getEnvVarOwned(b.allocator, "SDK");
716+
const include_path = try std.fmt.allocPrint(b.allocator, "{s}/usr/include", .{sdk_path});
717+
m.addIncludePath(.{ .cwd_relative = include_path });
718+
}
719+
678720
const curl = b.addLibrary(.{
679721
.name = "curl",
680722
.root_module = m,

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/84cdca7cd9065f67c7933388f2091810fc485bc6.tar.gz",
99
.hash = "v8-0.0.0-xddH67vcAwCuN2gBsAO8TBzEw523KMroIKGrdZwc-Q-y",
1010
},
11-
//.v8 = .{ .path = "../zig-v8-fork" }
11+
//.v8 = .{ .path = "../zig-v8-fork" },
1212
.@"ada-singleheader" = .{
1313
.url = "https://github.com/ada-url/ada/releases/download/v3.3.0/singleheader.zip",
1414
.hash = "N-V-__8AAPmhFAAw64ALjlzd5YMtzpSrmZ6KymsT84BKfB4s",

src/app.zig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ fn getAndMakeAppDir(allocator: Allocator) ?[]const u8 {
9898
if (@import("builtin").is_test) {
9999
return allocator.dupe(u8, "/tmp") catch unreachable;
100100
}
101+
102+
if (@import("builtin").os.tag == .ios) {
103+
return null; // getAppDataDir is not available on iOS
104+
}
105+
101106
const app_dir_path = std.fs.getAppDataDir(allocator, "lightpanda") catch |err| {
102107
log.warn(.app, "get data dir", .{ .err = err });
103108
return null;

src/server.zig

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,17 @@ pub const Server = struct {
7575
self.listener = listener;
7676

7777
try posix.setsockopt(listener, posix.SOL.SOCKET, posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
78-
if (@hasDecl(posix.TCP, "NODELAY")) {
79-
try posix.setsockopt(listener, posix.IPPROTO.TCP, posix.TCP.NODELAY, &std.mem.toBytes(@as(c_int, 1)));
78+
switch (builtin.os.tag) {
79+
.ios => {
80+
// TCP.NODELAY is not defined for iOS in posix module
81+
const TCP_NODELAY = 0x01;
82+
try posix.setsockopt(listener, posix.IPPROTO.TCP, TCP_NODELAY, &std.mem.toBytes(@as(c_int, 1)));
83+
},
84+
else => {
85+
if (@hasDecl(posix.TCP, "NODELAY")) {
86+
try posix.setsockopt(listener, posix.IPPROTO.TCP, posix.TCP.NODELAY, &std.mem.toBytes(@as(c_int, 1)));
87+
}
88+
},
8089
}
8190

8291
try posix.bind(listener, &address.any, address.getOsSockLen());

0 commit comments

Comments
 (0)