| ... | @@ -21,7 +21,9 @@ error NeedAnObject; | ... | @@ -21,7 +21,9 @@ error NeedAnObject; |
| 21 | | 21 | |
| 22 | pub const Builder = struct { | 22 | pub 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 default | 129 | 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 | } |
| 123 | | 133 | |
| 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 | } |
| 232 | | 242 | |
| | 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); |
| 245 | | 264 | |
| 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 | } |
| 249 | | 271 | |
| ... | @@ -530,24 +552,38 @@ pub const Builder = struct { | ... | @@ -530,24 +552,38 @@ pub const Builder = struct { |
| 530 | }; | 552 | }; |
| 531 | } | 553 | } |
| 532 | | 554 | |
| 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 | } |
| 539 | | 558 | |
| 540 | ///::dest_rel_path is relative to prefix path | 559 | 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); |
| 544 | | 580 | |
| 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 | } |
| 549 | | 585 | |
| 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 | }; |
| 1390 | | 1426 | |
| 1391 | pub const InstallCLibraryStep = struct { | 1427 | pub 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, |
| 1396 | | 1432 | |
| 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 | } |
| 1412 | | 1454 | |
| 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; |
| 1416 | | 1458 | |
| 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 | }; |