zig/src-self-hosted/stage2.zig

1218 lines
40 KiB
Zig
Raw Normal View History

stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 13:47:47 -07:00
// This is Zig code that is used by both stage1 and stage2.
// The prototypes in src/userland.h must match these definitions.
2019-05-26 10:17:34 -07:00
const std = @import("std");
const io = std.io;
const mem = std.mem;
const fs = std.fs;
const process = std.process;
const Allocator = mem.Allocator;
const ArrayList = std.ArrayList;
const Buffer = std.Buffer;
const Target = std.Target;
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
const CrossTarget = std.zig.CrossTarget;
2019-05-26 10:17:34 -07:00
const self_hosted_main = @import("main.zig");
const errmsg = @import("errmsg.zig");
const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
2020-01-21 09:14:43 -08:00
const assert = std.debug.assert;
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2019-05-26 10:17:34 -07:00
var stderr_file: fs.File = undefined;
var stderr: fs.File.OutStream = undefined;
var stdout: fs.File.OutStream = undefined;
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 13:47:47 -07:00
comptime {
_ = @import("dep_tokenizer.zig");
}
// ABI warning
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 13:47:47 -07:00
export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
const info_zen = @import("main.zig").info_zen;
ptr.* = info_zen;
stage1 is now a hybrid of C++ and Zig This modifies the build process of Zig to put all of the source files into libcompiler.a, except main.cpp and userland.cpp. Next, the build process links main.cpp, userland.cpp, and libcompiler.a into zig1. userland.cpp is a shim for functions that will later be replaced with self-hosted implementations. Next, the build process uses zig1 to build src-self-hosted/stage1.zig into libuserland.a, which does not depend on any of the things that are shimmed in userland.cpp, such as translate-c. Finally, the build process re-links main.cpp and libcompiler.a, except with libuserland.a instead of userland.cpp. Now the shims are replaced with .zig code. This provides all of the Zig standard library to the stage1 C++ compiler, and enables us to move certain things to userland, such as translate-c. As a proof of concept I have made the `zig zen` command use text defined in userland. I added `zig translate-c-2` which is a work-in-progress reimplementation of translate-c in userland, which currently calls `std.debug.panic("unimplemented")` and you can see the stack trace makes it all the way back into the C++ main() function (Thanks LemonBoy for improving that!). This could potentially let us move other things into userland, such as hashing algorithms, the entire cache system, .d file parsing, pretty much anything that libuserland.a itself doesn't need to depend on. This can also let us have `zig fmt` in stage1 without the overhead of child process execution, and without the initial compilation delay before it gets cached. See #1964
2019-04-16 13:47:47 -07:00
len.* = info_zen.len;
}
// ABI warning
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
@panic(ptr[0..len]);
}
// ABI warning
const Error = extern enum {
None,
OutOfMemory,
InvalidFormat,
SemanticAnalyzeFail,
AccessDenied,
Interrupted,
SystemResources,
FileNotFound,
FileSystem,
FileTooBig,
DivByZero,
Overflow,
PathAlreadyExists,
Unexpected,
ExactDivRemainder,
NegativeDenominator,
ShiftedOutOneBits,
CCompileErrors,
EndOfFile,
IsDir,
NotDir,
UnsupportedOperatingSystem,
SharingViolation,
PipeBusy,
PrimitiveTypeNotFound,
CacheUnavailable,
PathTooLong,
CCompilerCannotFindFile,
NoCCompilerInstalled,
ReadingDepFile,
InvalidDepFile,
MissingArchitecture,
MissingOperatingSystem,
UnknownArchitecture,
UnknownOperatingSystem,
UnknownABI,
InvalidFilename,
DiskQuota,
DiskSpace,
UnexpectedWriteFailure,
UnexpectedSeekFailure,
UnexpectedFileTruncationFailure,
Unimplemented,
OperationAborted,
BrokenPipe,
NoSpaceLeft,
NotLazy,
IsAsync,
ImportOutsidePkgPath,
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
UnknownCpuModel,
UnknownCpuFeature,
InvalidCpuFeatures,
InvalidLlvmCpuFeaturesFormat,
UnknownApplicationBinaryInterface,
ASTUnitFailure,
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
BadPathName,
SymLinkLoop,
ProcessFdQuotaExceeded,
SystemFdQuotaExceeded,
NoDevice,
DeviceBusy,
UnableToSpawnCCompiler,
CCompilerExitCode,
CCompilerCrashed,
CCompilerCannotFindHeaders,
LibCRuntimeNotFound,
LibCStdLibHeaderNotFound,
LibCKernel32LibNotFound,
UnsupportedArchitecture,
WindowsSdkNotFound,
2020-02-17 12:23:59 -08:00
UnknownDynamicLinkerPath,
TargetHasNoDynamicLinker,
InvalidAbiVersion,
InvalidOperatingSystemVersion,
};
const FILE = std.c.FILE;
const ast = std.zig.ast;
const translate_c = @import("translate_c.zig");
/// Args should have a null terminating last arg.
export fn stage2_translate_c(
out_ast: **ast.Tree,
out_errors_ptr: *[*]translate_c.ClangErrMsg,
out_errors_len: *usize,
args_begin: [*]?[*]const u8,
args_end: [*]?[*]const u8,
2019-12-15 23:55:37 -08:00
resources_path: [*:0]const u8,
) Error {
var errors: []translate_c.ClangErrMsg = &[0]translate_c.ClangErrMsg{};
2019-12-12 04:26:24 -08:00
out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
error.SemanticAnalyzeFail => {
out_errors_ptr.* = errors.ptr;
out_errors_len.* = errors.len;
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
return .CCompileErrors;
},
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
error.ASTUnitFailure => return .ASTUnitFailure,
error.OutOfMemory => return .OutOfMemory,
};
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
return .None;
}
export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
translate_c.freeErrors(errors_ptr[0..errors_len]);
}
export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
const c_out_stream = std.io.cOutStream(output_file);
_ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
std lib networking improvements, especially non-blocking I/O * delete the std/event/net directory * `std.event.Loop.waitUntilFdReadable` and related functions no longer have possibility of failure. On Linux, they fall back to poll() and then fall back to sleep(). * add some missing `noasync` decorations in `std.event.Loop` * redo the `std.net.Server` API. it's quite nice now, but shutdown does not work cleanly. There is a race condition with close() that I am actively working on. * move `std.io.OutStream` to its own file to match `std.io.InStream`. I started working on making `write` integrated with evented I/O, but it got tricky so I backed off and filed #3557. However I did integrate `std.os.writev` and `std.os.pwritev` with evented I/O. * add `std.Target.stack_align` * move networking tests to `lib/std/net/test.zig` * add `std.net.tcpConnectToHost` and `std.net.tcpConnectToAddress`. * rename `error.UnknownName` to `error.UnknownHostName` within the context of DNS resolution. * add `std.os.readv`, which is integrated with evented I/O. * `std.os.preadv`, is now integrated with evented I/O. * `std.os.accept4` now asserts that ENOTSOCK and EOPNOTSUPP never occur (misuse of API), instead of returning errors. * `std.os.connect` is now integrated with evented I/O. `std.os.connect_async` is gone. Just use `std.os.connect`. * fix false positive dependency loop regarding async function frames * add more compile notes to help when dependency loops occur in determining whether a function is async. * ir: change an assert to ir_assert to make it easier to find workarounds for when such an assert is triggered. In this case it was trying to parse an IPv4 address at comptime.
2019-10-29 19:59:30 -07:00
error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
error.SystemResources => return .SystemResources,
error.OperationAborted => return .OperationAborted,
error.BrokenPipe => return .BrokenPipe,
error.DiskQuota => return .DiskQuota,
error.FileTooBig => return .FileTooBig,
error.NoSpaceLeft => return .NoSpaceLeft,
error.AccessDenied => return .AccessDenied,
error.OutOfMemory => return .OutOfMemory,
error.Unexpected => return .Unexpected,
error.InputOutput => return .FileSystem,
};
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
return .None;
}
// TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377,
// we use a blocking implementation.
export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
if (std.debug.runtime_safety) {
fmtMain(argc, argv) catch unreachable;
} else {
fmtMain(argc, argv) catch |e| {
2019-12-08 20:46:50 -08:00
std.debug.warn("{}\n", .{@errorName(e)});
return -1;
2019-04-26 17:58:43 -07:00
};
}
return 0;
}
fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
const allocator = std.heap.c_allocator;
var args_list = std.ArrayList([]const u8).init(allocator);
const argc_usize = @intCast(usize, argc);
var arg_i: usize = 0;
while (arg_i < argc_usize) : (arg_i += 1) {
try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
}
stdout = std.io.getStdOut().outStream();
stderr_file = std.io.getStdErr();
stderr = stderr_file.outStream();
2019-12-10 23:08:33 -08:00
const args = args_list.toSliceConst()[2..];
var color: errmsg.Color = .Auto;
var stdin_flag: bool = false;
var check_flag: bool = false;
var input_files = ArrayList([]const u8).init(allocator);
{
var i: usize = 0;
while (i < args.len) : (i += 1) {
const arg = args[i];
if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "--help")) {
try stdout.writeAll(self_hosted_main.usage_fmt);
2019-12-10 23:08:33 -08:00
process.exit(0);
} else if (mem.eql(u8, arg, "--color")) {
if (i + 1 >= args.len) {
try stderr.writeAll("expected [auto|on|off] after --color\n");
2019-12-10 23:08:33 -08:00
process.exit(1);
}
i += 1;
const next_arg = args[i];
if (mem.eql(u8, next_arg, "auto")) {
color = .Auto;
} else if (mem.eql(u8, next_arg, "on")) {
color = .On;
} else if (mem.eql(u8, next_arg, "off")) {
color = .Off;
} else {
try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg});
process.exit(1);
}
} else if (mem.eql(u8, arg, "--stdin")) {
stdin_flag = true;
} else if (mem.eql(u8, arg, "--check")) {
check_flag = true;
} else {
try stderr.print("unrecognized parameter: '{}'", .{arg});
process.exit(1);
}
} else {
try input_files.append(arg);
}
}
2019-12-10 23:08:33 -08:00
}
2019-12-10 23:08:33 -08:00
if (stdin_flag) {
if (input_files.len != 0) {
try stderr.writeAll("cannot use --stdin with positional arguments\n");
2019-05-26 10:17:34 -07:00
process.exit(1);
}
const stdin_file = io.getStdIn();
var stdin = stdin_file.inStream();
const source_code = try stdin.readAllAlloc(allocator, self_hosted_main.max_src_size);
defer allocator.free(source_code);
const tree = std.zig.parse(allocator, source_code) catch |err| {
try stderr.print("error parsing stdin: {}\n", .{err});
2019-05-26 10:17:34 -07:00
process.exit(1);
};
defer tree.deinit();
var error_it = tree.errors.iterator(0);
while (error_it.next()) |parse_error| {
try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
}
if (tree.errors.len != 0) {
2019-05-26 10:17:34 -07:00
process.exit(1);
}
2019-12-10 23:08:33 -08:00
if (check_flag) {
const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
2019-05-26 10:17:34 -07:00
process.exit(code);
}
_ = try std.zig.render(allocator, stdout, tree);
return;
}
2019-12-10 23:08:33 -08:00
if (input_files.len == 0) {
try stderr.writeAll("expected at least one source file argument\n");
2019-05-26 10:17:34 -07:00
process.exit(1);
}
var fmt = Fmt{
.seen = Fmt.SeenMap.init(allocator),
.any_error = false,
.color = color,
.allocator = allocator,
};
2019-12-10 23:08:33 -08:00
for (input_files.toSliceConst()) |file_path| {
try fmtPath(&fmt, file_path, check_flag);
}
if (fmt.any_error) {
2019-05-26 10:17:34 -07:00
process.exit(1);
}
}
const FmtError = error{
SystemResources,
OperationAborted,
IoPending,
BrokenPipe,
Unexpected,
WouldBlock,
FileClosed,
DestinationAddressRequired,
DiskQuota,
FileTooBig,
InputOutput,
NoSpaceLeft,
AccessDenied,
OutOfMemory,
RenameAcrossMountPoints,
ReadOnlyFileSystem,
LinkQuotaExceeded,
FileBusy,
2019-05-26 10:17:34 -07:00
} || fs.File.OpenError;
2019-12-09 12:20:42 -08:00
fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
if (fmt.seen.exists(file_path)) return;
try fmt.seen.put(file_path);
const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
error.IsDir, error.AccessDenied => {
// TODO make event based (and dir.next())
var dir = try fs.cwd().openDir(file_path, .{ .iterate = true });
defer dir.close();
breaking: improve std.fs directory handling API * Added `std.c.unlinkat` and `std.os.unlinkat`. * Removed `std.fs.MAX_BUF_BYTES` (this declaration never made it to master branch) * Added `std.fs.Dir.deleteTree` to be used on an open directory handle. * `std.fs.deleteTree` has better behavior for both relative and absolute paths. For absolute paths, it opens the base directory and uses that handle for subsequent operations. For relative paths, it does a similar strategy, using the cwd handle. * The error set of `std.fs.deleteTree` is improved to no longer have these possible errors: - OutOfMemory - FileTooBig - IsDir - DirNotEmpty - PathAlreadyExists - NoSpaceLeft * Added `std.fs.Dir.posix_cwd` which is a statically initialized directory representing the current working directory. * The error set of `std.Dir.open` is improved to no longer have these possible errors: - FileTooBig - IsDir - NoSpaceLeft - PathAlreadyExists - OutOfMemory * Added more alternative functions to `std.fs` for when the path parameter is a null terminated string. This can sometimes be more effecient on systems which have an ABI based on null terminated strings. * Added `std.fs.Dir.openDir`, `std.fs.Dir.deleteFile`, and `std.fs.Dir.deleteDir` which all operate on an open directory handle. * `std.fs.Walker.Entry` now has a `dir` field, which can be used to do operations directly on `std.fs.Walker.Entry.basename`, avoiding `error.NameTooLong` for deeply nested paths. * Added more docs to `std.os.OpenError` This commit does the POSIX components for these changes. I plan to follow up shortly with a commit for Windows.
2019-10-20 18:48:23 -07:00
var dir_it = dir.iterate();
while (try dir_it.next()) |entry| {
if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name });
try fmtPath(fmt, full_path, check_mode);
}
}
return;
},
else => {
// TODO lock stderr printing
try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
fmt.any_error = true;
return;
},
};
defer fmt.allocator.free(source_code);
const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
try stderr.print("error parsing file '{}': {}\n", .{ file_path, err });
fmt.any_error = true;
return;
};
defer tree.deinit();
var error_it = tree.errors.iterator(0);
while (error_it.next()) |parse_error| {
try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
}
if (tree.errors.len != 0) {
fmt.any_error = true;
return;
}
if (check_mode) {
const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
if (anything_changed) {
try stderr.print("{}\n", .{file_path});
fmt.any_error = true;
}
} else {
const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
defer baf.destroy();
const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
if (anything_changed) {
try stderr.print("{}\n", .{file_path});
try baf.finish();
}
}
}
const Fmt = struct {
seen: SeenMap,
any_error: bool,
color: errmsg.Color,
allocator: *mem.Allocator,
2019-12-09 12:20:42 -08:00
const SeenMap = std.BufSet;
};
fn printErrMsgToFile(
allocator: *mem.Allocator,
parse_error: *const ast.Error,
tree: *ast.Tree,
path: []const u8,
2019-05-26 10:17:34 -07:00
file: fs.File,
color: errmsg.Color,
) !void {
const color_on = switch (color) {
.Auto => file.isTty(),
.On => true,
.Off => false,
};
const lok_token = parse_error.loc();
const span = errmsg.Span{
.first = lok_token,
.last = lok_token,
};
const first_token = tree.tokens.at(span.first);
const last_token = tree.tokens.at(span.last);
const start_loc = tree.tokenLocationPtr(0, first_token);
const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
var text_buf = try std.Buffer.initSize(allocator, 0);
const out_stream = &text_buf.outStream();
try parse_error.render(&tree.tokens, out_stream);
const text = text_buf.toOwnedSlice();
const stream = &file.outStream();
try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
if (!color_on) return;
// Print \r and \t as one space each so that column counts line up
for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| {
try stream.writeByte(switch (byte) {
'\r', '\t' => ' ',
else => byte,
});
}
try stream.writeByte('\n');
try stream.writeByteNTimes(' ', start_loc.column);
try stream.writeByteNTimes('~', last_token.end - first_token.start);
try stream.writeByte('\n');
}
export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
return stage2_DepTokenizer{
.handle = t,
};
}
export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
self.handle.deinit();
}
export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
const otoken = self.handle.next() catch {
const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
return stage2_DepNextResult{
.type_id = .error_,
.textz = textz.toSlice().ptr,
};
};
const token = otoken orelse {
return stage2_DepNextResult{
.type_id = .null_,
.textz = undefined,
};
};
const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
return stage2_DepNextResult{
.type_id = switch (token.id) {
.target => .target,
.prereq => .prereq,
},
.textz = textz.toSlice().ptr,
};
}
const stage2_DepTokenizer = extern struct {
handle: *DepTokenizer,
};
const stage2_DepNextResult = extern struct {
type_id: TypeId,
// when type_id == error --> error text
// when type_id == null --> undefined
// when type_id == target --> target pathname
// when type_id == prereq --> prereq pathname
textz: [*]const u8,
const TypeId = extern enum {
error_,
null_,
target,
prereq,
};
};
// ABI warning
export fn stage2_attach_segfault_handler() void {
if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
std.debug.attachSegfaultHandler();
}
}
// ABI warning
export fn stage2_progress_create() *std.Progress {
const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
ptr.* = std.Progress{};
return ptr;
}
// ABI warning
export fn stage2_progress_destroy(progress: *std.Progress) void {
std.heap.c_allocator.destroy(progress);
}
// ABI warning
export fn stage2_progress_start_root(
progress: *std.Progress,
name_ptr: [*]const u8,
name_len: usize,
estimated_total_items: usize,
) *std.Progress.Node {
return progress.start(
name_ptr[0..name_len],
if (estimated_total_items == 0) null else estimated_total_items,
) catch @panic("timer unsupported");
}
// ABI warning
export fn stage2_progress_disable_tty(progress: *std.Progress) void {
progress.terminal = null;
}
// ABI warning
export fn stage2_progress_start(
node: *std.Progress.Node,
name_ptr: [*]const u8,
name_len: usize,
estimated_total_items: usize,
) *std.Progress.Node {
const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory");
child_node.* = node.start(
name_ptr[0..name_len],
if (estimated_total_items == 0) null else estimated_total_items,
);
child_node.activate();
return child_node;
}
// ABI warning
export fn stage2_progress_end(node: *std.Progress.Node) void {
node.end();
if (&node.context.root != node) {
std.heap.c_allocator.destroy(node);
}
}
// ABI warning
export fn stage2_progress_complete_one(node: *std.Progress.Node) void {
node.completeOne();
}
// ABI warning
export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void {
node.completed_items = done_count;
node.estimated_total_items = total_count;
node.activate();
node.context.maybeRefresh();
}
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
fn detectNativeCpuWithLLVM(
arch: Target.Cpu.Arch,
llvm_cpu_name_z: ?[*:0]const u8,
llvm_cpu_features_opt: ?[*:0]const u8,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
) !Target.Cpu {
var result = Target.Cpu.baseline(arch);
if (llvm_cpu_name_z) |cpu_name_z| {
const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
for (arch.allCpuModels()) |model| {
const this_llvm_name = model.llvm_name orelse continue;
if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
// Here we use the non-dependencies-populated set,
// so that subtracting features later in this function
// affect the prepopulated set.
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
result = Target.Cpu{
.arch = arch,
.model = model,
.features = model.features,
};
break;
}
}
}
const all_features = arch.allFeaturesList();
if (llvm_cpu_features_opt) |llvm_cpu_features| {
var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
while (it.next()) |decorated_llvm_feat| {
var op: enum {
add,
sub,
} = undefined;
var llvm_feat: []const u8 = undefined;
if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
op = .add;
llvm_feat = decorated_llvm_feat[1..];
} else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
op = .sub;
llvm_feat = decorated_llvm_feat[1..];
} else {
return error.InvalidLlvmCpuFeaturesFormat;
}
for (all_features) |feature, index_usize| {
const this_llvm_name = feature.llvm_name orelse continue;
if (mem.eql(u8, llvm_feat, this_llvm_name)) {
const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
switch (op) {
.add => result.features.addFeature(index),
.sub => result.features.removeFeature(index),
}
break;
}
}
}
}
result.features.populateDependencies(all_features);
return result;
}
// ABI warning
export fn stage2_cmd_targets(
zig_triple: ?[*:0]const u8,
mcpu: ?[*:0]const u8,
dynamic_linker: ?[*:0]const u8,
) c_int {
cmdTargets(zig_triple, mcpu, dynamic_linker) catch |err| {
std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
return -1;
};
return 0;
}
2019-12-20 16:27:13 -08:00
fn cmdTargets(
zig_triple_oz: ?[*:0]const u8,
mcpu_oz: ?[*:0]const u8,
dynamic_linker_oz: ?[*:0]const u8,
) !void {
const cross_target = try stage2CrossTarget(zig_triple_oz, mcpu_oz, dynamic_linker_oz);
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
var dynamic_linker: ?[*:0]u8 = null;
const target = try crossTargetToTarget(cross_target, &dynamic_linker);
return @import("print_targets.zig").cmdTargets(
std.heap.c_allocator,
&[0][]u8{},
std.io.getStdOut().outStream(),
target,
);
}
2020-01-08 17:27:36 -08:00
// ABI warning
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
export fn stage2_target_parse(
target: *Stage2Target,
zig_triple: ?[*:0]const u8,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
mcpu: ?[*:0]const u8,
dynamic_linker: ?[*:0]const u8,
) Error {
stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) {
error.OutOfMemory => return .OutOfMemory,
error.UnknownArchitecture => return .UnknownArchitecture,
error.UnknownOperatingSystem => return .UnknownOperatingSystem,
error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
error.MissingOperatingSystem => return .MissingOperatingSystem,
error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
error.UnexpectedExtraField => return .SemanticAnalyzeFail,
error.InvalidAbiVersion => return .InvalidAbiVersion,
error.InvalidOperatingSystemVersion => return .InvalidOperatingSystemVersion,
error.FileSystem => return .FileSystem,
error.SymLinkLoop => return .SymLinkLoop,
error.SystemResources => return .SystemResources,
error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded,
error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded,
error.DeviceBusy => return .DeviceBusy,
};
return .None;
}
2020-01-08 18:35:26 -08:00
fn stage2CrossTarget(
zig_triple_oz: ?[*:0]const u8,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
mcpu_oz: ?[*:0]const u8,
dynamic_linker_oz: ?[*:0]const u8,
) !CrossTarget {
const zig_triple = if (zig_triple_oz) |zig_triple_z| mem.toSliceConst(u8, zig_triple_z) else "native";
const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null;
const dynamic_linker = if (dynamic_linker_oz) |dl_z| mem.toSliceConst(u8, dl_z) else null;
var diags: CrossTarget.ParseOptions.Diagnostics = .{};
const target: CrossTarget = CrossTarget.parse(.{
.arch_os_abi = zig_triple,
.cpu_features = mcpu,
.dynamic_linker = dynamic_linker,
.diagnostics = &diags,
}) catch |err| switch (err) {
error.UnknownCpuModel => {
std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
diags.cpu_name.?,
@tagName(diags.arch.?),
});
for (diags.arch.?.allCpuModels()) |cpu| {
std.debug.warn(" {}\n", .{cpu.name});
}
process.exit(1);
},
error.UnknownCpuFeature => {
std.debug.warn(
\\Unknown CPU feature: '{}'
\\Available CPU features for architecture '{}':
\\
, .{
diags.unknown_feature_name,
@tagName(diags.arch.?),
});
for (diags.arch.?.allFeaturesList()) |feature| {
std.debug.warn(" {}: {}\n", .{ feature.name, feature.description });
}
process.exit(1);
},
else => |e| return e,
};
return target;
}
fn stage2TargetParse(
stage1_target: *Stage2Target,
zig_triple_oz: ?[*:0]const u8,
mcpu_oz: ?[*:0]const u8,
dynamic_linker_oz: ?[*:0]const u8,
) !void {
const target = try stage2CrossTarget(zig_triple_oz, mcpu_oz, dynamic_linker_oz);
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
try stage1_target.fromTarget(target);
}
2020-01-22 14:35:57 -08:00
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
// ABI warning
const Stage2LibCInstallation = extern struct {
include_dir: [*:0]const u8,
include_dir_len: usize,
sys_include_dir: [*:0]const u8,
sys_include_dir_len: usize,
crt_dir: [*:0]const u8,
crt_dir_len: usize,
msvc_lib_dir: [*:0]const u8,
msvc_lib_dir_len: usize,
kernel32_lib_dir: [*:0]const u8,
kernel32_lib_dir_len: usize,
fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
if (libc.include_dir) |s| {
self.include_dir = s.ptr;
self.include_dir_len = s.len;
} else {
self.include_dir = "";
self.include_dir_len = 0;
}
if (libc.sys_include_dir) |s| {
self.sys_include_dir = s.ptr;
self.sys_include_dir_len = s.len;
} else {
self.sys_include_dir = "";
self.sys_include_dir_len = 0;
}
if (libc.crt_dir) |s| {
self.crt_dir = s.ptr;
self.crt_dir_len = s.len;
} else {
self.crt_dir = "";
self.crt_dir_len = 0;
}
if (libc.msvc_lib_dir) |s| {
self.msvc_lib_dir = s.ptr;
self.msvc_lib_dir_len = s.len;
} else {
self.msvc_lib_dir = "";
self.msvc_lib_dir_len = 0;
}
if (libc.kernel32_lib_dir) |s| {
self.kernel32_lib_dir = s.ptr;
self.kernel32_lib_dir_len = s.len;
} else {
self.kernel32_lib_dir = "";
self.kernel32_lib_dir_len = 0;
}
}
fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
var libc: LibCInstallation = .{};
if (self.include_dir_len != 0) {
libc.include_dir = self.include_dir[0..self.include_dir_len :0];
}
if (self.sys_include_dir_len != 0) {
libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
}
if (self.crt_dir_len != 0) {
libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
}
if (self.msvc_lib_dir_len != 0) {
libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
}
if (self.kernel32_lib_dir_len != 0) {
libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
}
return libc;
}
};
// ABI warning
export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {
stderr_file = std.io.getStdErr();
stderr = stderr_file.outStream();
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
const libc_file = mem.toSliceConst(u8, libc_file_z);
var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) {
error.ParseError => return .SemanticAnalyzeFail,
error.DiskQuota => return .DiskQuota,
error.FileTooBig => return .FileTooBig,
error.InputOutput => return .FileSystem,
error.NoSpaceLeft => return .NoSpaceLeft,
error.AccessDenied => return .AccessDenied,
error.BrokenPipe => return .BrokenPipe,
error.SystemResources => return .SystemResources,
error.OperationAborted => return .OperationAborted,
error.WouldBlock => unreachable,
error.Unexpected => return .Unexpected,
error.EndOfStream => return .EndOfFile,
error.IsDir => return .IsDir,
error.ConnectionResetByPeer => unreachable,
error.OutOfMemory => return .OutOfMemory,
error.Unseekable => unreachable,
error.SharingViolation => return .SharingViolation,
error.PathAlreadyExists => unreachable,
error.FileNotFound => return .FileNotFound,
error.PipeBusy => return .PipeBusy,
error.NameTooLong => return .PathTooLong,
error.InvalidUtf8 => return .BadPathName,
error.BadPathName => return .BadPathName,
error.SymLinkLoop => return .SymLinkLoop,
error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded,
error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded,
error.NoDevice => return .NoDevice,
error.NotDir => return .NotDir,
error.DeviceBusy => return .DeviceBusy,
};
stage1_libc.initFromStage2(libc);
return .None;
}
// ABI warning
export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error {
var libc = LibCInstallation.findNative(.{
.allocator = std.heap.c_allocator,
.verbose = true,
}) catch |err| switch (err) {
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
error.OutOfMemory => return .OutOfMemory,
error.FileSystem => return .FileSystem,
error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler,
error.CCompilerExitCode => return .CCompilerExitCode,
error.CCompilerCrashed => return .CCompilerCrashed,
error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders,
error.LibCRuntimeNotFound => return .LibCRuntimeNotFound,
error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound,
error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound,
error.UnsupportedArchitecture => return .UnsupportedArchitecture,
error.WindowsSdkNotFound => return .WindowsSdkNotFound,
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
};
stage1_libc.initFromStage2(libc);
return .None;
}
// ABI warning
export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error {
var libc = stage1_libc.toStage2();
const c_out_stream = std.io.cOutStream(output_file);
self-hosted libc detection * libc_installation.cpp is deleted. src-self-hosted/libc_installation.zig is now used for both stage1 and stage2 compilers. * (breaking) move `std.fs.File.access` to `std.fs.Dir.access`. The API now encourages use with an open directory handle. * Add `std.os.faccessat` and related functions. * Deprecate the "C" suffix naming convention for null-terminated parameters. "C" should be used when it is related to libc. However null-terminated parameters often have to do with the native system ABI rather than libc. "Z" suffix is the new convention. For example, `std.os.openC` is deprecated in favor of `std.os.openZ`. * Add `std.mem.dupeZ` for using an allocator to copy memory and add a null terminator. * Remove dead struct field `std.ChildProcess.llnode`. * Introduce `std.event.Batch`. This API allows expressing concurrency without forcing code to be async. It requires no Allocator and does not introduce any failure conditions. However it is not thread-safe. * There is now an ongoing experiment to transition away from `std.event.Group` in favor of `std.event.Batch`. * `std.os.execvpeC` calls `getenvZ` rather than `getenv`. This is slightly more efficient on most systems, and works around a limitation of `getenv` lack of integration with libc. * (breaking) `std.os.AccessError` gains `FileBusy`, `SymLinkLoop`, and `ReadOnlyFileSystem`. Previously these error codes were all reported as `PermissionDenied`. * Add `std.Target.isDragonFlyBSD`. * stage2: access to the windows_sdk functions is done with a manually maintained .zig binding file instead of `@cImport`. * Update src-self-hosted/libc_installation.zig with all the improvements that stage1 has seen to src/libc_installation.cpp until now. In addition, it now takes advantage of Batch so that evented I/O mode takes advantage of concurrency, but it still works in blocking I/O mode, which is how it is used in stage1.
2020-02-16 10:25:30 -08:00
libc.render(c_out_stream) catch |err| switch (err) {
error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
error.SystemResources => return .SystemResources,
error.OperationAborted => return .OperationAborted,
error.BrokenPipe => return .BrokenPipe,
error.DiskQuota => return .DiskQuota,
error.FileTooBig => return .FileTooBig,
error.NoSpaceLeft => return .NoSpaceLeft,
error.AccessDenied => return .AccessDenied,
error.Unexpected => return .Unexpected,
error.InputOutput => return .FileSystem,
};
return .None;
}
// ABI warning
2020-02-17 12:23:59 -08:00
const Stage2Target = extern struct {
arch: c_int,
vendor: c_int,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
2020-02-21 08:47:34 -08:00
abi: c_int,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
os: c_int,
2020-02-21 08:47:34 -08:00
2020-02-17 12:23:59 -08:00
is_native: bool,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
glibc_or_darwin_version: ?*Stage2SemVer,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
llvm_cpu_name: ?[*:0]const u8,
llvm_cpu_features: ?[*:0]const u8,
cpu_builtin_str: ?[*:0]const u8,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
cache_hash: ?[*:0]const u8,
cache_hash_len: usize,
os_builtin_str: ?[*:0]const u8,
dynamic_linker: ?[*:0]const u8,
standard_dynamic_linker_path: ?[*:0]const u8,
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void {
const allocator = std.heap.c_allocator;
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
var dynamic_linker: ?[*:0]u8 = null;
const target = try crossTargetToTarget(cross_target, &dynamic_linker);
var cache_hash = try std.Buffer.allocPrint(allocator, "{}\n{}\n", .{
target.cpu.model.name,
target.cpu.features.asBytes(),
});
defer cache_hash.deinit();
const generic_arch_name = target.cpu.arch.genericName();
var cpu_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
\\Cpu{{
\\ .arch = .{},
\\ .model = &Target.{}.cpu.{},
\\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
\\
, .{
@tagName(target.cpu.arch),
generic_arch_name,
target.cpu.model.name,
generic_arch_name,
generic_arch_name,
});
defer cpu_builtin_str_buffer.deinit();
var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
defer llvm_features_buffer.deinit();
for (target.cpu.arch.allFeaturesList()) |feature, index_usize| {
const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
const is_enabled = target.cpu.features.isEnabled(index);
if (feature.llvm_name) |llvm_name| {
const plus_or_minus = "-+"[@boolToInt(is_enabled)];
try llvm_features_buffer.appendByte(plus_or_minus);
try llvm_features_buffer.append(llvm_name);
try llvm_features_buffer.append(",");
}
if (is_enabled) {
// TODO some kind of "zig identifier escape" function rather than
// unconditionally using @"" syntax
try cpu_builtin_str_buffer.append(" .@\"");
try cpu_builtin_str_buffer.append(feature.name);
try cpu_builtin_str_buffer.append("\",\n");
}
}
try cpu_builtin_str_buffer.append(
\\ }),
\\};
\\
);
assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
var os_builtin_str_buffer = try std.Buffer.allocPrint(allocator,
\\Os{{
\\ .tag = .{},
\\ .version_range = .{{
, .{@tagName(target.os.tag)});
defer os_builtin_str_buffer.deinit();
// We'll re-use the OS version range builtin string for the cache hash.
const os_builtin_str_ver_start_index = os_builtin_str_buffer.len();
@setEvalBranchQuota(2000);
switch (target.os.tag) {
.freestanding,
.ananas,
.cloudabi,
.dragonfly,
.fuchsia,
.ios,
.kfreebsd,
.lv2,
.solaris,
.haiku,
.minix,
.rtems,
.nacl,
.cnk,
.aix,
.cuda,
.nvcl,
.amdhsa,
.ps4,
.elfiamcu,
.tvos,
.watchos,
.mesa3d,
.contiki,
.amdpal,
.hermit,
.hurd,
.wasi,
.emscripten,
.uefi,
.other,
=> try os_builtin_str_buffer.append(" .none = {} }\n"),
.freebsd,
.macosx,
.netbsd,
.openbsd,
=> try os_builtin_str_buffer.outStream().print(
\\ .semver = .{{
\\ .min = .{{
\\ .major = {},
\\ .minor = {},
\\ .patch = {},
\\ }},
\\ .max = .{{
\\ .major = {},
\\ .minor = {},
\\ .patch = {},
\\ }},
\\ }}}},
\\
, .{
target.os.version_range.semver.min.major,
target.os.version_range.semver.min.minor,
target.os.version_range.semver.min.patch,
target.os.version_range.semver.max.major,
target.os.version_range.semver.max.minor,
target.os.version_range.semver.max.patch,
}),
.linux => try os_builtin_str_buffer.outStream().print(
\\ .linux = .{{
\\ .range = .{{
\\ .min = .{{
\\ .major = {},
\\ .minor = {},
\\ .patch = {},
\\ }},
\\ .max = .{{
\\ .major = {},
\\ .minor = {},
\\ .patch = {},
\\ }},
\\ }},
\\ .glibc = .{{
\\ .major = {},
\\ .minor = {},
\\ .patch = {},
\\ }},
\\ }}}},
\\
, .{
target.os.version_range.linux.range.min.major,
target.os.version_range.linux.range.min.minor,
target.os.version_range.linux.range.min.patch,
target.os.version_range.linux.range.max.major,
target.os.version_range.linux.range.max.minor,
target.os.version_range.linux.range.max.patch,
target.os.version_range.linux.glibc.major,
target.os.version_range.linux.glibc.minor,
target.os.version_range.linux.glibc.patch,
}),
.windows => try os_builtin_str_buffer.outStream().print(
\\ .windows = .{{
\\ .min = .{},
\\ .max = .{},
\\ }}}},
\\
, .{
@tagName(target.os.version_range.windows.min),
@tagName(target.os.version_range.windows.max),
}),
}
try os_builtin_str_buffer.append("};\n");
try cache_hash.append(
os_builtin_str_buffer.toSlice()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()],
);
const glibc_or_darwin_version = blk: {
if (target.isGnuLibC()) {
const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer);
const stage2_glibc = target.os.version_range.linux.glibc;
stage1_glibc.* = .{
.major = stage2_glibc.major,
.minor = stage2_glibc.minor,
.patch = stage2_glibc.patch,
};
break :blk stage1_glibc;
} else if (target.isDarwin()) {
const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer);
const stage2_semver = target.os.version_range.semver.min;
stage1_semver.* = .{
.major = stage2_semver.major,
.minor = stage2_semver.minor,
.patch = stage2_semver.patch,
};
break :blk stage1_semver;
} else {
break :blk null;
}
};
const std_dl = target.standardDynamicLinkerPath();
const std_dl_z = if (std_dl.get()) |dl|
(try mem.dupeZ(std.heap.c_allocator, u8, dl)).ptr
else
null;
const cache_hash_slice = cache_hash.toOwnedSlice();
self.* = .{
.arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch
.vendor = 0,
.os = @enumToInt(target.os.tag),
.abi = @enumToInt(target.abi),
.llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null,
.llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr,
.cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr,
.os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr,
.cache_hash = cache_hash_slice.ptr,
.cache_hash_len = cache_hash_slice.len,
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
.is_native = cross_target.isNative(),
.glibc_or_darwin_version = glibc_or_darwin_version,
.dynamic_linker = dynamic_linker,
.standard_dynamic_linker_path = std_dl_z,
};
remove the concept of "sub-architecture" in favor of CPU features. Also rearrange the `std.Target` data structure. * note: `@import("builtin")` was already deprecated in favor of `@import("std").builtin`. * `std.builtin.arch` is now deprecated in favor of `std.builtin.cpu.arch`. * `std.Target.CpuFeatures.Cpu` is now `std.Target.Cpu.Model`. * `std.Target.CpuFeatures` is now `std.Target.Cpu`. * `std.Target` no longer has an `arch` field. Instead it has a `cpu` field, which has `arch`, `model`, and `features`. * `std.Target` no longer has a `cpu_features` field. * `std.Target.Arch` is moved to `std.Target.Cpu.Arch` and it is an enum instead of a tagged union. * `std.Target.parseOs` is moved to `std.Target.Os.parse`. * `std.Target.parseAbi` is moved to `std.Target.Abi.parse`. * `std.Target.parseArchSub` is only for arch now and moved to `std.Target.Cpu.Arch.parse`. * `std.Target.parse` is improved to accept CPU name and features. * `std.Target.Arch.getBaselineCpuFeatures` is moved to `std.Target.Cpu.baseline`. * `std.Target.allCpus` is renamed to `std.Target.allCpuModels`. * `std.Target.defaultAbi` is moved to `std.Target.Abi.default`. * Significant cleanup of aarch64 and arm CPU features, resulting in the needed bit count for cpu feature set going from 174 to 138. * Add `std.Target.Cpu.Feature.Set.addFeatureSet` for merging feature sets together. `-target-feature` and `-target-cpu` are removed in favor of `-mcpu`, to conform to established conventions, and it gains additional power to support cpu features. The syntax is: -mcpu=name+on1+on2-off1-off2 closes #4261
2020-02-19 18:30:36 -08:00
}
2020-02-17 12:23:59 -08:00
};
fn enumInt(comptime Enum: type, int: c_int) Enum {
return @intToEnum(Enum, @intCast(@TagType(Enum), int));
}
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target {
var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target);
if (info.cpu_detection_unimplemented) {
// TODO We want to just use detected_info.target but implementing
// CPU model & feature detection is todo so here we rely on LLVM.
const llvm = @import("llvm.zig");
const llvm_cpu_name = llvm.GetHostCPUName();
const llvm_cpu_features = llvm.GetNativeFeatures();
const arch = std.Target.current.cpu.arch;
info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features);
cross_target.updateCpuFeatures(&info.target.cpu.features);
2020-02-28 15:09:33 -08:00
info.target.cpu.arch = cross_target.getCpuArch();
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
}
if (info.dynamic_linker.get()) |dl| {
dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl);
} else {
dynamic_linker_ptr.* = null;
}
return info.target;
separate std.Target and std.zig.CrossTarget Zig now supports a more fine-grained sense of what is native and what is not. Some examples: This is now allowed: -target native Different OS but native CPU, default Windows C ABI: -target native-windows This could be useful for example when running in Wine. Different CPU but native OS, native C ABI. -target x86_64-native -mcpu=skylake Different C ABI but otherwise native target: -target native-native-musl -target native-native-gnu Lots of breaking changes to related std lib APIs. Calls to getOs() will need to be changed to getOsTag(). Calls to getArch() will need to be changed to getCpuArch(). Usage of Target.Cross and Target.Native need to be updated to use CrossTarget API. `std.build.Builder.standardTargetOptions` is changed to accept its parameters as a struct with default values. It now has the ability to specify a whitelist of targets allowed, as well as the default target. Rather than two different ways of collecting the target, it's now always a string that is validated, and prints helpful diagnostics for invalid targets. This feature should now be actually useful, and contributions welcome to further improve the user experience. `std.build.LibExeObjStep.setTheTarget` is removed. `std.build.LibExeObjStep.setTarget` is updated to take a CrossTarget parameter. `std.build.LibExeObjStep.setTargetGLibC` is removed. glibc versions are handled in the CrossTarget API and can be specified with the `-target` triple. `std.builtin.Version` gains a `format` method.
2020-02-25 22:18:23 -08:00
}
2020-02-17 12:23:59 -08:00
// ABI warning
const Stage2SemVer = extern struct {
2020-02-17 12:23:59 -08:00
major: u32,
minor: u32,
patch: u32,
};
// ABI warning
const Stage2NativePaths = extern struct {
include_dirs_ptr: [*][*:0]u8,
include_dirs_len: usize,
lib_dirs_ptr: [*][*:0]u8,
lib_dirs_len: usize,
rpaths_ptr: [*][*:0]u8,
rpaths_len: usize,
warnings_ptr: [*][*:0]u8,
warnings_len: usize,
};
// ABI warning
export fn stage2_detect_native_paths(stage1_paths: *Stage2NativePaths) Error {
stage2DetectNativePaths(stage1_paths) catch |err| switch (err) {
error.OutOfMemory => return .OutOfMemory,
};
return .None;
}
fn stage2DetectNativePaths(stage1_paths: *Stage2NativePaths) !void {
var paths = try std.zig.system.NativePaths.detect(std.heap.c_allocator);
errdefer paths.deinit();
try convertSlice(paths.include_dirs.toSlice(), &stage1_paths.include_dirs_ptr, &stage1_paths.include_dirs_len);
try convertSlice(paths.lib_dirs.toSlice(), &stage1_paths.lib_dirs_ptr, &stage1_paths.lib_dirs_len);
try convertSlice(paths.rpaths.toSlice(), &stage1_paths.rpaths_ptr, &stage1_paths.rpaths_len);
try convertSlice(paths.warnings.toSlice(), &stage1_paths.warnings_ptr, &stage1_paths.warnings_len);
}
fn convertSlice(slice: [][:0]u8, ptr: *[*][*:0]u8, len: *usize) !void {
len.* = slice.len;
const new_slice = try std.heap.c_allocator.alloc([*:0]u8, slice.len);
for (slice) |item, i| {
new_slice[i] = item.ptr;
}
ptr.* = new_slice.ptr;
}