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

macOS release binaries not able to create executables #138

Closed
myobie opened this issue Jun 1, 2020 · 28 comments
Closed

macOS release binaries not able to create executables #138

myobie opened this issue Jun 1, 2020 · 28 comments

Comments

@myobie
Copy link

myobie commented Jun 1, 2020

Given these env variables:

export PATH="${PROJECT}/wasi-sdk-10.0/bin:$PATH"
export WASI_SYSROOT="${PROJECT}/wasi-sdk-10.0/share/wasi-sysroot"
clang --target=wasm32-wasi --sysroot="${WASI_SYSROOT}" ...

I then see configure: error: C compiler cannot create executables.

  • ./configure --prefix=/.../wasm-build --with-sysroot=/.../wasi-sdk-10.0/share/wasi-sysroot --host=wasm32-wasi --disable-ssp --disable-shared
    checking build system type... i386-apple-darwin19.5.0
    checking host system type... wasm32-unknown-wasi
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for wasm32-wasi-strip... llvm-strip
    checking for a thread-safe mkdir -p... build-aux/install-sh -c -d
    checking for gawk... gawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking whether UID '501' is supported by ustar format... yes
    checking whether GID '20' is supported by ustar format... yes
    checking how to create a ustar tar archive... gnutar
    checking whether make supports nested variables... (cached) yes
    checking whether to enable maintainer-specific portions of Makefiles... no
    checking whether make supports the include directive... yes (GNU style)
    checking for wasm32-wasi-gcc... clang
    checking whether the C compiler works... no
    configure: error: in /.../': configure: error: C compiler cannot create executables See config.log' for more details

I am able to make a sysroot myself inside a checked out wasi-sdk repo with make install INSTALL_DIR="${PROJECT}/sysroot/" and I can use it to compile the same project (after I've downloaded and placed libclang_rt.builtins-wasm32-wasi-10.0.tar.gz into my llvm installation inside homebrew). However, I'd like to take advantage of the pre-compiled binaries + sysroots if at all possible because I've run into a problem too many times with one machine having a different version of llvm installed, etc.

One key difference I notice when using the version I compiled myself is it says it's build system type is x86_64-apple-darwin19.5.0.

I am using macOS 10.15.5 with the latest homebrew and llvm 10.0.0_3.

@jedisct1
Copy link
Member

jedisct1 commented Jun 1, 2020

The config.log file may tell you more about why executables cannot be created.

But macOS binaries available for download here are not notarized, so they cannot be used on Catalina if you download them using a web browser, or anything quarantining untrusted downloads.

A possible workaround is to download them using curl instead of a web browser.

But if you are using Homebrew, you really don't need a second installation of LLVM, especially since LLVM packages in Homebrew are always up to date.

The wasi-sdk downloads include a precompiled wasi-sysroot. This, in addition to the precompiled builtins, is all you need if you already installed llvm using homebrew.

I started to work on a Homebrew package to add these dependencies. A package for the wasi sysroot is pretty straightforward, but for the builtins, I couldn't figure out how to cleanly install them into another package's (llvm) path.

@pchickey
Copy link
Collaborator

pchickey commented Jun 1, 2020

Thanks @jedisct1 - we'd love to make notarized packages available for download but none of the current maintainers have the expertise (and most of us don't even have macs) to get it done, so we'd welcome help with that. Homebrew is another possibility, but similarly I don't have any idea how that actually works.

@jedisct1
Copy link
Member

jedisct1 commented Jun 1, 2020

Another option is having a curl | sh installation script similar to rustup.

That wouldn't require notarization, would provide a unified installation procedure on all operating systems, and would provide a single-step way to install wasi-sdk, with or without LLVM, and with optional components (Lucet, Wasmtime, etc).

@sbc100
Copy link
Member

sbc100 commented Jun 1, 2020

We already provide a tarball containing just the sysroot if you want to use the llvm from homebrew: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-10/wasi-sysroot-10.0.tar.gz

@myobie
Copy link
Author

myobie commented Jun 1, 2020

I downloaded the release with wget and the binaries that were un-tarred are able to be executed, they however do not produce executables on my machine. How can I help better diagnose this issue?

@jedisct1
Copy link
Member

jedisct1 commented Jun 1, 2020

clang --target=wasm32-wasi --sysroot="${WASI_SYSROOT}" ...

Is that version of clang before the the Homebrew (or Xcode) one in your $PATH?

If not, provide the full path to it, or set a temporary $PATH with the wasi-sdk version first.

@pchickey
Copy link
Collaborator

pchickey commented Jun 1, 2020

they however do not produce executables on my machine.

The default target is wasm32-wasi, so we would expect the file format of the executables to be a Wasm binary, with imports from the Wasi interface.

@sbc100
Copy link
Member

sbc100 commented Jun 1, 2020

Oh wait are you expecting to be able to run the output of the toolchain directly? Just to be clear this toolchain builds wasm files, which are not directly runnable. You need to run them in a wasm engine.

Assuming you already knew that can you build a simple hello world program, and include the full command line (with -v added) and the full output? Also can you attach the output file?

@jedisct1
Copy link
Member

jedisct1 commented Jun 1, 2020

configure: error: C compiler cannot create executables doesn't mean that autoconf tried to execute the program, just that it wasn't able to build it.

@sbc100
Copy link
Member

sbc100 commented Jun 1, 2020

Right, I would imaging that is what that means.

I was just confused by the statement: "they however do not produce executables on my machine". What does the toolchain produce then? What happens when you run clang directly?

@myobie
Copy link
Author

myobie commented Jun 2, 2020

I apologize, I was just repeating the error statement.

@jedisct1
Copy link
Member

jedisct1 commented Jun 2, 2020

The actual error is visible in the config.log file.

@sbc100
Copy link
Member

sbc100 commented Jun 2, 2020

@myobie when you use wget and you run clang directly from the command line (for example to build hello world) what error do you see?

@myobie
Copy link
Author

myobie commented Jun 3, 2020

@sbc100 I decided to create a simple example project today to isolate the issue and the included binaries do work on my Mac, so my and other's original suspicions were wrong. See https://gist.github.com/myobie/e5f15231cca4fc22e0b77a741ea64772

The project I am attempting to compile has a configure script and I dug into it today and it attempts to compile an example program and then looks for various possible output files like a.out, conftest.exe, etc. There are no wasm file names in its tests and since these release binaries only output wasm results, the configure script ends with the original error I posted above.

I manually edited the configure script to add conftest.wasm and a.wasm to the list of possible output file names and that allowed the script to complete. So I apologize, this appears to be an upstream error / assumption; however, it is very understandable how this could happen and it could happen to many projects that make similar tests / assumptions. I'm not sure how to fix this other than making a PR to the upstream project to change their scripts (and having a .patch for myself for now).

Thanks for your help. I'm going to close this, since the original issue wasn't really valid. However, I'll stay subscribed and if you all need or want any more info from me then let me know.

@myobie myobie closed this as completed Jun 3, 2020
@jedisct1
Copy link
Member

jedisct1 commented Jun 3, 2020

autoconf scripts generally only attempt to run produced executables in a non cross-compilation environment.

A typical set of options for configure in order to compile to WASI is

env CC="clang" ./configure --with-sysroot="$WASI_SYSROOT" --host=wasm32-wasi

--host=... (and not --target) is what causes the scripts to know that you are cross-compiling.

Some extra environment variables may have to be explicitly defined in addition to CC="clang":

NM="llvm-nm"
AR="llvm-ar"
RANLIB="llvm-ranlib"
STRIP="llvm-strip"

Running tests when cross-compiling to WASI is also fully supported by autoconf, by defining a LOG_COMPILER environment variable, containing the path to a script to run in order to execute compiled objects. Such a script can use wasmtime for that purpose.

@jedisct1
Copy link
Member

jedisct1 commented Jun 3, 2020

Also, if an old version of the autotools was used to generate it, the config.sub file may not support WASI.

You can download an up-to-date version of that script here.

@myobie
Copy link
Author

myobie commented Jun 3, 2020

@jedisct1 the config.sub in the project is the same as the one you linked to.

These are the env vars I am using in the project:

export CC="clang"
export NM="llvm-nm"
export AR="llvm-ar"
export RANLIB="llvm-ranlib"
export STRIP="llvm-strip"

And my configure line:

./configure --prefix="${PREFIX}" --with-sysroot="$WASI_SYSROOT" \
  --host=wasm32-wasi \
  --disable-ssp --disable-shared

The project includes an autogen.sh which runs autoreconf, but it doesn't change the configure. In the configure script itself there is a hard coded test and the project doesn't seem to have a way to generate a different type of configure. If I manually edit the configure to change the test then it proceeds fine.

The part of config.log that is relevant is:

