Skip to content

Commit 67abc32

Browse files
committed
Add support for building on iOS
1 parent a87f4ab commit 67abc32

File tree

5 files changed

+132
-69
lines changed

5 files changed

+132
-69
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
# -----
@@ -149,38 +154,40 @@ _install-netsurf: clean-netsurf
149154
mkdir -p $(BC_NS) && \
150155
cp -R vendor/netsurf/share $(BC_NS) && \
151156
export PREFIX=$(BC_NS) && \
152-
export OPTLDFLAGS="-L$(ICONV)/lib" && \
153-
export OPTCFLAGS="$(OPTCFLAGS) -I$(ICONV)/include" && \
157+
export OPTLDFLAGS="$(LDFLAGS) -L$(ICONV)/lib" && \
158+
export OPTCFLAGS="$(CFLAGS) $(OPTCFLAGS) -I$(ICONV)/include" && \
154159
printf "\e[33mInstalling libwapcaplet...\e[0m\n" && \
155160
cd vendor/netsurf/libwapcaplet && \
156-
BUILDDIR=$(BC_NS)/build/libwapcaplet make install && \
161+
BUILDDIR=$(BC_NS)/build/libwapcaplet $(MAKE) install && \
157162
cd ../libparserutils && \
158163
printf "\e[33mInstalling libparserutils...\e[0m\n" && \
159-
BUILDDIR=$(BC_NS)/build/libparserutils make install && \
164+
BUILDDIR=$(BC_NS)/build/libparserutils $(MAKE) install && \
160165
cd ../libhubbub && \
161166
printf "\e[33mInstalling libhubbub...\e[0m\n" && \
162-
BUILDDIR=$(BC_NS)/build/libhubbub make install && \
167+
BUILDDIR=$(BC_NS)/build/libhubbub $(MAKE) install && \
163168
rm src/treebuilder/autogenerated-element-type.c && \
164169
cd ../libdom && \
165170
printf "\e[33mInstalling libdom...\e[0m\n" && \
166-
BUILDDIR=$(BC_NS)/build/libdom make install && \
167-
printf "\e[33mRunning libdom example...\e[0m\n" && \
168-
cd examples && \
169-
$(ZIG) cc \
170-
-I$(ICONV)/include \
171-
-I$(BC_NS)/include \
172-
-L$(ICONV)/lib \
173-
-L$(BC_NS)/lib \
174-
-liconv \
175-
-ldom \
176-
-lhubbub \
177-
-lparserutils \
178-
-lwapcaplet \
179-
-o a.out \
180-
dom-structure-dump.c \
181-
$(ICONV)/lib/libiconv.a && \
182-
./a.out > /dev/null && \
183-
rm a.out && \
171+
BUILDDIR=$(BC_NS)/build/libdom $(MAKE) install && \
172+
if [ -z "$${SKIP_EXAMPLES}" ]; then \
173+
printf "\e[33mRunning libdom example...\e[0m\n" && \
174+
cd examples && \
175+
$(ZIG) cc \
176+
-I$(ICONV)/include \
177+
-I$(BC_NS)/include \
178+
-L$(ICONV)/lib \
179+
-L$(BC_NS)/lib \
180+
-liconv \
181+
-ldom \
182+
-lhubbub \
183+
-lparserutils \
184+
-lwapcaplet \
185+
-o a.out \
186+
dom-structure-dump.c \
187+
$(ICONV)/lib/libiconv.a && \
188+
./a.out > /dev/null && \
189+
rm a.out; \
190+
fi && \
184191
printf "\e[36mDone NetSurf $(OS)\e[0m\n"
185192

186193
clean-netsurf:
@@ -204,7 +211,7 @@ endif
204211

205212
build-libiconv: clean-libiconv
206213
@cd vendor/libiconv/libiconv-1.17 && \
207-
./configure --prefix=$(ICONV) --enable-static && \
214+
./configure --prefix=$(ICONV) --enable-static $(AUTOCONF_FLAGS) && \
208215
make && make install
209216

210217
install-libiconv: download-libiconv build-libiconv
@@ -224,7 +231,7 @@ MIMALLOC := $(BC)vendor/mimalloc/out/$(OS)-$(ARCH)
224231
_build_mimalloc: clean-mimalloc
225232
@mkdir -p $(MIMALLOC)/build && \
226233
cd $(MIMALLOC)/build && \
227-
cmake -DMI_BUILD_SHARED=OFF -DMI_BUILD_OBJECT=OFF -DMI_BUILD_TESTS=OFF -DMI_OVERRIDE=OFF $(OPTS) ../../.. && \
234+
$(CMAKE) -DMI_BUILD_SHARED=OFF -DMI_BUILD_OBJECT=OFF -DMI_BUILD_TESTS=OFF -DMI_OVERRIDE=OFF $(OPTS) ../../.. && \
228235
make && \
229236
mkdir -p $(MIMALLOC)/lib
230237

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
}
@@ -390,26 +405,47 @@ fn addDependencies(b: *Build, mod: *Build.Module, opts: *Build.Step.Options) !vo
390405
mod.linkFramework("CoreFoundation", .{});
391406
mod.linkFramework("SystemConfiguration", .{});
392407
},
408+
.ios => {
409+
const sdk_path = try std.process.getEnvVarOwned(mod.owner.allocator, "SDK");
410+
const framework_path = try std.fmt.allocPrint(mod.owner.allocator, "{s}/System/Library/Frameworks", .{sdk_path});
411+
mod.addSystemFrameworkPath(.{ .cwd_relative = framework_path });
412+
mod.linkFramework("CoreFoundation", .{});
413+
mod.linkFramework("SystemConfiguration", .{});
414+
},
393415
else => {},
394416
}
395417
}
396418
}
397419

