New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OS X 10.9: node-gyp links to libstdc++ instead of libc++ #469

Open
andrewaustin opened this Issue Jun 30, 2014 · 1 comment

Comments

Projects
None yet
3 participants
@andrewaustin

andrewaustin commented Jun 30, 2014

In OS X 10.9, Apple switched from gcc to clang which results in a change in the name of the standard library name from libstdc++ (gcc) to libc++ (clang).

However, it seems all modules compiled with node-gyp are linked against libstdc++ on OS X 10.9 . (For example, https://github.com/tbonelaforge/jinac/blob/master/binding.gyp ) Because dynamic libraries that node modules may link against are compiled on 10.9 with clang, there are issues resolving symbols in the standard library.

node-gyp -v
v0.13.1

I realize I can manually set the stdlib to be what it should be with "OTHER_CFLAGS": ["-stdlib=libc++"] but this will cause issues on OS X < 10.9.

@springmeyer

This comment has been minimized.

Show comment
Hide comment
@springmeyer

springmeyer Aug 11, 2014

Contributor

In OS X 10.9, Apple switched from gcc to clang which results in a change in the name of the standard library name from libstdc++ (gcc) to libc++ (clang).

Apple switched to clang well before. But, yes what switched in 10.9 is that the bundled clang++ version started defaulting to linking to libc++ rather than libstdc++.

However, it seems all modules compiled with node-gyp are linked against libstdc++ on OS X 10.9

Correct. This behavior results from this MACOSX_DEPLOYMENT_TARGET setting inside Node's common.gypi: https://github.com/joyent/node/blob/912b5e05811fd24f09f9d65200a1561a4482f166/common.gypi#L216

Because dynamic libraries that node modules may link against are compiled on 10.9 with clang, there are issues resolving symbols in the standard library.

Would be useful to see the exact errors you are seeing. Generally having Node C++ addons linked to libstdc++ works fine on 10.9 (and of course previous OS X versions). What breaks is when an addon also depends on an external c++ library and that library is linked against libc++ - that condition will lead to odd linking errors when common C++ symbols like std::string cannot be resolved. Or odder things might result like the runtime symbol errors as seen at mapbox/mapbox-studio-classic#73

I realize I can manually set the stdlib to be what it should be with "OTHER_CFLAGS": ["-stdlib=libc++"] but this will cause issues on OS X < 10.9.

Right, don't do that. Instead the best fix in my opinion is to override MACOSX_DEPLOYMENT_TARGET and do it only for users that are building on 10.9. Basically what you want is for 10.9 users to end up with node c++ addons linked to libc++ and users on older systems to continue to link against libstdc++. My approach to this can be seen at:

https://github.com/mapnik/node-mapnik/blob/e0041df852720f389ed6a4bd2e761f989d6368c1/common.gypi#L2-L14

Note: Users running node binaries or those who source compile and do not also override this option will end up with node binaries linked against libstdc++. Theoretically having node linked against libstdc++ and an addon linked against libc++ is not a very good idea and could lead to crashes or undefined behavior. In practice however I've not yet seen any problems. That said, if you are targeting >= 10.9 then recommending your users compile their own node that links against libc++ is a good idea. You can do this like:

export CXXFLAGS="-mmacosx-version-min=10.9"
export LDFLAGS="-mmacosx-version-min=10.9"
cd node
./configure && make && make install
Contributor

springmeyer commented Aug 11, 2014

In OS X 10.9, Apple switched from gcc to clang which results in a change in the name of the standard library name from libstdc++ (gcc) to libc++ (clang).

Apple switched to clang well before. But, yes what switched in 10.9 is that the bundled clang++ version started defaulting to linking to libc++ rather than libstdc++.

However, it seems all modules compiled with node-gyp are linked against libstdc++ on OS X 10.9

Correct. This behavior results from this MACOSX_DEPLOYMENT_TARGET setting inside Node's common.gypi: https://github.com/joyent/node/blob/912b5e05811fd24f09f9d65200a1561a4482f166/common.gypi#L216

Because dynamic libraries that node modules may link against are compiled on 10.9 with clang, there are issues resolving symbols in the standard library.

Would be useful to see the exact errors you are seeing. Generally having Node C++ addons linked to libstdc++ works fine on 10.9 (and of course previous OS X versions). What breaks is when an addon also depends on an external c++ library and that library is linked against libc++ - that condition will lead to odd linking errors when common C++ symbols like std::string cannot be resolved. Or odder things might result like the runtime symbol errors as seen at mapbox/mapbox-studio-classic#73

I realize I can manually set the stdlib to be what it should be with "OTHER_CFLAGS": ["-stdlib=libc++"] but this will cause issues on OS X < 10.9.

Right, don't do that. Instead the best fix in my opinion is to override MACOSX_DEPLOYMENT_TARGET and do it only for users that are building on 10.9. Basically what you want is for 10.9 users to end up with node c++ addons linked to libc++ and users on older systems to continue to link against libstdc++. My approach to this can be seen at:

https://github.com/mapnik/node-mapnik/blob/e0041df852720f389ed6a4bd2e761f989d6368c1/common.gypi#L2-L14

Note: Users running node binaries or those who source compile and do not also override this option will end up with node binaries linked against libstdc++. Theoretically having node linked against libstdc++ and an addon linked against libc++ is not a very good idea and could lead to crashes or undefined behavior. In practice however I've not yet seen any problems. That said, if you are targeting >= 10.9 then recommending your users compile their own node that links against libc++ is a good idea. You can do this like:

export CXXFLAGS="-mmacosx-version-min=10.9"
export LDFLAGS="-mmacosx-version-min=10.9"
cd node
./configure && make && make install

@Fishrock123 Fishrock123 added the MacOS label Aug 22, 2015

joshperry added a commit to prodatakey/node-usb that referenced this issue Oct 18, 2015

Fix gyp to work with old node and new OSX
Also add fix for when on 10.9 OSX switched to link against libc++ instead of libstdc++
This can cause issues when the module is linked against a different lib than other locally compiled code.

See: nodejs/node-gyp#469 (comment)

@renz45 renz45 referenced this issue Nov 17, 2015

Closed

Osx compat #45

RubenVerborgh added a commit to RubenVerborgh/HDT-Node that referenced this issue Sep 23, 2017

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