Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WASI libc/sysroot #2336

Closed
wants to merge 3 commits into from
Closed

WASI libc/sysroot #2336

wants to merge 3 commits into from

Conversation

fengb
Copy link
Contributor

@fengb fengb commented Apr 22, 2019

This is based on the preliminary spec that exists in WebAssembly/wasi-libc-old#11

WASI wants to be a real build target, and what better way than defining libc? Per README, this should be the reference ABI so any changes would be ABI compatible... assuming it gets merged in.

Outstanding stuff (reference https://gist.github.com/fengb/be916b5fede576d8066fcb20b684e3c0):

  • Fix Zig's $main: the compiler outputted a $main with 3 parameters: (func $main (type 4) (param i32 i32 i32) (result i32)
  • Resolve with the WASI allocator. I'm really not sure what would happen if both of them try to separately manage memory.
  • Remove --export-all since it exposes all of libc for no good reason.
  • Resolve and/or document the build. The WASI codebase is stitched together from separate upstreams. While it's not too difficult to understand it, trying to maintain a forked build of another forked build feels super brittle so I opted to include the pre-built libraries.
  • Double check process_headers.zig — I couldn't get it to run properly, so I'm not sure if I broke anything by working around it.
  • Naming? The libc doesn't have a good name. All the documentation refers to WASI Sysroot, which feels super clunky as a build target wasm32-wasi-wasisysroot

@@ -721,7 +724,7 @@ void get_target_triple(Buf *triple, const ZigTarget *target) {
ZigLLVMGetSubArchTypeName(target->sub_arch),
ZigLLVMGetVendorTypeName(target->vendor),
ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
ZigLLVMGetEnvironmentTypeName(target->abi));
target_abi_name(target->abi));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WASISysroot doesn't exist in LLVM so I had to shim it in here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at it closer, I defined the enum in ZigLLVM space. Maybe I should move this transform back into ZigLLVMGetEnvironmentTypeName?

@@ -463,6 +464,8 @@ ZigLLVM_EnvironmentType target_abi_enum(size_t index) {
const char *target_abi_name(ZigLLVM_EnvironmentType abi) {
if (abi == ZigLLVM_UnknownEnvironment)
return "none";
if (abi == ZigLLVM_WASISysroot)
return "sysroot";
Copy link
Contributor Author

@fengb fengb Apr 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what to do about naming. Sysroot is super generic, but putting wasi-sysroot everywhere is super clunky: e.g. wasm32-wasi-wasisysroot

@fengb
Copy link
Contributor Author

fengb commented Apr 25, 2019

Only the file system, stdout/stderr, and main() depend on syscalls and thus WASI-Sysroot works quite well on generic (browser) wasm even without WASI. How should we expose this functionality? wasm32-unknown-wasisysroot?

@shritesh
Copy link
Contributor

I think we can get away with following how libc is handled for Linux: std checks for builtin.link_libc and uses those implementations, otherwise makes syscalls directly.

From Lin Clark's "Standardizing WASI: A system interface to run WebAssembly outside the web"

Languages like Rust will use wasi-core directly in their standard libraries. For example, Rust’s open is implemented by calling __wasi_path_open when it’s compiled to WebAssembly.

For C and C++, we’ve created a wasi-sysroot that implements libc in terms of wasi-core functions.

Also,

Resolve with the WASI allocator. I'm really not sure what would happen if both of them try to separately manage memory.

This has been brought up by @andrewrk before. There can be a std.heap.global_allocator that points to std.heap.c_allocator or std.heap.wasm_allocator or a future std.heap.general_purpose_allocator. I also think instantiating a WasmAllocator on libc / non-wasm platforms should be a compile time error.

Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got the right idea here, and it's definitely planned to support a WASI libc with out-of-the-box zig. But we can't ship .a files or .o files - that's not how we achieve cross compilation. I'm happy to help with this, but I'll probably have to re-do a lot of this work myself, to double check your work. Perhaps you can start with something smaller, such as adding the wasi-sysroot C ABI?

I think WASI is a great candidate for having a pure-zig implementation of libc, and I would like to go down that road before shipping more libc implementations. These implementations can share a lot of code with the Zig standard library when targeting WASI without linking libc.

@andrewrk
Copy link
Member

Related: #2380

@fengb fengb closed this May 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants