zig build system: change target, compilation, and module APIs

Introduce the concept of "target query" and "resolved target". A target
query is what the user specifies, with some things left to default. A
resolved target has the default things discovered and populated.
In the future, std.zig.CrossTarget will be rename to std.Target.Query.
Introduces `std.Build.resolveTargetQuery` to get from one to the other.

The concept of `main_mod_path` is gone, no longer supported. You have to
put the root source file at the module root now.

* remove deprecated API
* update build.zig for the breaking API changes in this branch
* move std.Build.Step.Compile.BuildId to std.zig.BuildId
* add more options to std.Build.ExecutableOptions, std.Build.ObjectOptions,
  std.Build.SharedLibraryOptions, std.Build.StaticLibraryOptions, and
  std.Build.TestOptions.
* remove `std.Build.constructCMacro`. There is no use for this API.
* deprecate `std.Build.Step.Compile.defineCMacro`. Instead,
  `std.Build.Module.addCMacro` is provided.
  - remove `std.Build.Step.Compile.defineCMacroRaw`.
* deprecate `std.Build.Step.Compile.linkFrameworkNeeded`
  - use `std.Build.Module.linkFramework`
* deprecate `std.Build.Step.Compile.linkFrameworkWeak`
  - use `std.Build.Module.linkFramework`
* move more logic into `std.Build.Module`
* allow `target` and `optimize` to be `null` when creating a Module.
  Along with other fields, those unspecified options will be inherited
  from parent `Module` when inserted into an import table.
* the `target` field of `addExecutable` is now required. pass `b.host`
  to get the host target.
This commit is contained in:
Andrew Kelley 2023-12-02 21:51:34 -07:00
parent 579f572cf2
commit 142471fcc4
122 changed files with 1809 additions and 1335 deletions

View File

