Skip to content

Node.js errors when running emconfigure ./configure when there exists a package.json with type: "module" #24244

@jeremy-code

Description

@jeremy-code

Version

emscripten/emsdk@4.0.8-arm64

$ 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;
// package.json
{ "type": "module" }

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions