Opened 5 years ago

Closed 5 years ago

Last modified 2 years ago

#58695 closed defect (fixed)

nodejs12 @12.6.0: ld: library not found for -latomic

Reported by: dubiousjim Owned by: ci42
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc: chrstphrchvz (Christopher Chavez), bborrel (Benoit Borrel)
Port: nodejs12

Description (last modified by ryandesign (Ryan Carsten Schmidt))

nodejs12 v.12.5.0 installs fine. Building nodejs12 v.12.6.0 fails with:

  /opt/local/bin/clang++-mp-5.0 -Wl,-force_load,/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libzlib.a -Wl,-force_load,/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libuv.a -Wl,-force_load,/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_snapshot.a -Wl,-force_load,/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libopenssl.a -Wl,-no_pie -Wl,-search_paths_first -arch x86_64 -L/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release -stdlib=libc++ -L/opt/local/lib -Wl,-headerpad_max_install_names -o "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/cctest" /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/src/node_snapshot_stub.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/src/node_code_cache_stub.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/gtest/gtest-all.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/gtest/gtest_main.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/node_test_fixture.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_aliased_buffer.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_base64.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_node_postmortem_metadata.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_environment.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_linked_binding.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_per_process.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_platform.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_traced_value.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_util.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_url.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_inspector_socket.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_inspector_socket_server.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/obj.target/cctest/test/cctest/test_report_util.o /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libnode.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libhistogram.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_snapshot.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_libplatform.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libicui18n.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libzlib.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libhttp_parser.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libllhttp.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libcares.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libuv.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libnghttp2.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libbrotli.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libopenssl.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libicuucx.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libicudata.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libicustubdata.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_base_without_compiler.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_libbase.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_libsampler.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_compiler.a /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/libv8_initializers.a -latomic -framework CoreFoundation -lm
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out/Release/cctest] Error 1
rm 7210a804946c403507c4d25a63d542f46d886245.intermediate f95aa0ace4aa996d9b93e4d7574ac6468a03c4fa.intermediate 52eb81006942bf6ec2ceae6ab052ed6ee4c52f45.intermediate f2ba2013d40cee41155f8d3f039339c8952b80c0.intermediate
make[1]: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0/out'
make: *** [node] Error 2
make: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0'
Command failed:  cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.6.0" && /usr/bin/make -w all CC=/opt/local/bin/clang-mp-5.0 CXX=/opt/local/bin/clang++-mp-5.0 CXX.host=/opt/local/bin/clang++-mp-5.0 CPP=/usr/bin/cpp CFLAGS="-Os" CXXFLAGS="-Os -stdlib=libc++" LDFLAGS="-L/opt/local/lib -Wl,-headerpad_max_install_names" PYTHON=/opt/local/bin/python2.7 V=1 
Exit code: 2
Error: Failed to build nodejs12: command execution failed
DEBUG: Error code: CHILDSTATUS 35801 2
DEBUG: Backtrace: command execution failed
DEBUG:     while executing
DEBUG: "system {*}$notty {*}$nice $fullcmdstring"
DEBUG:     invoked from within
DEBUG: "command_exec build"
DEBUG:     (procedure "portbuild::build_main" line 8)
DEBUG:     invoked from within
DEBUG: "$procedure $targetname"
Error: See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/main.log for details.

Attachments (2)

nodejs12.log (5.5 MB) - added by dubiousjim 5 years ago.
log
main.log (5.7 MB) - added by dubiousjim 5 years ago.
debug log from failed attempt to build v12.10.0 (failed at linking stage)

Change History (16)

comment:1 Changed 5 years ago by jmroot (Joshua Root)

Cc: ci42 removed
Owner: set to ci42
Status: newassigned

Please attach the log.

Changed 5 years ago by dubiousjim

Attachment: nodejs12.log added

log

comment:2 Changed 5 years ago by chrstphrchvz (Christopher Chavez)

The current portfile claims NodeJS doesn't link to any C++ libraries, but I wonder if that's no longer true, since starting in NodeJS 12.6.0 they've added linking to libatomic: https://github.com/nodejs/node/commit/4d12cef2a5 . (I don't have any specific ideas of how to fix this.)

comment:3 Changed 5 years ago by chrstphrchvz (Christopher Chavez)

