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;...@@ -21,7 +21,9 @@ error NeedAnObject;
2121
22pub const Builder = struct {22pub const Builder = struct {
23 uninstall_tls: TopLevelStep,23 uninstall_tls: TopLevelStep,
24 install_tls: TopLevelStep,
24 have_uninstall_step: bool,25 have_uninstall_step: bool,
26 have_install_step: bool,
25 allocator: &Allocator,27 allocator: &Allocator,
26 lib_paths: List([]const u8),28 lib_paths: List([]const u8),
27 include_paths: List([]const u8),29 include_paths: List([]const u8),
...@@ -37,6 +39,7 @@ pub const Builder = struct {...@@ -37,6 +39,7 @@ pub const Builder = struct {
37 top_level_steps: List(&TopLevelStep),39 top_level_steps: List(&TopLevelStep),
38 prefix: []const u8,40 prefix: []const u8,
39 lib_dir: []const u8,41 lib_dir: []const u8,
42 exe_dir: []const u8,
40 installed_files: List([]const u8),43 installed_files: List([]const u8),
41 build_root: []const u8,44 build_root: []const u8,
42 cache_root: []const u8,45 cache_root: []const u8,
...@@ -96,12 +99,18 @@ pub const Builder = struct {...@@ -96,12 +99,18 @@ pub const Builder = struct {
96 .env_map = %%os.getEnvMap(allocator),99 .env_map = %%os.getEnvMap(allocator),
97 .prefix = undefined,100 .prefix = undefined,
98 .lib_dir = undefined,101 .lib_dir = undefined,
102 .exe_dir = undefined,
99 .installed_files = List([]const u8).init(allocator),103 .installed_files = List([]const u8).init(allocator),
100 .uninstall_tls = TopLevelStep {104 .uninstall_tls = TopLevelStep {
101 .step = Step.init("uninstall", allocator, makeUninstall),105 .step = Step.init("uninstall", allocator, makeUninstall),
102 .description = "Remove build artifacts from prefix path",106 .description = "Remove build artifacts from prefix path",
103 },107 },
104 .have_uninstall_step = false,108 .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,
105 };114 };
106 self.processNixOSEnvVars();115 self.processNixOSEnvVars();
107 self.default_step = self.step("default", "Build the project");116 self.default_step = self.step("default", "Build the project");
...@@ -119,6 +128,7 @@ pub const Builder = struct {...@@ -119,6 +128,7 @@ pub const Builder = struct {
119 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {128 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {
120 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default129 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default
121 self.lib_dir = %%os.path.join(self.allocator, self.prefix, "lib");130 self.lib_dir = %%os.path.join(self.allocator, self.prefix, "lib");
131 self.exe_dir = %%os.path.join(self.allocator, self.prefix, "bin");
122 }132 }
123133
124 pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {134 pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {
...@@ -230,6 +240,15 @@ pub const Builder = struct {...@@ -230,6 +240,15 @@ pub const Builder = struct {
230 }240 }
231 }241 }
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
233 pub fn getUninstallStep(self: &Builder) -> &Step {252 pub fn getUninstallStep(self: &Builder) -> &Step {
234 if (self.have_uninstall_step)253 if (self.have_uninstall_step)
235 return &self.uninstall_tls.step;254 return &self.uninstall_tls.step;
...@@ -244,6 +263,9 @@ pub const Builder = struct {...@@ -244,6 +263,9 @@ pub const Builder = struct {
244 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);263 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
245264
246 for (self.installed_files.toSliceConst()) |installed_file| {265 for (self.installed_files.toSliceConst()) |installed_file| {
266 if (self.verbose) {
267 %%io.stderr.printf("rm {}\n", installed_file);
268 }
247 _ = os.deleteFile(self.allocator, installed_file);269 _ = os.deleteFile(self.allocator, installed_file);
248 }270 }
249271
...@@ -530,24 +552,38 @@ pub const Builder = struct {...@@ -530,24 +552,38 @@ pub const Builder = struct {
530 };552 };
531 }553 }
532554
533 pub fn installCLibrary(self: &Builder, lib: &CLibExeObjStep) -> &InstallCLibraryStep {555 pub fn installCLibrary(self: &Builder, lib: &CLibExeObjStep) {
534 const install_step = %%self.allocator.create(InstallCLibraryStep);556 self.getInstallStep().dependOn(&self.addInstallCLibrary(lib).step);
535 *install_step = InstallCLibraryStep.init(self, lib);
536 install_step.step.dependOn(&lib.step);
537 return install_step;
538 }557 }
539558
540 ///::dest_rel_path is relative to prefix path559 pub fn addInstallCLibrary(self: &Builder, lib: &CLibExeObjStep) -> &InstallCArtifactStep {
541 pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) -> &InstallFileStep {560 return InstallCArtifactStep.create(self, lib);
542 const full_dest_path = %%os.path.join(self.allocator, self.prefix, dest_rel_path);561 }
543 self.addInstalledFile(full_dest_path);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
545 const install_step = %%self.allocator.create(InstallFileStep);581 const install_step = %%self.allocator.create(InstallFileStep);
546 *install_step = InstallFileStep.init(self, src_path, full_dest_path);582 *install_step = InstallFileStep.init(self, src_path, full_dest_path);
547 return install_step;583 return install_step;
548 }584 }
549585
550 pub fn addInstalledFile(self: &Builder, full_path: []const u8) {586 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) {
551 _ = self.getUninstallStep();587 _ = self.getUninstallStep();
552 %%self.installed_files.append(full_path);588 %%self.installed_files.append(full_path);
553 }589 }
...@@ -1388,36 +1424,42 @@ pub const CommandStep = struct {...@@ -1388,36 +1424,42 @@ pub const CommandStep = struct {
1388 }1424 }
1389};1425};
13901426
1391pub const InstallCLibraryStep = struct {1427pub const InstallCArtifactStep = struct {
1392 step: Step,1428 step: Step,
1393 builder: &Builder,1429 builder: &Builder,
1394 lib: &CLibExeObjStep,1430 artifact: &CLibExeObjStep,
1395 dest_file: []const u8,1431 dest_file: []const u8,
13961432
1397 pub fn init(builder: &Builder, lib: &CLibExeObjStep) -> InstallCLibraryStep {1433 pub fn create(builder: &Builder, artifact: &CLibExeObjStep) -> &InstallCArtifactStep {
1398 var self = InstallCLibraryStep {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 {
1399 .builder = builder,1441 .builder = builder,
1400 .step = Step.init(builder.fmt("install {}", lib.step.name), builder.allocator, make),1442 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
1401 .lib = lib,1443 .artifact = artifact,
1402 .dest_file = undefined,1444 .dest_file = %%os.path.join(builder.allocator, builder.lib_dir, artifact.out_filename),
1403 };1445 };
1404 self.dest_file = %%os.path.join(builder.allocator, builder.lib_dir, lib.out_filename);1446 self.step.dependOn(&artifact.step);
1405 builder.addInstalledFile(self.dest_file);1447 builder.pushInstalledFile(self.dest_file);
1406 if (!self.lib.static) {1448 if (self.artifact.kind == CLibExeObjStep.Kind.Lib and !self.artifact.static) {
1407 builder.addInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, lib.major_only_filename));1449 builder.pushInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, artifact.major_only_filename));
1408 builder.addInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, lib.name_only_filename));1450 builder.pushInstalledFile(%%os.path.join(builder.allocator, builder.lib_dir, artifact.name_only_filename));
1409 }1451 }
1410 return self;1452 return self;
1411 }1453 }
14121454
1413 fn make(step: &Step) -> %void {1455 fn make(step: &Step) -> %void {
1414 const self = @fieldParentPtr(InstallCLibraryStep, "step", step);1456 const self = @fieldParentPtr(InstallCArtifactStep, "step", step);
1415 const builder = self.builder;1457 const builder = self.builder;
14161458
1417 self.builder.copyFile(self.lib.getOutputPath(), self.dest_file);1459 builder.copyFile(self.artifact.getOutputPath(), self.dest_file);
1418 if (!self.lib.static) {1460 if (self.artifact.kind == CLibExeObjStep.Kind.Lib and !self.artifact.static) {
1419 %return doAtomicSymLinks(self.builder.allocator, self.dest_file, self.lib.major_only_filename,1461 %return doAtomicSymLinks(builder.allocator, self.dest_file,
1420 self.lib.name_only_filename);1462 self.artifact.major_only_filename, self.artifact.name_only_filename);
1421 }1463 }
1422 }1464 }
1423};1465};