Commit b6556c944b
Changed files (13)
doc/docgen.zig
@@ -4,7 +4,7 @@ const io = std.io;
const fs = std.fs;
const process = std.process;
const ChildProcess = std.ChildProcess;
-const warn = std.debug.warn;
+const print = std.debug.print;
const mem = std.mem;
const testing = std.testing;
@@ -215,23 +215,23 @@ const Tokenizer = struct {
fn parseError(tokenizer: *Tokenizer, token: Token, comptime fmt: []const u8, args: anytype) anyerror {
const loc = tokenizer.getTokenLocation(token);
const args_prefix = .{ tokenizer.source_file_name, loc.line + 1, loc.column + 1 };
- warn("{}:{}:{}: error: " ++ fmt ++ "\n", args_prefix ++ args);
+ print("{}:{}:{}: error: " ++ fmt ++ "\n", args_prefix ++ args);
if (loc.line_start <= loc.line_end) {
- warn("{}\n", .{tokenizer.buffer[loc.line_start..loc.line_end]});
+ print("{}\n", .{tokenizer.buffer[loc.line_start..loc.line_end]});
{
var i: usize = 0;
while (i < loc.column) : (i += 1) {
- warn(" ", .{});
+ print(" ", .{});
}
}
{
const caret_count = token.end - token.start;
var i: usize = 0;
while (i < caret_count) : (i += 1) {
- warn("~", .{});
+ print("~", .{});
}
}
- warn("\n", .{});
+ print("\n", .{});
}
return error.ParseError;
}
@@ -274,6 +274,7 @@ const Code = struct {
link_objects: []const []const u8,
target_str: ?[]const u8,
link_libc: bool,
+ disable_cache: bool,
const Id = union(enum) {
Test,
@@ -522,6 +523,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
defer link_objects.deinit();
var target_str: ?[]const u8 = null;
var link_libc = false;
+ var disable_cache = false;
const source_token = while (true) {
const content_tok = try eatToken(tokenizer, Token.Id.Content);
@@ -532,6 +534,8 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
mode = .ReleaseFast;
} else if (mem.eql(u8, end_tag_name, "code_release_safe")) {
mode = .ReleaseSafe;
+ } else if (mem.eql(u8, end_tag_name, "code_disable_cache")) {
+ disable_cache = true;
} else if (mem.eql(u8, end_tag_name, "code_link_object")) {
_ = try eatToken(tokenizer, Token.Id.Separator);
const obj_tok = try eatToken(tokenizer, Token.Id.TagContent);
@@ -572,6 +576,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
.link_objects = link_objects.toOwnedSlice(),
.target_str = target_str,
.link_libc = link_libc,
+ .disable_cache = disable_cache,
},
});
tokenizer.code_node_count += 1;
@@ -1032,7 +1037,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
},
.Code => |code| {
code_progress_index += 1;
- warn("docgen example code {}/{}...", .{ code_progress_index, tokenizer.code_node_count });
+ print("docgen example code {}/{}...", .{ code_progress_index, tokenizer.code_node_count });
const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
@@ -1055,30 +1060,17 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
var build_args = std.ArrayList([]const u8).init(allocator);
defer build_args.deinit();
try build_args.appendSlice(&[_][]const u8{
- zig_exe,
- "build-exe",
- tmp_source_file_name,
- "--name",
- code.name,
- "--color",
- "on",
- "--cache",
- "on",
+ zig_exe, "build-exe",
+ "--name", code.name,
+ "--color", "on",
+ "--enable-cache", tmp_source_file_name,
});
try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", .{code.name});
switch (code.mode) {
.Debug => {},
- .ReleaseSafe => {
- try build_args.append("--release-safe");
- try out.print(" --release-safe", .{});
- },
- .ReleaseFast => {
- try build_args.append("--release-fast");
- try out.print(" --release-fast", .{});
- },
- .ReleaseSmall => {
- try build_args.append("--release-small");
- try out.print(" --release-small", .{});
+ else => {
+ try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
+ try out.print(" -O {s}", .{@tagName(code.mode)});
},
}
for (code.link_objects) |link_object| {
@@ -1087,9 +1079,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
allocator,
&[_][]const u8{ tmp_dir_name, name_with_ext },
);
- try build_args.append("--object");
try build_args.append(full_path_object);
- try out.print(" --object {}", .{name_with_ext});
+ try out.print(" {s}", .{name_with_ext});
}
if (code.link_libc) {
try build_args.append("-lc");
@@ -1114,20 +1105,14 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
switch (result.term) {
.Exited => |exit_code| {
if (exit_code == 0) {
- warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
- for (build_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
+ dumpArgs(build_args.items);
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
}
},
else => {
- warn("{}\nThe following command crashed:\n", .{result.stderr});
- for (build_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command crashed:\n", .{result.stderr});
+ dumpArgs(build_args.items);
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
},
}
@@ -1174,11 +1159,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
switch (result.term) {
.Exited => |exit_code| {
if (exit_code == 0) {
- warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
- for (run_args) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
+ dumpArgs(run_args);
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
}
},
@@ -1206,27 +1188,13 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
- try test_args.appendSlice(&[_][]const u8{
- zig_exe,
- "test",
- tmp_source_file_name,
- "--cache",
- "on",
- });
+ try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name});
switch (code.mode) {
.Debug => {},
- .ReleaseSafe => {
- try test_args.append("--release-safe");
- try out.print(" --release-safe", .{});
- },
- .ReleaseFast => {
- try test_args.append("--release-fast");
- try out.print(" --release-fast", .{});
- },
- .ReleaseSmall => {
- try test_args.append("--release-small");
- try out.print(" --release-small", .{});
+ else => {
+ try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
+ try out.print(" -O {s}", .{@tagName(code.mode)});
},
}
if (code.link_libc) {
@@ -1252,23 +1220,13 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
"--color",
"on",
tmp_source_file_name,
- "--output-dir",
- tmp_dir_name,
});
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name});
switch (code.mode) {
.Debug => {},
- .ReleaseSafe => {
- try test_args.append("--release-safe");
- try out.print(" --release-safe", .{});
- },
- .ReleaseFast => {
- try test_args.append("--release-fast");
- try out.print(" --release-fast", .{});
- },
- .ReleaseSmall => {
- try test_args.append("--release-small");
- try out.print(" --release-small", .{});
+ else => {
+ try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
+ try out.print(" -O {s}", .{@tagName(code.mode)});
},
}
const result = try ChildProcess.exec(.{
@@ -1280,25 +1238,19 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
switch (result.term) {
.Exited => |exit_code| {
if (exit_code == 0) {
- warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
- for (test_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
+ dumpArgs(test_args.items);
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
}
},
else => {
- warn("{}\nThe following command crashed:\n", .{result.stderr});
- for (test_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command crashed:\n", .{result.stderr});
+ dumpArgs(test_args.items);
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
- warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
+ print("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
return parseError(tokenizer, code.source_token, "example did not have expected compile error", .{});
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
@@ -1314,23 +1266,21 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
zig_exe,
"test",
tmp_source_file_name,
- "--output-dir",
- tmp_dir_name,
});
var mode_arg: []const u8 = "";
switch (code.mode) {
.Debug => {},
.ReleaseSafe => {
- try test_args.append("--release-safe");
- mode_arg = " --release-safe";
+ try test_args.append("-OReleaseSafe");
+ mode_arg = "-OReleaseSafe";
},
.ReleaseFast => {
- try test_args.append("--release-fast");
- mode_arg = " --release-fast";
+ try test_args.append("-OReleaseFast");
+ mode_arg = "-OReleaseFast";
},
.ReleaseSmall => {
- try test_args.append("--release-small");
- mode_arg = " --release-small";
+ try test_args.append("-OReleaseSmall");
+ mode_arg = "-OReleaseSmall";
},
}
@@ -1343,25 +1293,19 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
switch (result.term) {
.Exited => |exit_code| {
if (exit_code == 0) {
- warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
- for (test_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
+ dumpArgs(test_args.items);
return parseError(tokenizer, code.source_token, "example test incorrectly succeeded", .{});
}
},
else => {
- warn("{}\nThe following command crashed:\n", .{result.stderr});
- for (test_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command crashed:\n", .{result.stderr});
+ dumpArgs(test_args.items);
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
- warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
+ print("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message", .{});
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
@@ -1395,32 +1339,20 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
"on",
"--name",
code.name,
- "--output-dir",
- tmp_dir_name,
+ try std.fmt.allocPrint(allocator, "-femit-bin={s}{c}{s}", .{
+ tmp_dir_name, fs.path.sep, name_plus_obj_ext,
+ }),
});
-
if (!code.is_inline) {
try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", .{code.name});
}
switch (code.mode) {
.Debug => {},
- .ReleaseSafe => {
- try build_args.append("--release-safe");
- if (!code.is_inline) {
- try out.print(" --release-safe", .{});
- }
- },
- .ReleaseFast => {
- try build_args.append("--release-fast");
- if (!code.is_inline) {
- try out.print(" --release-fast", .{});
- }
- },
- .ReleaseSmall => {
- try build_args.append("--release-small");
+ else => {
+ try build_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
if (!code.is_inline) {
- try out.print(" --release-small", .{});
+ try out.print(" -O {s}", .{@tagName(code.mode)});
}
},
}
@@ -1440,25 +1372,19 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
switch (result.term) {
.Exited => |exit_code| {
if (exit_code == 0) {
- warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
- for (build_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
+ dumpArgs(build_args.items);
return parseError(tokenizer, code.source_token, "example build incorrectly succeeded", .{});
}
},
else => {
- warn("{}\nThe following command crashed:\n", .{result.stderr});
- for (build_args.items) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command crashed:\n", .{result.stderr});
+ dumpArgs(build_args.items);
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
},
}
if (mem.indexOf(u8, result.stderr, error_match) == null) {
- warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
+ print("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
return parseError(tokenizer, code.source_token, "example did not have expected compile error message", .{});
}
const escaped_stderr = try escapeHtml(allocator, result.stderr);
@@ -1472,6 +1398,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
}
},
Code.Id.Lib => {
+ const bin_basename = try std.zig.binNameAlloc(allocator, .{
+ .root_name = code.name,
+ .target = std.Target.current,
+ .output_mode = .Lib,
+ });
+
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
@@ -1479,23 +1411,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
zig_exe,
"build-lib",
tmp_source_file_name,
- "--output-dir",
- tmp_dir_name,
+ try std.fmt.allocPrint(allocator, "-femit-bin={s}{s}{s}", .{
+ tmp_dir_name, fs.path.sep_str, bin_basename,
+ }),
});
try out.print("<pre><code class=\"shell\">$ zig build-lib {}.zig", .{code.name});
switch (code.mode) {
.Debug => {},
- .ReleaseSafe => {
- try test_args.append("--release-safe");
- try out.print(" --release-safe", .{});
- },
- .ReleaseFast => {
- try test_args.append("--release-fast");
- try out.print(" --release-fast", .{});
- },
- .ReleaseSmall => {
- try test_args.append("--release-small");
- try out.print(" --release-small", .{});
+ else => {
+ try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
+ try out.print(" -O {s}", .{@tagName(code.mode)});
},
}
if (code.target_str) |triple| {
@@ -1508,7 +1433,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: any
try out.print("\n{}{}</code></pre>\n", .{ escaped_stderr, escaped_stdout });
},
}
- warn("OK\n", .{});
+ print("OK\n", .{});
},
}
}
@@ -1524,20 +1449,14 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
switch (result.term) {
.Exited => |exit_code| {
if (exit_code != 0) {
- warn("{}\nThe following command exited with code {}:\n", .{ result.stderr, exit_code });
- for (args) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command exited with code {}:\n", .{ result.stderr, exit_code });
+ dumpArgs(args);
return error.ChildExitError;
}
},
else => {
- warn("{}\nThe following command crashed:\n", .{result.stderr});
- for (args) |arg|
- warn("{} ", .{arg})
- else
- warn("\n", .{});
+ print("{}\nThe following command crashed:\n", .{result.stderr});
+ dumpArgs(args);
return error.ChildCrashed;
},
}
@@ -1545,9 +1464,13 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
}
fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
- const result = try exec(allocator, env_map, &[_][]const u8{
- zig_exe,
- "builtin",
- });
+ const result = try exec(allocator, env_map, &[_][]const u8{ zig_exe, "build-obj", "--show-builtin" });
return result.stdout;
}
+
+fn dumpArgs(args: []const []const u8) void {
+ for (args) |arg|
+ print("{} ", .{arg})
+ else
+ print("\n", .{});
+}
doc/langref.html.in
@@ -1078,6 +1078,7 @@ const nan = std.math.nan(f128);
but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:</p>
{#code_begin|obj|foo#}
{#code_release_fast#}
+ {#code_disable_cache#}
const std = @import("std");
const builtin = std.builtin;
const big = @as(f64, 1 << 40);
lib/std/log.zig
@@ -101,14 +101,12 @@ pub const Level = enum {
debug,
};
-/// The default log level is based on build mode. Note that in ReleaseSmall
-/// builds the default level is emerg but no messages will be stored/logged
-/// by the default logger to save space.
+/// The default log level is based on build mode.
pub const default_level: Level = switch (builtin.mode) {
.Debug => .debug,
.ReleaseSafe => .notice,
.ReleaseFast => .err,
- .ReleaseSmall => .emerg,
+ .ReleaseSmall => .err,
};
/// The current log level. This is set to root.log_level if present, otherwise
@@ -131,7 +129,7 @@ fn log(
// On freestanding one must provide a log function; we do not have
// any I/O configured.
return;
- } else if (builtin.mode != .ReleaseSmall) {
+ } else {
const level_txt = switch (message_level) {
.emerg => "emergency",
.alert => "alert",
src/stage1/stage1.h
@@ -117,8 +117,8 @@ struct Stage2ProgressNode;
enum BuildMode {
BuildModeDebug,
- BuildModeFastRelease,
BuildModeSafeRelease,
+ BuildModeFastRelease,
BuildModeSmallRelease,
};
src/stage1/zig0.cpp
@@ -33,7 +33,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
"Options:\n"
" --color [auto|off|on] enable or disable colored error messages\n"
" --name [name] override output name\n"
- " --output-dir [dir] override output directory (defaults to cwd)\n"
+ " -femit-bin=[path] Output machine code\n"
" --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
" --pkg-end pop current pkg\n"
" -ODebug build with optimizations on and safety off\n"
src/Compilation.zig
@@ -714,6 +714,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
};
};
+ if (!use_llvm and options.emit_h != null) {
+ fatal("TODO implement support for -femit-h in the self-hosted backend", .{});
+ }
+
const bin_file = try link.File.openPath(gpa, .{
.emit = bin_file_emit,
.root_name = root_name,
@@ -1313,13 +1317,13 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest });
var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
defer zig_cache_tmp_dir.close();
- const cimport_c_basename = "cimport.c";
+ const cimport_basename = "cimport.h";
const out_h_path = try comp.local_cache_directory.join(arena, &[_][]const u8{
- tmp_dir_sub_path, cimport_c_basename,
+ tmp_dir_sub_path, cimport_basename,
});
const out_dep_path = try std.fmt.allocPrint(arena, "{}.d", .{out_h_path});
- try zig_cache_tmp_dir.writeFile(cimport_c_basename, c_src);
+ try zig_cache_tmp_dir.writeFile(cimport_basename, c_src);
if (comp.verbose_cimport) {
log.info("C import source: {}", .{out_h_path});
}
@@ -2542,6 +2546,9 @@ fn updateStage1Module(comp: *Compilation) !void {
});
break :blk try directory.join(arena, &[_][]const u8{bin_basename});
} else "";
+ if (comp.emit_h != null) {
+ log.warn("-femit-h is not available in the stage1 backend; no .h file will be produced", .{});
+ }
const emit_h_path = try stage1LocPath(arena, comp.emit_h, directory);
const emit_asm_path = try stage1LocPath(arena, comp.emit_asm, directory);
const emit_llvm_ir_path = try stage1LocPath(arena, comp.emit_llvm_ir, directory);
src/main.zig
@@ -7,16 +7,18 @@ const process = std.process;
const Allocator = mem.Allocator;
const ArrayList = std.ArrayList;
const ast = std.zig.ast;
+const warn = std.log.warn;
+
const Compilation = @import("Compilation.zig");
const link = @import("link.zig");
const Package = @import("Package.zig");
const zir = @import("zir.zig");
const build_options = @import("build_options");
-const warn = std.log.warn;
const introspect = @import("introspect.zig");
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
const translate_c = @import("translate_c.zig");
const Cache = @import("Cache.zig");
+const target_util = @import("target.zig");
pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
std.log.emerg(format, args);
@@ -773,6 +775,7 @@ fn buildOutputType(
dll_export_fns = false;
} else if (mem.eql(u8, arg, "--show-builtin")) {
show_builtin = true;
+ emit_bin = .no;
} else if (mem.eql(u8, arg, "--strip")) {
strip = true;
} else if (mem.eql(u8, arg, "--single-threaded")) {
@@ -1219,12 +1222,12 @@ fn buildOutputType(
var i: usize = 0;
while (i < system_libs.items.len) {
const lib_name = system_libs.items[i];
- if (is_libc_lib_name(target_info.target, lib_name)) {
+ if (target_util.is_libc_lib_name(target_info.target, lib_name)) {
link_libc = true;
_ = system_libs.orderedRemove(i);
continue;
}
- if (is_libcpp_lib_name(target_info.target, lib_name)) {
+ if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) {
link_libcpp = true;
_ = system_libs.orderedRemove(i);
continue;
@@ -2809,62 +2812,6 @@ pub const ClangArgIterator = struct {
}
};
-fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
- if (ignore_case) {
- return std.ascii.eqlIgnoreCase(a, b);
- } else {
- return mem.eql(u8, a, b);
- }
-}
-
-fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
- const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
-
- if (eqlIgnoreCase(ignore_case, name, "c"))
- return true;
-
- if (target.isMinGW()) {
- if (eqlIgnoreCase(ignore_case, name, "m"))
- return true;
-
- return false;
- }
-
- if (target.abi.isGnu() or target.abi.isMusl() or target.os.tag.isDarwin()) {
- if (eqlIgnoreCase(ignore_case, name, "m"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "rt"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "pthread"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "crypt"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "util"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "xnet"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "resolv"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "dl"))
- return true;
- if (eqlIgnoreCase(ignore_case, name, "util"))
- return true;
- }
-
- if (target.os.tag.isDarwin() and eqlIgnoreCase(ignore_case, name, "System"))
- return true;
-
- return false;
-}
-
-fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool {
- const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
-
- return eqlIgnoreCase(ignore_case, name, "c++") or
- eqlIgnoreCase(ignore_case, name, "stdc++") or
- eqlIgnoreCase(ignore_case, name, "c++abi");
-}
-
fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {
return std.meta.stringToEnum(std.builtin.CodeModel, arg) orelse
fatal("unsupported machine code model: '{}'", .{arg});
src/stage1.zig
@@ -5,13 +5,15 @@
const std = @import("std");
const assert = std.debug.assert;
const mem = std.mem;
+const CrossTarget = std.zig.CrossTarget;
+const Target = std.Target;
+
const build_options = @import("build_options");
const stage2 = @import("main.zig");
const fatal = stage2.fatal;
-const CrossTarget = std.zig.CrossTarget;
-const Target = std.Target;
const Compilation = @import("Compilation.zig");
const translate_c = @import("translate_c.zig");
+const target_util = @import("target.zig");
comptime {
assert(std.builtin.link_libc);
@@ -370,7 +372,25 @@ export fn stage2_add_link_lib(
symbol_name_ptr: [*c]const u8,
symbol_name_len: usize,
) ?[*:0]const u8 {
- return null; // no error
+ const comp = @intToPtr(*Compilation, stage1.userdata);
+ const lib_name = lib_name_ptr[0..lib_name_len];
+ const symbol_name = symbol_name_ptr[0..symbol_name_len];
+ const target = comp.getTarget();
+ const is_libc = target_util.is_libc_lib_name(target, lib_name);
+ if (is_libc and !comp.bin_file.options.link_libc) {
+ return "dependency on libc must be explicitly specified in the build command";
+ }
+
+ if (!is_libc and !target.isWasm() and !comp.bin_file.options.pic) {
+ const msg = std.fmt.allocPrint0(
+ comp.gpa,
+ "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
+ .{ lib_name, lib_name },
+ ) catch return "out of memory";
+ return msg.ptr;
+ }
+
+ return null;
}
export fn stage2_fetch_file(
src/target.zig
@@ -223,3 +223,59 @@ pub fn osToLLVM(os_tag: std.Target.Os.Tag) llvm.OSType {
.emscripten => .Emscripten,
};
}
+
+fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
+ if (ignore_case) {
+ return std.ascii.eqlIgnoreCase(a, b);
+ } else {
+ return std.mem.eql(u8, a, b);
+ }
+}
+
+pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
+ const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
+
+ if (eqlIgnoreCase(ignore_case, name, "c"))
+ return true;
+
+ if (target.isMinGW()) {
+ if (eqlIgnoreCase(ignore_case, name, "m"))
+ return true;
+
+ return false;
+ }
+
+ if (target.abi.isGnu() or target.abi.isMusl() or target.os.tag.isDarwin()) {
+ if (eqlIgnoreCase(ignore_case, name, "m"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "rt"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "pthread"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "crypt"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "util"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "xnet"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "resolv"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "dl"))
+ return true;
+ if (eqlIgnoreCase(ignore_case, name, "util"))
+ return true;
+ }
+
+ if (target.os.tag.isDarwin() and eqlIgnoreCase(ignore_case, name, "System"))
+ return true;
+
+ return false;
+}
+
+pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool {
+ const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
+
+ return eqlIgnoreCase(ignore_case, name, "c++") or
+ eqlIgnoreCase(ignore_case, name, "stdc++") or
+ eqlIgnoreCase(ignore_case, name, "c++abi");
+}
test/compile_errors.zig
@@ -2347,7 +2347,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ exit(0);
\\}
, &[_][]const u8{
- "tmp.zig:3:5: error: dependency on library c must be explicitly specified in the build command",
+ "tmp.zig:3:5: error: dependency on libc must be explicitly specified in the build command",
});
cases.addTest("libc headers note",
test/tests.zig
@@ -634,7 +634,7 @@ pub const StackTracesContext = struct {
warn("Test {}/{} {}...", .{ self.test_index + 1, self.context.test_index, self.name });
- const child = std.ChildProcess.init(args.span(), b.allocator) catch unreachable;
+ const child = std.ChildProcess.init(args.items, b.allocator) catch unreachable;
defer child.deinit();
child.stdin_behavior = .Ignore;
@@ -643,7 +643,7 @@ pub const StackTracesContext = struct {
child.env_map = b.env_map;
if (b.verbose) {
- printInvocation(args.span());
+ printInvocation(args.items);
}
child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", .{ full_exe_path, @errorName(err) });
@@ -666,23 +666,23 @@ pub const StackTracesContext = struct {
code,
expect_code,
});
- printInvocation(args.span());
+ printInvocation(args.items);
return error.TestFailed;
}
},
.Signal => |signum| {
warn("Process {} terminated on signal {}\n", .{ full_exe_path, signum });
- printInvocation(args.span());
+ printInvocation(args.items);
return error.TestFailed;
},
.Stopped => |signum| {
warn("Process {} stopped on signal {}\n", .{ full_exe_path, signum });
- printInvocation(args.span());
+ printInvocation(args.items);
return error.TestFailed;
},
.Unknown => |code| {
warn("Process {} terminated unexpectedly with error code {}\n", .{ full_exe_path, code });
- printInvocation(args.span());
+ printInvocation(args.items);
return error.TestFailed;
},
}
@@ -837,34 +837,27 @@ pub const CompileErrorContext = struct {
} else {
try zig_args.append("build-obj");
}
- const root_src_basename = self.case.sources.span()[0].filename;
+ const root_src_basename = self.case.sources.items[0].filename;
try zig_args.append(self.write_src.getOutputPath(root_src_basename));
zig_args.append("--name") catch unreachable;
zig_args.append("test") catch unreachable;
- zig_args.append("--output-dir") catch unreachable;
- zig_args.append(b.pathFromRoot(b.cache_root)) catch unreachable;
-
if (!self.case.target.isNative()) {
try zig_args.append("-target");
try zig_args.append(try self.case.target.zigTriple(b.allocator));
}
- switch (self.build_mode) {
- Mode.Debug => {},
- Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable,
- Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable,
- Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,
- }
+ zig_args.append("-O") catch unreachable;
+ zig_args.append(@tagName(self.build_mode)) catch unreachable;
warn("Test {}/{} {}...", .{ self.test_index + 1, self.context.test_index, self.name });
if (b.verbose) {
- printInvocation(zig_args.span());
+ printInvocation(zig_args.items);
}
- const child = std.ChildProcess.init(zig_args.span(), b.allocator) catch unreachable;
+ const child = std.ChildProcess.init(zig_args.items, b.allocator) catch unreachable;
defer child.deinit();
child.env_map = b.env_map;
@@ -886,19 +879,19 @@ pub const CompileErrorContext = struct {
switch (term) {
.Exited => |code| {
if (code == 0) {
- printInvocation(zig_args.span());
+ printInvocation(zig_args.items);
return error.CompilationIncorrectlySucceeded;
}
},
else => {
warn("Process {} terminated unexpectedly\n", .{b.zig_exe});
- printInvocation(zig_args.span());
+ printInvocation(zig_args.items);
return error.TestFailed;
},
}
- const stdout = stdout_buf.span();
- const stderr = stderr_buf.span();
+ const stdout = stdout_buf.items;
+ const stderr = stderr_buf.items;
if (stdout.len != 0) {
warn(
@@ -927,12 +920,12 @@ pub const CompileErrorContext = struct {
if (!ok) {
warn("\n======== Expected these compile errors: ========\n", .{});
- for (self.case.expected_errors.span()) |expected| {
+ for (self.case.expected_errors.items) |expected| {
warn("{}\n", .{expected});
}
}
} else {
- for (self.case.expected_errors.span()) |expected| {
+ for (self.case.expected_errors.items) |expected| {
if (mem.indexOf(u8, stderr, expected) == null) {
warn(
\\
@@ -1032,7 +1025,7 @@ pub const CompileErrorContext = struct {
if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
const write_src = b.addWriteFiles();
- for (case.sources.span()) |src_file| {
+ for (case.sources.items) |src_file| {
write_src.add(src_file.filename, src_file.source);
}
@@ -1079,7 +1072,7 @@ pub const StandaloneContext = struct {
zig_args.append("--verbose") catch unreachable;
}
- const run_cmd = b.addSystemCommand(zig_args.span());
+ const run_cmd = b.addSystemCommand(zig_args.items);
const log_step = b.addLog("PASS {}\n", .{annotated_case_name});
log_step.step.dependOn(&run_cmd.step);
@@ -1179,7 +1172,7 @@ pub const GenHContext = struct {
const full_h_path = self.obj.getOutputHPath();
const actual_h = try io.readFileAlloc(b.allocator, full_h_path);
- for (self.case.expected_lines.span()) |expected_line| {
+ for (self.case.expected_lines.items) |expected_line| {
if (mem.indexOf(u8, actual_h, expected_line) == null) {
warn(
\\
@@ -1240,7 +1233,7 @@ pub const GenHContext = struct {
}
const write_src = b.addWriteFiles();
- for (case.sources.span()) |src_file| {
+ for (case.sources.items) |src_file| {
write_src.add(src_file.filename, src_file.source);
}
BRANCH_TODO
@@ -1,18 +1,15 @@
- * restore the legacy -femit-h feature using the stage1 backend
- * tests passing with -Dskip-non-native
- * `-ftime-report`
- * -fstack-report print stack size diagnostics\n"
+ * MachO LLD linking
* subsystem
* mingw-w64
- * MachO LLD linking
* COFF LLD linking
* WASM LLD linking
* audit the CLI options for stage2
* audit the base cache hash
* On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
- * restore error messages for stage2_add_link_lib
* windows CUSTOMBUILD : error : unable to build compiler_rt: FileNotFound [D:\a\1\s\build\zig_install_lib_files.vcxproj]
* try building some software with zig cc to make sure it didn't regress
+ * `-ftime-report`
+ * -fstack-report print stack size diagnostics\n"
* implement proper parsing of clang stderr/stdout and exposing compile errors with the Compilation API
* implement proper parsing of LLD stderr/stdout and exposing compile errors with the Compilation API
@@ -51,3 +48,4 @@
* update musl.zig static data to use native path separator in static data rather than replacing '/' at runtime
* linking hello world with LLD, lld is silently calling exit(1) instead of reporting ok=false. when run standalone the error message is: ld.lld: error: section [index 3] has a sh_offset (0x57000) + sh_size (0x68) that is greater than the file size (0x57060)
* submit PR to godbolt and update the CLI options (see changes to test/cli.zig)
+ * make proposal about log levels
build.zig
@@ -211,10 +211,7 @@ pub fn build(b: *Builder) !void {
test_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes));
test_step.dependOn(tests.addStandaloneTests(b, test_filter, modes));
test_step.dependOn(tests.addStackTraceTests(b, test_filter, modes));
- const test_cli = tests.addCliTests(b, test_filter, modes);
- const test_cli_step = b.step("test-cli", "Run zig cli tests");
- test_cli_step.dependOn(test_cli);
- test_step.dependOn(test_cli);
+ test_step.dependOn(tests.addCliTests(b, test_filter, modes));
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter, modes));
test_step.dependOn(tests.addTranslateCTests(b, test_filter));