Cc: chrstphrchvz added

comment:4 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Description: modified (diff)
Summary: nodejs12 can't buildnodejs12 @12.6.0: ld: library not found for -latomic

Changed 5 years ago by dubiousjim

Attachment: main.log added

debug log from failed attempt to build v12.10.0 (failed at linking stage)

comment:5 Changed 5 years ago by kencu (Ken)

See long discussion here <https://github.com/nodejs/node/pull/28232> and commit that broke it here <https://github.com/nodejs/node/commit/4d12cef2a5f9c834df588c9b5d7631dfa17606a2>.

I'm not 100% sure what the issue was they were trying to fix, but it appears this fix wasn't really it.

comment:6 Changed 5 years ago by dubiousjim

When I do find /lib /usr/lib /usr/local/lib /opt/local/lib -name 'libatomic*' I see that libatomic files are in /opt/local/lib/gcc*. They're provided by ports like gcc8, and so on.

I tried upgrading with options like configure.compiler=macports-gcc-8 or configure.cxx=/opt/local/bin/gcc-mp-8 but these fail with the message:

gcc-mp-8: error: unrecognized command line option '-stdlib=libc++'

So it looks like the makefiles are set up to use clang. I tried upgrading using just configure.ldflags-append="-L/opt/local/lib/gcc8" (but allowing the build to use clang), and that gets pretty far. But eventually it also fails with:

ld: library not found for -latomic

The log shows that the failing make command was:

Command failed: cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_devel_nodejs12/nodejs12/work/node-v12.11.0" && /usr/bin/make -w all CC=/opt/local/bin/clang-mp-8.0 CXX=/opt/local/bin/clang++-mp-8.0 CXX.host=/opt/local/bin/clang++-mp-8.0 CPP=/opt/local/bin/clang-cpp-mp-8.0 CFLAGS="-Os" CXXFLAGS="-Os -stdlib=libc++" LDFLAGS="-L/opt/local/lib -Wl,-headerpad_max_install_names" PYTHON=/opt/local/bin/python2.7 V=1

Somehow the -L/opt/local/lib/gcc8 did't make it into those LDFLAGS. If I then sudo -s and enter that failing command line manually, appending -L/opt/local/lib/gcc8 to the LDFLAGS, and the command can complete. But I don't know how then to resume the macports build/install/upgrade.

Does anyone have insight into how to coerce macports into coercing the node Makefiles to include that library folder?

comment:7 Changed 5 years ago by dubiousjim

Okay, I've made progress on this. As I understand it, node is supposed to build on Mac with either gcc or clang, but somewhere either in their build toolchain or Macports' (I'm guesing the latter) the -stdlib=libc++ gets added to the compiler options, and only clang understands that. So either that has to be changed or we have to continue building with clang.

I think clang expects users to use gcc's libatomics library; see http://releases.llvm.org/8.0.0/tools/clang/docs/Toolchain.html#atomics-library.

As I said in a previous comment, libatomic files are available on my machine, in /opt/local/lib/gcc*. I was able to successfully upgrade nodejs12 using this invocation:

sudo port upgrade nodejs12 configure.ldflags="-L/opt/local/lib/gcc8"

My grasp of Macports isn't solid enough to know why this should work, although it didn't work when I attempted to upgrade using configure.ldflags-append="-L/opt/local/lib/gcc8". Are the -append variables not recognized on the command line? Using that -append variable seemed to have some effect though; but perhaps that was an illusion.

Anyway, I managed to upgrade and perhaps this gives enough information for the port maintainers to determine how to revise the Portfile. And/or other users getting blocked by this can find the solution here.

comment:8 Changed 5 years ago by dubiousjim

Note that /opt/local/lib/gcc8/libatomic.dylib aliases /opt/local/lib/gcc8/libatomic.1.dylib, which in turn aliases the (gcc version-free) path /opt/local/lib/libgcc/libatomic.1.dylib. That's what really gets linked into the node binary. But I think using configure.ldflags="-L/opt/local/lib/libgcc" doesn't work, unless you also create an alias at /opt/local/lib/libgcc/libatomic.dylib.

comment:9 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Cc: bborrel added

This ticket's log shows this was on Yosemite.

Duplicate #59458 show the same problem on El Capitan.

comment:10 in reply to:  7 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Replying to dubiousjim:

As I understand it, node is supposed to build on Mac with either gcc or clang, but somewhere either in their build toolchain or Macports' (I'm guesing the latter) the -stdlib=libc++ gets added to the compiler options, and only clang understands that. So either that has to be changed or we have to continue building with clang.

