diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig index 5f1d34cbe9f95c8dc8536231d7fdfe09b3eaeaf0..bbf9044814e18fff0bb51c4710ffbfa9ba34b32b 100644 --- a/lib/compiler/Maker.zig +++ b/lib/compiler/Maker.zig @@ -44,7 +44,8 @@ pub const std_options: std.Options = .{ gpa: Allocator, graph: *Graph, -install_paths: InstallPaths, +install_paths: PrefixPaths, +deployed_paths: PrefixPaths, scanned_config: *const ScannedConfig, /// Includes an extra auto-generated placeholder Step at the end that indicates /// configure must be rerun. It is done this way so that the hot path of file @@ -95,7 +96,7 @@ const use_safe_allocator = switch (builtin.mode) { .fast, .small => false, }; -const InstallPaths = struct { +const PrefixPaths = struct { prefix: Path, lib: Path, bin: Path, @@ -692,42 +693,62 @@ pub fn main(init: process.Init.Minimal) !void { }); defer main_progress_node.end(); - const install_prefix_path: Path = if (graph.environ_map.get("DESTDIR")) |dest_dir| .{ - .root_dir = .cwd(), - .sub_path = try Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }), - } else if (override_install_prefix) |cwd_relative| .{ - .root_dir = .cwd(), - .sub_path = cwd_relative, - } else .{ - .root_dir = graph.build_root_directory, - .sub_path = "zig-out", + const deployed_paths: PrefixPaths = blk: { + const prefix: Path = if (override_install_prefix) |cwd_relative| .{ + .root_dir = .cwd(), + .sub_path = cwd_relative, + } else if (graph.environ_map.get("DESTDIR") != null) .{ + .root_dir = .cwd(), + .sub_path = "/usr", + } else .{ + .root_dir = graph.build_root_directory, + .sub_path = "zig-out", + }; + break :blk .{ + .prefix = prefix, + // The lib/bin/include overrides are interpreted relative to the + // install prefix unless absolute paths are used. + .lib = if (override_lib_dir) |lib_dir| + if (Dir.path.isAbsolute(lib_dir)) .{ + .root_dir = .cwd(), + .sub_path = lib_dir, + } else try prefix.join(arena, lib_dir) + else + try prefix.join(arena, "lib"), + .bin = if (override_bin_dir) |bin_dir| + if (Dir.path.isAbsolute(bin_dir)) .{ + .root_dir = .cwd(), + .sub_path = bin_dir, + } else try prefix.join(arena, bin_dir) + else + try prefix.join(arena, "bin"), + .include = if (override_include_dir) |include_dir| + if (Dir.path.isAbsolute(include_dir)) .{ + .root_dir = .cwd(), + .sub_path = include_dir, + } else try prefix.join(arena, include_dir) + else + try prefix.join(arena, "include"), + }; }; - - // These three overrides are meant to be relative to the install prefix, - // not current working directory, unless absolute paths are used. - const install_lib_path: Path = if (override_lib_dir) |lib_dir| - if (Dir.path.isAbsolute(lib_dir)) .{ + const install_paths: PrefixPaths = if (graph.environ_map.get("DESTDIR")) |destdir| .{ + .prefix = .{ .root_dir = .cwd(), - .sub_path = lib_dir, - } else try install_prefix_path.join(arena, lib_dir) - else - try install_prefix_path.join(arena, "lib"); - - const install_bin_path: Path = if (override_bin_dir) |bin_dir| - if (Dir.path.isAbsolute(bin_dir)) .{ + .sub_path = try Dir.path.join(arena, &.{ destdir, deployed_paths.prefix.sub_path }), + }, + .lib = .{ .root_dir = .cwd(), - .sub_path = bin_dir, - } else try install_prefix_path.join(arena, bin_dir) - else - try install_prefix_path.join(arena, "bin"); - - const install_include_path: Path = if (override_include_dir) |include_dir| - if (Dir.path.isAbsolute(include_dir)) .{ + .sub_path = try Dir.path.join(arena, &.{ destdir, deployed_paths.lib.sub_path }), + }, + .bin = .{ .root_dir = .cwd(), - .sub_path = include_dir, - } else try install_prefix_path.join(arena, include_dir) - else - try install_prefix_path.join(arena, "include"); + .sub_path = try Dir.path.join(arena, &.{ destdir, deployed_paths.bin.sub_path }), + }, + .include = .{ + .root_dir = .cwd(), + .sub_path = try Dir.path.join(arena, &.{ destdir, deployed_paths.include.sub_path }), + }, + } else deployed_paths; const now = Io.Clock.Timestamp.now(io, .awake); @@ -830,12 +851,8 @@ pub fn main(init: process.Init.Minimal) !void { .gpa = gpa, .graph = &graph, .scanned_config = &scanned_config, - .install_paths = .{ - .prefix = install_prefix_path, - .lib = install_lib_path, - .bin = install_bin_path, - .include = install_include_path, - }, + .install_paths = install_paths, + .deployed_paths = deployed_paths, .steps = &.{}, .generated_files = &.{}, @@ -4099,6 +4116,10 @@ pub fn relativePath( .install_lib => try maker.install_paths.lib.join(arena, sub_path), .install_bin => try maker.install_paths.bin.join(arena, sub_path), .install_include => try maker.install_paths.include.join(arena, sub_path), + .deployed_prefix => try maker.deployed_paths.prefix.join(arena, sub_path), + .deployed_lib => try maker.deployed_paths.lib.join(arena, sub_path), + .deployed_bin => try maker.deployed_paths.bin.join(arena, sub_path), + .deployed_include => try maker.deployed_paths.include.join(arena, sub_path), .libc_runtimes => if (maker.graph.libc_runtimes_dir) |libc_runtimes_dir| .{ .root_dir = .cwd(), .sub_path = try Dir.path.join(arena, &.{ libc_runtimes_dir, sub_path }), @@ -4708,6 +4729,10 @@ fn confPathDepToCachePath( .install_lib => @panic("TODO"), .install_bin => @panic("TODO"), .install_include => @panic("TODO"), + .deployed_prefix => @panic("TODO"), + .deployed_lib => @panic("TODO"), + .deployed_bin => @panic("TODO"), + .deployed_include => @panic("TODO"), .libc_runtimes => @panic("TODO"), }; } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index ec2f57d2911a681571e9116ab48828868642e637..86f36b3722e359c1076236d16cce94d3b900b369 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2760,6 +2760,10 @@ fn validateConfigureDependency(lazy_path: LazyPath) void { .install_lib, .install_bin, .install_include, + .deployed_prefix, + .deployed_lib, + .deployed_bin, + .deployed_include, => @panic("configure phase cannot depend on files installed during make phase"), .libc_runtimes, => @panic("configure phase cannot depend on directory known only during make phase"), diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index ee7b77085b177a456bacbe6115619197c0d86e49..e85e19cd1e7d7ba37128ab208de61e4e39690a3e 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -1607,6 +1607,13 @@ pub const LazyPath = union(@This().Tag) { _: u16 = 0, }; + /// The deployed_prefix and related paths exist to support the use-case + /// of embedding absolute paths to other build artifacts in the build + /// artifacts themselves. For example pkg-config files are artifacts + /// which must contain absolute paths to the other library/header + /// artifacts they describe. Note that this feature is only supported to + /// faciliate interoperability with such legacy systems. In general, + /// embedding absolute paths in build artifacts should be avoided. pub const Base = enum(u8) { cwd, local_cache, @@ -1615,10 +1622,33 @@ pub const LazyPath = union(@This().Tag) { build_root, zig_exe, zig_lib, + + /// Path that artifacts will be written to by the build system. + /// Equivalent to $DESTDIR/deployed_prefix if $DESTDIR is set. install_prefix, + /// Path that artifacts will be written to by the build system. + /// Equivalent to $DESTDIR/deployed_lib if $DESTDIR is set. install_lib, + /// Path that artifacts will be written to by the build system. + /// Equivalent to $DESTDIR/deployed_bin if $DESTDIR is set. install_bin, + /// Path that artifacts will be written to by the build system. + /// Equivalent to $DESTDIR/deployed_include if $DESTDIR is set. install_include, + + /// Path that artifacts will be deployed to on the target system. + /// Unaffected by $DESTDIR. + deployed_prefix, + /// Path that artifacts will be deployed to on the target system. + /// Unaffected by $DESTDIR. + deployed_lib, + /// Path that artifacts will be deployed to on the target system. + /// Unaffected by $DESTDIR. + deployed_bin, + /// Path that artifacts will be deployed to on the target system. + /// Unaffected by $DESTDIR. + deployed_include, + libc_runtimes, }; };