authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-30 21:03:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-30 21:03:23-04:00
log943dbe5b5098b243cea5e174cc2238f24d884253
tree40d385a3c30900b6dbd79ae51d53d6b7fa86ddc9
parent97f6b6093c082c232c0769d2e82e7503c7891248

zig build: improved API for installing C build artifacts

see #332

1 files changed, 69 insertions(+), 27 deletions(-)

std/build.zig+69-27
......@@ -21,7 +21,9 @@ error NeedAnObject;
2121
2222pub const Builder = struct {
2323 uninstall_tls: TopLevelStep,
24 install_tls: TopLevelStep,
2425 have_uninstall_step: bool,
26 have_install_step: bool,
2527 allocator: &Allocator,
2628 lib_paths: List([]const u8),
2729 include_paths: List([]const u8),
......@@ -37,6 +39,7 @@ pub const Builder = struct {
3739 top_level_steps: List(&TopLevelStep),
3840 prefix: []const u8,
3941 lib_dir: []const u8,
42 exe_dir: []const u8,
4043 installed_files: List([]const u8),
4144 build_root: []const u8,
4245 cache_root: []const u8,
......@@ -96,12 +99,18 @@ pub const Builder = struct {
9699 .env_map = %%os.getEnvMap(allocator),
97100 .prefix = undefined,
98101 .lib_dir = undefined,
102 .exe_dir = undefined,
99103 .installed_files = List([]const u8).init(allocator),
100104 .uninstall_tls = TopLevelStep {
101105 .step = Step.init("uninstall", allocator, makeUninstall),
102106 .description = "Remove build artifacts from prefix path",
103107 },
104108 .have_uninstall_step = false,
109 .install_tls = TopLevelStep {
110 .step = Step.initNoOp("install", allocator),
111 .description = "Copy build artifacts to prefix path",
112 },
113 .have_install_step = false,
105114 };
106115 self.processNixOSEnvVars();
107116 self.default_step = self.step("default", "Build the project");
......@@ -119,6 +128,7 @@ pub const Builder = struct {
119128 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {
120129 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default
121130 self.lib_dir = %%os.path.join(self.allocator, self.prefix, "lib");
131 self.exe_dir = %%os.path.join(self.allocator, self.prefix, "bin");
122132 }
123133
124134 pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
......@@ -230,6 +240,15 @@ pub const Builder = struct {
230240 }
231241 }
232242
243 pub fn getInstallStep(self: &Builder) -> &Step {
244 if (self.have_install_step)
245 return &self.install_tls.step;
246
247 %%self.top_level_steps.append(&self.install_tls);
248 self.have_install_step = true;
249 return &self.install_tls.step;
250 }
251
233252 pub fn getUninstallStep(self: &Builder) -> &Step {
234253 if (self.have_uninstall_step)
235254 return &self.uninstall_tls.step;
......@@ -244,6 +263,9 @@ pub const Builder = struct {
244263 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
245264
246265 for (self.installed_files.toSliceConst()) |installed_file| {
266 if (self.verbose) {
267 %%io.stderr.printf("rm {}\n", installed_file);
268 }
247269 _ = os.deleteFile(self.allocator, installed_file);
248270 }
249271
......@@ -530,24 +552,38 @@ pub const Builder = struct {
530552 };
531553 }
532554
533 pub fn installCLibrary(self: &Builder, lib: &CLibExeObjStep) -> &InstallCLibraryStep {
534 const install_step = %%self.allocator.create(InstallCLibraryStep);
535 *install_step = InstallCLibraryStep.init(self, lib);
536 install_step.step.dependOn(&lib.step);
537 return install_step;
555 pub fn installCLibrary(self: &Builder, lib: &CLibExeObjStep) {
556 self.getInstallStep().dependOn(&self.addInstallCLibrary(lib).step);
538557 }
539558
540 ///::dest_rel_path is relative to prefix path
541 pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) -> &InstallFileStep {
542 const full_dest_path = %%os.path.join(self.allocator, self.prefix, dest_rel_path);
543 self.addInstalledFile(full_dest_path);
559 pub fn addInstallCLibrary(self: &Builder, lib: &CLibExeObjStep) -> &InstallCArtifactStep {
560 return InstallCArtifactStep.create(self, lib);
561 }
562
563 pub fn installCExecutable(self: &Builder, exe: &CLibExeObjStep) {
564 self.getInstallStep().dependOn(&self.addInstallCExecutable(exe).step);
565 }
566
567 pub fn addInstallCExecutable(self: &Builder, exe: &CLibExeObjStep) -> &InstallCArtifactStep {
568 return InstallCArtifactStep.create(self, exe);
569 }
570
571 ///::dest_rel_path is relative to prefix path or it can be an absolute path
572 pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) {
573 self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step);
574 }
575
576 ///::dest_rel_path is relative to prefix path or it can be an absolute path
577 pub fn addInstallFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) -> &InstallFileStep {
578 const full_dest_path = %%os.path.resolve(self.allocator, self.prefix, dest_rel_path);
579 self.pushInstalledFile(full_dest_path);
544580
545581 const install_step = %%self.allocator.create(InstallFileStep);
546582 *install_step = InstallFileStep.init(self, src_path, full_dest_path);
547583 return install_step;
548584 }
549585
550 pub fn addInstalledFile(self: &Builder, full_path: []const u8) {
586 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) {
551587 _ = self.getUninstallStep();
552588 %%self.installed_files.append(full_path);
553589 }
......@@ -1388,36 +1424,42 @@ pub const CommandStep = struct {
13881424 }
13891425};
13901426
1391pub const InstallCLibraryStep = struct {
1427pub const InstallCArtifactStep = struct {
13921428 step: Step,
13931429 builder: &Builder,
1394 lib: &CLibExeObjStep,
1430 artifact: &CLibExeObjStep,
13951431 dest_file: []const u8,
13961432
1397 pub fn init(builder: &Builder, lib: &CLibExeObjStep) -> InstallCLibraryStep {
1398 var self = InstallCLibraryStep {
1433 pub fn create(builder: &Builder, artifact: &CLibExeObjStep) -> &InstallCArtifactStep {
1434 const self = %%builder.allocator.create(InstallCArtifactStep);
1435 const dest_dir = switch (artifact.kind) {
1436 CLibExeObjStep.Kind.Obj => unreachable,
1437 CLibExeObjStep.Kind.Exe => builder.exe_dir,
1438 CLibExeObjStep.Kind.Lib => builder.lib_dir,
1439 };
1440 *self = InstallCArtifactStep {
13991441 .builder = builder,
1400 .step = Step.init(builder.fmt("install {}", lib.step.name), builder.allocator, make),
1401 .lib = lib,
1402 .dest_file = undefined,
1442 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
1443 .artifact = artifact,
1444 .dest_file = %%os.path.join(builder.allocator, builder.lib_dir, artifact.out_filename),
14031445 };
1404 self.dest_file = %%os.path.join(builder.allocator, builder.lib_dir, lib.out_filename);
1405 builder.addInstalledFile(self.dest_file);
1406 if (!self.lib.static) {
1407 builder.addInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, lib.major_only_filename));
1408 builder.addInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, lib.name_only_filename));
1446 self.step.dependOn(&artifact.step);
1447 builder.pushInstalledFile(self.dest_file);
1448 if (self.artifact.kind == CLibExeObjStep.Kind.Lib and !self.artifact.static) {
1449 builder.pushInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, artifact.major_only_filename));
1450 builder.pushInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, artifact.name_only_filename));
14091451 }
14101452 return self;
14111453 }
14121454
14131455 fn make(step: &Step) -> %void {
1414 const self = @fieldParentPtr(InstallCLibraryStep, "step", step);
1456 const self = @fieldParentPtr(InstallCArtifactStep, "step", step);
14151457 const builder = self.builder;
14161458
1417 self.builder.copyFile(self.lib.getOutputPath(), self.dest_file);
1418 if (!self.lib.static) {
1419 %return doAtomicSymLinks(self.builder.allocator, self.dest_file, self.lib.major_only_filename,
1420 self.lib.name_only_filename);
1459 builder.copyFile(self.artifact.getOutputPath(), self.dest_file);
1460 if (self.artifact.kind == CLibExeObjStep.Kind.Lib and !self.artifact.static) {
1461 %return doAtomicSymLinks(builder.allocator, self.dest_file,
1462 self.artifact.major_only_filename, self.artifact.name_only_filename);
14211463 }
14221464 }
14231465};