From 38a04a267c11fdedc62102ab8e5989cafa3073ef Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 30 Apr 2017 13:01:35 -0400 Subject: [PATCH] zig build: when compiling C files put .o files in cache dir See #328 --- std/build.zig | 32 ++++++++++++++++++++++---------- std/os/path.zig | 2 +- std/special/build_runner.zig | 7 ++++++- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/std/build.zig b/std/build.zig index 89079f722f..60600b5ac0 100644 --- a/std/build.zig +++ b/std/build.zig @@ -284,7 +284,7 @@ pub const Builder = struct { return &top_level_step.step; } } - %%io.stderr.printf("Cannot run step '{}' because it does not exist.", name); + %%io.stderr.printf("Cannot run step '{}' because it does not exist\n", name); return error.InvalidStepName; } @@ -529,6 +529,13 @@ pub const Builder = struct { } + pub fn makePath(self: &Builder, path: []const u8) -> %void { + os.makePath(self.allocator, path) %% |err| { + %%io.stderr.printf("Unable to create path {}: {}\n", path, @errorName(err)); + return err; + }; + } + pub fn installCLibrary(self: &Builder, lib: &CLibrary) -> &InstallCLibraryStep { const install_step = %%self.allocator.create(InstallCLibraryStep); *install_step = InstallCLibraryStep.init(self, lib); @@ -1090,11 +1097,13 @@ pub const CLibrary = struct { %%cc_args.append("-c"); %%cc_args.append(source_file); - // TODO don't dump the .o file in the same place as the source file - const o_file = builder.fmt("{}{}", source_file, self.target.oFileExt()); - defer builder.allocator.free(o_file); + const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file); + const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path); + const cache_o_dir = os.path.dirname(cache_o_src); + %return builder.makePath(cache_o_dir); + const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); %%cc_args.append("-o"); - %%cc_args.append(o_file); + %%cc_args.append(cache_o_file); for (self.cflags.toSliceConst()) |cflag| { %%cc_args.append(cflag); @@ -1107,7 +1116,7 @@ pub const CLibrary = struct { %return builder.spawnChild(cc, cc_args.toSliceConst()); - %%self.object_files.append(o_file); + %%self.object_files.append(cache_o_file); } if (self.static) { @@ -1248,10 +1257,13 @@ pub const CExecutable = struct { %%cc_args.append(builder.pathFromRoot(source_file)); // TODO don't dump the .o file in the same place as the source file - const o_file = builder.fmt("{}{}", source_file, self.target.oFileExt()); - defer builder.allocator.free(o_file); + const rel_src_path = %%os.path.relative(builder.allocator, builder.build_root, source_file); + const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, rel_src_path); + const cache_o_dir = os.path.dirname(cache_o_src); + %return builder.makePath(cache_o_dir); + const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); %%cc_args.append("-o"); - %%cc_args.append(o_file); + %%cc_args.append(cache_o_file); for (self.cflags.toSliceConst()) |cflag| { %%cc_args.append(cflag); @@ -1264,7 +1276,7 @@ pub const CExecutable = struct { %return builder.spawnChild(cc, cc_args.toSliceConst()); - %%self.object_files.append(o_file); + %%self.object_files.append(cache_o_file); } %%cc_args.resize(0); diff --git a/std/os/path.zig b/std/os/path.zig index 9b86efe509..b3de010d43 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -17,7 +17,7 @@ pub const delimiter = switch (@compileVar("os")) { /// Naively combines a series of paths with the native path seperator. /// Allocates memory for the result, which must be freed by the caller. pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 { - assert(paths.len >= 2); + comptime assert(paths.len >= 2); var total_paths_len: usize = paths.len; // 1 slash per path { comptime var path_i = 0; diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index a374194fe3..374caf003d 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -95,7 +95,12 @@ pub fn main() -> %void { if (builder.validateUserInputDidItFail()) return usage(&builder, true, &io.stderr); - %return builder.make(targets.toSliceConst()); + builder.make(targets.toSliceConst()) %% |err| { + if (err == error.InvalidStepName) { + return usage(&builder, true, &io.stderr); + } + return err; + }; } fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> %void {