Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ macos-sdk/
c_examples/libcapy.so.0
c_examples/c_template
.direnv
.serena
.worktrees
35 changes: 17 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

**As of now, Capy is NOT ready for use in production as I'm still making breaking changes**

**Capy targets Zig version `0.14.1`, the plan is to return to [Nominated Zig versions](https://machengine.org/docs/nominated-zig/)
once a new one is published**
**Capy targets Zig version `0.15.2`**

---

Expand Down Expand Up @@ -102,8 +101,8 @@ Legends:
✅ Windows x86_64
✅ Windows i386

🏃 macOS M1
🏃 macOS x86_64
🧪 macOS M1 (Apple Silicon)
🧪 macOS x86_64

✅ Linux x86_64
✅ Linux i386
Expand All @@ -130,20 +129,20 @@ with other DEs.
## Supported components
For now, not every platform supports the same components. So here's a list of the ones that are supported:

| |win32|macOS|GTK|Android|wasm|
|------------------|-----|-----|---|-----|-----|
| |win32|macOS|GTK |Android|wasm|
|------------------|-----|-----|-------|-------|-----|
|Button |✅|✅|✅|✅|✅|
|Canvas |❌||✅|✅|✅|
|CheckBox |✅||✅|❌|❌|
|Dropdown |✅||✅|❌|❌|
|Image |❌||✅|❌|✅|
|Canvas |❌|🧪|✅|✅|✅|
|CheckBox |✅|🧪|✅|❌|❌|
|Dropdown |✅|🧪|✅|❌|❌|
|Image |❌|🧪|✅|❌|✅|
|Label |✅|✅|✅|✅|✅|
|Menu |❌|❌|❌|❌|❌|
|Navigation |❌|❌||❌|❌|
|NavigationSidebar |❌||✅|❌|❌|
|Scrollable |✅||✅|❌|❌|
|Slider |✅||✅|❌|✅|
|Tabs |✅||✅|❌|❌|
|TextArea |✅||✅|❌|❌|
|TextField |✅||✅|✅|✅|
|Menu |✅|🧪|✅|❌|❌|
|Navigation |❌|❌||❌|❌|
|NavigationSidebar |❌|🧪|✅|❌|❌|
|Scrollable |✅|🧪|✅|❌|❌|
|Slider |✅|🧪|✅|❌|✅|
|Tabs |✅|🧪|✅|❌|❌|
|TextArea |✅|🧪|✅|❌|❌|
|TextField |✅|🧪|✅|✅|✅|
|Window |✅|✅|✅|✅|✅
55 changes: 30 additions & 25 deletions android/Sdk.zig
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ pub fn init(b: *Builder, user_config: ?UserConfig, toolchains: ToolchainVersions
const host_tools = blk: {
const zip_add = b.addExecutable(.{
.name = "zip_add",
.root_source_file = b.path(sdkRoot() ++ "/tools/zip_add.zig"),
.target = b.resolveTargetQuery(.{}),
.root_module = b.createModule(.{
.root_source_file = b.path(sdkRoot() ++ "/tools/zip_add.zig"),
.target = b.resolveTargetQuery(.{}),
}),
});
zip_add.addCSourceFile(.{
.file = b.path(sdkRoot() ++ "/vendor/kuba-zip/zip.c"),
Expand Down Expand Up @@ -468,10 +470,10 @@ pub fn createApp(
) CreateAppStep {
const write_xml_step = sdk.b.addWriteFiles();
const write_xml_file_source = write_xml_step.add("strings.xml", blk: {
var buf = std.ArrayList(u8).init(sdk.b.allocator);
errdefer buf.deinit();
var buf: std.ArrayList(u8) = .empty;
errdefer buf.deinit(sdk.b.allocator);

var writer = buf.writer();
var writer = buf.writer(sdk.b.allocator);

writer.writeAll(
\\<?xml version="1.0" encoding="utf-8"?>
Expand All @@ -495,15 +497,15 @@ pub fn createApp(
\\
) catch unreachable;

break :blk buf.toOwnedSlice() catch unreachable;
break :blk buf.toOwnedSlice(sdk.b.allocator) catch unreachable;
});

const manifest_step = sdk.b.addWriteFiles();
const manifest_file_source = manifest_step.add("AndroidManifest.xml", blk: {
var buf = std.ArrayList(u8).init(sdk.b.allocator);
errdefer buf.deinit();
var buf: std.ArrayList(u8) = .empty;
errdefer buf.deinit(sdk.b.allocator);

var writer = buf.writer();
var writer = buf.writer(sdk.b.allocator);

@setEvalBranchQuota(1_000_000);
writer.print(
Expand Down Expand Up @@ -540,7 +542,7 @@ pub fn createApp(
.theme = theme,
}) catch unreachable;

break :blk buf.toOwnedSlice() catch unreachable;
break :blk buf.toOwnedSlice(sdk.b.allocator) catch unreachable;
});

const resource_dir_step = CreateResourceDirectory.create(sdk.b);
Expand Down Expand Up @@ -613,8 +615,8 @@ pub fn createApp(
const copy_to_zip_step = WriteToZip.init(sdk, unaligned_apk_file, unaligned_apk_name);
copy_to_zip_step.run_step.step.dependOn(&make_unsigned_apk.step);

var libs = std.ArrayList(*std.Build.Step.Compile).init(sdk.b.allocator);
defer libs.deinit();
var libs: std.ArrayList(*std.Build.Step.Compile) = .empty;
defer libs.deinit(sdk.b.allocator);

const build_options = BuildOptionStep.create(sdk.b);
build_options.add([]const u8, "app_name", app_config.app_name);
Expand Down Expand Up @@ -711,7 +713,7 @@ pub fn createApp(
target_name,
// build_options.getPackage("build_options"),
);
libs.append(step) catch unreachable;
libs.append(sdk.b.allocator, step) catch unreachable;

// https://developer.android.com/ndk/guides/abis#native-code-in-app-packages
const so_dir = switch (target_name) {
Expand All @@ -736,7 +738,7 @@ pub fn createApp(
.sdk = sdk,
.first_step = &make_unsigned_apk.step,
.final_step = &sign_step.step,
.libraries = libs.toOwnedSlice() catch unreachable,
.libraries = libs.toOwnedSlice(sdk.b.allocator) catch unreachable,
.build_options = build_options,
.package_name = sdk.b.dupe(app_config.package_name),
.apk_file = apk_file.dupe(sdk.b),
Expand All @@ -762,13 +764,13 @@ const CreateResourceDirectory = struct {
.makeFn = CreateResourceDirectory.make,
}),
.directory = .{ .step = &self.step },
.resources = std.ArrayList(Resource).init(b.allocator),
.resources = .empty,
};
return self;
}

pub fn add(self: *Self, resource: Resource) void {
self.resources.append(Resource{
self.resources.append(self.builder.allocator, Resource{
.path = self.builder.dupe(resource.path),
.content = resource.content.dupe(self.builder),
}) catch @panic("out of memory");
Expand Down Expand Up @@ -944,11 +946,14 @@ pub fn compileAppLibrary(
target: Target,
// build_options: std.Build.Pkg,
) *std.Build.Step.Compile {
const exe = sdk.b.addSharedLibrary(.{
const exe = sdk.b.addLibrary(.{
.linkage = .dynamic,
.name = app_config.app_name,
.root_source_file = sdk.b.path(src_file),
.target = sdk.b.resolveTargetQuery(target.getTargetConfig().target),
.optimize = mode,
.root_module = sdk.b.createModule(.{
.root_source_file = sdk.b.path(src_file),
.target = sdk.b.resolveTargetQuery(target.getTargetConfig().target),
.optimize = mode,
}),
});
configureStep(
sdk,
Expand All @@ -962,10 +967,10 @@ pub fn compileAppLibrary(
fn createLibCFile(sdk: *const Sdk, version: AndroidVersion, folder_name: []const u8, include_dir: []const u8, sys_include_dir: []const u8, crt_dir: []const u8) !std.Build.LazyPath {
const fname = sdk.b.fmt("android-{d}-{s}.conf", .{ @intFromEnum(version), folder_name });

var contents = std.ArrayList(u8).init(sdk.b.allocator);
errdefer contents.deinit();
var contents: std.ArrayList(u8) = .empty;
errdefer contents.deinit(sdk.b.allocator);

var writer = contents.writer();
var writer = contents.writer(sdk.b.allocator);

// The directory that contains `stdlib.h`.
// On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null
Expand Down Expand Up @@ -1149,7 +1154,7 @@ const BuildOptionStep = struct {
.owner = b,
.makeFn = make,
}),
.file_content = std.ArrayList(u8).init(b.allocator),
.file_content = .empty,
.package_file = std.Build.GeneratedFile{ .step = &options.step },
};
const build_options = b.addModule("build_options", .{
Expand All @@ -1172,7 +1177,7 @@ const BuildOptionStep = struct {
}

pub fn add(self: *Self, comptime T: type, name: []const u8, value: T) void {
const out = self.file_content.writer();
const out = self.file_content.writer(self.builder.allocator);
switch (T) {
[]const []const u8 => {
out.print("pub const {}: []const []const u8 = &[_][]const u8{{\n", .{std.zig.fmtId(name)}) catch unreachable;
Expand Down
16 changes: 8 additions & 8 deletions android/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ pub fn build(b: *std.build.Builder) !void {
.password = "ziguana",
};

var libraries = std.ArrayList([]const u8).init(b.allocator);
try libraries.append("GLESv2");
try libraries.append("EGL");
try libraries.append("android");
try libraries.append("log");

if (opensl) try libraries.append("OpenSLES");
if (aaudio) try libraries.append("aaudio");
var libraries: std.ArrayList([]const u8) = .empty;
try libraries.append(b.allocator, "GLESv2");
try libraries.append(b.allocator, "EGL");
try libraries.append(b.allocator, "android");
try libraries.append(b.allocator, "log");

if (opensl) try libraries.append(b.allocator, "OpenSLES");
if (aaudio) try libraries.append(b.allocator, "aaudio");

// This is a configuration for your application.
// Android requires several configurations to be done, this is a typical config
Expand Down
7 changes: 4 additions & 3 deletions android/build/auto-detect.zig
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,14 @@ pub fn findUserConfig(b: *Builder, versions: Sdk.ToolchainVersions) !UserConfig
};
defer file.close();

var buf_writer = std.io.bufferedWriter(file.writer());
var write_buf: [4096]u8 = undefined;
var fw = file.writer(&write_buf);

std.json.stringify(config, .{}, buf_writer.writer()) catch |err| {
std.json.Stringify.value(config, .{}, &fw.interface) catch |err| {
print("Error writing config file {s}: {s}\n", .{ config_path, @errorName(err) });
return err;
};
buf_writer.flush() catch |err| {
fw.interface.flush() catch |err| {
print("Error writing config file {s}: {s}\n", .{ config_path, @errorName(err) });
return err;
};
Expand Down
8 changes: 5 additions & 3 deletions android/src/android-support.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ pub const NativeInvocationHandler = @import("NativeInvocationHandler.zig");

const app_log = std.log.scoped(.app_glue);

// Export the flat functions for now
// pub const native = android;
pub usingnamespace android;
// TODO: `pub usingnamespace android;` was removed to eliminate usingnamespace.
// The android-bind.zig module contains hundreds of auto-generated Android NDK bindings.
// To complete this replacement, identify which declarations from android-bind.zig are
// actually used by consumers of this module and forward them explicitly.
// For now, this is Android-only code and does not affect macOS compilation.

const AndroidApp = @import("root").AndroidApp;

Expand Down
10 changes: 9 additions & 1 deletion android/src/c.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
const build_options = @import("build_options");
pub usingnamespace @cImport({

// TODO: `pub usingnamespace @cImport({...});` was removed to eliminate usingnamespace.
// This file re-exported all declarations from the cImport of EGL, GLES2, and optionally
// AAudio/OpenSLES headers. To complete this replacement, identify which C declarations
// are actually used by consumers of this module and forward them explicitly from the
// cImport below. For now, this is Android-only code and does not affect macOS compilation.
const _c = @cImport({
@cInclude("EGL/egl.h");
// @cInclude("EGL/eglext.h");
@cInclude("GLES2/gl2.h");
Expand All @@ -14,3 +20,5 @@ pub usingnamespace @cImport({
@cInclude("SLES/OpenSLES_Android.h");
}
});
// TODO: Forward specific declarations from _c that are needed by consumers of this module.
// Example: pub const EGLDisplay = _c.EGLDisplay;
Loading