diff --git a/README.md b/README.md index 37d137e56d50916c45a2c041111bc9d821cc1fa0..9da4670648e5912642a58ecbc05198af3fd96e58 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ zigmod add --> #### Available types +- `system_lib` - `git` - `hg` @@ -102,7 +103,7 @@ pub fn build(b: *Builder) void { #### Dep object | Name | Type | Note | Description | |------|------|------|-------------| -| `type` | `string` | required, enum | One of `git`, `hg` | +| `type` | `string` | required, enum | One of `system_lib`, `git`, `hg` | | `path` | `string` | required | URL/path to this dependency. depends on the type | | `version` | `string` | only on some types | pin this dependency at a specific version | | `only_os` | `string` | | comma separated list of OS names to add this Dep to | diff --git a/src/cmd_fetch.zig b/src/cmd_fetch.zig index 03b96181d33ec647c768f29a94a92b4e415a4f71..8c6837ddd8e0d8c800d77365d7ac33034467b252 100644 --- a/src/cmd_fetch.zig +++ b/src/cmd_fetch.zig @@ -40,6 +40,9 @@ pub fn execute(args: [][]u8) !void { \\ inline for (c_source_files) |fpath| { \\ exe.addCSourceFile(fpath[1], @field(c_source_flags, fpath[0])); \\ } + \\ for (system_libs) |lib| { + \\ exe.linkSystemLibrary(lib); + \\ } \\} \\ \\fn get_flags(comptime index: usize) []const u8 { @@ -62,6 +65,11 @@ pub fn execute(args: [][]u8) !void { try w.print("{}\n", .{"pub const c_source_files = &[_][2][]const u8{"}); try print_csrc_dirs_to(w, top_module, &std.ArrayList([]const u8).init(gpa), true); try w.print("{};\n", .{"}"}); + try w.print("\n", .{}); + try w.print("{}\n", .{"pub const system_libs = &[_][]const u8{"}); + try print_sys_libs_to(w, top_module, &std.ArrayList([]const u8).init(gpa), &std.ArrayList([]const u8).init(gpa)); + try w.print("{};\n", .{"}"}); + } fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { @@ -74,6 +82,9 @@ fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { u.print("fetch: {}: {}: {}", .{m.name, @tagName(d.type), d.path}); moddir = p; switch (d.type) { + .system_lib => { + // no op + }, .git => blk: { if (!try u.does_file_exist(p)) { _ = try d.type.pull(d.path, p); @@ -121,6 +132,20 @@ fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { }, } switch (d.type) { + .system_lib => { + if (d.is_for_this()) try moduledeps.append(u.Module{ + .is_sys_lib = true, + .name = d.path, + .only_os = d.only_os, + .except_os = d.except_os, + .main = "", + .c_include_dirs = &[_][]const u8{}, + .c_source_flags = &[_][]const u8{}, + .c_source_files = &[_][]const u8{}, + .deps = &[_]u.Module{}, + .clean_path = "", + }); + }, else => blk: { var dd = try fetch_deps(dir, try u.concat(&[_][]const u8{moddir, "/zig.mod"})) catch |e| switch (e) { error.FileNotFound => { @@ -148,6 +173,7 @@ fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { } } return u.Module{ + .is_sys_lib = false, .name = m.name, .main = m.main, .c_include_dirs = m.c_include_dirs, @@ -196,6 +222,7 @@ fn print_incl_dirs_to(w: fs.File.Writer, mod: u.Module, list: *std.ArrayList([]c } } for (mod.deps) |d| { + if (d.is_sys_lib) continue; try print_incl_dirs_to(w, d, list, false); } } @@ -213,6 +240,7 @@ fn print_csrc_dirs_to(w: fs.File.Writer, mod: u.Module, list: *std.ArrayList([]c } } for (mod.deps) |d| { + if (d.is_sys_lib) continue; try print_csrc_dirs_to(w, d, list, false); } } @@ -233,6 +261,25 @@ fn print_csrc_flags_to(w: fs.File.Writer, mod: u.Module, list: *std.ArrayList([] try w.print("{};\n", .{"}"}); } for (mod.deps) |d| { + if (d.is_sys_lib) continue; try print_csrc_flags_to(w, d, list, false); } } + +fn print_sys_libs_to(w: fs.File.Writer, mod: u.Module, list: *std.ArrayList([]const u8), list2: *std.ArrayList([]const u8)) anyerror!void { + if (u.list_contains(list.items, mod.clean_path)) { + return; + } + try list.append(mod.clean_path); + // + for (mod.deps) |d| { + if (!d.is_sys_lib) continue; + // + if (!u.list_contains(list2.items, d.name)) { + try w.print(" \"{}\",\n", .{d.name}); + try list2.append(d.name); + } + // + try print_sys_libs_to(w, d, list, list2); + } +} diff --git a/src/common.zig b/src/common.zig index 681a64a7c33915dfb99e53e9d0fb381a5b505928..06916e981d8e876e809a229833fcb9b864bc8983 100644 --- a/src/common.zig +++ b/src/common.zig @@ -21,6 +21,20 @@ pub fn collect_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { moddir = p; } switch (d.type) { + .system_lib => { + if (d.is_for_this()) try moduledeps.append(u.Module{ + .is_sys_lib = true, + .name = d.path, + .only_os = d.only_os, + .except_os = d.except_os, + .main = "", + .c_include_dirs = &[_][]const u8{}, + .c_source_flags = &[_][]const u8{}, + .c_source_files = &[_][]const u8{}, + .deps = &[_]u.Module{}, + .clean_path = "", + }); + }, else => blk: { var dd = try collect_deps(dir, try u.concat(&[_][]const u8{moddir, "/zig.mod"})) catch |e| switch (e) { error.FileNotFound => { @@ -48,6 +62,7 @@ pub fn collect_deps(dir: []const u8, mpath: []const u8) anyerror!u.Module { } } return u.Module{ + .is_sys_lib = false, .name = m.name, .main = m.main, .c_include_dirs = m.c_include_dirs, diff --git a/src/util/dep.zig b/src/util/dep.zig index dd68a070abae62f59c47700f9d54e920cc8b644f..5277a947e7d5b7df88b98083ab0b1aa6042b19b5 100644 --- a/src/util/dep.zig +++ b/src/util/dep.zig @@ -1,5 +1,6 @@ const std = @import("std"); const gpa = std.heap.c_allocator; +const builtin = @import("builtin"); const u = @import("index.zig"); @@ -29,4 +30,15 @@ pub const Dep = struct { p = try std.fmt.allocPrint(gpa, "{}{}{}", .{@tagName(self.type), "/", p}); return p; } + + pub fn is_for_this(self: Dep) bool { + const os = @tagName(builtin.os.tag); + if (self.only_os.len > 0) { + return u.list_contains(self.only_os, os); + } + if (self.except_os.len > 0) { + return !u.list_contains(self.except_os, os); + } + return true; + } }; diff --git a/src/util/dep_type.zig b/src/util/dep_type.zig index e5bfd964c46d3b648a402ae56307a73d92f2d490..8a1c63961090f6228fdd659780831e5c6e5376ca 100644 --- a/src/util/dep_type.zig +++ b/src/util/dep_type.zig @@ -4,11 +4,13 @@ const u = @import("./index.zig"); // pub const DepType = enum { + system_lib, // std.build.LibExeObjStep.linkSystemLibrary git, // https://git-scm.com/ hg, // https://www.mercurial-scm.org/ pub fn pull(self: DepType, rpath: []const u8, dpath: []const u8) !void { switch (self) { + .system_lib => {}, .git => { _ = try u.run_cmd(null, &[_][]const u8{"git", "clone", rpath, dpath}); }, @@ -21,6 +23,7 @@ pub const DepType = enum { pub fn update(self: DepType, dpath: []const u8, rpath: []const u8) !void { switch (self) { + .system_lib => {}, .git => { _ = try u.run_cmd(dpath, &[_][]const u8{"git", "fetch"}); _ = try u.run_cmd(dpath, &[_][]const u8{"git", "pull"}); diff --git a/src/util/module.zig b/src/util/module.zig index 05b6dd0760fe978c53098a7dc749d6dd6fb96789..788d4ca6db8f4a1e4d618e0f52232273ca579155 100644 --- a/src/util/module.zig +++ b/src/util/module.zig @@ -12,6 +12,7 @@ const kb = b * 1024; const mb = kb * 1024; pub const Module = struct { + is_sys_lib: bool, name: []const u8, main: []const u8, c_include_dirs: [][]const u8, @@ -25,6 +26,7 @@ pub const Module = struct { pub fn from(dep: u.Dep) !Module { return Module{ + .is_sys_lib = false, .name = dep.name, .main = dep.main, .c_include_dirs = dep.c_include_dirs,