Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zig 12 Support #38

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .vscode/c_cpp_properties.json

This file was deleted.

28 changes: 0 additions & 28 deletions .vscode/settings.json

This file was deleted.

92 changes: 42 additions & 50 deletions Sdk.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ fn sdkRoot() *const [sdkRootIntern().len]u8 {

// linux-x86_64
pub fn toolchainHostTag() []const u8 {
comptime {
const os = builtin.os.tag;
const arch = builtin.cpu.arch;
return @tagName(os) ++ "-" ++ @tagName(arch);
}
const os = builtin.os.tag;
const arch = builtin.cpu.arch;
return (comptime if (std.mem.eql(u8, @tagName(os), "macos")) "darwin" else @tagName(os)) ++ "-" ++ @tagName(arch);
}

/// This file encodes a instance of an Android SDK interface.
Expand Down Expand Up @@ -92,12 +90,12 @@ pub fn init(b: *Builder, user_config: ?UserConfig, toolchains: ToolchainVersions
.name = "zip_add",
.root_source_file = .{ .path = sdkRoot() ++ "/tools/zip_add.zig" },
});
zip_add.addCSourceFile(sdkRoot() ++ "/vendor/kuba-zip/zip.c", &[_][]const u8{
zip_add.addCSourceFile(.{ .file = .{ .path = sdkRoot() ++ "/vendor/kuba-zip/zip.c" }, .flags = &[_][]const u8{
"-std=c99",
"-fno-sanitize=undefined",
"-D_POSIX_C_SOURCE=200112L",
});
zip_add.addIncludePath(sdkRoot() ++ "/vendor/kuba-zip");
} });
zip_add.addIncludePath(.{ .path = sdkRoot() ++ "/vendor/kuba-zip" });
zip_add.linkLibC();

