Open yutannihilation opened 9 months ago
A great find, thank you for sharing! I think we should take care of this in rwasm
if we can.
We could tweak webr-vars.mk
to export some of the make variables so that they're available in the environment with changes such as,
- CC = emcc
- CXX = em++
- FC = $(EMFC)
- CFLAGS = $(WASM_CFLAGS)
- CPPFLAGS = $(WASM_CPPFLAGS)
- CXXFLAGS = -std=gnu++11 $(WASM_CXXFLAGS)
+ export CC = emcc
+ export CXX = em++
+ export FC = $(EMFC)
+ export CFLAGS = $(WASM_CFLAGS)
+ export CPPFLAGS = $(WASM_CPPFLAGS)
+ export CXXFLAGS = -std=gnu++11 $(WASM_CXXFLAGS)
With this, Rust should pick up the emcc
compiler without package authors having to add CC=$(CC)
manually.
One thing I am not sure about is how this change could potentially affect other R packages. I can think of a situation where this might break things: if some package is building an executable as an intermediate step, then running it on the host machine to generate some further output to be included in the package. I don't actually know if any R packages work like that - @jeroen, can you think of any? Or think of any other issues with simply exporting these variables to the build environment?
Either way, I suppose any packages doing something like that could be made to use the compiler given in HOST_CC
by a configure step instead:
$ emconfigure env | grep CC
CC=/Users/georgestagg/emsdk/upstream/emscripten/emcc
HOST_CC=/Users/georgestagg/emsdk/upstream/bin/clang
Sounds great!
To be fair, the use of Rust is not majority and probably only few of them invokes C compiler. So, it might not be really worth the risk. At the moment, we anyway need to use Makevars.webr
for overriding settings, so it might be reasonable to leave it for the author to specify it.
Also, to be precise, CC=$(CC)
might not be strictly necessary. It seems choosing the wasm32-unknown-emscripten
target determines the C compiler is emcc
. (But, since I couldn't figured out the mechanism, I specify CC
for safety).
At the moment, we anyway need to use
Makevars.webr
for overriding settings
We shim uname
in rwasm
to return "Emscripten" when cross-compiling, so you might be able to combine things into a single Makevars
by testing for that:
UNAME := $(shell uname -s)
ifeq ($(UNAME),Emscripten)
[...]
endif
Oh, good to know, thanks.
FYI, I chose to use configure
instead of relying on ifeq
GNU make extension. I'm not sure how it's meaningful, but it seems it's the preference of the CRAN maintainers to avoid extensions for the maximum portability. YMMV.
https://github.com/yutannihilation/savvy-webr-test/commit/257f8fbb20da472797cb6a05cf2e1bb42a12a742
One thing I am not sure about is how this change could potentially affect other R packages. I can think of a situation where this might break things: if some package is building an executable as an intermediate step, then running it on the host machine to generate some further output to be included in the package. I don't actually know if any R packages work like that - @jeroen, can you think of any?
The maps
package is one example.
(This issue is mainly for sharing the information, so feel free to close. But I hope this helps somehow.)
Probably you already know, the Rust compiler sometimes invokes the C compiler inside.
https://doc.rust-lang.org/cargo/reference/build-scripts.html
rwasm overrides the
CC
andCFLAGS
Makevars, but I found these settings are not propagated to the C compiler unless the same name of envvars are set.https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables
I'm not sure if this is what rwasm should take care of or the package author should, but I actually had to specify it in my package, which compiles a bit of C code in the crate.
https://github.com/yutannihilation/savvy-webr-test/commit/5ee66d793e9036a1e6bcdbe11c876cee63b00d04