Description
Version
$ emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.8 (70404efec4458b60b953bc8f1529f2fa112cdfd1)
clang version 21.0.0git (https:/github.com/llvm/llvm-project 23e3cbb2e82b62586266116c8ab77ce68e412cf8)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin
$ node -v
v20.18.0
$ which node
/emsdk/node/20.18.0_64bit/bin/node
Description
Suppose you had the following files: configure.ac
, dummy.c
, and a package.json
with type: "module"
. This is true even if that package.json
is not in the same directory as ./configure
but only the closest package.json
.
# configure.ac
AC_INIT([dummy], [0.1])
AC_CONFIG_SRCDIR([dummy.c])
AC_PROG_CC
AC_OUTPUT
// dummy.c
int x = 20;
Failing command line in full:
autoreconf && emconfigure ./configure
(or any variation that uses autoconf)
Terminal output:
$ emconfigure ./configure
configure: ./configure
checking for gcc... /emsdk/upstream/emscripten/emcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... configure: error: in `/src':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details
emconfigure: error: './configure' failed (returned 77)
config.log
output snippet: (full output, full output with EMCC_DEBUG=1
)
# config.log
# ...
configure:2721: checking whether we are cross compiling
configure:2729: /emsdk/upstream/emscripten/emcc -o conftest conftest.c >&5
configure:2733: $? = 0
configure:2740: ./conftest
file:///src/conftest:79
var fs = require('fs');
^
ReferenceError: require is not defined in ES module scope, you can use import instead
at file:///src/conftest:79:12
at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)
Node.js v20.18.0
configure:2744: $? = 1
configure:2751: error: in `/src':
configure:2753: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
Indeed, if you remove type: "module"
from package.json
, config.log
will be able to proceed past that test and a.wasm
, config.status
will be generated.
configure:2721: checking whether we are cross compiling
configure:2729: /emsdk/upstream/emscripten/emcc -o conftest conftest.c >&5
configure:2733: $? = 0
configure:2740: ./conftest
configure:2744: $? = 0
configure:2759: result: no
configure:2764: checking for suffix of object files
Hence, the failing command seems to be emcc -o conftest conftest.c >&5
. I have linked the pastebins for the output of the generated files conftest
and conftest.c
.
I believe the reason this occurs is that a feature was added in Node.js v21.0.0 to automatically run extensionless JavaScript as modules based on the nearest package.json
(see nodejs/node#49974). This was backported to Node.js v20.10.0 (nodejs/node#50682).
I haven't found any solutions for this other than generating a package.json
in the configure
directory with npm init --yes
or removing type: "module"
altogether. Setting --experimental-default-type=commonjs
doesn't seem to fix it.
EDIT:
Alternatively, emconfigure ./configure CFLAGS='-sEXPORT_ES6=1'
(or LDFLAGS
, LIBS
, CPPFLAGS
) will work as intended.