MacPorts adds the -stdlib=... flag to all builds when clang++ is selected as the compiler.

Please do not attempt to build C++ software on macOS using anything other than clang++. Do not attempt to use g++. You will encounter no end of problems due to mismatched C++ standard libraries.

As I said in a previous comment, libatomic files are available on my machine, in /opt/local/lib/gcc*. I was able to successfully upgrade nodejs12 using this invocation:

sudo port upgrade nodejs12 configure.ldflags="-L/opt/local/lib/gcc8"

My grasp of Macports isn't solid enough to know why this should work, although it didn't work when I attempted to upgrade using configure.ldflags-append="-L/opt/local/lib/gcc8". Are the -append variables not recognized on the command line? Using that -append variable seemed to have some effect though; but perhaps that was an illusion.

configure.ldflags is a variable (well, an "option" in MacPorts base parlance). You can override options on the command line to aid in debugging. configure.ldflags-append is a procedure. You cannot invoke procedures on the command line.

It looks like upstream has fixed this in nodejs13. We could backport that to earlier versions.

comment:11 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Looks like upstream fixed nodejs12 too. Looks like nodejs12 built successfully in MacPorts on OS X 10.11 and up (using Xcode clang), but not on 10.10 and lower (using MacPorts clang 9).

The code they're using now says:

      ['(OS=="linux" or OS=="mac") and llvm_version!=0', {
         'libraries': ['-latomic'],
       }],

I don't understand this. The idea is we want to use the atomic library when not using llvm when using llvm on Linux. So shouldn't the condition be (OS=="linux" or OS=="mac") and llvm_version==0 OS=="linux" and llvm_version==0?

I also think llvm_version is being set wrong. It's set like this:

def get_llvm_version(cc):
  return get_version_helper(
    cc, r"(^(?:FreeBSD )?clang version|based on LLVM) ([3-9]\.[0-9]+)")

This will only work correctly with open source clang and with Apple clang from Xcode 6 and earlier. As of Xcode 7, the Apple clang version no longer claims to be "based on" an open source clang version since they have diverged too much.

I'll file upstream bug reports...

Last edited 5 years ago by ryandesign (Ryan Carsten Schmidt) (previous) (diff)

comment:12 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

comment:13 Changed 5 years ago by ryandesign (Ryan Carsten Schmidt)

Resolution: fixed
Status: assignedclosed

In b1505aa16a54615dba9dd67535fb90d15fb1b2f7/macports-ports (master):

nodejs12: Don't use -latomic on macOS

Fixes build with MacPorts clang. Due to another bug, builds with Xcode clang
were misidentified as "not clang" and therefore already didn't add the -latomic
flag, allowing the build to succeed.

Closes: #58695

comment:14 in reply to:  6 Changed 2 years ago by barracuda156

Replying to dubiousjim:

When I do find /lib /usr/lib /usr/local/lib /opt/local/lib -name 'libatomic*' I see that libatomic files are in /opt/local/lib/gcc*. They're provided by ports like gcc8, and so on.

I tried upgrading with options like configure.compiler=macports-gcc-8 or configure.cxx=/opt/local/bin/gcc-mp-8 but these fail with the message:

gcc-mp-8: error: unrecognized command line option '-stdlib=libc++'

So it looks like the makefiles are set up to use clang.

It is in common.gypi. I did this to initiate building for PPC (where Clang is broken):

diff --git a/common.gypi b/common.gypi
index 2bfae462d0..4917ffe04c 100644
--- a/common.gypi
+++ b/common.gypi
@@ -132,7 +132,7 @@
       }, {
         'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
       }],
-      ['OS=="mac"', {
+      ['OS=="mac" and target_arch!="ppc" and target_arch!="ppc64"', {
         'clang%': 1,
       }],
       ['target_arch in "ppc64 s390x"', {
Note: See TracTickets for help on using tickets.