Skip to content

Commit

Permalink
basic support for specifying packages at the command line
Browse files Browse the repository at this point in the history
See #226
  • Loading branch information
andrewrk committed May 1, 2017
1 parent 17b9353 commit 3cbd006
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 7 deletions.
68 changes: 65 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ static int usage(const char *arg0) {
" --name [name] override output name\n"
" --output [file] override destination path\n"
" --output-h [file] override generated header file path\n"
" --pkg-begin [name] [path] make package available to import and push current pkg\n"
" --pkg-end pop current pkg\n"
" --release build with optimizations on and debug protection off\n"
" --static output will be statically linked\n"
" --strip exclude debug symbols\n"
Expand Down Expand Up @@ -121,6 +123,36 @@ enum Cmd {

static const char *default_zig_cache_name = "zig-cache";

struct CliPkg {
const char *name;
const char *path;
ZigList<CliPkg *> children;
CliPkg *parent;
};

static void add_package(CodeGen *g, CliPkg *cli_pkg, PackageTableEntry *pkg) {
for (size_t i = 0; i < cli_pkg->children.length; i += 1) {
CliPkg *child_cli_pkg = cli_pkg->children.at(i);

Buf *dirname = buf_alloc();
Buf *basename = buf_alloc();
os_path_split(buf_create_from_str(child_cli_pkg->path), dirname, basename);

PackageTableEntry *child_pkg = codegen_create_package(g, buf_ptr(dirname), buf_ptr(basename));
auto entry = pkg->package_table.put_unique(buf_create_from_str(child_cli_pkg->name), child_pkg);
if (entry) {
PackageTableEntry *existing_pkg = entry->value;
Buf *full_path = buf_alloc();
os_path_join(&existing_pkg->root_src_dir, &existing_pkg->root_src_path, full_path);
fprintf(stderr, "Unable to add package '%s'->'%s': already exists as '%s'\n",
child_cli_pkg->name, child_cli_pkg->path, buf_ptr(full_path));
exit(EXIT_FAILURE);
}

add_package(g, child_cli_pkg, child_pkg);
}
}

int main(int argc, char **argv) {
os_init();

Expand Down Expand Up @@ -168,6 +200,7 @@ int main(int argc, char **argv) {
size_t ver_patch = 0;
bool timing_info = false;
const char *cache_dir = nullptr;
CliPkg *cur_pkg = allocate<CliPkg>(1);

if (argc >= 2 && strcmp(argv[1], "build") == 0) {
const char *zig_exe_path = arg0;
Expand Down Expand Up @@ -309,13 +342,31 @@ int main(int argc, char **argv) {
} else if (arg[1] == 'L' && arg[2] != 0) {
// alias for --library-path
lib_dirs.append(&arg[2]);
} else if (strcmp(arg, "--pkg-begin") == 0) {
if (i + 2 >= argc) {
fprintf(stderr, "Expected 2 arguments after --pkg-begin\n");
return usage(arg0);
}
CliPkg *new_cur_pkg = allocate<CliPkg>(1);
i += 1;
new_cur_pkg->name = argv[i];
i += 1;
new_cur_pkg->path = argv[i];
new_cur_pkg->parent = cur_pkg;
cur_pkg->children.append(new_cur_pkg);
cur_pkg = new_cur_pkg;
} else if (strcmp(arg, "--pkg-end") == 0) {
if (cur_pkg->parent == nullptr) {
fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n");
return EXIT_FAILURE;
}
cur_pkg = cur_pkg->parent;
} else if (i + 1 >= argc) {
fprintf(stderr, "Expected another argument after %s\n", arg);
return usage(arg0);
} else {
i += 1;
if (i >= argc) {
return usage(arg0);
} else if (strcmp(arg, "--output") == 0) {
if (strcmp(arg, "--output") == 0) {
out_file = argv[i];
} else if (strcmp(arg, "--output-h") == 0) {
out_file_h = argv[i];
Expand All @@ -327,6 +378,7 @@ int main(int argc, char **argv) {
} else if (strcmp(argv[i], "off") == 0) {
color = ErrColorOff;
} else {
fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n");
return usage(arg0);
}
} else if (strcmp(arg, "--name") == 0) {
Expand Down Expand Up @@ -421,18 +473,25 @@ int main(int argc, char **argv) {
if (!in_file) {
in_file = arg;
} else {
fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
return usage(arg0);
}
break;
case CmdVersion:
case CmdTargets:
fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
return usage(arg0);
case CmdInvalid:
zig_unreachable();
}
}
}

if (cur_pkg->parent != nullptr) {
fprintf(stderr, "Unmatched --pkg-begin\n");
return EXIT_FAILURE;
}

switch (cmd) {
case CmdBuild:
case CmdParseH:
Expand Down Expand Up @@ -579,6 +638,9 @@ int main(int argc, char **argv) {
if (out_file_h)
codegen_set_output_h_path(g, buf_create_from_str(out_file_h));


add_package(g, cur_pkg, g->root_package);

if (cmd == CmdBuild) {
for (size_t i = 0; i < objects.length; i += 1) {
codegen_add_object(g, buf_create_from_str(objects.at(i)));
Expand Down
29 changes: 26 additions & 3 deletions std/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,12 @@ pub const LibExeObjStep = struct {
name_only_filename: []const u8,
object_files: List([]const u8),
assembly_files: List([]const u8),
packages: List(Pkg),

const Pkg = struct {
name: []const u8,
path: []const u8,
};

const Kind = enum {
Exe,
Expand Down Expand Up @@ -736,6 +742,7 @@ pub const LibExeObjStep = struct {
.name_only_filename = undefined,
.object_files = List([]const u8).init(builder.allocator),
.assembly_files = List([]const u8).init(builder.allocator),
.packages = List(Pkg).init(builder.allocator),
};
self.computeOutFileNames();
return self;
Expand Down Expand Up @@ -835,6 +842,13 @@ pub const LibExeObjStep = struct {
%%self.object_files.append(obj.getOutputPath());
}

pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) {
%%self.packages.append(Pkg {
.name = name,
.path = pkg_index_path,
});
}

fn make(step: &Step) -> %void {
const self = @fieldParentPtr(LibExeObjStep, "step", step);
const builder = self.builder;
Expand Down Expand Up @@ -883,9 +897,11 @@ pub const LibExeObjStep = struct {
%%zig_args.append("--output");
%%zig_args.append(output_path);

const output_h_path = self.getOutputHPath();
%%zig_args.append("--output-h");
%%zig_args.append(builder.pathFromRoot(output_h_path));
if (self.kind != Kind.Exe) {
const output_h_path = self.getOutputHPath();
%%zig_args.append("--output-h");
%%zig_args.append(builder.pathFromRoot(output_h_path));
}

%%zig_args.append("--name");
%%zig_args.append(self.name);
Expand Down Expand Up @@ -929,6 +945,13 @@ pub const LibExeObjStep = struct {
}
}

for (self.packages.toSliceConst()) |pkg| {
%%zig_args.append("--pkg-begin");
%%zig_args.append(pkg.name);
%%zig_args.append(builder.pathFromRoot(pkg.path));
%%zig_args.append("--pkg-end");
}

for (builder.include_paths.toSliceConst()) |include_path| {
%%zig_args.append("-isystem");
%%zig_args.append(include_path);
Expand Down
1 change: 1 addition & 0 deletions test/build_examples.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ pub fn addCases(cases: &tests.BuildExamplesContext) {
cases.addBuildFile("example/shared_library/build.zig");
cases.addBuildFile("example/mix_o_files/build.zig");
cases.addBuildFile("test/standalone/issue_339/build.zig");
cases.addBuildFile("test/standalone/pkg_import/build.zig");
}
12 changes: 12 additions & 0 deletions test/standalone/pkg_import/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const Builder = @import("std").build.Builder;

pub fn build(b: &Builder) {
const exe = b.addExecutable("test", "test.zig");
exe.addPackagePath("my_pkg", "pkg.zig");

const run = b.addCommand(".", b.env_map, exe.getOutputPath(), [][]const u8{});
run.step.dependOn(&exe.step);

const test_step = b.step("test", "Test it");
test_step.dependOn(&run.step);
}
1 change: 1 addition & 0 deletions test/standalone/pkg_import/pkg.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub fn add(a: i32, b: i32) -> i32 { a + b }
6 changes: 6 additions & 0 deletions test/standalone/pkg_import/test.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const my_pkg = @import("my_pkg");
const assert = @import("std").debug.assert;

pub fn main() -> %void {
assert(my_pkg.add(10, 20) == 30);
}
2 changes: 1 addition & 1 deletion test/tests.zig
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ pub const BuildExamplesContext = struct {
pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) {
const b = self.b;

const annotated_case_name = b.fmt("build {}", build_file);
const annotated_case_name = b.fmt("build {} (debug)", build_file);
test (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null)
return;
Expand Down

0 comments on commit 3cbd006

Please sign in to comment.