@ -39,10 +39,10 @@ pub fn build(b: *std.Build) !void {
const docgen_exe = b.addExecutable(.{
.name = "docgen",
.root_source_file = .{ .path = "tools/docgen.zig" },
.target = .{},
.target = b.host,
.optimize = .Debug,
.single_threaded = single_threaded,
});
docgen_exe.single_threaded = single_threaded;
const docgen_cmd = b.addRunArtifact(docgen_exe);
docgen_cmd.addArgs(&.{ "--zig", b.zig_exe });
@ -89,11 +89,11 @@ pub fn build(b: *std.Build) !void {
const check_case_exe = b.addExecutable(.{
.name = "check-case",
.root_source_file = .{ .path = "test/src/Cases.zig" },
.target = b.host,
.optimize = optimize,
.main_mod_path = .{ .path = "." },
.single_threaded = single_threaded,
});
check_case_exe.stack_size = stack_size;
check_case_exe.single_threaded = single_threaded;
const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;
const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
@ -194,14 +194,18 @@ pub fn build(b: *std.Build) !void {
break :blk 4;
};
const exe = addCompilerStep(b, optimize, target);
exe.strip = strip;
const exe = addCompilerStep(b, .{
.optimize = optimize,
.target = target,
.strip = strip,
.sanitize_thread = sanitize_thread,
.single_threaded = single_threaded,
});
exe.pie = pie;
exe.sanitize_thread = sanitize_thread;
exe.entitlements = entitlements;
exe.build_id = b.option(
std.Build.Step.Compile.BuildId,
std.zig.BuildId,
"build-id",
"Request creation of '.note.gnu.build-id' section",
);
@ -217,9 +221,7 @@ pub fn build(b: *std.Build) !void {
test_step.dependOn(&exe.step);
exe.single_threaded = single_threaded;
if (target.isWindows() and target.getAbi() == .gnu) {
if (target.target.os.tag == .windows and target.target.abi == .gnu) {
// LTO is currently broken on mingw, this can be removed when it's fixed.
exe.want_lto = false;
check_case_exe.want_lto = false;
@ -230,7 +232,7 @@ pub fn build(b: *std.Build) !void {
exe.use_lld = use_llvm;
const exe_options = b.addOptions();
exe.addOptions("build_options", exe_options);
exe.root_module.addOptions("build_options", exe_options);
exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames);
exe_options.addOption(bool, "skip_non_native", skip_non_native);
@ -345,7 +347,7 @@ pub fn build(b: *std.Build) !void {
try addStaticLlvmOptionsToExe(exe);
try addStaticLlvmOptionsToExe(check_case_exe);
}
if (target.isWindows()) {
if (target.target.os.tag == .windows) {
inline for (.{ exe, check_case_exe }) |artifact| {
artifact.linkSystemLibrary("version");
artifact.linkSystemLibrary("uuid");
@ -369,7 +371,7 @@ pub fn build(b: *std.Build) !void {
);
// On mingw, we need to opt into windows 7+ to get some features required by tracy.
const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu)
const tracy_c_flags: []const []const u8 = if (target.target.os.tag == .windows and target.target.abi == .gnu)
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" }
else
&[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" };
@ -377,11 +379,11 @@ pub fn build(b: *std.Build) !void {
exe.addIncludePath(.{ .cwd_relative = tracy_path });
exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags });
if (!enable_llvm) {
exe.linkSystemLibraryName("c++");
exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no });
}
exe.linkLibC();
if (target.isWindows()) {
if (target.target.os.tag == .windows) {
exe.linkSystemLibrary("dbghelp");
exe.linkSystemLibrary("ws2_32");
}
@ -390,7 +392,7 @@ pub fn build(b: *std.Build) !void {
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
const test_cases_options = b.addOptions();
check_case_exe.addOptions("build_options", test_cases_options);
check_case_exe.root_module.addOptions("build_options", test_cases_options);
test_cases_options.addOption(bool, "enable_tracy", false);
test_cases_options.addOption(bool, "enable_logging", enable_logging);
@ -540,16 +542,19 @@ pub fn build(b: *std.Build) !void {
fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
const semver = try std.SemanticVersion.parse(version);
var target: std.zig.CrossTarget = .{
var target_query: std.zig.CrossTarget = .{
.cpu_arch = .wasm32,
.os_tag = .wasi,
};
target.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
target_query.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
const exe = addCompilerStep(b, .ReleaseSmall, target);
const exe = addCompilerStep(b, .{
.optimize = .ReleaseSmall,
.target = b.resolveTargetQuery(target_query),
});
const exe_options = b.addOptions();
exe.addOptions("build_options", exe_options);
exe.root_module.addOptions("build_options", exe_options);
exe_options.addOption(u32, "mem_leak_frames", 0);
exe_options.addOption(bool, "have_llvm", false);
@ -584,17 +589,24 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
update_zig1_step.dependOn(&copy_zig_h.step);
}
fn addCompilerStep(
b: *std.Build,
const AddCompilerStepOptions = struct {
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
) *std.Build.Step.Compile {
target: std.Build.ResolvedTarget,
strip: ?bool = null,
sanitize_thread: ?bool = null,
single_threaded: ?bool = null,
};
fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
.target = options.target,
.optimize = options.optimize,
.max_rss = 7_000_000_000,
.strip = options.strip,
.sanitize_thread = options.sanitize_thread,
.single_threaded = options.single_threaded,
});
exe.stack_size = stack_size;
@ -602,15 +614,15 @@ fn addCompilerStep(
aro_options.addOption([]const u8, "version_str", "aro-zig");
const aro_options_module = aro_options.createModule();
const aro_backend = b.createModule(.{
.source_file = .{ .path = "deps/aro/backend.zig" },
.dependencies = &.{.{
.root_source_file = .{ .path = "deps/aro/backend.zig" },
.imports = &.{.{
.name = "build_options",
.module = aro_options_module,
}},
});
const aro_module = b.createModule(.{
.source_file = .{ .path = "deps/aro/aro.zig" },
.dependencies = &.{
.root_source_file = .{ .path = "deps/aro/aro.zig" },
.imports = &.{
.{
.name = "build_options",
.module = aro_options_module,
@ -625,7 +637,7 @@ fn addCompilerStep(
},
});
exe.addModule("aro", aro_module);
exe.root_module.addImport("aro", aro_module);
return exe;
}
@ -649,7 +661,7 @@ fn addCmakeCfgOptionsToExe(
exe: *std.Build.Step.Compile,
use_zig_libcxx: bool,
) !void {
if (exe.target.isDarwin()) {
if (exe.rootModuleTarget().isDarwin()) {
// useful for package maintainers
exe.headerpad_max_install_names = true;
}
@ -677,8 +689,8 @@ fn addCmakeCfgOptionsToExe(
// against system-provided LLVM, Clang, LLD.
const need_cpp_includes = true;
const static = cfg.llvm_linkage == .static;
const lib_suffix = if (static) exe.target.staticLibSuffix()[1..] else exe.target.dynamicLibSuffix()[1..];
switch (exe.target.getOsTag()) {
const lib_suffix = if (static) exe.rootModuleTarget().staticLibSuffix()[1..] else exe.rootModuleTarget().dynamicLibSuffix()[1..];
switch (exe.rootModuleTarget().os.tag) {
.linux => {
// First we try to link against the detected libcxx name. If that doesn't work, we fall
// back to -lc++ and cross our fingers.
@ -694,7 +706,7 @@ fn addCmakeCfgOptionsToExe(
exe.linkLibCpp();
},
.windows => {
if (exe.target.getAbi() != .msvc) exe.linkLibCpp();
if (exe.rootModuleTarget().abi != .msvc) exe.linkLibCpp();
},
.freebsd => {
if (static) {
@ -756,12 +768,12 @@ fn addStaticLlvmOptionsToExe(exe: *std.Build.Step.Compile) !void {
exe.linkSystemLibrary("z");
exe.linkSystemLibrary("zstd");
if (exe.target.getOs().tag != .windows or exe.target.getAbi() != .msvc) {
if (exe.rootModuleTarget().os.tag != .windows or exe.rootModuleTarget().abi != .msvc) {
// This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.
exe.linkSystemLibrary("c++");
}
if (exe.target.getOs().tag == .windows) {
if (exe.rootModuleTarget().os.tag == .windows) {
exe.linkSystemLibrary("version");
exe.linkSystemLibrary("uuid");
exe.linkSystemLibrary("ole32");
@ -810,7 +822,9 @@ fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void {
while (it.next()) |lib| {
if (mem.startsWith(u8, lib, "-l")) {
exe.linkSystemLibrary(lib["-l".len..]);
} else if (exe.target.isWindows() and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) {
} else if (exe.rootModuleTarget().os.tag == .windows and
mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib))
{
exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]);
} else {
exe.addObjectFile(.{ .cwd_relative = lib });

View File

@ -21,7 +21,7 @@ pub const Options = struct {
pub const Kind = enum { dafsa, named };
};
pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency {
pub fn create(owner: *std.Build, options: Options) std.Build.Module.Import {
const self = owner.allocator.create(GenerateDef) catch @panic("OOM");
const path = owner.pathJoin(&.{ options.src_prefix, options.name });
@ -39,7 +39,7 @@ pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency {
.generated_file = .{ .step = &self.step },
};
const module = self.step.owner.createModule(.{
.source_file = .{ .generated = &self.generated_file },
.root_source_file = .{ .generated = &self.generated_file },
});
return .{
.module = module,

View File

@ -46,7 +46,12 @@ pub fn main() !void {
return error.InvalidArgs;
};
const host = try std.zig.system.NativeTargetInfo.detect(.{});
const detected = try std.zig.system.NativeTargetInfo.detect(.{});
const host: std.Build.ResolvedTarget = .{
.query = .{},
.target = detected.target,
.dynamic_linker = detected.dynamic_linker,
};
const build_root_directory: std.Build.Cache.Directory = .{
.path = build_root,

View File

@ -14,20 +14,11 @@ const process = std.process;
const EnvMap = std.process.EnvMap;
const fmt_lib = std.fmt;
const File = std.fs.File;
const CrossTarget = std.zig.CrossTarget;
const NativeTargetInfo = std.zig.system.NativeTargetInfo;
const TargetQuery = std.zig.CrossTarget;
const Sha256 = std.crypto.hash.sha2.Sha256;
const Build = @This();
pub const Cache = @import("Build/Cache.zig");
/// deprecated: use `Step.Compile`.
pub const LibExeObjStep = Step.Compile;
/// deprecated: use `Build`.
pub const Builder = Build;
/// deprecated: use `Step.InstallDir.Options`
pub const InstallDirectoryOptions = Step.InstallDir.Options;
pub const Step = @import("Build/Step.zig");
pub const Module = @import("Build/Module.zig");
@ -94,7 +85,7 @@ enable_wine: bool = false,
glibc_runtimes_dir: ?[]const u8 = null,
/// Information about the native target. Computed before build() is invoked.
host: NativeTargetInfo,
host: ResolvedTarget,
dep_prefix: []const u8 = "",
@ -220,7 +211,7 @@ pub fn create(
build_root: Cache.Directory,
cache_root: Cache.Directory,
global_cache_root: Cache.Directory,
host: NativeTargetInfo,
host: ResolvedTarget,
cache: *Cache,
available_deps: AvailableDeps,
) !*Build {
@ -384,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption
const v = @field(args, field.name);
const T = @TypeOf(v);
switch (T) {
CrossTarget => {
TargetQuery => {
user_input_options.put(field.name, .{
.name = field.name,
.value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") },
@ -593,14 +584,22 @@ pub fn addOptions(self: *Build) *Step.Options {
pub const ExecutableOptions = struct {
name: []const u8,
/// If you want the executable to run on the same computer as the one
/// building the package, pass the `host` field of the package's `Build`
/// instance.
target: ResolvedTarget,
root_source_file: ?LazyPath = null,
version: ?std.SemanticVersion = null,
target: CrossTarget = .{},
optimize: std.builtin.OptimizeMode = .Debug,
linkage: ?Step.Compile.Linkage = null,
max_rss: usize = 0,
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
unwind_tables: ?bool = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
@ -621,6 +620,11 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
.optimize = options.optimize,
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
},
.version = options.version,
.kind = .exe,
@ -636,11 +640,18 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
pub const ObjectOptions = struct {
name: []const u8,
root_source_file: ?LazyPath = null,
target: CrossTarget,
/// To choose the same computer as the one building the package, pass the
/// `host` field of the package's `Build` instance.
target: ResolvedTarget,
optimize: std.builtin.OptimizeMode,
max_rss: usize = 0,
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
unwind_tables: ?bool = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
@ -655,6 +666,11 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
.optimize = options.optimize,
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
},
.kind = .obj,
.max_rss = options.max_rss,
@ -666,13 +682,20 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
pub const SharedLibraryOptions = struct {
name: []const u8,
/// To choose the same computer as the one building the package, pass the
/// `host` field of the package's `Build` instance.
target: ResolvedTarget,
optimize: std.builtin.OptimizeMode,
root_source_file: ?LazyPath = null,
version: ?std.SemanticVersion = null,
target: CrossTarget,
optimize: std.builtin.OptimizeMode,
max_rss: usize = 0,
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
unwind_tables: ?bool = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
@ -693,6 +716,11 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
.root_source_file = options.root_source_file,
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
},
.kind = .lib,
.linkage = .dynamic,
@ -708,12 +736,19 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
pub const StaticLibraryOptions = struct {
name: []const u8,
root_source_file: ?LazyPath = null,
target: CrossTarget,
/// To choose the same computer as the one building the package, pass the
/// `host` field of the package's `Build` instance.
target: ResolvedTarget,
optimize: std.builtin.OptimizeMode,
version: ?std.SemanticVersion = null,
max_rss: usize = 0,
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
unwind_tables: ?bool = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
@ -728,6 +763,11 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
.root_source_file = options.root_source_file,
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
},
.kind = .lib,
.linkage = .static,
@ -742,7 +782,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
pub const TestOptions = struct {
name: []const u8 = "test",
root_source_file: LazyPath,
target: CrossTarget = .{},
target: ?ResolvedTarget = null,
optimize: std.builtin.OptimizeMode = .Debug,
version: ?std.SemanticVersion = null,
max_rss: usize = 0,
@ -750,6 +790,11 @@ pub const TestOptions = struct {
test_runner: ?[]const u8 = null,
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
unwind_tables: ?bool = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
use_llvm: ?bool = null,
use_lld: ?bool = null,
zig_lib_dir: ?LazyPath = null,
@ -761,10 +806,15 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
.kind = .@"test",
.root_module = .{
.root_source_file = options.root_source_file,
.target = options.target,
.target = options.target orelse b.host,
.optimize = options.optimize,
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
},
.max_rss = options.max_rss,
.filter = options.filter,
@ -778,7 +828,9 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
pub const AssemblyOptions = struct {
name: []const u8,
source_file: LazyPath,
target: CrossTarget,
/// To choose the same computer as the one building the package, pass the
/// `host` field of the package's `Build` instance.
target: ResolvedTarget,
optimize: std.builtin.OptimizeMode,
max_rss: usize = 0,
zig_lib_dir: ?LazyPath = null,
@ -1061,7 +1113,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
return null;
},
.scalar => |s| {
if (Step.Compile.BuildId.parse(s)) |build_id| {
if (std.zig.BuildId.parse(s)) |build_id| {
return build_id;
} else |err| {
log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });
@ -1126,13 +1178,20 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio
}
pub const StandardTargetOptionsArgs = struct {
whitelist: ?[]const CrossTarget = null,
whitelist: ?[]const TargetQuery = null,
default_target: CrossTarget = CrossTarget{},
default_target: TargetQuery = .{},
};
/// Exposes standard `zig build` options for choosing a target and additionally
/// resolves the target query.
pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) ResolvedTarget {
const query = b.standardTargetOptionsQueryOnly(args);
return b.resolveTargetQuery(query);
}
/// Exposes standard `zig build` options for choosing a target.
pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) CrossTarget {
pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) TargetQuery {
const maybe_triple = self.option(
[]const u8,
"target",
@ -1146,8 +1205,8 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
const triple = maybe_triple orelse "native";
var diags: CrossTarget.ParseOptions.Diagnostics = .{};
const selected_target = CrossTarget.parse(.{
var diags: TargetQuery.ParseOptions.Diagnostics = .{};
const selected_target = TargetQuery.parse(.{
.arch_os_abi = triple,
.cpu_features = mcpu,
.diagnostics = &diags,
@ -1203,7 +1262,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
// Make sure it's a match of one of the list.
var mismatch_triple = true;
var mismatch_cpu_features = true;
var whitelist_item = CrossTarget{};
var whitelist_item: TargetQuery = .{};
for (list) |t| {
mismatch_cpu_features = true;
mismatch_triple = true;
@ -1340,7 +1399,7 @@ pub fn addUserInputFlag(self: *Build, name_raw: []const u8) !bool {
fn typeToEnum(comptime T: type) TypeId {
return switch (T) {
Step.Compile.BuildId => .build_id,
std.zig.BuildId => .build_id,
else => return switch (@typeInfo(T)) {
.Int => .int,
.Float => .float,
@ -1408,7 +1467,7 @@ pub fn installFile(self: *Build, src_path: []const u8, dest_rel_path: []const u8
self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .prefix, dest_rel_path).step);
}
pub fn installDirectory(self: *Build, options: InstallDirectoryOptions) void {
pub fn installDirectory(self: *Build, options: Step.InstallDir.Options) void {
self.getInstallStep().dependOn(&self.addInstallDirectory(options).step);
}
@ -1454,7 +1513,7 @@ pub fn addInstallFileWithDir(
return Step.InstallFile.create(self, source.dupe(self), install_dir, dest_rel_path);
}
pub fn addInstallDirectory(self: *Build, options: InstallDirectoryOptions) *Step.InstallDir {
pub fn addInstallDirectory(self: *Build, options: Step.InstallDir.Options) *Step.InstallDir {
return Step.InstallDir.create(self, options);
}
@ -1511,7 +1570,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 {
pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {
// TODO report error for ambiguous situations
const exe_extension = @as(CrossTarget, .{}).exeFileExt();
const exe_extension = @as(TargetQuery, .{}).exeFileExt();
for (self.search_prefixes.items) |search_prefix| {
for (names) |name| {
if (fs.path.isAbsolute(name)) {
@ -1957,22 +2016,6 @@ pub fn dumpBadGetPathHelp(
tty_config.setColor(w, .reset) catch {};
}
/// Allocates a new string for assigning a value to a named macro.
/// If the value is omitted, it is set to 1.
/// `name` and `value` need not live longer than the function call.
pub fn constructCMacro(allocator: Allocator, name: []const u8, value: ?[]const u8) []const u8 {
var macro = allocator.alloc(
u8,
name.len + if (value) |value_slice| value_slice.len + 1 else 0,
) catch |err| if (err == error.OutOfMemory) @panic("Out of memory") else unreachable;
@memcpy(macro[0..name.len], name);
if (value) |value_slice| {
macro[name.len] = '=';
@memcpy(macro[name.len + 1 ..][0..value_slice.len], value_slice);
}
return macro;
}
pub const InstallDir = union(enum) {
prefix: void,
lib: void,
@ -2062,6 +2105,44 @@ pub fn hex64(x: u64) [16]u8 {
return result;
}
/// A pair of target query and fully resolved target.
/// This type is generally required by build system API that need to be given a
/// target. The query is kept because the Zig toolchain needs to know which parts
/// of the target are "native". This can apply to the CPU, the OS, or even the ABI.
pub const ResolvedTarget = struct {
query: TargetQuery,
target: std.Target,
dynamic_linker: std.Target.DynamicLinker,
pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo {
return .{
.target = self.target,
.dynamic_linker = self.dynamic_linker,
};
}
};
/// Converts a target query into a fully resolved target that can be passed to
/// various parts of the API.
pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget {
// This context will likely be required in the future when the target is
// resolved via a WASI API or via the build protocol.
_ = b;
const result = std.zig.system.NativeTargetInfo.detect(query) catch
@panic("unable to resolve target query");
return .{
.query = query,
.target = result.target,
.dynamic_linker = result.dynamic_linker,
};
}
pub fn wantSharedLibSymLinks(target: std.Target) bool {
return target.os.tag != .windows;
}
test {
_ = Cache;
_ = Step;

View File

@ -270,7 +270,7 @@ pub const HashHelper = struct {
.none => {},
}
},
std.Build.Step.Compile.BuildId => switch (x) {
std.zig.BuildId => switch (x) {
.none, .fast, .uuid, .sha1, .md5 => hh.add(std.meta.activeTag(x)),
.hexstring => |hex_string| hh.addBytes(hex_string.toSlice()),
},

View File

@ -3,27 +3,24 @@ owner: *std.Build,
/// Tracks the set of steps that depend on this `Module`. This ensures that
/// when making this `Module` depend on other `Module` objects and `Step`
/// objects, respective `Step` dependencies can be added.
depending_steps: std.AutoArrayHashMapUnmanaged(*std.Build.Step.Compile, void),
/// This could either be a generated file, in which case the module
/// contains exactly one file, or it could be a path to the root source
/// file of directory of files which constitute the module.
/// If `null`, it means this module is made up of only `link_objects`.
depending_steps: std.AutoArrayHashMapUnmanaged(*Step.Compile, void),
root_source_file: ?LazyPath,
/// The modules that are mapped into this module's import table.
import_table: std.StringArrayHashMap(*Module),
/// Use `addImport` rather than modifying this field directly in order to
/// maintain step dependency edges.
import_table: std.StringArrayHashMapUnmanaged(*Module),
target: std.zig.CrossTarget,
target_info: NativeTargetInfo,
optimize: std.builtin.OptimizeMode,
target: ?std.Build.ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
dwarf_format: ?std.dwarf.Format,
c_macros: std.ArrayList([]const u8),
include_dirs: std.ArrayList(IncludeDir),
lib_paths: std.ArrayList(LazyPath),
rpaths: std.ArrayList(LazyPath),
frameworks: std.StringArrayHashMapUnmanaged(FrameworkLinkInfo),
c_macros: std.ArrayListUnmanaged([]const u8),
include_dirs: std.ArrayListUnmanaged(IncludeDir),
lib_paths: std.ArrayListUnmanaged(LazyPath),
rpaths: std.ArrayListUnmanaged(RPath),
frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions),
c_std: std.Build.CStd,
link_objects: std.ArrayList(LinkObject),
link_objects: std.ArrayListUnmanaged(LinkObject),
strip: ?bool,
unwind_tables: ?bool,
@ -53,9 +50,14 @@ link_libcpp: ?bool,
/// Symbols to be exported when compiling to WebAssembly.
export_symbol_names: []const []const u8 = &.{},
pub const RPath = union(enum) {
lazy_path: LazyPath,
special: []const u8,
};
pub const LinkObject = union(enum) {
static_path: LazyPath,
other_step: *std.Build.Step.Compile,
other_step: *Step.Compile,
system_lib: SystemLib,
assembly_file: LazyPath,
c_source_file: *CSourceFile,
@ -133,21 +135,32 @@ pub const IncludeDir = union(enum) {
path_after: LazyPath,
framework_path: LazyPath,
framework_path_system: LazyPath,
other_step: *std.Build.Step.Compile,
config_header_step: *std.Build.Step.ConfigHeader,
other_step: *Step.Compile,
config_header_step: *Step.ConfigHeader,
};
pub const FrameworkLinkInfo = struct {
pub const LinkFrameworkOptions = struct {
needed: bool = false,
weak: bool = false,
};
/// Unspecified options here will be inherited from parent `Module` when
/// inserted into an import table.
pub const CreateOptions = struct {
target: std.zig.CrossTarget,
target_info: ?NativeTargetInfo = null,
optimize: std.builtin.OptimizeMode,
/// This could either be a generated file, in which case the module
/// contains exactly one file, or it could be a path to the root source
/// file of directory of files which constitute the module.
/// If `null`, it means this module is made up of only `link_objects`.
root_source_file: ?LazyPath = null,
import_table: []const Import = &.{},
/// The table of other modules that this module can access via `@import`.
/// Imports are allowed to be cyclical, so this table can be added to after
/// the `Module` is created via `addImport`.
imports: []const Import = &.{},
target: ?std.Build.ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
link_libc: ?bool = null,
link_libcpp: ?bool = null,
single_threaded: ?bool = null,
@ -173,26 +186,26 @@ pub const Import = struct {
module: *Module,
};
pub fn init(owner: *std.Build, options: CreateOptions, compile: ?*std.Build.Step.Compile) Module {
var m: Module = .{
pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*Step.Compile) void {
const allocator = owner.allocator;
m.* = .{
.owner = owner,
.depending_steps = .{},
.root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,
.import_table = std.StringArrayHashMap(*Module).init(owner.allocator),
.import_table = .{},
.target = options.target,
.target_info = options.target_info orelse
NativeTargetInfo.detect(options.target) catch @panic("unhandled error"),
.optimize = options.optimize,
.link_libc = options.link_libc,
.link_libcpp = options.link_libcpp,
.dwarf_format = options.dwarf_format,
.c_macros = std.ArrayList([]const u8).init(owner.allocator),
.include_dirs = std.ArrayList(IncludeDir).init(owner.allocator),
.lib_paths = std.ArrayList(LazyPath).init(owner.allocator),
.rpaths = std.ArrayList(LazyPath).init(owner.allocator),
.c_macros = .{},
.include_dirs = .{},
.lib_paths = .{},
.rpaths = .{},
.frameworks = .{},
.c_std = options.c_std,
.link_objects = std.ArrayList(LinkObject).init(owner.allocator),
.link_objects = .{},
.strip = options.strip,
.unwind_tables = options.unwind_tables,
.single_threaded = options.single_threaded,
@ -208,31 +221,30 @@ pub fn init(owner: *std.Build, options: CreateOptions, compile: ?*std.Build.Step
.export_symbol_names = &.{},
};
if (compile) |c| {
m.depending_steps.put(owner.allocator, c, {}) catch @panic("OOM");
}
m.import_table.ensureUnusedCapacity(options.import_table.len) catch @panic("OOM");
for (options.import_table) |dep| {
m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM");
for (options.imports) |dep| {
m.import_table.putAssumeCapacity(dep.name, dep.module);
}
var it = m.iterateDependencies(null);
while (it.next()) |item| addShallowDependencies(&m, item.module);
if (compile) |c| {
m.depending_steps.put(allocator, c, {}) catch @panic("OOM");
}
return m;
// This logic accesses `depending_steps` which was just modified above.
var it = m.iterateDependencies(null);
while (it.next()) |item| addShallowDependencies(m, item.module);
}
pub fn create(owner: *std.Build, options: CreateOptions) *Module {
const m = owner.allocator.create(Module) catch @panic("OOM");
m.* = init(owner, options, null);
m.init(owner, options, null);
return m;
}
/// Adds an existing module to be used with `@import`.
pub fn addImport(m: *Module, name: []const u8, module: *Module) void {
const b = m.owner;
m.import_table.put(b.dupe(name), module) catch @panic("OOM");
m.import_table.put(b.allocator, b.dupe(name), module) catch @panic("OOM");
var it = module.iterateDependencies(null);
while (it.next()) |item| addShallowDependencies(m, item.module);
@ -244,7 +256,10 @@ pub fn addImport(m: *Module, name: []const u8, module: *Module) void {
fn addShallowDependencies(m: *Module, dependee: *Module) void {
if (dependee.root_source_file) |lazy_path| addLazyPathDependencies(m, dependee, lazy_path);
for (dependee.lib_paths.items) |lib_path| addLazyPathDependencies(m, dependee, lib_path);
for (dependee.rpaths.items) |rpath| addLazyPathDependencies(m, dependee, rpath);
for (dependee.rpaths.items) |rpath| switch (rpath) {
.lazy_path => |lp| addLazyPathDependencies(m, dependee, lp),
.special => {},
};
for (dependee.link_objects.items) |link_object| switch (link_object) {
.other_step => |compile| addStepDependencies(m, dependee, &compile.step),
@ -277,7 +292,7 @@ fn addLazyPathDependenciesOnly(m: *Module, lazy_path: LazyPath) void {
}
}
fn addStepDependencies(m: *Module, module: *Module, dependee: *std.Build.Step) void {
fn addStepDependencies(m: *Module, module: *Module, dependee: *Step) void {
addStepDependenciesOnly(m, dependee);
if (m != module) {
for (m.depending_steps.keys()) |compile| {
@ -286,20 +301,19 @@ fn addStepDependencies(m: *Module, module: *Module, dependee: *std.Build.Step) v
}
}
fn addStepDependenciesOnly(m: *Module, dependee: *std.Build.Step) void {
fn addStepDependenciesOnly(m: *Module, dependee: *Step) void {
for (m.depending_steps.keys()) |compile| {
compile.step.dependOn(dependee);
}
}
/// Creates a new module and adds it to be used with `@import`.
pub fn addAnonymousImport(m: *Module, name: []const u8, options: std.Build.CreateModuleOptions) void {
const b = m.step.owner;
const module = b.createModule(options);
pub fn addAnonymousImport(m: *Module, name: []const u8, options: CreateOptions) void {
const module = create(m.owner, options);
return addImport(m, name, module);
}
pub fn addOptions(m: *Module, module_name: []const u8, options: *std.Build.Step.Options) void {
pub fn addOptions(m: *Module, module_name: []const u8, options: *Step.Options) void {
addImport(m, module_name, options.createModule());
}
@ -311,14 +325,14 @@ pub const DependencyIterator = struct {
pub const Key = struct {
/// The compilation that contains the `Module`. Note that a `Module` might be
/// used by more than one compilation.
compile: ?*std.Build.Step.Compile,
compile: ?*Step.Compile,
module: *Module,
};
pub const Item = struct {
/// The compilation that contains the `Module`. Note that a `Module` might be
/// used by more than one compilation.
compile: ?*std.Build.Step.Compile,
compile: ?*Step.Compile,
module: *Module,
name: []const u8,
};
@ -368,7 +382,7 @@ pub const DependencyIterator = struct {
pub fn iterateDependencies(
m: *Module,
chase_steps: ?*std.Build.Step.Compile,
chase_steps: ?*Step.Compile,
) DependencyIterator {
var it: DependencyIterator = .{
.allocator = m.owner.allocator,
@ -397,16 +411,18 @@ pub fn linkSystemLibrary(
options: LinkSystemLibraryOptions,
) void {
const b = m.owner;
if (m.target_info.target.is_libc_lib_name(name)) {
const target = m.requireKnownTarget();
if (target.is_libc_lib_name(name)) {
m.link_libc = true;
return;
}
if (m.target_info.target.is_libcpp_lib_name(name)) {
if (target.is_libcpp_lib_name(name)) {
m.link_libcpp = true;
return;
}
m.link_objects.append(.{
m.link_objects.append(b.allocator, .{
.system_lib = .{
.name = b.dupe(name),
.needed = options.needed,
@ -418,6 +434,11 @@ pub fn linkSystemLibrary(
}) catch @panic("OOM");
}
pub fn linkFramework(m: *Module, name: []const u8, options: LinkFrameworkOptions) void {
const b = m.owner;
m.frameworks.put(b.allocator, b.dupe(name), options) catch @panic("OOM");
}
pub const AddCSourceFilesOptions = struct {
/// When provided, `files` are relative to `dependency` rather than the
/// package that owns the `Compile` step.
@ -428,19 +449,23 @@ pub const AddCSourceFilesOptions = struct {
/// Handy when you have many C/C++ source files and want them all to have the same flags.
pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void {
const c_source_files = m.owner.allocator.create(CSourceFiles) catch @panic("OOM");
const b = m.owner;
const allocator = b.allocator;
const c_source_files = allocator.create(CSourceFiles) catch @panic("OOM");
c_source_files.* = .{
.dependency = options.dependency,
.files = m.owner.dupeStrings(options.files),
.flags = m.owner.dupeStrings(options.flags),
.files = b.dupeStrings(options.files),
.flags = b.dupeStrings(options.flags),
};
m.link_objects.append(.{ .c_source_files = c_source_files }) catch @panic("OOM");
m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM");
}
pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
const c_source_file = m.owner.allocator.create(CSourceFile) catch @panic("OOM");
c_source_file.* = source.dupe(m.owner);
m.link_objects.append(.{ .c_source_file = c_source_file }) catch @panic("OOM");
const b = m.owner;
const allocator = b.allocator;
const c_source_file = allocator.create(CSourceFile) catch @panic("OOM");
c_source_file.* = source.dupe(b);
m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, source.file);
}
@ -448,30 +473,122 @@ pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
/// Can be called regardless of target. The .rc file will be ignored
/// if the target object format does not support embedded resources.
pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void {
const b = m.owner;
const allocator = b.allocator;
const target = m.requireKnownTarget();
// Only the PE/COFF format has a Resource Table, so for any other target
// the resource file is ignored.
if (m.target_info.target.ofmt != .coff) return;
if (target.ofmt != .coff) return;
const rc_source_file = m.owner.allocator.create(RcSourceFile) catch @panic("OOM");
rc_source_file.* = source.dupe(m.owner);
m.link_objects.append(.{ .win32_resource_file = rc_source_file }) catch @panic("OOM");
const rc_source_file = allocator.create(RcSourceFile) catch @panic("OOM");
rc_source_file.* = source.dupe(b);
m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, source.file);
}
pub fn addAssemblyFile(m: *Module, source: LazyPath) void {
m.link_objects.append(.{ .assembly_file = source.dupe(m.owner) }) catch @panic("OOM");
const b = m.owner;
m.link_objects.append(b.allocator, .{ .assembly_file = source.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, source);
}
pub fn addObjectFile(m: *Module, source: LazyPath) void {
m.link_objects.append(.{ .static_path = source.dupe(m.owner) }) catch @panic("OOM");
addLazyPathDependencies(m, source);
pub fn addObjectFile(m: *Module, object: LazyPath) void {
const b = m.owner;
m.link_objects.append(b.allocator, .{ .static_path = object.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, object);
}
pub fn addObject(m: *Module, object: *Step.Compile) void {
assert(object.kind == .obj);
m.linkLibraryOrObject(object);
}
pub fn linkLibrary(m: *Module, library: *Step.Compile) void {
assert(library.kind == .lib);
m.linkLibraryOrObject(library);
}
pub fn addAfterIncludePath(m: *Module, lazy_path: LazyPath) void {
const b = m.owner;
m.include_dirs.append(b.allocator, .{ .path_after = lazy_path.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, lazy_path);
}
pub fn addSystemIncludePath(m: *Module, lazy_path: LazyPath) void {
const b = m.owner;
m.include_dirs.append(b.allocator, .{ .path_system = lazy_path.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, lazy_path);
}
pub fn addIncludePath(m: *Module, lazy_path: LazyPath) void {
const b = m.owner;
m.include_dirs.append(b.allocator, .{ .path = lazy_path.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, lazy_path);
}
pub fn addConfigHeader(m: *Module, config_header: *Step.ConfigHeader) void {
const allocator = m.owner.allocator;
m.include_dirs.append(allocator, .{ .config_header_step = config_header }) catch @panic("OOM");
addStepDependenciesOnly(m, &config_header.step);
}
pub fn addSystemFrameworkPath(m: *Module, directory_path: LazyPath) void {
const b = m.owner;
m.include_dirs.append(b.allocator, .{ .framework_path_system = directory_path.dupe(b) }) catch
@panic("OOM");
addLazyPathDependenciesOnly(m, directory_path);
}
pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {
const b = m.owner;
m.include_dirs.append(b.allocator, .{ .framework_path = directory_path.dupe(b) }) catch
@panic("OOM");
addLazyPathDependenciesOnly(m, directory_path);
}
pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {
const b = m.owner;
m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");
addLazyPathDependenciesOnly(m, directory_path);
}
pub fn addRPath(m: *Module, directory_path: LazyPath) void {
const b = m.owner;
switch (directory_path) {
.path, .cwd_relative => |path| {
// TODO: remove this check after people upgrade and stop expecting it to work
if (std.mem.startsWith(u8, path, "@executable_path") or
std.mem.startsWith(u8, path, "@loader_path"))
{
@panic("this function is for adding directory paths. It does not support special rpaths. use addRPathSpecial for that.");
}
},
else => {},
}
m.rpaths.append(b.allocator, .{ .lazy_path = directory_path.dupe(b) }) catch @panic("OOM");
addLazyPathDependenciesOnly(m, directory_path);
}
pub fn addRPathSpecial(m: *Module, bytes: []const u8) void {
const b = m.owner;
m.rpaths.append(b.allocator, .{ .special = b.dupe(bytes) }) catch @panic("OOM");
}
/// Equvialent to the following C code, applied to all C source files owned by
/// this `Module`:
/// ```c
/// #define name value
/// ```
/// `name` and `value` need not live longer than the function call.
pub fn addCMacro(m: *Module, name: []const u8, value: []const u8) void {
const b = m.owner;
m.c_macros.append(b.allocator, b.fmt("-D{s}={s}", .{ name, value })) catch @panic("OOM");
}
pub fn appendZigProcessFlags(
m: *Module,
zig_args: *std.ArrayList([]const u8),
asking_step: ?*std.Build.Step,
asking_step: ?*Step,
) !void {
const b = m.owner;
@ -495,27 +612,30 @@ pub fn appendZigProcessFlags(
}
try zig_args.ensureUnusedCapacity(1);
switch (m.optimize) {
.Debug => {}, // Skip since it's the default.
if (m.optimize) |optimize| switch (optimize) {
.Debug => zig_args.appendAssumeCapacity("-ODebug"),
.ReleaseSmall => zig_args.appendAssumeCapacity("-OReleaseSmall"),
.ReleaseFast => zig_args.appendAssumeCapacity("-OReleaseFast"),
.ReleaseSafe => zig_args.appendAssumeCapacity("-OReleaseSafe"),
}
};
if (m.code_model != .default) {
try zig_args.append("-mcmodel");
try zig_args.append(@tagName(m.code_model));
}
if (!m.target.isNative()) {
try zig_args.appendSlice(&.{
"-target", try m.target.zigTriple(b.allocator),
"-mcpu", try std.Build.serializeCpu(b.allocator, m.target.getCpu()),
});
if (m.target) |target| {
// Communicate the query via CLI since it's more compact.
if (!target.query.isNative()) {
try zig_args.appendSlice(&.{
"-target", try target.query.zigTriple(b.allocator),
"-mcpu", try std.Build.serializeCpu(b.allocator, target.query.getCpu()),
});
if (m.target.dynamic_linker.get()) |dynamic_linker| {
try zig_args.append("--dynamic-linker");
try zig_args.append(dynamic_linker);
if (target.query.dynamic_linker.get()) |dynamic_linker| {
try zig_args.append("--dynamic-linker");
try zig_args.append(dynamic_linker);
}
}
}
@ -565,10 +685,7 @@ pub fn appendZigProcessFlags(
}
}
for (m.c_macros.items) |c_macro| {
try zig_args.append("-D");
try zig_args.append(c_macro);
}
try zig_args.appendSlice(m.c_macros.items);
try zig_args.ensureUnusedCapacity(2 * m.lib_paths.items.len);
for (m.lib_paths.items) |lib_path| {
@ -577,26 +694,16 @@ pub fn appendZigProcessFlags(
}
try zig_args.ensureUnusedCapacity(2 * m.rpaths.items.len);
for (m.rpaths.items) |rpath| {
zig_args.appendAssumeCapacity("-rpath");
if (m.target_info.target.isDarwin()) switch (rpath) {
.path, .cwd_relative => |path| {
// On Darwin, we should not try to expand special runtime paths such as
// * @executable_path
// * @loader_path
if (std.mem.startsWith(u8, path, "@executable_path") or
std.mem.startsWith(u8, path, "@loader_path"))
{
zig_args.appendAssumeCapacity(path);
continue;
}
},
.generated, .dependency => {},
};
zig_args.appendAssumeCapacity(rpath.getPath2(b, asking_step));
}
for (m.rpaths.items) |rpath| switch (rpath) {
.lazy_path => |lp| {
zig_args.appendAssumeCapacity("-rpath");
zig_args.appendAssumeCapacity(lp.getPath2(b, asking_step));
},
.special => |bytes| {
zig_args.appendAssumeCapacity("-rpath");
zig_args.appendAssumeCapacity(bytes);
},
};
}
fn addFlag(
@ -609,8 +716,32 @@ fn addFlag(
return args.append(if (cond) then_name else else_name);
}
fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void {
const allocator = m.owner.allocator;
_ = other.getEmittedBin(); // Indicate there is a dependency on the outputted binary.
addStepDependenciesOnly(m, &other.step);
if (other.rootModuleTarget().os.tag == .windows and other.isDynamicLibrary()) {
_ = other.getEmittedImplib(); // Indicate dependency on the outputted implib.
}
m.link_objects.append(allocator, .{ .other_step = other }) catch @panic("OOM");
m.include_dirs.append(allocator, .{ .other_step = other }) catch @panic("OOM");
for (other.installed_headers.items) |install_step| {
addStepDependenciesOnly(m, install_step);
}
}
fn requireKnownTarget(m: *Module) std.Target {
const resolved_target = m.target orelse
@panic("this API requires the Module to be created with a known 'target' field");
return resolved_target.target;
}
const Module = @This();
const std = @import("std");
const assert = std.debug.assert;
const LazyPath = std.Build.LazyPath;
const NativeTargetInfo = std.zig.system.NativeTargetInfo;
const Step = std.Build.Step;

View File

@ -44,11 +44,11 @@ pub fn create(
const SearchPhrase = struct {
string: []const u8,
file_source: ?std.Build.LazyPath = null,
lazy_path: ?std.Build.LazyPath = null,
fn resolve(phrase: SearchPhrase, b: *std.Build, step: *Step) []const u8 {
const file_source = phrase.file_source orelse return phrase.string;
return b.fmt("{s} {s}", .{ phrase.string, file_source.getPath2(b, step) });
const lazy_path = phrase.lazy_path orelse return phrase.string;
return b.fmt("{s} {s}", .{ phrase.string, lazy_path.getPath2(b, step) });
}
};
@ -321,14 +321,14 @@ pub fn checkExact(self: *CheckObject, phrase: []const u8) void {
/// Like `checkExact()` but takes an additional argument `LazyPath` which will be
/// resolved to a full search query in `make()`.
pub fn checkExactPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
self.checkExactInner(phrase, file_source);
pub fn checkExactPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
self.checkExactInner(phrase, lazy_path);
}
fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.LazyPath) void {
fn checkExactInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
assert(self.checks.items.len > 0);
const last = &self.checks.items[self.checks.items.len - 1];
last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
last.exact(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
}
/// Adds a fuzzy match phrase to the latest created Check.
@ -336,16 +336,20 @@ pub fn checkContains(self: *CheckObject, phrase: []const u8) void {
self.checkContainsInner(phrase, null);
}
/// Like `checkContains()` but takes an additional argument `FileSource` which will be
/// Like `checkContains()` but takes an additional argument `lazy_path` which will be
/// resolved to a full search query in `make()`.
pub fn checkContainsPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
self.checkContainsInner(phrase, file_source);
pub fn checkContainsPath(
self: *CheckObject,
phrase: []const u8,
lazy_path: std.Build.LazyPath,
) void {
self.checkContainsInner(phrase, lazy_path);
}
fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
fn checkContainsInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
assert(self.checks.items.len > 0);
const last = &self.checks.items[self.checks.items.len - 1];
last.contains(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
last.contains(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
}
/// Adds an exact match phrase with variable extractor to the latest created Check.
@ -353,16 +357,16 @@ pub fn checkExtract(self: *CheckObject, phrase: []const u8) void {
self.checkExtractInner(phrase, null);
}
/// Like `checkExtract()` but takes an additional argument `FileSource` which will be
/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
/// resolved to a full search query in `make()`.
pub fn checkExtractFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
self.checkExtractInner(phrase, file_source);
pub fn checkExtractLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
self.checkExtractInner(phrase, lazy_path);
}
fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
fn checkExtractInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
assert(self.checks.items.len > 0);
const last = &self.checks.items[self.checks.items.len - 1];
last.extract(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
last.extract(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
}
/// Adds another searched phrase to the latest created Check
@ -371,16 +375,16 @@ pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void {
self.checkNotPresentInner(phrase, null);
}
/// Like `checkExtract()` but takes an additional argument `FileSource` which will be
/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
/// resolved to a full search query in `make()`.
pub fn checkNotPresentFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
self.checkNotPresentInner(phrase, file_source);
pub fn checkNotPresentLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
self.checkNotPresentInner(phrase, lazy_path);
}
fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
assert(self.checks.items.len > 0);
const last = &self.checks.items[self.checks.items.len - 1];
last.notPresent(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
last.notPresent(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
}
/// Creates a new check checking in the file headers (section, program headers, etc.).

View File

@ -88,7 +88,7 @@ each_lib_rpath: ?bool = null,
/// As an example, the bloaty project refuses to work unless its inputs have
/// build ids, in order to prevent accidental mismatches.
/// The default is to not include this section because it slows down linking.
build_id: ?BuildId = null,
build_id: ?std.zig.BuildId = null,
/// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF
/// file.
@ -200,7 +200,7 @@ pub const ExpectedCompileErrors = union(enum) {
exact: []const []const u8,
};
const Entry = union(enum) {
pub const Entry = union(enum) {
/// Let the compiler decide whether to make an entry point and what to name
/// it.
default,
@ -232,82 +232,6 @@ pub const Options = struct {
win32_manifest: ?LazyPath = null,
};
pub const BuildId = union(enum) {
none,
fast,
uuid,
sha1,
md5,
hexstring: HexString,
pub fn eql(a: BuildId, b: BuildId) bool {
const a_tag = std.meta.activeTag(a);
const b_tag = std.meta.activeTag(b);
if (a_tag != b_tag) return false;
return switch (a) {
.none, .fast, .uuid, .sha1, .md5 => true,
.hexstring => |a_hexstring| mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
};
}
pub const HexString = struct {
bytes: [32]u8,
len: u8,
/// Result is byte values, *not* hex-encoded.
pub fn toSlice(hs: *const HexString) []const u8 {
return hs.bytes[0..hs.len];
}
};
/// Input is byte values, *not* hex-encoded.
/// Asserts `bytes` fits inside `HexString`
pub fn initHexString(bytes: []const u8) BuildId {
var result: BuildId = .{ .hexstring = .{
.bytes = undefined,
.len = @as(u8, @intCast(bytes.len)),
} };
@memcpy(result.hexstring.bytes[0..bytes.len], bytes);
return result;
}
/// Converts UTF-8 text to a `BuildId`.
pub fn parse(text: []const u8) !BuildId {
if (mem.eql(u8, text, "none")) {
return .none;
} else if (mem.eql(u8, text, "fast")) {
return .fast;
} else if (mem.eql(u8, text, "uuid")) {
return .uuid;
} else if (mem.eql(u8, text, "sha1") or mem.eql(u8, text, "tree")) {
return .sha1;
} else if (mem.eql(u8, text, "md5")) {
return .md5;
} else if (mem.startsWith(u8, text, "0x")) {
var result: BuildId = .{ .hexstring = undefined };
const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
result.hexstring.len = @as(u8, @intCast(slice.len));
return result;
}
return error.InvalidBuildIdStyle;
}
test parse {
try std.testing.expectEqual(BuildId.md5, try parse("md5"));
try std.testing.expectEqual(BuildId.none, try parse("none"));
try std.testing.expectEqual(BuildId.fast, try parse("fast"));
try std.testing.expectEqual(BuildId.uuid, try parse("uuid"));
try std.testing.expectEqual(BuildId.sha1, try parse("sha1"));
try std.testing.expectEqual(BuildId.sha1, try parse("tree"));
try std.testing.expect(BuildId.initHexString("").eql(try parse("0x")));
try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456")));
try std.testing.expectError(error.InvalidLength, parse("0x12-34"));
try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb"));
try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx"));
}
};
pub const Kind = enum {
exe,
lib,
@ -329,6 +253,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
else
owner.fmt("{s} ", .{name});
const target = options.root_module.target.?.target;
const step_name = owner.fmt("{s} {s}{s} {s}", .{
switch (options.kind) {
.exe => "zig build-exe",
@ -337,16 +263,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
.@"test" => "zig test",
},
name_adjusted,
@tagName(options.root_module.optimize),
options.root_module.target.zigTriple(owner.allocator) catch @panic("OOM"),
@tagName(options.root_module.optimize orelse .Debug),
target.zigTriple(owner.allocator) catch @panic("OOM"),
});
const target_info = NativeTargetInfo.detect(options.root_module.target) catch
@panic("unhandled error");
const out_filename = std.zig.binNameAlloc(owner.allocator, .{
.root_name = name,
.target = target_info.target,
.target = target,
.output_mode = switch (options.kind) {
.lib => .Lib,
.obj => .Obj,
@ -361,7 +284,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
const self = owner.allocator.create(Compile) catch @panic("OOM");
self.* = .{
.root_module = Module.init(owner, options.root_module, self),
.root_module = undefined,
.verbose_link = false,
.verbose_cc = false,
.linkage = options.linkage,
@ -403,6 +326,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
.use_lld = options.use_lld,
};
self.root_module.init(owner, options.root_module, self);
if (options.zig_lib_dir) |lp| {
self.zig_lib_dir = lp.dupe(self.step.owner);
lp.addStepDependencies(&self.step);
@ -410,7 +335,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
// Only the PE/COFF format has a Resource Table which is where the manifest
// gets embedded, so for any other target the manifest file is just ignored.
if (target_info.target.ofmt == .coff) {
if (target.ofmt == .coff) {
if (options.win32_manifest) |lp| {
self.win32_manifest = lp.dupe(self.step.owner);
lp.addStepDependencies(&self.step);
@ -421,14 +346,14 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
if (self.linkage != null and self.linkage.? == .static) {
self.out_lib_filename = self.out_filename;
} else if (self.version) |version| {
if (target_info.target.isDarwin()) {
if (target.isDarwin()) {
self.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
self.name,
version.major,
});
self.name_only_filename = owner.fmt("lib{s}.dylib", .{self.name});
self.out_lib_filename = self.out_filename;
} else if (target_info.target.os.tag == .windows) {
} else if (target.os.tag == .windows) {
self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});
} else {
self.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ self.name, version.major });
@ -436,9 +361,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
self.out_lib_filename = self.out_filename;
}
} else {
if (target_info.target.isDarwin()) {
if (target.isDarwin()) {
self.out_lib_filename = self.out_filename;
} else if (target_info.target.os.tag == .windows) {
} else if (target.os.tag == .windows) {
self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});
} else {
self.out_lib_filename = self.out_filename;
@ -545,7 +470,7 @@ pub const run = @compileError("deprecated; use std.Build.addRunArtifact");
pub const install = @compileError("deprecated; use std.Build.installArtifact");
pub fn checkObject(self: *Compile) *Step.CheckObject {
return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.target_info.target.ofmt);
return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.rootModuleTarget().ofmt);
}
/// deprecated: use `setLinkerScript`
@ -562,25 +487,6 @@ pub fn forceUndefinedSymbol(self: *Compile, symbol_name: []const u8) void {
self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM");
}
pub fn linkFramework(self: *Compile, framework_name: []const u8) void {
const b = self.step.owner;
self.frameworks.put(b.dupe(framework_name), .{}) catch @panic("OOM");
}
pub fn linkFrameworkNeeded(self: *Compile, framework_name: []const u8) void {
const b = self.step.owner;
self.frameworks.put(b.dupe(framework_name), .{
.needed = true,
}) catch @panic("OOM");
}
pub fn linkFrameworkWeak(self: *Compile, framework_name: []const u8) void {
const b = self.step.owner;
self.frameworks.put(b.dupe(framework_name), .{
.weak = true,
}) catch @panic("OOM");
}
/// Returns whether the library, executable, or object depends on a particular system library.
pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {
var is_linking_libc = false;
@ -598,22 +504,17 @@ pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {
is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true;
}
if (self.root_module.target_info.target.is_libc_lib_name(name)) {
if (self.rootModuleTarget().is_libc_lib_name(name)) {
return is_linking_libc;
}
if (self.root_module.target_info.target.is_libcpp_lib_name(name)) {
if (self.rootModuleTarget().is_libcpp_lib_name(name)) {
return is_linking_libcpp;
}
return false;
}
pub fn linkLibrary(self: *Compile, lib: *Compile) void {
assert(lib.kind == .lib);
self.linkLibraryOrObject(lib);
}
pub fn isDynamicLibrary(self: *const Compile) bool {
return self.kind == .lib and self.linkage == Linkage.dynamic;
}
@ -623,16 +524,24 @@ pub fn isStaticLibrary(self: *const Compile) bool {
}
pub fn producesPdbFile(self: *Compile) bool {
const target = self.rootModuleTarget();
// TODO: Is this right? Isn't PDB for *any* PE/COFF file?
// TODO: just share this logic with the compiler, silly!
if (!self.target.isWindows() and !self.target.isUefi()) return false;
if (self.target.getObjectFormat() == .c) return false;
if (self.strip == true or (self.strip == null and self.optimize == .ReleaseSmall)) return false;
switch (target.os.tag) {
.windows, .uefi => {},
else => return false,
}
if (target.ofmt == .c) return false;
if (self.root_module.strip == true or
(self.root_module.strip == null and self.root_module.optimize == .ReleaseSmall))
{
return false;
}
return self.isDynamicLibrary() or self.kind == .exe or self.kind == .@"test";
}
pub fn producesImplib(self: *Compile) bool {
return self.isDynamicLibrary() and self.root_module.target_info.target.os.tag == .windows;
return self.isDynamicLibrary() and self.rootModuleTarget().os.tag == .windows;
}
pub fn linkLibC(self: *Compile) void {
@ -643,18 +552,9 @@ pub fn linkLibCpp(self: *Compile) void {
self.root_module.link_libcpp = true;
}
/// If the value is omitted, it is set to 1.
/// `name` and `value` need not live longer than the function call.
pub fn defineCMacro(self: *Compile, name: []const u8, value: ?[]const u8) void {
const b = self.step.owner;
const macro = std.Build.constructCMacro(b.allocator, name, value);
self.c_macros.append(macro) catch @panic("OOM");
}
/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1.
pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void {
const b = self.step.owner;
self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM");
/// Deprecated. Use `c.root_module.addCMacro`.
pub fn defineCMacro(c: *Compile, name: []const u8, value: ?[]const u8) void {
c.root_module.addCMacro(name, value orelse "1");
}
/// Run pkg-config for the given library name and parse the output, returning the arguments
@ -765,6 +665,20 @@ pub fn linkSystemLibrary2(
return self.root_module.linkSystemLibrary(name, options);
}
pub fn linkFramework(c: *Compile, name: []const u8) void {
c.root_module.linkFramework(name, .{});
}
/// Deprecated. Use `c.root_module.linkFramework`.
pub fn linkFrameworkNeeded(c: *Compile, name: []const u8) void {
c.root_module.linkFramework(name, .{ .needed = true });
}
/// Deprecated. Use `c.root_module.linkFramework`.
pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
c.root_module.linkFramework(name, .{ .weak = true });
}
/// Handy when you have many C/C++ source files and want them all to have the same flags.
pub fn addCSourceFiles(self: *Compile, options: Module.AddCSourceFilesOptions) void {
self.root_module.addCSourceFiles(options);
@ -805,27 +719,18 @@ fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath
return .{ .generated = generated_file };
}
/// deprecated: use `getEmittedBinDirectory`
pub const getOutputDirectorySource = getEmittedBinDirectory;
/// Returns the path to the directory that contains the emitted binary file.
pub fn getEmittedBinDirectory(self: *Compile) LazyPath {
_ = self.getEmittedBin();
return self.getEmittedFileGeneric(&self.emit_directory);
}
/// deprecated: use `getEmittedBin`
pub const getOutputSource = getEmittedBin;
/// Returns the path to the generated executable, library or object file.
/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
pub fn getEmittedBin(self: *Compile) LazyPath {
return self.getEmittedFileGeneric(&self.generated_bin);
}
/// deprecated: use `getEmittedImplib`
pub const getOutputLibSource = getEmittedImplib;
/// Returns the path to the generated import library.
/// This function can only be called for libraries.
pub fn getEmittedImplib(self: *Compile) LazyPath {
@ -833,9 +738,6 @@ pub fn getEmittedImplib(self: *Compile) LazyPath {
return self.getEmittedFileGeneric(&self.generated_implib);
}
/// deprecated: use `getEmittedH`
pub const getOutputHSource = getEmittedH;
/// Returns the path to the generated header file.
/// This function can only be called for libraries or objects.
pub fn getEmittedH(self: *Compile) LazyPath {
@ -843,9 +745,6 @@ pub fn getEmittedH(self: *Compile) LazyPath {
return self.getEmittedFileGeneric(&self.generated_h);
}
/// deprecated: use `getEmittedPdb`.
pub const getOutputPdbSource = getEmittedPdb;
/// Returns the generated PDB file.
/// If the compilation does not produce a PDB file, this causes a FileNotFound error
/// at build time.
@ -882,56 +781,44 @@ pub fn addObjectFile(self: *Compile, source: LazyPath) void {
self.root_module.addObjectFile(source);
}
pub fn addObject(self: *Compile, obj: *Compile) void {
assert(obj.kind == .obj);
self.linkLibraryOrObject(obj);
pub fn addObject(self: *Compile, object: *Compile) void {
self.root_module.addObject(object);
}
pub fn addAfterIncludePath(self: *Compile, path: LazyPath) void {
const b = self.step.owner;
self.include_dirs.append(.{ .path_after = path.dupe(b) }) catch @panic("OOM");
path.addStepDependencies(&self.step);
pub fn linkLibrary(self: *Compile, library: *Compile) void {
self.root_module.linkLibrary(library);
}
pub fn addSystemIncludePath(self: *Compile, path: LazyPath) void {
const b = self.step.owner;
self.include_dirs.append(.{ .path_system = path.dupe(b) }) catch @panic("OOM");
path.addStepDependencies(&self.step);
pub fn addAfterIncludePath(self: *Compile, lazy_path: LazyPath) void {
self.root_module.addAfterIncludePath(lazy_path);
}
pub fn addIncludePath(self: *Compile, path: LazyPath) void {
const b = self.step.owner;
self.include_dirs.append(.{ .path = path.dupe(b) }) catch @panic("OOM");
path.addStepDependencies(&self.step);
pub fn addSystemIncludePath(self: *Compile, lazy_path: LazyPath) void {
self.root_module.addSystemIncludePath(lazy_path);
}
pub fn addIncludePath(self: *Compile, lazy_path: LazyPath) void {
self.root_module.addIncludePath(lazy_path);
}
pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {
self.step.dependOn(&config_header.step);
self.include_dirs.append(.{ .config_header_step = config_header }) catch @panic("OOM");
self.root_module.addConfigHeader(config_header);
}
pub fn addLibraryPath(self: *Compile, directory_source: LazyPath) void {
const b = self.step.owner;
self.lib_paths.append(directory_source.dupe(b)) catch @panic("OOM");
directory_source.addStepDependencies(&self.step);
pub fn addLibraryPath(self: *Compile, directory_path: LazyPath) void {
self.root_module.addLibraryPath(directory_path);
}
pub fn addRPath(self: *Compile, directory_source: LazyPath) void {
const b = self.step.owner;
self.rpaths.append(directory_source.dupe(b)) catch @panic("OOM");
directory_source.addStepDependencies(&self.step);
pub fn addRPath(self: *Compile, directory_path: LazyPath) void {
self.root_module.addRPath(directory_path);
}
pub fn addSystemFrameworkPath(self: *Compile, directory_source: LazyPath) void {
const b = self.step.owner;
self.include_dirs.append(.{ .framework_path_system = directory_source.dupe(b) }) catch @panic("OOM");
directory_source.addStepDependencies(&self.step);
pub fn addSystemFrameworkPath(self: *Compile, directory_path: LazyPath) void {
self.root_module.addSystemFrameworkPath(directory_path);
}
pub fn addFrameworkPath(self: *Compile, directory_source: LazyPath) void {
const b = self.step.owner;
self.include_dirs.append(.{ .framework_path = directory_source.dupe(b) }) catch @panic("OOM");
directory_source.addStepDependencies(&self.step);
pub fn addFrameworkPath(self: *Compile, directory_path: LazyPath) void {
self.root_module.addFrameworkPath(directory_path);
}
pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void {
@ -944,20 +831,6 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void {
self.exec_cmd_args = duped_args;
}
fn linkLibraryOrObject(self: *Compile, other: *Compile) void {
other.getEmittedBin().addStepDependencies(&self.step);
if (other.target.isWindows() and other.isDynamicLibrary()) {
other.getEmittedImplib().addStepDependencies(&self.step);
}
self.link_objects.append(.{ .other_step = other }) catch @panic("OOM");
self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM");
for (other.installed_headers.items) |install_step| {
self.step.dependOn(install_step);
}
}
fn appendModuleArgs(cs: *Compile, zig_args: *ArrayList([]const u8)) !void {
const b = cs.step.owner;
// First, traverse the whole dependency graph and give every module a
@ -1014,7 +887,7 @@ fn appendModuleArgs(cs: *Compile, zig_args: *ArrayList([]const u8)) !void {
fn constructDepString(
allocator: std.mem.Allocator,
mod_names: std.AutoArrayHashMapUnmanaged(*Module, []const u8),
deps: std.StringArrayHashMap(*Module),
deps: std.StringArrayHashMapUnmanaged(*Module),
) ![]const u8 {
var deps_str = std.ArrayList(u8).init(allocator);
var it = deps.iterator();
@ -1082,7 +955,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try addFlag(&zig_args, "llvm", self.use_llvm);
try addFlag(&zig_args, "lld", self.use_lld);
if (self.root_module.target.ofmt) |ofmt| {
if (self.root_module.target.?.query.ofmt) |ofmt| {
try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)}));
}
@ -1110,7 +983,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
{
var seen_system_libs: std.StringHashMapUnmanaged(void) = .{};
var frameworks: std.StringArrayHashMapUnmanaged(Module.FrameworkLinkInfo) = .{};
var frameworks: std.StringArrayHashMapUnmanaged(Module.LinkFrameworkOptions) = .{};
var prev_has_cflags = false;
var prev_has_rcflags = false;
@ -1240,7 +1113,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(full_path_lib);
if (other.linkage == Linkage.dynamic and
self.root_module.target_info.target.os.tag != .windows)
self.rootModuleTarget().os.tag != .windows)
{
if (fs.path.dirname(full_path_lib)) |dirname| {
try zig_args.append("-rpath");
@ -1471,11 +1344,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(b.fmt("{}", .{version}));
}
if (self.root_module.target_info.target.isDarwin()) {
if (self.rootModuleTarget().isDarwin()) {
const install_name = self.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{
self.root_module.target_info.target.libPrefix(),
self.rootModuleTarget().libPrefix(),
self.name,
self.root_module.target_info.target.dynamicLibSuffix(),
self.rootModuleTarget().dynamicLibSuffix(),
});
try zig_args.append("-install_name");
try zig_args.append(install_name);
@ -1763,7 +1636,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
}
if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and
self.version != null and self.root_module.target.wantSharedLibSymLinks())
self.version != null and std.Build.wantSharedLibSymLinks(self.rootModuleTarget()))
{
try doAtomicSymLinks(
step,
@ -1932,3 +1805,8 @@ fn matchCompileError(actual: []const u8, expected: []const u8) bool {
}
return false;
}
pub fn rootModuleTarget(c: *Compile) std.Target {
// The root module is always given a target, so we know this to be non-null.
return c.root_module.target.?.target;
}

View File

@ -15,9 +15,6 @@ pub const Style = union(enum) {
/// Start with nothing, like blank, and output a nasm .asm file.
nasm,
/// deprecated: use `getPath`
pub const getFileSource = getPath;
pub fn getPath(style: Style) ?std.Build.LazyPath {
switch (style) {
.autoconf, .cmake => |s| return s,
@ -107,9 +104,6 @@ pub fn addValues(self: *ConfigHeader, values: anytype) void {
return addValuesInner(self, values) catch @panic("OOM");
}
/// deprecated: use `getOutput`
pub const getFileSource = getOutput;
pub fn getOutput(self: *ConfigHeader) std.Build.LazyPath {
return .{ .generated = &self.output_file };
}

View File

@ -94,7 +94,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
.dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and
artifact.isDynamicLibrary() and
artifact.version != null and
artifact.target.wantSharedLibSymLinks())) .{
std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{
.major_only_filename = artifact.major_only_filename.?,
.name_only_filename = artifact.name_only_filename.?,
} else null,

View File

@ -165,9 +165,6 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void {
}
}
/// deprecated: use `addOptionPath`
pub const addOptionFileSource = addOptionPath;
/// The value is the path in the cache dir.
/// Adds a dependency automatically.
pub fn addOptionPath(
@ -189,8 +186,7 @@ pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compi
pub fn createModule(self: *Options) *std.Build.Module {
return self.step.owner.createModule(.{
.source_file = self.getOutput(),
.dependencies = &.{},
.root_source_file = self.getOutput(),
});
}

View File

@ -197,16 +197,10 @@ pub fn addPrefixedOutputFileArg(
return .{ .generated = &output.generated_file };
}
/// deprecated: use `addFileArg`
pub const addFileSourceArg = addFileArg;
pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void {
self.addPrefixedFileArg("", lp);
}
// deprecated: use `addPrefixedFileArg`
pub const addPrefixedFileSourceArg = addPrefixedFileArg;
pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {
const b = self.step.owner;
@ -488,7 +482,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
man.hash.addBytes(file_path);
},
.artifact => |artifact| {
if (artifact.root_module.target_info.target.os.tag == .windows) {
if (artifact.rootModuleTarget().os.tag == .windows) {
// On Windows we don't have rpaths so we have to add .dll search paths to PATH
self.addPathForDynLibs(artifact);
}
@ -682,9 +676,10 @@ fn runCommand(
else => break :interpret,
}
const need_cross_glibc = exe.root_module.target_info.target.isGnuLibC() and
const need_cross_glibc = exe.rootModuleTarget().isGnuLibC() and
exe.is_linking_libc;
switch (b.host.getExternalExecutor(&exe.root_module.target_info, .{
const other_target_info = exe.root_module.target.?.toNativeTargetInfo();
switch (b.host.toNativeTargetInfo().getExternalExecutor(&other_target_info, .{
.qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null,
.link_libc = exe.is_linking_libc,
})) {
@ -715,9 +710,9 @@ fn runCommand(
// needs the directory to be called "i686" rather than
// "x86" which is why we do it manually here.
const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
const cpu_arch = exe.root_module.target_info.target.cpu.arch;
const os_tag = exe.root_module.target_info.target.os.tag;
const abi = exe.root_module.target_info.target.abi;
const cpu_arch = exe.rootModuleTarget().cpu.arch;
const os_tag = exe.rootModuleTarget().os.tag;
const abi = exe.rootModuleTarget().abi;
const cpu_arch_name: []const u8 = if (cpu_arch == .x86)
"i686"
else
@ -770,7 +765,7 @@ fn runCommand(
if (allow_skip) return error.MakeSkipped;
const host_name = try b.host.target.zigTriple(b.allocator);
const foreign_name = try exe.root_module.target_info.target.zigTriple(b.allocator);
const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{
host_name, foreign_name,
@ -778,7 +773,7 @@ fn runCommand(
},
}
if (exe.root_module.target_info.target.os.tag == .windows) {
if (exe.rootModuleTarget().os.tag == .windows) {
// On Windows we don't have rpaths so we have to add .dll search paths to PATH
self.addPathForDynLibs(exe);
}
@ -1300,7 +1295,7 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {
while (it.next()) |item| {
const other = item.compile.?;
if (item.module == &other.root_module) {
if (item.module.target_info.target.os.tag == .windows and other.isDynamicLibrary()) {
if (item.module.target.?.target.os.tag == .windows and other.isDynamicLibrary()) {
addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);
addPathForDynLibs(self, other);
}
@ -1321,7 +1316,7 @@ fn failForeign(
const b = self.step.owner;
const host_name = try b.host.target.zigTriple(b.allocator);
const foreign_name = try exe.root_module.target_info.target.zigTriple(b.allocator);
const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
return self.step.fail(
\\unable to spawn foreign binary '{s}' ({s}) on host system ({s})

View File

@ -2,7 +2,6 @@ const std = @import("std");
const Step = std.Build.Step;
const fs = std.fs;
const mem = std.mem;
const CrossTarget = std.zig.CrossTarget;
const TranslateC = @This();
@ -13,7 +12,7 @@ source: std.Build.LazyPath,
include_dirs: std.ArrayList([]const u8),
c_macros: std.ArrayList([]const u8),
out_basename: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
output_file: std.Build.GeneratedFile,
link_libc: bool,
@ -21,7 +20,7 @@ use_clang: bool,
pub const Options = struct {
source_file: std.Build.LazyPath,
target: CrossTarget,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
link_libc: bool = true,
use_clang: bool = true,
@ -54,7 +53,7 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {
pub const AddExecutableOptions = struct {
name: ?[]const u8 = null,
version: ?std.SemanticVersion = null,
target: ?CrossTarget = null,
target: ?std.Build.ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
linkage: ?Step.Compile.Linkage = null,
};
@ -139,9 +138,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try argv_list.append("--listen=-");
if (!self.target.isNative()) {
if (!self.target.query.isNative()) {
try argv_list.append("-target");
try argv_list.append(try self.target.zigTriple(b.allocator));
try argv_list.append(try self.target.query.zigTriple(b.allocator));
}
switch (self.optimize) {

View File

@ -28,9 +28,6 @@ pub const File = struct {
sub_path: []const u8,
contents: Contents,
/// deprecated: use `getPath`
pub const getFileSource = getPath;
pub fn getPath(self: *File) std.Build.LazyPath {
return .{ .generated = &self.generated_file };
}
@ -126,10 +123,6 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8)
}) catch @panic("OOM");
}
pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getPath()");
pub const getDirectorySource = getDirectory;
/// Returns a `LazyPath` representing the base directory that contains all the
/// files from this `WriteFile`.
pub fn getDirectory(wf: *WriteFile) std.Build.LazyPath {

View File

@ -194,9 +194,6 @@ pub const zig = @import("zig.zig");
pub const start = @import("start.zig");
/// deprecated: use `Build`.
pub const build = Build;
const root = @import("root");
const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {};

View File

@ -203,6 +203,83 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error
}
}
pub const BuildId = union(enum) {
none,
fast,
uuid,
sha1,
md5,
hexstring: HexString,
pub fn eql(a: BuildId, b: BuildId) bool {
const Tag = @TypeOf(BuildId).Union.tag_type.?;
const a_tag: Tag = a;
const b_tag: Tag = b;
if (a_tag != b_tag) return false;
return switch (a) {
.none, .fast, .uuid, .sha1, .md5 => true,
.hexstring => |a_hexstring| std.mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
};
}
pub const HexString = struct {
bytes: [32]u8,
len: u8,
/// Result is byte values, *not* hex-encoded.
pub fn toSlice(hs: *const HexString) []const u8 {
return hs.bytes[0..hs.len];
}
};
/// Input is byte values, *not* hex-encoded.
/// Asserts `bytes` fits inside `HexString`
pub fn initHexString(bytes: []const u8) BuildId {
var result: BuildId = .{ .hexstring = .{
.bytes = undefined,
.len = @intCast(bytes.len),
} };
@memcpy(result.hexstring.bytes[0..bytes.len], bytes);
return result;
}
/// Converts UTF-8 text to a `BuildId`.
pub fn parse(text: []const u8) !BuildId {
if (std.mem.eql(u8, text, "none")) {
return .none;
} else if (std.mem.eql(u8, text, "fast")) {
return .fast;
} else if (std.mem.eql(u8, text, "uuid")) {
return .uuid;
} else if (std.mem.eql(u8, text, "sha1") or std.mem.eql(u8, text, "tree")) {
return .sha1;
} else if (std.mem.eql(u8, text, "md5")) {
return .md5;
} else if (std.mem.startsWith(u8, text, "0x")) {
var result: BuildId = .{ .hexstring = undefined };
const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
result.hexstring.len = @as(u8, @intCast(slice.len));
return result;
}
return error.InvalidBuildIdStyle;
}
test parse {
try std.testing.expectEqual(BuildId.md5, try parse("md5"));
try std.testing.expectEqual(BuildId.none, try parse("none"));
try std.testing.expectEqual(BuildId.fast, try parse("fast"));
try std.testing.expectEqual(BuildId.uuid, try parse("uuid"));
try std.testing.expectEqual(BuildId.sha1, try parse("sha1"));
try std.testing.expectEqual(BuildId.sha1, try parse("tree"));
try std.testing.expect(BuildId.initHexString("").eql(try parse("0x")));
try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456")));
try std.testing.expectError(error.InvalidLength, parse("0x12-34"));
try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb"));
try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx"));
}
};
test {
@import("std").testing.refAllDecls(@This());
}

View File

@ -632,10 +632,6 @@ pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
}
pub fn wantSharedLibSymLinks(self: CrossTarget) bool {
return self.getOsTag() != .windows;
}
pub fn isGnuLibC(self: CrossTarget) bool {
return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
}

View File

@ -1008,8 +1008,8 @@ pub const GetExternalExecutorOptions = struct {
link_libc: bool = false,
};
/// Return whether or not the given host target is capable of executing natively executables
/// of the other target.
/// Return whether or not the given host is capable of running executables of
/// the other target.
pub fn getExternalExecutor(
host: NativeTargetInfo,
candidate: *const NativeTargetInfo,

View File

@ -30,7 +30,6 @@ const fatal = @import("main.zig").fatal;
const clangMain = @import("main.zig").clangMain;
const Module = @import("Module.zig");
const InternPool = @import("InternPool.zig");
const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const c_codegen = @import("codegen/c.zig");
const libtsan = @import("libtsan.zig");
@ -910,7 +909,7 @@ pub const InitOptions = struct {
linker_print_map: bool = false,
linker_opt_bisect_limit: i32 = -1,
each_lib_rpath: ?bool = null,
build_id: ?BuildId = null,
build_id: ?std.zig.BuildId = null,
disable_c_depfile: bool = false,
linker_z_nodelete: bool = false,
linker_z_notext: bool = false,

View File

@ -10,7 +10,6 @@ const wasi_libc = @import("wasi_libc.zig");
const Air = @import("Air.zig");
const Allocator = std.mem.Allocator;
const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const Compilation = @import("Compilation.zig");
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
@ -185,7 +184,7 @@ pub const Options = struct {
error_return_tracing: bool,
skip_linker_dependencies: bool,
each_lib_rpath: bool,
build_id: BuildId,
build_id: std.zig.BuildId,
disable_lld_caching: bool,
is_test: bool,
hash_style: HashStyle,

View File

@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
const EnvVar = introspect.EnvVar;
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
const wasi_libc = @import("wasi_libc.zig");
const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const target_util = @import("target.zig");
const crash_report = @import("crash_report.zig");
@ -882,7 +881,7 @@ fn buildOutputType(
var link_eh_frame_hdr = false;
var link_emit_relocs = false;
var each_lib_rpath: ?bool = null;
var build_id: ?BuildId = null;
var build_id: ?std.zig.BuildId = null;
var sysroot: ?[]const u8 = null;
var libc_paths_file: ?[]const u8 = try EnvVar.ZIG_LIBC.get(arena);
var machine_code_model: std.builtin.CodeModel = .default;
@ -1551,7 +1550,7 @@ fn buildOutputType(
build_id = .fast;
} else if (mem.startsWith(u8, arg, "--build-id=")) {
const style = arg["--build-id=".len..];
build_id = BuildId.parse(style) catch |err| {
build_id = std.zig.BuildId.parse(style) catch |err| {
fatal("unable to parse --build-id style '{s}': {s}", .{
style, @errorName(err),
});
@ -1847,7 +1846,7 @@ fn buildOutputType(
const key = linker_arg[0..equals_pos];
const value = linker_arg[equals_pos + 1 ..];
if (mem.eql(u8, key, "--build-id")) {
build_id = BuildId.parse(value) catch |err| {
build_id = std.zig.BuildId.parse(value) catch |err| {
fatal("unable to parse --build-id style '{s}': {s}", .{
value, @errorName(err),
});

View File

@ -876,27 +876,27 @@ test "two comptime calls with array default initialized to undefined" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const S = struct {
const CrossTarget = struct {
dynamic_linker: DynamicLinker = DynamicLinker{},
const A = struct {
c: B = B{},
pub fn parse() void {
var result: CrossTarget = .{};
result.getCpuArch();
pub fn d() void {
var f: A = .{};
f.e();
}
pub fn getCpuArch(self: CrossTarget) void {
_ = self;
pub fn e(g: A) void {
_ = g;
}
};
const DynamicLinker = struct {
const B = struct {
buffer: [255]u8 = undefined,
};
};
comptime {
S.CrossTarget.parse();
S.CrossTarget.parse();
S.A.d();
S.A.d();
}
}

View File

@ -9,9 +9,9 @@ pub const BuildOptions = struct {
llvm_has_xtensa: bool,
};
pub fn addCases(cases: *Cases, build_options: BuildOptions) !void {
try @import("compile_errors.zig").addCases(cases);
try @import("cbe.zig").addCases(cases);
try @import("llvm_targets.zig").addCases(cases, build_options);
try @import("nvptx.zig").addCases(cases);
pub fn addCases(cases: *Cases, build_options: BuildOptions, b: *std.Build) !void {
try @import("compile_errors.zig").addCases(cases, b);
try @import("cbe.zig").addCases(cases, b);
try @import("llvm_targets.zig").addCases(cases, build_options, b);
try @import("nvptx.zig").addCases(cases, b);
}

View File

@ -2,16 +2,16 @@ const std = @import("std");
const Cases = @import("src/Cases.zig");
const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n";
// These tests should work with all platforms, but we're using linux_x64 for
// now for consistency. Will be expanded eventually.
const linux_x64 = std.zig.CrossTarget{
.cpu_arch = .x86_64,
.os_tag = .linux,
};
pub fn addCases(ctx: *Cases, b: *std.Build) !void {
// These tests should work with all platforms, but we're using linux_x64 for
// now for consistency. Will be expanded eventually.
const linux_x64: std.zig.CrossTarget = .{
.cpu_arch = .x86_64,
.os_tag = .linux,
};
pub fn addCases(ctx: *Cases) !void {
{
var case = ctx.exeFromCompiledC("hello world with updates", .{});
var case = ctx.exeFromCompiledC("hello world with updates", .{}, b);
// Regular old hello world
case.addCompareOutput(
@ -59,7 +59,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("var args", .{});
var case = ctx.exeFromCompiledC("var args", .{}, b);
case.addCompareOutput(
\\extern fn printf(format: [*:0]const u8, ...) c_int;
@ -72,7 +72,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("errorFromInt", .{});
var case = ctx.exeFromCompiledC("errorFromInt", .{}, b);
case.addCompareOutput(
\\pub export fn main() c_int {
@ -108,7 +108,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64);
var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64, b);
// Exit with 0
case.addCompareOutput(
@ -202,7 +202,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("alloc and retptr", .{});
var case = ctx.exeFromCompiledC("alloc and retptr", .{}, b);
case.addCompareOutput(
\\fn add(a: i32, b: i32) i32 {
@ -220,7 +220,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("inferred local const and var", .{});
var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
case.addCompareOutput(
\\fn add(a: i32, b: i32) i32 {
@ -236,7 +236,7 @@ pub fn addCases(ctx: *Cases) !void {
, "");
}
{
var case = ctx.exeFromCompiledC("control flow", .{});
var case = ctx.exeFromCompiledC("control flow", .{}, b);
// Simple while loop
case.addCompareOutput(
@ -423,7 +423,7 @@ pub fn addCases(ctx: *Cases) !void {
});
}
//{
// var case = ctx.exeFromCompiledC("optionals", .{});
// var case = ctx.exeFromCompiledC("optionals", .{}, b);
// // Simple while loop
// case.addCompareOutput(
@ -451,7 +451,7 @@ pub fn addCases(ctx: *Cases) !void {
//}
{
var case = ctx.exeFromCompiledC("errors", .{});
var case = ctx.exeFromCompiledC("errors", .{}, b);
case.addCompareOutput(
\\pub export fn main() c_int {
\\ var e1 = error.Foo;
@ -495,7 +495,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("structs", .{});
var case = ctx.exeFromCompiledC("structs", .{}, b);
case.addError(
\\const Point = struct { x: i32, y: i32 };
\\pub export fn main() c_int {
@ -562,7 +562,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("unions", .{});
var case = ctx.exeFromCompiledC("unions", .{}, b);
case.addError(
\\const U = union {
@ -596,7 +596,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("enums", .{});
var case = ctx.exeFromCompiledC("enums", .{}, b);
case.addError(
\\const E1 = packed enum { a, b, c };
@ -838,7 +838,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("shift right and left", .{});
var case = ctx.exeFromCompiledC("shift right and left", .{}, b);
case.addCompareOutput(
\\pub export fn main() c_int {
\\ var i: u32 = 16;
@ -863,7 +863,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("inferred error sets", .{});
var case = ctx.exeFromCompiledC("inferred error sets", .{}, b);
case.addCompareOutput(
\\pub export fn main() c_int {
@ -884,7 +884,7 @@ pub fn addCases(ctx: *Cases) !void {
{
// TODO: add u64 tests, ran into issues with the literal generated for std.math.maxInt(u64)
var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{});
var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{}, b);
case.addCompareOutput(
\\pub export fn main() c_int {
\\ // Addition
@ -933,7 +933,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = ctx.exeFromCompiledC("rem", linux_x64);
var case = ctx.exeFromCompiledC("rem", linux_x64, b);
case.addCompareOutput(
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;

View File

@ -2,9 +2,9 @@ const std = @import("std");
const builtin = @import("builtin");
const Cases = @import("src/Cases.zig");
pub fn addCases(ctx: *Cases) !void {
pub fn addCases(ctx: *Cases, b: *std.Build) !void {
{
const case = ctx.obj("multiline error messages", .{});
const case = ctx.obj("multiline error messages", b.host);
case.addError(
\\comptime {
@ -39,7 +39,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("isolated carriage return in multiline string literal", .{});
const case = ctx.obj("isolated carriage return in multiline string literal", b.host);
case.addError("const foo = \\\\\test\r\r rogue carriage return\n;", &[_][]const u8{
":1:19: error: expected ';' after declaration",
@ -48,7 +48,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("missing semicolon at EOF", .{});
const case = ctx.obj("missing semicolon at EOF", b.host);
case.addError(
\\const foo = 1
, &[_][]const u8{
@ -57,7 +57,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("argument causes error", .{});
const case = ctx.obj("argument causes error", b.host);
case.addError(
\\pub export fn entry() void {
@ -80,7 +80,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("astgen failure in file struct", .{});
const case = ctx.obj("astgen failure in file struct", b.host);
case.addError(
\\pub export fn entry() void {
@ -95,7 +95,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("invalid store to comptime field", .{});
const case = ctx.obj("invalid store to comptime field", b.host);
case.addError(
\\const a = @import("a.zig");
@ -119,7 +119,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("file in multiple modules", .{});
const case = ctx.obj("file in multiple modules", b.host);
case.addDepModule("foo", "foo.zig");
case.addError(
@ -138,7 +138,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("wrong same named struct", .{});
const case = ctx.obj("wrong same named struct", b.host);
case.addError(
\\const a = @import("a.zig");
@ -172,7 +172,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("non-printable invalid character", .{});
const case = ctx.obj("non-printable invalid character", b.host);
case.addError("\xff\xfe" ++
\\export fn foo() bool {
@ -185,7 +185,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
const case = ctx.obj("imported generic method call with invalid param", .{});
const case = ctx.obj("imported generic method call with invalid param", b.host);
case.addError(
\\pub const import = @import("import.zig");

View File

@ -7,6 +7,7 @@ pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "bss",
.root_source_file = .{ .path = "main.zig" },
.target = b.host,
.optimize = .Debug,
});

View File

@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib_a = b.addStaticLibrary(.{
.name = "a",
.optimize = optimize,
.target = .{},
.target = b.host,
});
lib_a.addCSourceFiles(.{
.files = &.{ "c.c", "a.c", "b.c" },

View File

@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib_a = b.addStaticLibrary(.{
.name = "a",
.optimize = optimize,
.target = .{},
.target = b.host,
});
lib_a.addCSourceFiles(.{
.files = &.{"a.c"},

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@ pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = t,
.root_source_file = .{ .path = "main.c" },
.target = std.zig.CrossTarget.parse(
.target = b.resolveTargetQuery(std.zig.CrossTarget.parse(
.{ .arch_os_abi = t },
) catch unreachable,
) catch unreachable),
});
exe.linkLibC();
// TODO: actually test the output

View File

@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib_a = b.addStaticLibrary(.{
.name = "a",
.optimize = optimize,
.target = .{},
.target = b.host,
});
lib_a.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &[_][]const u8{} });
lib_a.addIncludePath(.{ .path = "." });
@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib_b = b.addStaticLibrary(.{
.name = "b",
.optimize = optimize,
.target = .{},
.target = b.host,
});
lib_b.addCSourceFile(.{ .file = .{ .path = "b.c" }, .flags = &[_][]const u8{} });
lib_b.addIncludePath(.{ .path = "." });

View File

@ -7,62 +7,160 @@ pub fn build(b: *Build) void {
}
pub const Options = struct {
target: CrossTarget,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode = .Debug,
use_llvm: bool = true,
use_lld: bool = false,
};
pub fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
const target = opts.target.zigTriple(b.allocator) catch @panic("OOM");
pub fn addTestStep(b: *Build, prefix: []const u8, opts: Options) *Step {
const target = opts.target.target.zigTriple(b.allocator) catch @panic("OOM");
const optimize = @tagName(opts.optimize);
const use_llvm = if (opts.use_llvm) "llvm" else "no-llvm";
const name = std.fmt.allocPrint(b.allocator, "test-" ++ prefix ++ "-{s}-{s}-{s}", .{
target,
optimize,
use_llvm,
const name = std.fmt.allocPrint(b.allocator, "test-{s}-{s}-{s}-{s}", .{
prefix, target, optimize, use_llvm,
}) catch @panic("OOM");
return b.step(name, "");
}
pub fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile {
return b.addExecutable(.{
.name = name,
.target = opts.target,
.optimize = opts.optimize,
.use_llvm = opts.use_llvm,
.use_lld = opts.use_lld,
const OverlayOptions = struct {
name: []const u8,
asm_source_bytes: ?[]const u8 = null,
c_source_bytes: ?[]const u8 = null,
c_source_flags: []const []const u8 = &.{},
cpp_source_bytes: ?[]const u8 = null,
cpp_source_flags: []const []const u8 = &.{},
zig_source_bytes: ?[]const u8 = null,
pic: ?bool = null,
strip: ?bool = null,
};
pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Step.Compile {
const compile_step = b.addExecutable(.{
.name = overlay.name,
.root_source_file = rsf: {
const bytes = overlay.zig_source_bytes orelse break :rsf null;
break :rsf b.addWriteFiles().add("a.zig", bytes);
},
.target = base.target,
.optimize = base.optimize,
.use_llvm = base.use_llvm,
.use_lld = base.use_lld,
.pic = overlay.pic,
.strip = overlay.strip,
});
if (overlay.cpp_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.cpp", bytes),
.flags = overlay.cpp_source_flags,
});
}
if (overlay.c_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.c", bytes),
.flags = overlay.c_source_flags,
});
}
if (overlay.asm_source_bytes) |bytes| {
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
}
return compile_step;
}
pub fn addObject(b: *Build, name: []const u8, opts: Options) *Compile {
return b.addObject(.{
.name = name,
.target = opts.target,
.optimize = opts.optimize,
.use_llvm = opts.use_llvm,
.use_lld = opts.use_lld,
pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Step.Compile {
const compile_step = b.addObject(.{
.name = overlay.name,
.root_source_file = rsf: {
const bytes = overlay.zig_source_bytes orelse break :rsf null;
break :rsf b.addWriteFiles().add("a.zig", bytes);
},
.target = base.target,
.optimize = base.optimize,
.use_llvm = base.use_llvm,
.use_lld = base.use_lld,
.pic = overlay.pic,
.strip = overlay.strip,
});
if (overlay.cpp_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.cpp", bytes),
.flags = overlay.cpp_source_flags,
});
}
if (overlay.c_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.c", bytes),
.flags = overlay.c_source_flags,
});
}
if (overlay.asm_source_bytes) |bytes| {
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
}
return compile_step;
}
pub fn addStaticLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
return b.addStaticLibrary(.{
.name = name,
.target = opts.target,
.optimize = opts.optimize,
.use_llvm = opts.use_llvm,
.use_lld = opts.use_lld,
pub fn addStaticLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
const compile_step = b.addStaticLibrary(.{
.name = overlay.name,
.root_source_file = rsf: {
const bytes = overlay.zig_source_bytes orelse break :rsf null;
break :rsf b.addWriteFiles().add("a.zig", bytes);
},
.target = base.target,
.optimize = base.optimize,
.use_llvm = base.use_llvm,
.use_lld = base.use_lld,
.pic = overlay.pic,
.strip = overlay.strip,
});
if (overlay.cpp_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.cpp", bytes),
.flags = overlay.cpp_source_flags,
});
}
if (overlay.c_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.c", bytes),
.flags = overlay.c_source_flags,
});
}
if (overlay.asm_source_bytes) |bytes| {
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
}
return compile_step;
}
pub fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
return b.addSharedLibrary(.{
.name = name,
.target = opts.target,
.optimize = opts.optimize,
.use_llvm = opts.use_llvm,
.use_lld = opts.use_lld,
pub fn addSharedLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
const compile_step = b.addSharedLibrary(.{
.name = overlay.name,
.root_source_file = rsf: {
const bytes = overlay.zig_source_bytes orelse break :rsf null;
break :rsf b.addWriteFiles().add("a.zig", bytes);
},
.target = base.target,
.optimize = base.optimize,
.use_llvm = base.use_llvm,
.use_lld = base.use_lld,
.pic = overlay.pic,
.strip = overlay.strip,
});
if (overlay.cpp_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.cpp", bytes),
.flags = overlay.cpp_source_flags,
});
}
if (overlay.c_source_bytes) |bytes| {
compile_step.addCSourceFile(.{
.file = b.addWriteFiles().add("a.c", bytes),
.flags = overlay.c_source_flags,
});
}
if (overlay.asm_source_bytes) |bytes| {
compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
}
return compile_step;
}
pub fn addRunArtifact(comp: *Compile) *Run {
@ -72,13 +170,6 @@ pub fn addRunArtifact(comp: *Compile) *Run {
return run;
}
pub fn addZigSourceBytes(comp: *Compile, bytes: []const u8) void {
const b = comp.step.owner;
const file = WriteFile.create(b).add("a.zig", bytes);
file.addStepDependencies(&comp.step);
comp.root_src = file;
}
pub fn addCSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void {
const b = comp.step.owner;
const file = WriteFile.create(b).add("a.c", bytes);

View File

@ -1,26 +1,29 @@
//! Here we test our MachO linker for correctness and functionality.
//! TODO migrate standalone tests from test/link/macho/* to here.
pub fn testAll(b: *Build) *Step {
pub fn testAll(b: *std.Build) *Step {
const macho_step = b.step("test-macho", "Run MachO tests");
const default_target = CrossTarget{ .os_tag = .macos };
macho_step.dependOn(testResolvingBoundarySymbols(b, .{ .target = default_target }));
macho_step.dependOn(testResolvingBoundarySymbols(b, .{
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
}));
return macho_step;
}
fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
fn testResolvingBoundarySymbols(b: *std.Build, opts: Options) *Step {
const test_step = addTestStep(b, "macho-resolving-boundary-symbols", opts);
const obj1 = addObject(b, "obj1", opts);
addCppSourceBytes(obj1,
const obj1 = addObject(b, opts, .{
.name = "obj1",
.cpp_source_bytes =
\\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST,__message_ptr"))) = "codebase";
, &.{});
,
});
const main_o = addObject(b, "main", opts);
addZigSourceBytes(main_o,
const main_o = addObject(b, opts, .{
.name = "main",
.zig_source_bytes =
\\const std = @import("std");
\\extern fn interop() [*:0]const u8;
\\pub fn main() !void {
@ -28,23 +31,27 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
\\ std.mem.span(interop()),
\\ });
\\}
);
,
});
{
const obj2 = addObject(b, "obj2", opts);
addCppSourceBytes(obj2,
const obj2 = addObject(b, opts, .{
.name = "obj2",
.cpp_source_bytes =
\\extern const char* message_pointer __asm("section$start$__DATA_CONST$__message_ptr");
\\extern "C" const char* interop() {
\\ return message_pointer;
\\}
, &.{});
,
});
const exe = addExecutable(b, "test", opts);
const exe = addExecutable(b, opts, .{ .name = "test" });
exe.addObject(obj1);
exe.addObject(obj2);
exe.addObject(main_o);
const run = addRunArtifact(exe);
const run = b.addRunArtifact(exe);
run.skip_foreign_checks = true;
run.expectStdErrEqual("All your codebase are belong to us.\n");
test_step.dependOn(&run.step);
@ -55,15 +62,17 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
}
{
const obj3 = addObject(b, "obj3", opts);
addCppSourceBytes(obj3,
const obj3 = addObject(b, opts, .{
.name = "obj3",
.cpp_source_bytes =
\\extern const char* message_pointer __asm("section$start$__DATA$__message_ptr");
\\extern "C" const char* interop() {
\\ return message_pointer;
\\}
, &.{});
,
});
const exe = addExecutable(b, "test", opts);
const exe = addExecutable(b, opts, .{ .name = "test" });
exe.addObject(obj1);
exe.addObject(obj3);
exe.addObject(main_o);
@ -77,20 +86,16 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
return test_step;
}
fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step {
return link.addTestStep(b, "macho-" ++ prefix, opts);
}
const addCppSourceBytes = link.addCppSourceBytes;
const addExecutable = link.addExecutable;
const addObject = link.addObject;
const addRunArtifact = link.addRunArtifact;
const addZigSourceBytes = link.addZigSourceBytes;
const addExecutable = link.addExecutable;
const expectLinkErrors = link.expectLinkErrors;
const link = @import("link.zig");
const std = @import("std");
const Build = std.Build;
const CrossTarget = std.zig.CrossTarget;
const Options = link.Options;
const Step = Build.Step;
const Step = std.Build.Step;

View File

@ -14,14 +14,14 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable;
const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse
@panic("macOS SDK is required to run the test");
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = b.host,
});
exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) });
exe.addIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include/c++/v1" }) });

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const exe = b.addExecutable(.{
.name = "test",

View File

@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const lib = b.addSharedLibrary(.{
.name = "a",

View File

@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const exe = b.addExecutable(.{
.name = "test",

View File

@ -4,7 +4,7 @@ pub const requires_symlinks = true;
pub fn build(b: *std.Build) void {
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const test_step = b.step("test", "Test the program");
b.default_step = test_step;
@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void {
fn createScenario(
b: *std.Build,
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
target: std.Build.ResolvedTarget,
name: []const u8,
) *std.Build.Step.Compile {
const exe = b.addExecutable(.{

View File

@ -52,6 +52,7 @@ fn createScenario(
const exe = b.addExecutable(.{
.name = name,
.optimize = optimize,
.target = b.host,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
exe.linkLibC();

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const dylib = b.addSharedLibrary(.{
.name = "a",
@ -55,7 +55,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
check_exe.checkInHeaders();
check_exe.checkExact("cmd RPATH");
check_exe.checkExactPath("path", dylib.getOutputDirectorySource());
check_exe.checkExactPath("path", dylib.getEmittedBinDirectory());
test_step.dependOn(&check_exe.step);
const run = b.addRunArtifact(exe);

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const exe = b.addExecutable(.{
.name = "test",

View File

@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "main",
.optimize = optimize,
.target = .{ .os_tag = .macos },
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibC();

View File

@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addStaticLibrary(.{
.name = "main",
.optimize = optimize,
.target = .{ .os_tag = .macos },
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
});
lib.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
lib.linkLibC();
@ -24,7 +24,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "main",
.optimize = optimize,
.target = .{ .os_tag = .macos },
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
});
exe.linkLibrary(lib);
exe.linkLibC();

View File

@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addSharedLibrary(.{
.name = "bootstrap",
.optimize = optimize,
.target = .{ .os_tag = .macos },
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
});
lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} });
lib.linkLibC();
@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "main",
.optimize = optimize,
.target = .{ .os_tag = .macos },
.target = b.resolveTargetQuery(.{ .os_tag = .macos }),
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibrary(lib);

View File

@ -112,6 +112,7 @@ fn simpleExe(
const exe = b.addExecutable(.{
.name = name,
.optimize = optimize,
.target = b.host,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibC();

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target = std.zig.CrossTarget{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const obj = b.addObject(.{
.name = "test",

View File

@ -19,6 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = b.host,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
exe.linkLibC();

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const dylib = b.addSharedLibrary(.{
.name = "a",
@ -33,7 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
exe.linkLibC();
exe.linkSystemLibraryNeeded("a");
exe.root_module.linkSystemLibrary("a", .{ .needed = true });
exe.addLibraryPath(dylib.getEmittedBinDirectory());
exe.addRPath(dylib.getEmittedBinDirectory());
exe.dead_strip_dylibs = true;

View File

@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = b.host,
});
exe.addIncludePath(.{ .path = "." });
exe.addCSourceFile(.{ .file = .{ .path = "Foo.m" }, .flags = &[0][]const u8{} });

View File

@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = b.host,
});
b.default_step.dependOn(&exe.step);
exe.addIncludePath(.{ .path = "." });

View File

@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
{
const exe = b.addExecutable(.{

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const lib = b.addStaticLibrary(.{
.name = "a",

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
{
// -search_dylibs_first
@ -45,9 +45,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
fn createScenario(
b: *std.Build,
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
target: std.Build.ResolvedTarget,
name: []const u8,
search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy,
search_strategy: std.Build.Module.SystemLib.SearchStrategy,
) *std.Build.Step.Compile {
const static = b.addStaticLibrary(.{
.name = name,

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const exe = b.addExecutable(.{
.name = "main",

View File

@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const exe = b.addExecutable(.{
.name = "main",

View File

@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const lib = b.addSharedLibrary(.{
.name = "a",

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const lib = b.addSharedLibrary(.{
.name = "a",

View File

@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
testUnwindInfo(b, test_step, optimize, target, false, "no-dead-strip");
testUnwindInfo(b, test_step, optimize, target, true, "yes-dead-strip");
@ -24,7 +24,7 @@ fn testUnwindInfo(
b: *std.Build,
test_step: *std.Build.Step,
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
target: std.Build.ResolvedTarget,
dead_strip: bool,
name: []const u8,
) void {
@ -66,7 +66,7 @@ fn testUnwindInfo(
fn createScenario(
b: *std.Build,
optimize: std.builtin.OptimizeMode,
target: std.zig.CrossTarget,
target: std.Build.ResolvedTarget,
name: []const u8,
) *std.Build.Step.Compile {
const exe = b.addExecutable(.{

View File

@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = b.host,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
exe.linkLibC();

View File

@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
const dylib = b.addSharedLibrary(.{
.name = "a",
@ -32,7 +32,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
exe.linkLibC();
exe.linkSystemLibraryWeak("a");
exe.root_module.linkSystemLibrary("a", .{ .weak = true });
exe.addLibraryPath(dylib.getEmittedBinDirectory());
exe.addRPath(dylib.getEmittedBinDirectory());

View File

@ -59,7 +59,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
.name = "test1",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{},
.target = b.host,
});
for (files) |file| {
@ -77,12 +77,12 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
{
const lib_a = b.addStaticLibrary(.{
.name = "test2_a",
.target = .{},
.target = b.host,
.optimize = optimize,
});
const lib_b = b.addStaticLibrary(.{
.name = "test2_b",
.target = .{},
.target = b.host,
.optimize = optimize,
});
@ -94,6 +94,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
const exe = b.addExecutable(.{
.name = "test2",
.root_source_file = .{ .path = "main.zig" },
.target = b.host,
.optimize = optimize,
});
exe.linkLibrary(lib_a);
@ -110,19 +111,19 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
{
const lib_a = b.addStaticLibrary(.{
.name = "test3_a",
.target = .{},
.target = b.host,
.optimize = optimize,
});
const lib_b = b.addStaticLibrary(.{
.name = "test3_b",
.target = .{},
.target = b.host,
.optimize = optimize,
});
for (files, 1..) |file, i| {
const obj = b.addObject(.{
.name = b.fmt("obj_{}", .{i}),
.target = .{},
.target = b.host,
.optimize = optimize,
});
obj.addCSourceFile(.{ .file = file, .flags = &flags });
@ -134,6 +135,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
const exe = b.addExecutable(.{
.name = "test3",
.root_source_file = .{ .path = "main.zig" },
.target = b.host,
.optimize = optimize,
});
exe.linkLibrary(lib_a);

View File

@ -20,11 +20,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
const check = lib.checkObject();
check.checkInHeaders();

View File

@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void {
.name = "lib",
.root_source_file = .{ .path = "main.zig" },
.optimize = .Debug,
.target = .{
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
.cpu_features_add = std.Target.wasm.featureSet(&.{.atomics}),
.os_tag = .freestanding,
},
}),
});
lib.entry = .disabled;
lib.use_llvm = false;

View File

@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize_mode,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
// to make sure the bss segment is emitted, we must import memory
lib.import_memory = true;
lib.link_gc_sections = false;
@ -65,13 +65,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib2.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize_mode,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
// to make sure the bss segment is emitted, we must import memory
lib.import_memory = true;
lib.link_gc_sections = false;

View File

@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
});
lib.entry = .disabled;
lib.use_lld = false;
lib.export_symbol_names = &.{ "foo", "bar" };
lib.root_module.export_symbol_names = &.{ "foo", "bar" };
lib.global_base = 0; // put data section at address 0 to make data symbols easier to parse
const check_lib = lib.checkObject();

View File

@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
.name = "no-export",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
});
no_export.entry = .disabled;
no_export.use_llvm = false;
@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
.name = "dynamic",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
});
dynamic_export.entry = .disabled;
dynamic_export.rdynamic = true;
@ -38,10 +38,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
.name = "force",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
});
force_export.entry = .disabled;
force_export.export_symbol_names = &.{"foo"};
force_export.root_module.export_symbol_names = &.{"foo"};
force_export.use_llvm = false;
force_export.use_lld = false;

View File

@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
});
lib.entry = .disabled;

View File

@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
.name = "extern",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .wasi },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }),
});
exe.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
exe.use_llvm = false;

View File

@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const import_table = b.addExecutable(.{
.name = "import_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
});
import_table.entry = .disabled;
@ -28,7 +28,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const export_table = b.addExecutable(.{
.name = "export_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
});
export_table.entry = .disabled;
@ -40,7 +40,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const regular_table = b.addExecutable(.{
.name = "regular_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
});
regular_table.entry = .disabled;

View File

@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void {
const c_obj = b.addObject(.{
.name = "c_obj",
.optimize = .Debug,
.target = .{
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge },
.os_tag = .freestanding,
},
}),
});
c_obj.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
@ -21,11 +21,11 @@ pub fn build(b: *std.Build) void {
.name = "lib",
.root_source_file = .{ .path = "main.zig" },
.optimize = .Debug,
.target = .{
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
.os_tag = .freestanding,
},
}),
});
lib.entry = .disabled;
lib.use_llvm = false;

View File

@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
b.installArtifact(lib);
const version_fmt = "version " ++ builtin.zig_version_string;

View File

@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
lib.link_gc_sections = false; // so data is not garbage collected and we can verify data section
b.installArtifact(lib);

View File

@ -21,16 +21,16 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
.os_tag = .freestanding,
},
.optimize = optimize_mode,
.strip = false,
.single_threaded = false,
});
lib.entry = .disabled;
lib.use_lld = false;
lib.strip = false;
lib.import_memory = true;
lib.export_memory = true;
lib.shared_memory = true;
lib.max_memory = 67108864;
lib.single_threaded = false;
lib.export_symbol_names = &.{"foo"};
lib.root_module.export_symbol_names = &.{"foo"};
const check_lib = lib.checkObject();

View File

@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size
lib.link_gc_sections = false;
b.installArtifact(lib);

View File

@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
.optimize = optimize,
.strip = false,
});
lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
b.installArtifact(lib);
const check_lib = lib.checkObject();

View File

@ -127,17 +127,21 @@ const targets = [_]std.zig.CrossTarget{
.{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none },
};
pub fn addCases(ctx: *Cases, build_options: @import("cases.zig").BuildOptions) !void {
pub fn addCases(
ctx: *Cases,
build_options: @import("cases.zig").BuildOptions,
b: *std.Build,
) !void {
if (!build_options.enable_llvm) return;
for (targets) |target| {
if (target.cpu_arch) |arch| switch (arch) {
for (targets) |target_query| {
if (target_query.cpu_arch) |arch| switch (arch) {
.m68k => if (!build_options.llvm_has_m68k) continue,
.csky => if (!build_options.llvm_has_csky) continue,
.arc => if (!build_options.llvm_has_arc) continue,
.xtensa => if (!build_options.llvm_has_xtensa) continue,
else => {},
};
var case = ctx.noEmitUsingLlvmBackend("llvm_targets", target);
var case = ctx.noEmitUsingLlvmBackend("llvm_targets", b.resolveTargetQuery(target_query));
case.addCompile("");
}
}

View File

@ -1,9 +1,14 @@
const std = @import("std");
const Cases = @import("src/Cases.zig");
pub fn addCases(ctx: *Cases) !void {
pub fn addCases(ctx: *Cases, b: *std.Build) !void {
const target = b.resolveTargetQuery(.{
.cpu_arch = .nvptx64,
.os_tag = .cuda,
});
{
var case = addPtx(ctx, "simple addition and subtraction");
var case = addPtx(ctx, target, "simple addition and subtraction");
case.addCompile(
\\fn add(a: i32, b: i32) i32 {
@ -20,7 +25,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = addPtx(ctx, "read special registers");
var case = addPtx(ctx, target, "read special registers");
case.addCompile(
\\fn threadIdX() u32 {
@ -37,7 +42,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = addPtx(ctx, "address spaces");
var case = addPtx(ctx, target, "address spaces");
case.addCompile(
\\var x: i32 addrspace(.global) = 0;
@ -50,7 +55,7 @@ pub fn addCases(ctx: *Cases) !void {
}
{
var case = addPtx(ctx, "reduce in shared mem");
var case = addPtx(ctx, target, "reduce in shared mem");
case.addCompile(
\\fn threadIdX() u32 {
\\ return asm ("mov.u32 \t%[r], %tid.x;"
@ -82,18 +87,10 @@ pub fn addCases(ctx: *Cases) !void {
}
}
const nvptx_target = std.zig.CrossTarget{
.cpu_arch = .nvptx64,
.os_tag = .cuda,
};
pub fn addPtx(
ctx: *Cases,
name: []const u8,
) *Cases.Case {
fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Cases.Case {
ctx.cases.append(.{
.name = name,
.target = nvptx_target,
.target = target,
.updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
.output_mode = .Obj,
.deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator),

View File

@ -76,7 +76,7 @@ pub const Case = struct {
name: []const u8,
/// The platform the test targets. For non-native platforms, an emulator
/// such as QEMU is required for tests to complete.
target: CrossTarget,
target: std.Build.ResolvedTarget,
/// In order to be able to run e.g. Execution updates, this must be set
/// to Executable.
output_mode: std.builtin.OutputMode,
@ -155,7 +155,7 @@ pub const Translate = struct {
name: []const u8,
input: [:0]const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
link_libc: bool,
c_frontend: CFrontend,
kind: union(enum) {
@ -171,7 +171,7 @@ pub const Translate = struct {
pub fn addExe(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
) *Case {
ctx.cases.append(Case{
.name = name,
@ -184,16 +184,16 @@ pub fn addExe(
}
/// Adds a test case for Zig input, producing an executable
pub fn exe(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
return ctx.addExe(name, target);
}
pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
var target_adjusted = target;
target_adjusted.ofmt = .c;
pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.zig.CrossTarget, b: *std.Build) *Case {
var adjusted_query = target_query;
adjusted_query.ofmt = .c;
ctx.cases.append(Case{
.name = name,
.target = target_adjusted,
.target = b.resolveTargetQuery(adjusted_query),
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Exe,
.deps = std.ArrayList(DepModule).init(ctx.arena),
@ -202,7 +202,7 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Cas
return &ctx.cases.items[ctx.cases.items.len - 1];
}
pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
ctx.cases.append(Case{
.name = name,
.target = target,
@ -217,7 +217,7 @@ pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget
/// Adds a test case that uses the LLVM backend to emit an executable.
/// Currently this implies linking libc, because only then we can generate a testable executable.
pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
ctx.cases.append(Case{
.name = name,
.target = target,
@ -233,7 +233,7 @@ pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *
pub fn addObj(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
) *Case {
ctx.cases.append(Case{
.name = name,
@ -248,7 +248,7 @@ pub fn addObj(
pub fn addTest(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
) *Case {
ctx.cases.append(Case{
.name = name,
@ -262,17 +262,17 @@ pub fn addTest(
}
/// Adds a test case for Zig input, producing an object file.
pub fn obj(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn obj(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
return ctx.addObj(name, target);
}
/// Adds a test case for ZIR input, producing an object file.
pub fn objZIR(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn objZIR(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
return ctx.addObj(name, target, .ZIR);
}
/// Adds a test case for Zig or ZIR input, producing C code.
pub fn addC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
var target_adjusted = target;
target_adjusted.ofmt = std.Target.ObjectFormat.c;
ctx.cases.append(Case{
@ -308,7 +308,7 @@ pub fn compareOutput(
pub fn addTransform(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
src: [:0]const u8,
result: [:0]const u8,
) void {
@ -320,7 +320,7 @@ pub fn addTransform(
pub fn transform(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
src: [:0]const u8,
result: [:0]const u8,
) void {
@ -330,7 +330,7 @@ pub fn transform(
pub fn addError(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
src: [:0]const u8,
expected_errors: []const []const u8,
) void {
@ -343,7 +343,7 @@ pub fn addError(
pub fn compileError(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
src: [:0]const u8,
expected_errors: []const []const u8,
) void {
@ -355,7 +355,7 @@ pub fn compileError(
pub fn addCompile(
ctx: *Cases,
name: []const u8,
target: CrossTarget,
target: std.Build.ResolvedTarget,
src: [:0]const u8,
) void {
ctx.addObj(name, target).addCompile(src);
@ -368,9 +368,9 @@ pub fn addCompile(
/// Each file should include a test manifest as a contiguous block of comments at
/// the end of the file. The first line should be the test type, followed by a set of
/// key-value config values, followed by a blank line, then the expected output.
pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir) void {
pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir, b: *std.Build) void {
var current_file: []const u8 = "none";
ctx.addFromDirInner(dir, &current_file) catch |err| {
ctx.addFromDirInner(dir, &current_file, b) catch |err| {
std.debug.panicExtra(
@errorReturnTrace(),
@returnAddress(),
@ -386,6 +386,7 @@ fn addFromDirInner(
/// This is kept up to date with the currently being processed file so
/// that if any errors occur the caller knows it happened during this file.
current_file: *[]const u8,
b: *std.Build,
) !void {
var it = try iterable_dir.walk(ctx.arena);
var filenames = std.ArrayList([]const u8).init(ctx.arena);
@ -422,7 +423,7 @@ fn addFromDirInner(
var manifest = try TestManifest.parse(ctx.arena, src);
const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend);
const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget);
const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.zig.CrossTarget);
const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
@ -430,12 +431,12 @@ fn addFromDirInner(
if (manifest.type == .translate_c) {
for (c_frontends) |c_frontend| {
for (targets) |target| {
for (targets) |target_query| {
const output = try manifest.trailingLinesSplit(ctx.arena);
try ctx.translate.append(.{
.name = std.fs.path.stem(filename),
.c_frontend = c_frontend,
.target = target,
.target = b.resolveTargetQuery(target_query),
.link_libc = link_libc,
.input = src,
.kind = .{ .translate = output },
@ -446,12 +447,12 @@ fn addFromDirInner(
}
if (manifest.type == .run_translated_c) {
for (c_frontends) |c_frontend| {
for (targets) |target| {
for (targets) |target_query| {
const output = try manifest.trailingSplit(ctx.arena);
try ctx.translate.append(.{
.name = std.fs.path.stem(filename),
.c_frontend = c_frontend,
.target = target,
.target = b.resolveTargetQuery(target_query),
.link_libc = link_libc,
.input = src,
.kind = .{ .run = output },
@ -464,16 +465,18 @@ fn addFromDirInner(
var cases = std.ArrayList(usize).init(ctx.arena);
// Cross-product to get all possible test combinations
for (backends) |backend| {
for (targets) |target| {
for (targets) |target_query| {
const resolved_target = b.resolveTargetQuery(target_query);
const target = resolved_target.target;
for (backends) |backend| {
if (backend == .stage2 and
target.getCpuArch() != .wasm32 and target.getCpuArch() != .x86_64)
target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64)
{
// Other backends don't support new liveness format
continue;
}
if (backend == .stage2 and target.getOsTag() == .macos and
target.getCpuArch() == .x86_64 and builtin.cpu.arch == .aarch64)
if (backend == .stage2 and target.os.tag == .macos and
target.cpu.arch == .x86_64 and builtin.cpu.arch == .aarch64)
{
// Rosetta has issues with ZLD
continue;
@ -482,7 +485,7 @@ fn addFromDirInner(
const next = ctx.cases.items.len;
try ctx.cases.append(.{
.name = std.fs.path.stem(filename),
.target = target,
.target = resolved_target,
.backend = backend,
.updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
.is_test = is_test,
@ -622,8 +625,8 @@ pub fn lowerToBuildSteps(
}
for (case.deps.items) |dep| {
artifact.addAnonymousModule(dep.name, .{
.source_file = file_sources.get(dep.path).?,
artifact.root_module.addAnonymousImport(dep.name, .{
.root_source_file = file_sources.get(dep.path).?,
});
}
@ -644,9 +647,8 @@ pub fn lowerToBuildSteps(
parent_step.dependOn(&artifact.step);
},
.Execution => |expected_stdout| no_exec: {
const run = if (case.target.ofmt == .c) run_step: {
const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err|
std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)});
const run = if (case.target.target.ofmt == .c) run_step: {
const target_info = case.target.toNativeTargetInfo();
if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) {
// We wouldn't be able to run the compiled C code.
break :no_exec;
@ -666,7 +668,7 @@ pub fn lowerToBuildSteps(
"--",
"-lc",
"-target",
case.target.zigTriple(b.allocator) catch @panic("OOM"),
case.target.target.zigTriple(b.allocator) catch @panic("OOM"),
});
run_c.addArtifactArg(artifact);
break :run_step run_c;
@ -692,8 +694,7 @@ pub fn lowerToBuildSteps(
continue; // Pass test.
}
const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err|
std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)});
const target_info = case.target.toNativeTargetInfo();
if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) {
// We wouldn't be able to run the compiled C code.
continue; // Pass test.
@ -1159,9 +1160,9 @@ const TestManifest = struct {
}
fn getDefaultParser(comptime T: type) ParseFn(T) {
if (T == CrossTarget) return struct {
if (T == std.zig.CrossTarget) return struct {
fn parse(str: []const u8) anyerror!T {
return CrossTarget.parse(.{ .arch_os_abi = str });
return std.zig.CrossTarget.parse(.{ .arch_os_abi = str });
}
}.parse;
@ -1198,7 +1199,6 @@ const builtin = @import("builtin");
const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const CrossTarget = std.zig.CrossTarget;
const Compilation = @import("../../src/Compilation.zig");
const zig_h = @import("../../src/link.zig").File.C.zig_h;
const introspect = @import("../../src/introspect.zig");
@ -1287,7 +1287,7 @@ pub fn main() !void {
if (cases.items.len == 0) {
const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend);
const targets = try manifest.getConfigForKeyAlloc(arena, "target", CrossTarget);
const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.zig.CrossTarget);
const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
@ -1295,12 +1295,12 @@ pub fn main() !void {
if (manifest.type == .translate_c) {
for (c_frontends) |c_frontend| {
for (targets) |target| {
for (targets) |target_query| {
const output = try manifest.trailingLinesSplit(ctx.arena);
try ctx.translate.append(.{
.name = std.fs.path.stem(filename),
.c_frontend = c_frontend,
.target = target,
.target = resolveTargetQuery(target_query),
.is_test = is_test,
.link_libc = link_libc,
.input = src,
@ -1312,12 +1312,12 @@ pub fn main() !void {
}
if (manifest.type == .run_translated_c) {
for (c_frontends) |c_frontend| {
for (targets) |target| {
for (targets) |target_query| {
const output = try manifest.trailingSplit(ctx.arena);
try ctx.translate.append(.{
.name = std.fs.path.stem(filename),
.c_frontend = c_frontend,
.target = target,
.target = resolveTargetQuery(target_query),
.is_test = is_test,
.link_libc = link_libc,
.output = output,
@ -1385,6 +1385,17 @@ pub fn main() !void {
return runCases(&ctx, zig_exe_path);
}
fn resolveTargetQuery(query: std.zig.CrossTarget) std.Build.ResolvedTarget {
const result = std.zig.system.NativeTargetInfo.detect(query) catch
@panic("unable to resolve target query");
return .{
.query = query,
.target = result.target,
.dynamic_linker = result.dynamic_linker,
};
}
fn runCases(self: *Cases, zig_exe_path: []const u8) !void {
const host = try std.zig.system.NativeTargetInfo.detect(.{});

View File

@ -96,7 +96,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
const exe = b.addExecutable(.{
.name = "test",
.target = .{},
.target = b.host,
.optimize = .Debug,
});
exe.addAssemblyFile(write_src.files.items[0].getPath());
@ -121,7 +121,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
.name = "test",
.root_source_file = write_src.files.items[0].getPath(),
.optimize = optimize,
.target = .{},
.target = b.host,
});
if (case.link_libc) {
exe.linkSystemLibrary("c");
@ -146,7 +146,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = write_src.files.items[0].getPath(),
.target = .{},
.target = b.host,
.optimize = .Debug,
});
if (case.link_libc) {

View File

@ -77,7 +77,7 @@ fn addExpect(
.name = "test",
.root_source_file = write_src.files.items[0].getPath(),
.optimize = optimize_mode,
.target = .{},
.target = b.host,
});
const run = b.addRunArtifact(exe);

View File

@ -11,7 +11,7 @@ pub const RunTranslatedCContext = struct {
step: *std.Build.Step,
test_index: usize,
test_filter: ?[]const u8,
target: std.zig.CrossTarget,
target: std.Build.ResolvedTarget,
const TestCase = struct {
name: []const u8,
@ -86,7 +86,7 @@ pub const RunTranslatedCContext = struct {
}
const translate_c = b.addTranslateC(.{
.source_file = write_src.files.items[0].getPath(),
.target = .{},
.target = b.host,
.optimize = .Debug,
});

View File

@ -18,7 +18,7 @@ pub const TranslateCContext = struct {
sources: ArrayList(SourceFile),
expected_lines: ArrayList([]const u8),
allow_warnings: bool,
target: CrossTarget = CrossTarget{},
target: CrossTarget = .{},
const SourceFile = struct {
filename: []const u8,
@ -109,7 +109,7 @@ pub const TranslateCContext = struct {
const translate_c = b.addTranslateC(.{
.source_file = write_src.files.items[0].getPath(),
.target = case.target,
.target = b.resolveTargetQuery(case.target),
.optimize = .Debug,
});

View File

@ -89,10 +89,6 @@ pub const build_cases = [_]BuildCase{
// .build_root = "test/standalone/issue_13970",
// .import = @import("standalone/issue_13970/build.zig"),
//},
.{
.build_root = "test/standalone/main_pkg_path",
.import = @import("standalone/main_pkg_path/build.zig"),
},
.{
.build_root = "test/standalone/shared_library",
.import = @import("standalone/shared_library/build.zig"),

View File

@ -23,7 +23,7 @@ fn add(
cpp_name: []const u8,
optimize: std.builtin.OptimizeMode,
) void {
const target: std.zig.CrossTarget = .{};
const target = b.host;
const exe_c = b.addExecutable(.{
.name = c_name,
@ -42,7 +42,7 @@ fn add(
exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} });
exe_cpp.linkLibCpp();
switch (target.getOsTag()) {
switch (target.target.os.tag) {
.windows => {
// https://github.com/ziglang/zig/issues/8531
exe_cpp.want_lto = false;

View File

@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{};
const target = b.host;
if (builtin.os.tag == .wasi) return;

View File

@ -4,16 +4,16 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const target = b.standardTargetOptions(.{});
const resolved_target = b.standardTargetOptions(.{});
const target = resolved_target.target;
const optimize = b.standardOptimizeOption(.{});
const abi = target.getAbi();
if (target.getObjectFormat() != .elf or !(abi.isMusl() or abi.isGnu())) return;
if (target.ofmt != .elf or !(target.abi.isMusl() or target.abi.isGnu())) return;
const exe = b.addExecutable(.{
.name = "main",
.optimize = optimize,
.target = target,
.target = resolved_target,
});
exe.linkLibC();
exe.addCSourceFile(.{

View File

@ -7,21 +7,22 @@ pub fn build(b: *std.Build) void {
const optimize: std.builtin.OptimizeMode = .Debug;
const shared = b.createModule(.{
.source_file = .{ .path = "shared.zig" },
.root_source_file = .{ .path = "shared.zig" },
});
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.target = b.host,
.optimize = optimize,
});
exe.addAnonymousModule("foo", .{
.source_file = .{ .path = "foo.zig" },
.dependencies = &.{.{ .name = "shared", .module = shared }},
exe.root_module.addAnonymousImport("foo", .{
.root_source_file = .{ .path = "foo.zig" },
.imports = &.{.{ .name = "shared", .module = shared }},
});
exe.addAnonymousModule("bar", .{
.source_file = .{ .path = "bar.zig" },
.dependencies = &.{.{ .name = "shared", .module = shared }},
exe.root_module.addAnonymousImport("bar", .{
.root_source_file = .{ .path = "bar.zig" },
.imports = &.{.{ .name = "shared", .module = shared }},
});
const run = b.addRunArtifact(exe);

View File

@ -7,20 +7,21 @@ pub fn build(b: *std.Build) void {
const optimize: std.builtin.OptimizeMode = .Debug;
const foo = b.createModule(.{
.source_file = .{ .path = "foo.zig" },
.root_source_file = .{ .path = "foo.zig" },
});
const bar = b.createModule(.{
.source_file = .{ .path = "bar.zig" },
.root_source_file = .{ .path = "bar.zig" },
});
foo.dependencies.put("bar", bar) catch @panic("OOM");
bar.dependencies.put("foo", foo) catch @panic("OOM");
foo.addImport("bar", bar);
bar.addImport("foo", foo);
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.target = b.host,
.optimize = optimize,
});
exe.addModule("foo", foo);
exe.root_module.addImport("foo", foo);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);

View File

@ -7,16 +7,17 @@ pub fn build(b: *std.Build) void {
const optimize: std.builtin.OptimizeMode = .Debug;
const foo = b.createModule(.{
.source_file = .{ .path = "foo.zig" },
.root_source_file = .{ .path = "foo.zig" },
});
foo.dependencies.put("foo", foo) catch @panic("OOM");
foo.addImport("foo", foo);
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.target = b.host,
.optimize = optimize,
});
exe.addModule("foo", foo);
exe.root_module.addImport("foo", foo);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);

View File

@ -9,10 +9,11 @@ pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.target = b.host,
.optimize = optimize,
});
exe.addAnonymousModule("foo", .{
.source_file = .{ .path = "foo.zig" },
exe.root_module.addAnonymousImport("foo", .{
.root_source_file = .{ .path = "foo.zig" },
});
const run = b.addRunArtifact(exe);

View File

@ -7,19 +7,20 @@ pub fn build(b: *std.Build) void {
const optimize: std.builtin.OptimizeMode = .Debug;
const shared = b.createModule(.{
.source_file = .{ .path = "shared.zig" },
.root_source_file = .{ .path = "shared.zig" },
});
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.target = b.host,
.optimize = optimize,
});
exe.addAnonymousModule("foo", .{
.source_file = .{ .path = "foo.zig" },
.dependencies = &.{.{ .name = "shared", .module = shared }},
exe.root_module.addAnonymousImport("foo", .{
.root_source_file = .{ .path = "foo.zig" },
.imports = &.{.{ .name = "shared", .module = shared }},
});
exe.addModule("shared", shared);
exe.root_module.addImport("shared", shared);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);

View File

@ -7,10 +7,10 @@ pub fn build(b: *std.Build) void {
const bootloader = b.addExecutable(.{
.name = "bootloader",
.root_source_file = .{ .path = "bootloader.zig" },
.target = .{
.target = b.resolveTargetQuery(.{
.cpu_arch = .x86,
.os_tag = .freestanding,
},
}),
.optimize = .ReleaseSmall,
});
@ -18,8 +18,8 @@ pub fn build(b: *std.Build) void {
.root_source_file = .{ .path = "main.zig" },
.optimize = .Debug,
});
exe.addAnonymousModule("bootloader.elf", .{
.source_file = bootloader.getEmittedBin(),
exe.root_module.addAnonymousImport("bootloader.elf", .{
.root_source_file = bootloader.getEmittedBin(),
});
// TODO: actually check the output

View File

@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void {
const main = b.addExecutable(.{
.name = "main",
.root_source_file = .{ .path = "main.zig" },
.target = b.host,
.optimize = optimize,
});

View File

@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
const obj = b.addObject(.{
.name = "exports",
.root_source_file = .{ .path = "exports.zig" },
.target = .{},
.target = b.host,
.optimize = optimize,
});
const main = b.addTest(.{

View File

@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{};
const target = b.host;
const obj1 = b.addStaticLibrary(.{
.name = "obj1",

View File

@ -5,12 +5,12 @@ pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const target = .{
const target = b.resolveTargetQuery(.{
.cpu_arch = .thumb,
.cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
.os_tag = .freestanding,
.abi = .gnueabihf,
};
});
const optimize: std.builtin.OptimizeMode = .Debug;

View File

@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{
const target = b.resolveTargetQuery(.{
.cpu_arch = .aarch64,
.os_tag = .ios,
};
const target_info = std.zig.system.NativeTargetInfo.detect(target) catch @panic("couldn't detect native target");
const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse @panic("no iOS SDK found");
});
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse
@panic("no iOS SDK found");
b.sysroot = sdk;
const exe = b.addExecutable(.{

View File

@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{};
const target = b.host;
if (builtin.os.tag == .windows) {
// https://github.com/ziglang/zig/issues/12419

View File

@ -5,13 +5,12 @@ pub fn build(b: *std.Build) void {
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{};
const obj = b.addObject(.{
.name = "main",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = target,
.target = b.host,
});
_ = obj.getEmittedLlvmIr();
_ = obj.getEmittedLlvmBc();

View File

@ -1,13 +1,12 @@
const std = @import("std");
const builtin = @import("builtin");
const CrossTarget = std.zig.CrossTarget;
pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
const optimize: std.builtin.OptimizeMode = .Debug;
const target: std.zig.CrossTarget = .{};
const target = b.host;
const exe = b.addExecutable(.{
.name = "main",

Some files were not shown because too many files have changed in this diff Show More