Skip to content

Commit

Permalink
zig build system supports building a library
Browse files Browse the repository at this point in the history
See #329

Supporting work:
 * move std.cstr.Buffer0 to std.buffer.Buffer
 * add build.zig to example/shared_library/ and add an automated test
   for it
 * add std.list.List.resizeDown
 * improve std.os.makePath
   - no longer recursive
   - takes into account . and ..
 * add std.os.path.isAbsolute
 * add std.os.path.resolve
 * reimplement std.os.path.dirname
   - no longer requires an allocator
   - handles edge cases correctly
  • Loading branch information
andrewrk committed Apr 21, 2017
1 parent 599215c commit fb492d1
Show file tree
Hide file tree
Showing 17 changed files with 641 additions and 245 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})
install(FILES "${CMAKE_SOURCE_DIR}/std/base64.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/buf_map.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/buf_set.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/buffer.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")
install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")
Expand Down
20 changes: 20 additions & 0 deletions example/shared_library/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const Builder = @import("std").build.Builder;

pub fn build(b: &Builder) {
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));

const exe = b.addCExecutable("test");
exe.addCompileFlags([][]const u8 {
"-std=c99",
});
exe.addSourceFile("test.c");
exe.linkLibrary(lib);

b.default_step.dependOn(&exe.step);

const run_cmd = b.addCommand(b.out_dir, b.env_map, "./test", [][]const u8{});
run_cmd.step.dependOn(&exe.step);

const test_step = b.step("test", "Test the program");
test_step.dependOn(&run_cmd.step);
}
4 changes: 0 additions & 4 deletions example/shared_library/mathtest.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export fn add(a: i32, b: i32) -> i32 {
a + b
}

export fn hang() -> unreachable {
while (true) { }
}
4 changes: 2 additions & 2 deletions example/shared_library/test.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mathtest.h"
#include <stdio.h>
#include <assert.h>

int main(int argc, char **argv) {
printf("%d\n", add(42, 1137));
assert(add(42, 1337) == 1379);
return 0;
}
6 changes: 6 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
g->test_name_prefix = prefix;
}

void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch) {
g->version_major = major;
g->version_minor = minor;
g->version_patch = patch;
}

void codegen_set_is_test(CodeGen *g, bool is_test_build) {
g->is_test_build = is_test_build;
}
Expand Down
1 change: 1 addition & 0 deletions src/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void codegen_set_linker_script(CodeGen *g, const char *linker_script);
void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
void codegen_set_test_filter(CodeGen *g, Buf *filter);
void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);

PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
Expand Down
14 changes: 14 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ static int usage(const char *arg0) {
"Test Options:\n"
" --test-filter [text] skip tests that do not match filter\n"
" --test-name-prefix [text] add prefix to all tests\n"
"Dynamic Library Options:\n"
" --ver-major [ver] semver major version\n"
" --ver-minor [ver] semver minor version\n"
" --ver-patch [ver] semver patch version\n"
, arg0);
return EXIT_FAILURE;
}
Expand Down Expand Up @@ -156,6 +160,9 @@ int main(int argc, char **argv) {
ZigList<const char *> objects = {0};
const char *test_filter = nullptr;
const char *test_name_prefix = nullptr;
size_t ver_major = 0;
size_t ver_minor = 0;
size_t ver_patch = 0;

if (argc >= 2 && strcmp(argv[1], "build") == 0) {
const char *zig_exe_path = arg0;
Expand Down Expand Up @@ -350,6 +357,12 @@ int main(int argc, char **argv) {
test_filter = argv[i];
} else if (strcmp(arg, "--test-name-prefix") == 0) {
test_name_prefix = argv[i];
} else if (strcmp(arg, "--ver-major") == 0) {
ver_major = atoi(argv[i]);
} else if (strcmp(arg, "--ver-minor") == 0) {
ver_minor = atoi(argv[i]);
} else if (strcmp(arg, "--ver-patch") == 0) {
ver_patch = atoi(argv[i]);
} else {
fprintf(stderr, "Invalid argument: %s\n", arg);
return usage(arg0);
Expand Down Expand Up @@ -509,6 +522,7 @@ int main(int argc, char **argv) {
}

CodeGen *g = codegen_create(&root_source_dir, target);
codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
codegen_set_is_release(g, is_release_build);
codegen_set_is_test(g, cmd == CmdTest);
codegen_set_linker_script(g, linker_script);
Expand Down
117 changes: 117 additions & 0 deletions std/buffer.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const debug = @import("debug.zig");
const mem = @import("mem.zig");
const Allocator = mem.Allocator;
const assert = debug.assert;
const List = @import("list.zig").List;

/// A buffer that allocates memory and maintains a null byte at the end.
pub const Buffer = struct {
list: List(u8),

/// Must deinitialize with deinit.
pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {
var self = %return initSize(allocator, m.len);
mem.copy(u8, self.list.items, m);
return self;
}

/// Must deinitialize with deinit.
pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {
var self = initNull(allocator);
%return self.resize(size);
return self;
}

/// Must deinitialize with deinit.
/// None of the other operations are valid until you do one of these:
/// * ::replaceContents
/// * ::replaceContentsBuffer
/// * ::resize
pub fn initNull(allocator: &Allocator) -> Buffer {
Buffer {
.list = List(u8).init(allocator),
}
}

/// Must deinitialize with deinit.
pub fn initFromBuffer(buffer: &const Buffer) -> %Buffer {
return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
}

pub fn deinit(self: &Buffer) {
self.list.deinit();
}

pub fn toSlice(self: &Buffer) -> []u8 {
return self.list.toSlice()[0...self.len()];
}

pub fn toSliceConst(self: &const Buffer) -> []const u8 {
return self.list.toSliceConst()[0...self.len()];
}

pub fn resize(self: &Buffer, new_len: usize) -> %void {
%return self.list.resize(new_len + 1);
self.list.items[self.len()] = 0;
}

pub fn isNull(self: &const Buffer) -> bool {
return self.list.len == 0;
}

pub fn len(self: &const Buffer) -> usize {
return self.list.len - 1;
}

pub fn append(self: &Buffer, m: []const u8) -> %void {
const old_len = self.len();
%return self.resize(old_len + m.len);
mem.copy(u8, self.list.toSlice()[old_len...], m);
}

pub fn appendByte(self: &Buffer, byte: u8) -> %void {
%return self.resize(self.len() + 1);
self.list.items[self.len() - 1] = byte;
}

pub fn eql(self: &const Buffer, m: []const u8) -> bool {
mem.eql(u8, self.toSliceConst(), m)
}

pub fn startsWith(self: &const Buffer, m: []const u8) -> bool {
if (self.len() < m.len) return false;
return mem.eql(u8, self.list.items[0...m.len], m);
}

pub fn endsWith(self: &const Buffer, m: []const u8) -> bool {
const l = self.len();
if (l < m.len) return false;
const start = l - m.len;
return mem.eql(u8, self.list.items[start...], m);
}

pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {
%return self.resize(m.len);
mem.copy(u8, self.list.toSlice(), m);
}
};

test "simple Buffer" {
const cstr = @import("cstr.zig");

var buf = %%Buffer.init(&debug.global_allocator, "");
assert(buf.len() == 0);
%%buf.append("hello");
%%buf.appendByte(' ');
%%buf.append("world");
assert(buf.eql("hello world"));
assert(mem.eql(u8, cstr.toSliceConst(buf.toSliceConst().ptr), buf.toSliceConst()));

var buf2 = %%Buffer.initFromBuffer(&buf);
assert(buf.eql(buf2.toSliceConst()));

assert(buf.startsWith("hell"));

%%buf2.resize(4);
assert(buf.startsWith(buf2.toSliceConst()));
}
Loading

0 comments on commit fb492d1

Please sign in to comment.