Skip to content

Static build on macOS fails beacuse the sources list for libnode.a is empty #65026

Description

@Xmader

Version

v26.4.0

Platform

arm64 macOS

Subsystem

Build system

What steps will reproduce the bug?

Build with ./configure --enable-static <...>

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

Build succeeds.

What do you see instead?

rm -f <node_root>/out/Release/libnode.a && /opt/local/bin/python3.12 gyp-mac-tool filter-libtool libtool  -static -o <node_root>/out/Release/libnode.a 

error: libtool: no files specified
Usage: libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]

Additional information

In https://github.com/nodejs/node/blob/v26.4.0/node.gyp#L1087-L1113, no C++ sources are provided for 'target_name': '<(node_lib_target_name)', so the arguments for libtool is empty (Should be bunch of .o files).

Compare the sources list for 'target_name': '<(node_lib_target_name)' in Node v25: https://github.com/nodejs/node/blob/v25.9.0/node.gyp#L888-L913

Activity

  1. Renegade334 commented on Aug 4, 2026

    @Renegade334
    Member

    Refs: #63626

  2. added
    buildIssues and PRs related to Node.js builds or CI infrastructure.
    on Aug 4, 2026
  3. added a commit that references this issue on Aug 5, 2026
  4. bitpshr commented on Aug 5, 2026

    @bitpshr
    Contributor

    It looks like the culprit is the node_base split in #63626. That moved node's C++ sources into an always-static node_base target, and libnode now only lists <@(library_files) and <@(deps_files) (the JS files) as its own sources. It gets node's objects from its node_base dependency, but only through the node_shared=="true" block in node.gyp (around line 1197), which force-loads libnode_base.a at link time. There is no equivalent for a static libnode, and as the comment near line 1220 notes, gyp only auto-applies whole-archive to static dependencies of shared_library targets, not static_library ones. So with --enable-static, libnode.a is archived from its JS-only sources and libtool gets no object files, which is the "no files specified" error.

    I think the fix needs the static case to fold node_base's archive into libnode.a rather than relying on the link-time force-load that only runs for shared builds.

  5. legendecas commented on Aug 7, 2026

    @legendecas
    Member

    There is a subsequent condition that adds a c++ source file for startup snapshot:

    node/node.gyp

    Lines 1124 to 1172 in 2022edf

    ['node_use_node_snapshot=="true"', {
    'dependencies': [
    'node_mksnapshot',
    ],
    'conditions': [
    ['node_snapshot_main!=""', {
    'actions': [
    {
    'action_name': 'node_mksnapshot',
    'process_outputs_as_sources': 1,
    'inputs': [
    '<(node_mksnapshot_exec)',
    '<(node_snapshot_main)',
    ],
    'outputs': [
    '<(SHARED_INTERMEDIATE_DIR)/node_snapshot.cc',
    ],
    'action': [
    '<(node_mksnapshot_exec)',
    '--build-snapshot',
    '<(node_snapshot_main)',
    '<@(_outputs)',
    ],
    },
    ],
    }, {
    'actions': [
    {
    'action_name': 'node_mksnapshot',
    'process_outputs_as_sources': 1,
    'inputs': [
    '<(node_mksnapshot_exec)',
    ],
    'outputs': [
    '<(SHARED_INTERMEDIATE_DIR)/node_snapshot.cc',
    ],
    'action': [
    '<@(_inputs)',
    '<@(_outputs)',
    ],
    },
    ],
    }],
    ],
    }, {
    'sources': [
    'src/node_snapshot_stub.cc'
    ],
    }],

    (src/node_snapshot_stub.cc when snapshot is not enabled, and <(SHARED_INTERMEDIATE_DIR)/node_snapshot.cc when snapshot is enabled)

    so the source list is not supposed to be empty.

    I built locally on a macOS with ./configure --enable-static and the build is successful.

  6. added
    macosIssues and PRs related to the macOS platform.
    on Aug 7, 2026
  7. legendecas commented on Aug 7, 2026

    @legendecas
    Member

    Would you mind sharing which macOS and toolchain version are you building with?

  8. Xmader commented on Aug 7, 2026

    @Xmader
    Author

    There is a subsequent condition that adds a c++ source file for startup snapshot

    I guess that's the reason. I forgot to mention I explicitly disabled the snapshot.

  9. legendecas commented on Aug 7, 2026

    @legendecas
    Member

    Disabling snapshot still adds src/node_snapshot_stub.cc to the source list, as the negative condition implies.

    I'm closing this as the issue is not reproducible on the authoritative source repo, but on a custom modified source. Please feel free to reopen if there is anything new.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    buildIssues and PRs related to Node.js builds or CI infrastructure.macosIssues and PRs related to the macOS platform.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions