I am trying to use emscripten to port some C code that requires libm. Usually, it uses my system's version, and I don't need to worry about linking to it, but I need to manually link it with emscripten.
How can I link libm?
I have tried using openlibm, but when I make it with emcc (the emscripten compiler) it cannot find all dependencies, as openlibm still depends on system headers.
I have also tried using the GNU libc source, but cannot navigate those Makefiles.
What I need is the bitcode, as generated by emcc, to link to when compiling to JavaScript, using the -lm flag in the compiler.
libm is linked by default.
The emcc compiler will not be able to link it if it is specified (as -lm), as this requires an explicit search path (with -L/path/). It has an internal implementation which should not be overwritten, unless you can supply your own emcc-compiled bitcode.
The compiler will throw warnings for the unresolved library until you compile to JavaScript, as libm is not included until the final compile. These errors on the intermediate targets can and should be ignored - it is a known issue.
The available libraries through the compiler can be found at https://github.com/kripken/emscripten/tree/master/system/include. Specifically, libm is included in the musl headers. It is not explicit, but that is covered in the musl FAQs.
Related
I want to import shared memory in my WASM module and trying to link my object files all compiled with -matomics and -mbulk-memory, and wasi-libc -lc, lc++ and -lc++abi libraries. But getting an error:
wasm-ld: error: --shared-memory is disallowed by errno.o because it was not compiled with 'atomics' or 'bulk-memory' features.
As i understand wasm-ld links some libc object files, compiled without flags above, so it can't be linked. How can i provide these flags to linker? Or need to build wasi-libc from source with these flags?
Problem has been solved by specifying --no-check-features flag at linking.
wasi-libc does not support shared memory or multi-threading today. If you want to try to make something work you would, at minimum, need to recompile the the core libraries (libc, compiler-rt, libcxx, libcxxabi) with the -pthread compiler flag.
If you want to use mutli-threading with WebAssembly as of today (2021) the only reasonable option it use emscripten and its Web Worker-based multi-threading approach.
I'm compiling c++ to web assembly using clang --target=wasm32 --no-standard-libraries. Is there a way to convince clang to generate sqrt? It's not finding <math.h> with this target.
Do you already tried to compile without the flag --no-standard-libraries? If you remove it, the clang probably will find math.h library (because its a standard library).
This is because wasm32-unknown-unknown is a completely barebones targets in Clang, and doesn't have any standard library - that is, no math.h, no I/O functions, not even memcpy.
However, you can usually get away with using --target wasm32-wasi + WASI SDK instead: https://github.com/WebAssembly/wasi-sdk
It includes the whole standard library, including even functions for interacting with the filesystem via the WASI standard in compatible environments.
If your code doesn't depend on filesystem / clock / other I/O, then you can safely use WASI-SDK to get math.h, memcpy, malloc and other standard functions, and the resulting WebAssembly will be compatible with any non-WASI environments as well.
I am trying to get LLVM IR for a file which is linked with some static libararies.
I tried to link using llvm-link . It just copy the .bc files in one file ( not like native linking).
clang -L$(T_LIB_PATH) -lpthread -emit-llvm gives an error: emit-llvm can not be used with linking. When passing -c option, it gives warning that the linking options were not used.
My main goal is to get .bc file with all resolved symbols and references. How can I achieve that with clang version 3.4.?
You may have a look at wllvm. It is a wrapper on the compiler, which enable to build a project and extract the LLVM bitcode of the whole program.
You need to use wllvm and wllvm++ for C and C++, respectively (after setting some environment variables).
Some symbols come from source code via LLVM IR. IR is short for intermediate representation. Those symbols are easy to handle, just stop in the middle of the build process.
Some others come from a library and probably were generated by some other compiler, one that never makes any IR, and in any case the compiler was run by some other people at some other location. You can't go back in time and make those people build IR for you, even if their compiler has the right options. All you can do is obtain the source code for the libraries and build your entire application from source.
I'm confused about one aspect of LLVM:
For all the languages it supports, does it support compiling both to the intermediate code AND to straight binary?
For instance, if I write something in C, can LLVM (or Clang?) compile to either binary (like GCC) or intermediate code?
Or can only some languages be converted to intermediate? I guess it goes without saying that this intermediate requires some type of LLVM runtime? I never really hear bout the runtime, though.
LLVM is a framework for manipulating LLVM IR (the "bytecode" you're alluding to) and lowering it to target-specific binaries (for example x86 machine code). Clang is a front-end for C/C++ (and Objective C) that translates these source languages into LLVM IR.
With this in mind, answering your questions:
For all the languages it supports, does it support compiling both to
the intermediate code AND to straight binary?
LLVM can compile IR (intermediate code) to binary (or to assembly text).
For instance, if I write something in C, can LLVM (or Clang?) compile
to either binary (like GCC) or intermediate code?
Yes. Clang can compile your code to a binary directly (using LLVM as a backend), or just emit LLVM IR if you want that.
Or can only some languages be converted to intermediate? I guess it
goes without saying that this intermediate requires some type of LLVM
runtime?
Theoretically, once you have LLVM IR, the LLVM library can convert it to binary. Some languages require a runtime (say Java, or Python), so any compiler from these languages to LLVM IR will have to provide a runtime in one way or another. LLVM has some support for connecting to such runtimes (for example - GC hooks) but carries no "runtime of its own". The only "runtime" project related to LLVM is compiler-rt, which provides fast implementations of some language/compiler builtins and intrinsics. It's mainly used for C/C++/Objective C. It's not officially part of LLVM, though full toolchains based on Clang often use it.
OpenMPI strongly recommends using their wrapper compilers. Behind the scenes, their wrapper compiler mpiCC calls gcc (by default?) and adds the necessary flags for MPI code to compile. However, other compilers give more descriptive error messages than gcc (e.g. clang which is also GCC-compatible). So, I'd like to be able to use clang with Open MPI.
I tried:
1) finding an mpiCC option for specifying the compiler, but
mpiCC --help
just spits out the g++ help page.
2) using the --showme:compile option
mpiCC --showme:compile ./test-boost.cc -lboost_mpi -lboost_serialization -o test-boost
which, instead of calling gcc, prints the flags needed for compiling the MPI code. I can then use those with clang (since it's GCC-compatible). This should work, but I'm looking for an easier solution.
Open MPI FAQ says which environmental variables can be set to override the default choice of the compiler called by the wrapper.
http://www.open-mpi.org/faq/?category=mpi-apps#override-wrappers-after-v1.0
Depending on the version of OpenMPI you should set OMPI_CXX=clang++ or OMPI_MPICC=clang. For OpenMPI v.1.1 and later use OMPI_CXX and then call the wrapper compiler. The wrapper would call clang++ in turn.
Setting OMPI_CC=clang or OMPI_CXX=clang++ as environment variables in .bashrc, as described in the official FAQ of OpenMPI, is NOT working for me. I have to attach them ahead whenever I use mpicc, e.g.
OMPI_CC=clang mpicc --showme:command
So in Makefile, I set CC=OMPI_CC=clang mpicc, which works well for me.