398420
fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
399421
const target = mod.resolved_target.?;
400-
const os = target.result.os.tag;
401-
const arch = target.result.cpu.arch;
422+
const os = switch (target.result.os.tag) {
423+
.linux => "linux",
424+
.macos => "macos",
425+
.ios => switch (target.result.abi) {
426+
.simulator => "iphonesimulator",
427+
else => return error.UnsupportedPlatform,
428+
},
429+
else => return error.UnsupportedPlatform,
430+
};
431+
const arch = switch (target.result.os.tag) {
432+
.ios => switch (target.result.cpu.arch) {
433+
.aarch64 => "arm64",
434+
else => @tagName(target.result.cpu.arch),
435+
},
436+
else => @tagName(target.result.cpu.arch),
437+
};
402438

403439
// iconv
404440
const libiconv_lib_path = try std.fmt.allocPrint(
405441
b.allocator,
406442
"vendor/libiconv/out/{s}-{s}/lib/libiconv.a",
407-
.{ @tagName(os), @tagName(arch) },
443+
.{ os, arch },
408444
);
409445
const libiconv_include_path = try std.fmt.allocPrint(
410446
b.allocator,
411447
"vendor/libiconv/out/{s}-{s}/lib/libiconv.a",
412-
.{ @tagName(os), @tagName(arch) },
448+
.{ os, arch },
413449
);
414450
mod.addObjectFile(b.path(libiconv_lib_path));
415451
mod.addIncludePath(b.path(libiconv_include_path));
@@ -420,7 +456,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
420456
const lib_path = try std.fmt.allocPrint(
421457
b.allocator,
422458
mimalloc ++ "/out/{s}-{s}/lib/libmimalloc.a",
423-
.{ @tagName(os), @tagName(arch) },
459+
.{ os, arch },
424460
);
425461
mod.addObjectFile(b.path(lib_path));
426462
mod.addIncludePath(b.path(mimalloc ++ "/include"));
@@ -431,7 +467,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
431467
const ns_include_path = try std.fmt.allocPrint(
432468
b.allocator,
433469
ns ++ "/out/{s}-{s}/include",
434-
.{ @tagName(os), @tagName(arch) },
470+
.{ os, arch },
435471
);
436472
mod.addIncludePath(b.path(ns_include_path));
437473

@@ -445,7 +481,7 @@ fn moduleNetSurf(b: *Build, mod: *Build.Module) !void {
445481
const ns_lib_path = try std.fmt.allocPrint(
446482
b.allocator,
447483
ns ++ "/out/{s}-{s}/lib/" ++ lib ++ ".a",
448-
.{ @tagName(os), @tagName(arch) },
484+
.{ os, arch },
449485
);
450486
mod.addObjectFile(b.path(ns_lib_path));
451487
mod.addIncludePath(b.path(ns ++ "/" ++ lib ++ "/src"));
@@ -494,7 +530,7 @@ fn buildMbedtls(b: *Build, m: *Build.Module) !void {
494530
mbedtls.addIncludePath(b.path(root ++ "include"));
495531
mbedtls.addIncludePath(b.path(root ++ "library"));
496532

497-
mbedtls.addCSourceFiles(.{ .flags = &.{}, .files = &.{
533+
mbedtls.addCSourceFiles(.{ .flags = &.{"-Wno-nullability-completeness"}, .files = &.{
498534
root ++ "library/aes.c",
499535
root ++ "library/aesni.c",
500536
root ++ "library/aesce.c",
@@ -648,6 +684,12 @@ fn buildNghttp2(b: *Build, m: *Build.Module) !void {
648684
}
649685

650686
fn buildCurl(b: *Build, m: *Build.Module) !void {
687+
if (m.resolved_target.?.result.os.tag == .ios) {
688+
const sdk_path = try std.process.getEnvVarOwned(b.allocator, "SDK");
689+
const include_path = try std.fmt.allocPrint(b.allocator, "{s}/usr/include", .{sdk_path});
690+
m.addIncludePath(.{ .cwd_relative = include_path });
691+
}
692+
651693
const curl = b.addLibrary(.{
652694
.name = "curl",
653695
.root_module = m,

build.zig.zon

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
.version = "0.0.0",
55
.fingerprint = 0xda130f3af836cea0,
66
.dependencies = .{
7-
.v8 = .{
8-
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/7177ee1ae267a44751a0e7e012e257177699a375.tar.gz",
9-
.hash = "v8-0.0.0-xddH63TCAwC1D1hEiOtbEnLBbtz9ZPHrdiGWLcBcYQB7",
10-
},
11-
// .v8 = .{ .path = "../zig-v8-fork" }
7+
// .v8 = .{
8+
// .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/7177ee1ae267a44751a0e7e012e257177699a375.tar.gz",
9+
// .hash = "v8-0.0.0-xddH63TCAwC1D1hEiOtbEnLBbtz9ZPHrdiGWLcBcYQB7",
10+
// },
11+
.v8 = .{ .path = "../zig-v8-fork" },
1212
},
1313
}

src/app.zig

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

src/server.zig

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

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

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

0 commit comments

Comments
 (0)