int
main ()
{

  ;
  return 0;
}
configure:3805: error: in `/...':
configure:3807: error: C compiler cannot create executables

@jedisct1
Copy link
Member

jedisct1 commented Jun 3, 2020

Wait, are you trying to compile libsodium?

@myobie
Copy link
Author

myobie commented Jun 3, 2020

@jedisct1 some parts of it are included in my project, yes. Is that a problem or known issue?

@jedisct1
Copy link
Member

jedisct1 commented Jun 3, 2020

That configure line looked familiar :)

Not a problem at all, especially since WASI is a supported platform.

Make sure that you are using the stable branch (or libsodium-1.0.18-stable). It can then be compiled just by running dist-build/wasm32-wasi.sh .

If you still have issues, it may be better to continue the discussion in the libsodium issue tracker than here, then.

Thanks!

@myobie
Copy link
Author

myobie commented Jun 3, 2020

@jedisct1 Ha! OK, good, that's what I thought 😄

Ah good point, I'll try to create a small example script like I did before and make an issue over there after I can easily replicate it outside my project. I am using a vendor-ed tar of the 1.0.18 release. Thanks again for the help.

@jedisct1
Copy link
Member

jedisct1 commented Jun 3, 2020

I am using a vendor-ed tar of the 1.0.18 release.

Breaking changes happened to wasi-sdk, wasi and to various runtimes since the release.

The stable branch doesn't change the API and doesn't introduce new features, but was introduced to backport performance improvements, and to keep up with external breaking changes, as well as add support for new compilers (such as Visual Studio 2019 that was also released since).

@sbc100
Copy link
Member

sbc100 commented Jun 3, 2020

The project I am attempting to compile has a configure script and I dug into it today and it attempts to compile an example program and then looks for various possible output files like a.out, conftest.exe, etc. There are no wasm file names in its tests and since these release binaries only output wasm results, the configure script ends with the original error I posted above.

I'm a little confused by why such a fix would work. The clang driver, even when run as part of wasi-sdk won't ever default to creating files that end in .wasm as far as I know. They just output whatever -o is given on the command line, and default of a.out... which should be fine for your configure script since its already looking for that.

So, why are files ending in .wasm being created by the configure script?

@myobie
Copy link
Author

myobie commented Jun 4, 2020

@sbc100 while I did edit the configure script and then it worked, it might have been because my env was different in a single way: I may not have had CC set or exported. I've took some time to isolate my issue down to a smaller project I can share and for some reason when I have CC=clang the configure script fails with the original error. My larger project has CC set so it's picked up by some Makefiles, but I'm now looking into not setting it and what that means.

I've created a new gist which uses libsodium to show the problem: https://gist.github.com/myobie/dedd68a05245db0376a803a19fd635e1
(Uncommenting line 22 will show my original error.)

/cc @jedisct1 since it's libsodium I used as the example

(Oh and this is still just using the libsodium release tar and not the stable branch, I haven't taken the time to try to use it yet.)

@jedisct1
Copy link
Member

jedisct1 commented Jun 4, 2020

The error you get is

configure:3760: clang    conftest.c  >&5
wasm-ld: error: cannot open crt1.o: No such file or directory
wasm-ld: error: unable to find library -lc

Because your script should set the sysroot before calling ./configure.

 env CFLAGS="--sysroot=/tmp/wasi-sdk-10.0/share/wasi-sysroot -O2" ./configure --host=wasm32-wasi

But please just use the provided script, that works out of the box and is the only supported way to compile it to WebAssembly. The resulting library can be linked with other object files like any other library.

@myobie
Copy link
Author

myobie commented Jun 5, 2020

@jedisct1 oh, interesting that you get a different error than I do 😕 – I updated https://gist.github.com/myobie/dedd68a05245db0376a803a19fd635e1 to include the output from my run of the test script. Also, setting CFLAGS doesn't change the output I see.

This does give me more evidence that my build environment is not clean or easily reproducible. I want my larger project to have predictable/reproducible builds and I'll need to track down what is in my environment before I can have that.

Also, I would use the script if I were just compiling libsodium yes, but my larger project is one that includes libsodium header files and has a few different outputs, etc so I have my own scripts and tooling for that project. I just wanted to use libsodium here as an example since it shows the same problem as my larger project – sorry if that wasn't clear.

@dominictobias
Copy link

dominictobias commented Jan 10, 2021

I'm running into the same issue, I followed https://doc.libsodium.org/installation which didn't produce a .wasm binary so I'm trying to execute ./dist-build/wasm32-wasi.sh on Catalina MacOS but getting the same error. Have the extended XCode tools, tried installing llvm from brew and adding it to path, but doesn't change the error.

Seems to start failing here:

InstalledDir: /usr/local/opt/llvm/bin
configure:3670: $? = 0
configure:3659: clang -V >&5
clang-11: error: argument to '-V' is missing (expected 1 value)
clang-11: error: no input files
configure:3670: $? = 1
configure:3659: clang -qversion >&5
clang-11: error: unknown argument '-qversion'; did you mean '--version'?
clang-11: error: no input files
configure:3670: $? = 1
configure:3690: checking whether the C compiler works
configure:3712: clang -DED25519_NONDETERMINISTIC=1 --target=wasm32-wasi --sysroot=/Users/***/Projects/wasi-sdk-12.0/ -O2  -s -Wl,--stack-first conftest.c  >&5
wasm-ld: error: cannot open crt1.o: No such file or directory
wasm-ld: error: unable to find library -lc
wasm-ld: error: cannot open /usr/local/Cellar/llvm/11.0.0_1/lib/clang/11.0.0/lib/wasi/libclang_rt.builtins-wasm32.a: No such file or directory
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
configure:3716: $? = 1
configure:3754: result: no
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "libsodium"
| #define PACKAGE_TARNAME "libsodium"
| #define PACKAGE_VERSION "1.0.18"
| #define PACKAGE_STRING "libsodium 1.0.18"
| #define PACKAGE_BUGREPORT "https://github.com/jedisct1/libsodium/issues"
| #define PACKAGE_URL "https://github.com/jedisct1/libsodium"
| #define PACKAGE "libsodium"
| #define VERSION "1.0.18"
| /* end confdefs.h.  */
| 
| int
| main ()
| {
| 
|   ;
|   return 0;
| }
configure:3759: error: in `/Users/***/Projects/***/libsodium-stable':
configure:3761: error: C compiler cannot create executables
See `config.log' for more details

Any ideas how to get it to compile? Sorry if I missed it in the above ^^

@jedisct1
Copy link
Member

wasm-ld: error: cannot open /usr/local/Cellar/llvm/11.0.0_1/lib/clang/11.0.0/lib/wasi/libclang_rt.builtins-wasm32.a: No such file or directory

You need to install that file (eventually, the Homebrew formula will install it along with llvm but it is not the case yet).

See https://github.com/jedisct1/libclang_rt.builtins-wasm32.a

kildom pushed a commit to kildom/clang-wasi-port that referenced this issue Jul 14, 2021
alexcrichton pushed a commit to alexcrichton/wasi-sdk that referenced this issue Apr 5, 2023
This brings in the following changes:

f645f49 Update signal macros after upgrade to snapshot1 (WebAssembly#144)
8b3266d github actions: pin checkout action to v1 (WebAssembly#145)
410c660 Use constructor functions for optional init routines. (WebAssembly#142)
fe13053 c header generation updated for reorganized witx ast (WebAssembly#139)
cd74e1d Correct the version of WebAssembly#136 on master (WebAssembly#141)
446cb3f Wasi snapshot preview1 (WebAssembly#140)
54102f0 Ignore rights in libpreopen. (WebAssembly#129)
8c9e1c6 Make the `__original_main` definition weak, fixing -flto. (WebAssembly#138)
cf81683 Optimize `fmin`, `fmax`, etc. (WebAssembly#120)
deb8eae Don't pre-check capabilities in `openat`. (WebAssembly#130)
ca9046d Use consistent style for wasi-libc C source files. (WebAssembly#131)
951cc3e Fix unintended recursion in __wasilibc_register_preopened_fd. (WebAssembly#133)
5216983 Avoid a `strdup` call in `__wasilibc_populate_libpreopen`. (WebAssembly#128)
70099d4 Don't link in libpreopen initialization code when it isn't needed. (WebAssembly#127)
ec4549d Temporarily disable the use of `__heap_base`. (WebAssembly#132)
a214f1c Use __heap_base by dlmalloc (WebAssembly#114)
a94d2d0 Avoid varargs conventions when calling open (WebAssembly#126)
7fcc4f2 Revamp and simplify the libpreopen code. (WebAssembly#110)
eb7230c Remove more unsupported headers. (WebAssembly#123)
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

No branches or pull requests

5 participants