break :blk HostTools{
Expand Down Expand Up @@ -503,10 +501,10 @@ pub fn createApp(
}
resource_dir_step.add(Resource{
.path = "values/strings.xml",
.content = write_xml_step.getFileSource("strings.xml").?,
.content = write_xml_step.files.items[0].getPath(),
});

const sdk_version_int = @enumToInt(app_config.target_version);
const sdk_version_int = @intFromEnum(app_config.target_version);

if (sdk_version_int < 16) @panic("Minimum supported sdk version is 16.");

Expand Down Expand Up @@ -549,10 +547,10 @@ pub fn createApp(
const unaligned_apk_file = make_unsigned_apk.addOutputFileArg(unaligned_apk_name);

make_unsigned_apk.addArg("-M"); // specify full path to AndroidManifest.xml to include in zip
make_unsigned_apk.addFileSourceArg(manifest_step.getFileSource("AndroidManifest.xml").?);
make_unsigned_apk.addFileArg(manifest_step.files.items[0].getPath());

make_unsigned_apk.addArg("-S"); // directory in which to find resources. Multiple directories will be scanned and the first match found (left to right) will take precedence
make_unsigned_apk.addDirectorySourceArg(resource_dir_step.getOutputDirectory());
make_unsigned_apk.addDirectoryArg(resource_dir_step.getOutputDirectory());

make_unsigned_apk.addArgs(&[_][]const u8{
"-v",
Expand Down Expand Up @@ -593,13 +591,10 @@ pub fn createApp(
"-v", // verbose
"4",
});
align_step.addFileSourceArg(copy_to_zip_step.output_source);
align_step.addFileArg(copy_to_zip_step.output_source);
align_step.step.dependOn(&make_unsigned_apk.step);
const apk_file = align_step.addOutputFileArg(apk_filename);

const apk_install = sdk.b.addInstallBinFile(apk_file, apk_filename);
sdk.b.getInstallStep().dependOn(&apk_install.step);

const java_dir = sdk.b.getInstallPath(.lib, "java");
if (java_files_opt) |java_files| {
const d8_cmd_builder = sdk.b.addSystemCommand(&[_][]const u8{sdk.system_tools.d8});
Expand All @@ -615,13 +610,13 @@ pub fn createApp(
"-d",
java_dir,
});
javac_cmd.addFileSourceArg(std.build.FileSource.relative(java_file));
javac_cmd.addFileArg(std.build.FileSource.relative(java_file));

const name = std.fs.path.stem(java_file);
const name_ext = sdk.b.fmt("{s}.class", .{name});
const class_file = std.fs.path.resolve(sdk.b.allocator, &[_][]const u8{ java_dir, name_ext }) catch unreachable;

d8_cmd_builder.addFileSourceArg(.{ .path = class_file });
d8_cmd_builder.addFileArg(.{ .path = class_file });
d8_cmd_builder.step.dependOn(&javac_cmd.step);
}

Expand All @@ -640,6 +635,11 @@ pub fn createApp(
align_step.step.dependOn(&copy_to_zip_step.run_step.step);
}

if (!auto_detect.fileExists(key_store.file)) {
// sadly we lack a FailStep
std.log.err("missing keystore file at `{s}`", .{key_store.file});
}

// const sign_step = sdk.signApk(apk_filename, key_store);
const sign_step = sdk.b.addSystemCommand(&[_][]const u8{
sdk.system_tools.apksigner,
Expand All @@ -651,9 +651,14 @@ pub fn createApp(
{
const pass = sdk.b.fmt("pass:{s}", .{key_store.password});
sign_step.addArgs(&.{ "--ks-pass", pass });
sign_step.addFileSourceArg(apk_file);
sign_step.addFileArg(apk_file);
}

const apk_install = sdk.b.addInstallBinFile(apk_file, apk_filename);
sdk.b.getInstallStep().dependOn(&apk_install.step);
// only install after singing the apk
apk_install.step.dependOn(&sign_step.step);

inline for (std.meta.fields(AppTargetConfig)) |fld| {
const target_name = @field(Target, fld.name);
if (@field(targets, fld.name).?) {
Expand All @@ -678,6 +683,7 @@ pub fn createApp(

copy_to_zip_step.addFile(step.getOutputSource(), target_filename);
copy_to_zip_step.run_step.step.dependOn(&step.step);
// why this is inside the for loop
align_step.step.dependOn(&copy_to_zip_step.run_step.step);
}
}
Expand Down Expand Up @@ -769,8 +775,8 @@ const CreateResourceDirectory = struct {
fn run_copy_to_zip(sdk: *Sdk, input_file: std.build.FileSource, apk_file: std.build.FileSource, target_file: []const u8) *std.Build.RunStep {
const run_cp = sdk.b.addRunArtifact(sdk.host_tools.zip_add);

run_cp.addFileSourceArg(apk_file);
run_cp.addFileSourceArg(input_file);
run_cp.addFileArg(apk_file);
run_cp.addFileArg(input_file);
run_cp.addArg(target_file);

return run_cp;
Expand All @@ -783,7 +789,7 @@ const WriteToZip = struct {
pub fn init(sdk: *Sdk, zip_file: std.Build.FileSource, out_name: []const u8) WriteToZip {
const run_cp = sdk.b.addRunArtifact(sdk.host_tools.zip_add);

run_cp.addFileSourceArg(zip_file);
run_cp.addFileArg(zip_file);
const output_source = run_cp.addOutputFileArg(out_name);

return WriteToZip{
Expand All @@ -793,7 +799,7 @@ const WriteToZip = struct {
}

pub fn addFile(step: *const WriteToZip, input_file: std.Build.FileSource, target_file: []const u8) void {
step.run_step.addFileSourceArg(input_file);
step.run_step.addFileArg(input_file);
step.run_step.addArg(target_file);
}
};
Expand Down Expand Up @@ -848,7 +854,7 @@ pub fn compileAppLibrary(
ndk_root,
toolchainHostTag(),
config.lib_dir,
@enumToInt(app_config.target_version),
@intFromEnum(app_config.target_version),
});

const include_dir = std.fs.path.resolve(sdk.b.allocator, &[_][]const u8{
Expand Down Expand Up @@ -887,7 +893,7 @@ pub fn compileAppLibrary(

// exe.addIncludePath(include_dir);

exe.addLibraryPath(lib_dir);
exe.addLibraryPath(.{ .path = lib_dir });

// exe.addIncludePath(include_dir);
// exe.addIncludePath(system_include_dir);
Expand All @@ -904,7 +910,7 @@ 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.FileSource {
const fname = sdk.b.fmt("android-{d}-{s}.conf", .{ @enumToInt(version), folder_name });
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();
Expand All @@ -926,7 +932,8 @@ fn createLibCFile(sdk: *const Sdk, version: AndroidVersion, folder_name: []const
try writer.writeAll("gcc_dir=\n");

const step = sdk.b.addWriteFile(fname, contents.items);
return step.getFileSource(fname) orelse unreachable;
// return step.getFileSource(fname) orelse unreachable;
return step.files.items[0].getPath();
}

pub fn compressApk(sdk: Sdk, input_apk_file: []const u8, output_apk_file: []const u8) *Step {
Expand Down Expand Up @@ -966,7 +973,7 @@ pub fn compressApk(sdk: Sdk, input_apk_file: []const u8, output_apk_file: []cons

pub fn installApp(sdk: Sdk, apk_file: std.build.FileSource) *Step {
const step = sdk.b.addSystemCommand(&[_][]const u8{ sdk.system_tools.adb, "install" });
step.addFileSourceArg(apk_file);
step.addFileArg(apk_file);
return &step.step;
}

Expand Down Expand Up @@ -997,18 +1004,17 @@ pub fn startApp(sdk: Sdk, package_name: []const u8) *Step {
pub const KeyConfig = struct {
pub const Algorithm = enum { RSA };
key_algorithm: Algorithm = .RSA,
key_size: u32 = 2048, // bits
key_size: u32 = 4096, // bits
validity: u32 = 10_000, // days
distinguished_name: []const u8 = "CN=example.com, OU=ID, O=Example, L=Doe, S=John, C=GB",
distinguished_name: []const u8 = "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, S=Unknown, C=Unknown",
};
/// A build step that initializes a new key store from the given configuration.
/// `android_config.key_store` must be non-`null` as it is used to initialize the key store.
pub fn initKeystore(sdk: Sdk, key_store: KeyStore, key_config: KeyConfig) *Step {
if (auto_detect.fileExists(key_store.file)) {
std.log.warn("keystore already exists: {s}", .{key_store.file});
return sdk.b.step("init_keystore_noop", "Do nothing, since key exists");
} else {
const step = sdk.b.addSystemCommand(&[_][]const u8{
const args = &[_][]const u8{
sdk.system_tools.keytool,
"-genkey",
"-v",
Expand All @@ -1028,8 +1034,10 @@ pub fn initKeystore(sdk: Sdk, key_store: KeyStore, key_config: KeyConfig) *Step
key_store.password,
"-dname",
key_config.distinguished_name,
});
return &step.step;
};

const run = sdk.b.addSystemCommand(args);
return &run.step;
}
}

Expand Down Expand Up @@ -1151,22 +1159,6 @@ const BuildOptionStep = struct {
}
return;
},
std.builtin.Version => {
out.print(
\\pub const {}: @import("std").builtin.Version = .{{
\\ .major = {d},
\\ .minor = {d},
\\ .patch = {d},
\\}};
\\
, .{
std.zig.fmtId(name),

value.major,
value.minor,
value.patch,
}) catch unreachable;
},
std.SemanticVersion => {
out.print(
\\pub const {}: @import("std").SemanticVersion = .{{
Expand Down
17 changes: 8 additions & 9 deletions build/auto-detect.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ pub fn findUserConfig(b: *Builder, versions: Sdk.ToolchainVersions) !UserConfig
// Check for a user config file.
if (std.fs.cwd().openFile(config_path, .{})) |file| {
defer file.close();
const bytes = file.readToEndAlloc(b.allocator, 1 * 1000 * 1000) catch |err| {
const bytes = file.readToEndAlloc(b.allocator, 2 * 1024 * 1024) catch |err| {
print("Unexpected error reading {s}: {s}\n", .{ config_path, @errorName(err) });
return err;
};
var stream = std.json.TokenStream.init(bytes);
if (std.json.parse(UserConfig, &stream, .{ .allocator = b.allocator })) |conf| {
if (std.json.parseFromSliceLeaky(UserConfig, b.allocator, bytes, .{})) |conf| {
config = conf;
} else |err| {
print("Could not parse {s} ({s}).\n", .{ config_path, @errorName(err) });
Expand Down Expand Up @@ -99,10 +98,10 @@ pub fn findUserConfig(b: *Builder, versions: Sdk.ToolchainVersions) !UserConfig
const LSTATUS = u32;
const DWORD = u32;

// const HKEY_CLASSES_ROOT = @intToPtr(HKEY, 0x80000000);
const HKEY_CURRENT_USER = @intToPtr(HKEY, 0x80000001);
const HKEY_LOCAL_MACHINE = @intToPtr(HKEY, 0x80000002);
// const HKEY_USERS = @intToPtr(HKEY, 0x80000003);
// const HKEY_CLASSES_ROOT: HKEY= @ptrFromInt(0x80000000);
const HKEY_CURRENT_USER: HKEY = @ptrFromInt(0x80000001);
const HKEY_LOCAL_MACHINE: HKEY = @ptrFromInt(0x80000002);
// const HKEY_USERS: HKEY= @ptrFromInt(0x80000003);

// const RRF_RT_ANY: DWORD = 0xFFFF;
// const RRF_RT_REG_BINARY: DWORD = 0x08;
Expand Down Expand Up @@ -142,7 +141,7 @@ pub fn findUserConfig(b: *Builder, versions: Sdk.ToolchainVersions) !UserConfig

// get the data
const buffer = allocator.alloc(u8, len) catch unreachable;
len = @intCast(DWORD, buffer.len);
len = @as(DWORD, @intCast(buffer.len));
res = RegGetValueA(key, null, value, RRF_RT_REG_SZ, null, buffer.ptr, &len);
if (res == ERROR_SUCCESS) {
for (buffer[0..len], 0..) |c, i| {
Expand All @@ -156,7 +155,7 @@ pub fn findUserConfig(b: *Builder, versions: Sdk.ToolchainVersions) !UserConfig
};

// Get the android studio registry entry
var android_studio_key: HKEY = for ([_]HKEY{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }) |root_key| {
const android_studio_key: HKEY = for ([_]HKEY{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }) |root_key| {
var software: HKEY = null;
if (reg.RegOpenKeyA(root_key, "software", &software) == ERROR_SUCCESS) {
defer _ = reg.RegCloseKey(software);
Expand Down
Loading