Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Support clang C++ library #733

Closed
saper opened this issue Mar 4, 2015 · 14 comments
Closed

Support clang C++ library #733

saper opened this issue Mar 4, 2015 · 14 comments
Milestone

Comments

@saper
Copy link
Member

saper commented Mar 4, 2015

Some systems provide clang C++ runtime library, not libstdc++ (FreeBSD switched in version 10).
Since clang is also slowly coming to Linux systems, too, I would propose to lib/extensions.js and build.js to recognize different versions of C++ runtimes.

Here's my freshly built ( sass/node-sass-binaries#46 ) binding library:

$ ldd vendor/freebsd-x64-node-0.12/binding.node 
vendor/freebsd-x64-node-0.12/binding.node:
        libc++.so.1 => /usr/lib/libc++.so.1 (0x80179e000)
        libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x801a5e000)
        libm.so.5 => /lib/libm.so.5 (0x801c7a000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x801ea0000)
        libthr.so.3 => /lib/libthr.so.3 (0x8020ae000)
        libc.so.7 => /lib/libc.so.7 (0x80081f000)
@am11
Copy link
Contributor

am11 commented Mar 4, 2015

Some systems provide clang C++ runtime library, not libstdc++ (FreeBSD switched in version 10).

I presume on those system GCC also consumes the system level libc++, instead of linking against something else? @mgreter, please do correct me if I am wrong, otherwise it will be a fiasco! 🔥 🚒

I think this is a bad idea to scope the binary based on C++ runtime as it will bring a lot of challenges to maintain the binaries. The first challenge is that it will permute the number of binaries to manage. The second challenge is to build those binaries for every release (persistently). Again, please skim through it #712 till the bottom. Unless we have some kind of relaxed strategy, which let user change the URL format, change the binary lookup path, allow us to defer the binary upload even after the build has released, we are being very skeptical about such expansions. :)

Also we seek widespread coverage with sleekest possible way that is: DRY: . :)

@mgreter, @xzyfer, @QuLogic, any thoughts here?

@am11 am11 added the npm build label Mar 4, 2015
@saper
Copy link
Member Author

saper commented Mar 4, 2015

I presume on those system GCC also consumes the system level libc++, instead of linking against something else?

On a clang-by-default system we usually don't have gcc at all. Therefore the user installing node-sass via npm will expect that binary dropped on her system will support LLVM libc++.
Of course we might compile node-sass binding and libsass using gcc46, as it can be additonally installed, but the resulting binary will be good only for those who have this version of gcc installed
(FreeBSD ports offer currently gcc 4.6, 4.7, 4.8, 4.9 and 5.0 snapshot 20150222).

This is binding.node compiled with additionally installed gcc46 on FreeBSD 10:

/home/saper/sw/test4/node-sass/vendor/freebsd-x64-node-0.12/binding.node:
    libstdc++.so.6 => /usr/local/lib/gcc46/libstdc++.so.6 (0x801777000)
    libm.so.5 => /lib/libm.so.5 (0x801a7a000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x801ca0000)
    libthr.so.3 => /lib/libthr.so.3 (0x801eae000)
    libc.so.7 => /lib/libc.so.7 (0x80081f000)

/usr/local/lib/gcc46/libstdc++.so.6 got installed by the GCC port (package) and is not guaranteed
to exist in the base system.

An automated build when using built-in compiler takes only over 10 minutes on my slow machine (this is a clean-state build in a virtualized container, a.k.a. FreeBSD jail). I wonder if I should add a major version number to the build to safeguard against future base library changes ( similar to #517 ), but I am not ready with a fully automated node-sass build yet.

@am11
Copy link
Contributor

am11 commented Mar 4, 2015

My initial thoughts were; for the first release, we might need to statically compile libstdc++ (gcc) for FreeBSD, preferably the older version.

The reason being, our gyp config is setup with gcc only. (I don't know why did I say that? probably confused .travis.yml with binding.gyp 😄)

On Linux, we had to compile using gcc4.4.7 on CentOS 5.11 since old CentOS runs on many hosting servers which node-sass main audience use. That was also to support lowest possible versions of all distributions.

But going by the information you have provided (thanks for that), it seems like FreeBSD changed the dependency to libc++ in v10. Which means the binaries which were linked against libstdc++ in versions of FreeBSD prior to v10 would need to be recompiled either with LLVM libc++ or statically linked with libstdc++, right? Any ideas how else others might have managed the forward-compatibility of their binary when FreeBSD moved from vPrevious to v10 or was recompiling the only option for them as well?

@saper
Copy link
Member Author

saper commented Mar 4, 2015

For completeness, this is ldd for the gcc 4.6 based system (FreeBSD 8):

vendor/freebsd-x64-node-0.10/binding.node:
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x800f75000)
    libm.so.5 => /lib/libm.so.5 (0x800880000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x80117e000)
    libthr.so.3 => /lib/libthr.so.3 (0x80128b000)
    libc.so.7 => /lib/libc.so.7 (0x800646000)

Here /usr/lib/libstdc++.so.6 is coming from the base system (based on gcc 4.2 actually). This library is not present on newer systems, you have to use /usr/lib/libc++.so.1 for that. That's why we have a problem.

@am11
Copy link
Contributor

am11 commented Mar 4, 2015

In this case, I think dropping the OOTB binaries support for FreeBSD versions, prior to v10 (when the shift from libstdc++ -> libc++ transpired) would make sense. The users using lower FBSD versions would be able to manually build node-sass. This is the easiest course of action for us to release node-sass versions with little less pain..

@mgreter
Copy link
Contributor

mgreter commented Mar 4, 2015

Well the only advice I can give here is that this is exactly the reason why most software products (including libsass) do not provide binary releases and leave it for package maintainers of each distribution, since nobody can really create binaries that will universally work in all possible situation.

OK, so FreeBSD opted to replace its standard system library from libstdc++ with libc++. So node-sass can now either add additional binaries linked against libc++ or leave it to the users to install lang/gcc from ports. Btw. there exist even more stdlib implementations in the wild!

As another side note: Gentoo linux has extra packages (sys-libs/libstdc++-v3) for old stdlibs that only install the libraries. Technically you would not need to install a full blown gcc to get it running! I tried to search for FreeBSD 10 in that direction, but pretty much all recommend to install lang/gcc from ports.

@am11
Copy link
Contributor

am11 commented Mar 11, 2015

The pre-release v3.0.0-pre is out. See the breaking changes in README.

npm install node-sass@3.0.0-pre

To see the runtime coverage matrix, see node-sass-binaries readme: https://github.com/sass/node-sass-binaries/#node-sass-binaries.

@saper, would you like to send a PR for FreeBSD for the entire matrix?

@saper
Copy link
Member Author

saper commented Mar 13, 2015

Submitted #756 as a tracking bug. I am pretty close to be done :) How do you think shall we make binaries for 3.0.0? You can tag branch first and then I generate binaries and submit them to http://github.com/sass/node-sass-binaries ?

@xzyfer
Copy link
Contributor

xzyfer commented May 5, 2015

@saper having a little trouble following this issue. What, if any, action items are remaining?

@saper
Copy link
Member Author

saper commented May 5, 2015

Our current FreeBSD binaries are for clang libc++, so only FreeBSD 10+ is supported.

We would need something either something like

vendor/freebsd8-x64-14/binding.node
vendor/freebsd9-x64-14/binding.node
vendor/freebsd10-x64-14/binding.node

in our binary matrix or (maybe more generic, also for some other OS'es using clang and/or gcc):

vendor/freebsd-gcc48-x64-14/binding.node
vendor/freebsd-clang-x64-14/binding.node

At the moment I am building binaries for FreeBSD 8.4 and 9.3 (both gcc-based) and 10.1 (clang-based).
Only the latter got published on our site because of this limitation. But I haven't got any requests
for older versions yet.

For troubleshooting: gcc-based FreeBSD versions will probably end up with #918 because the wrong binary will be downloaded.

@xzyfer
Copy link
Contributor

xzyfer commented Mar 26, 2016

@saper this seems fairly specific to FreeBSD. It's up to you if this is a maintenance burden you want to take on. At last check FreeBSD is our least used OS and there have so far been no requests for this.

Also worth noting that I build the OS X binaries with clang since OS X does not ship with gcc.

@saper
Copy link
Member Author

saper commented Mar 26, 2016

@xzyfer this is less about the compiler, it is more about the runtime C++ library ABI. From the issues we have had in the tracker I assume that Apple is still shipping a pretty ancient libstdc++ version. Once Apple starts shipping LLVM libc++ (or do they already?) we will have the same problem with OS X.
For now I assume node is using libstdc++ on OS X, but once they switch we will have a problem.

Similarly one cannot reliably link Windows bindings compiled with v140 (VS2015) platform against v120 node engine (VS2013). Once node switches to VS2015 we will need to differentiate that.

That's why I think we might need an C++ ABI identifier in the binary naming scheme sooner or later. With FreeBSD it will be less of a problem as more and more people switch to versions 10.x an 11.x or use clang on 9.x already.

@saper
Copy link
Member Author

saper commented Sep 10, 2017

Ok, this is a more generic subject. Linux systems have similar issue with ABIs - glibc vs musl, for example. As FreeBSD switched to clang currently this is not a pressing issue to solve right now, but a more generic ABI compatibility solution is needed. Unfortunately, NAPI is going to solve only a V8 side of things.

@saper saper closed this as completed Sep 10, 2017
@springmeyer
Copy link

springmeyer commented Nov 21, 2017

From the issues we have had in the tracker I assume that Apple is still shipping a pretty ancient libstdc++ version. Once Apple starts shipping LLVM libc++ (or do they already?) we will have the same problem with OS X.
For now I assume node is using libstdc++ on OS X, but once they switch we will have a problem.

Apple ships with both libstdc++ and libc++. They (apple) put in work (magic) to make it okay to use binaries that link both of these libraries. So, while this would result in major problems on linux, it is okay on OS X. So, most of the binaries for node C++ addons I ship link libc++ on OS X (like this https://github.com/mapbox/node-cpp-skel/blob/dbc48924b3e30bba903e6b9220b0cdf2854f717f/binding.gyp#L98, in order to get C++11 support) and work fine with a nodejs binary that links libstdc++.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants