nodejs / TSC

The Node.js Technical Steering Committee
569 stars 127 forks source link

Strategic initiative: future of Node.js build toolchain #901

Closed mmarchini closed 2 years ago

mmarchini commented 3 years ago

This was brought up several times, most recently on the Build IRC channel. Our current build toolchain is based on GYP, which is not the default toolchain for V8 anymore and was discontinued by Google. As a result, we have to maintain our own GYP fork, and keeping dependencies (especially V8) up to date requires considerable manual labor. Furthermore, the build experience for Windows and Unix is extremely different, with different config files for those platforms (which makes it hard to keep them in sync feature wise).

Switching to a modern, widely used build toolchain like CMake has been brought up a few times. There were also suggestions to move to GN, which comes with a completely different set of tradeoffs. In the recent discussion on the Build chat I suggested we should investigate an hybrid mode where V8 is built with GN and the rest of the project is built with CMake* (this also would come with a completely different set of tradeoffs). And this is only talking about building Node.js itself, we also need to evaluate how each toolchain will impact native modules, and we'll need to provide gyp + something else for some time on the native modules side.

I suggest we create a strategic initiative to start planning, exploring options and working on the future of our build toolchain. This could potentially become a working group in the future depending on the amount of work we have ahead as well as the number of collaborators interested in helping. I'm willing to champion this initiative.

* I would really like to explore this one because if it works, we can provide pre-built V8 binaries which can be downloaded by collaborators, reducing significantly the build time of the project

mmarchini commented 3 years ago

cc @nodejs/build-files @nodejs/gyp @nodejs/tsc

ryzokuken commented 3 years ago

Thanks for taking this up, @mmarchini. I suppose a good first step would be to list down the pros and cons of each approach so that everyone would have a good idea of what exactly are the tradeoffs involved. This has always been a tough pill for me to swallow personally because of the fact that:

1) Building V8 with CMake doesn't really fix the problem of "considerable manual labor", we'd just end up having to maintain CMakeLists for V8 instead of gypfiles. It might be easier due to various reasons, but it would not go away completely IIUC, unless we switch to GN.

2) Building with GN comes with its own set of problems, since IIUC, GN supports a much smaller set of platforms than Node. I don't know for sure what the Chromium team feels about it, but adding support for the missing platforms in GN would be a significant undertaking in itself which would come with attached maintenance costs.

I had never considered your suggestion of using GN to build V8 and CMake to build everything else, but it might just work. That said, I am afraid it would still require us to add support for platforms like SmartOS to GN.

mmarchini commented 3 years ago

I'll need to dig deeper on the whole "GN unsupported platforms" story. My understanding is that, as long as we can target some of those platforms, we should be fine, right? Especially platforms which are more common on servers.

Totally agree with you that changing from gyp to cmake doesn't solve the issues with upgrading V8, which is why I would like to think of it as a last resort. I think there's a lot of investigation and experimentation to do before making any decisions on the path forward.

ryzokuken commented 3 years ago

I'll need to dig deeper on the whole "GN unsupported platforms" story. My understanding is that, as long as we can target some of those platforms, we should be fine, right? Especially platforms which are more common on servers.

I mean, if GN doesn't support a platform that we currently do, either we would have to consider dropping support or continue maintaining gypfiles, right?

I think there's a lot of investigation and experimentation to do before making any decisions on the path forward.

Absolutely agreed. Let's figure this one out, shall we? :smile:

mmarchini commented 3 years ago

I mean, if GN doesn't support a platform that we currently do, either we would have to consider dropping support or continue maintaining gypfiles, right?

I mean, that's probably the case, but I'm not 100% sure :woman_shrugging:. From what I can tell GN just generates Ninja files, so as long as we can use it to generate Ninja files to build on SmartOS and friends we should be fine.

mmarchini commented 3 years ago

I wonder if we could, as a starting point, use CMake as a frontend for gyp, replacing configure and vcbuild (assuming we can use CMake to generate build files on Windows).

devsnek commented 3 years ago

+1 for cmake, we could vendor stuff so much more easily.

mmarchini commented 3 years ago

+1 for cmake, we could vendor stuff so much more easily.

Except for V8 :sweat_smile:

victorgomes commented 3 years ago

Regarding "GN unsupported platforms": GN is an extensible build system, even if there are platforms that currently unsupported, one can also add new scripts and config files to include a new toolchain. https://gn.googlesource.com/gn/+/master/docs/reference.md#func_toolchain

richardlau commented 3 years ago

Re. gn, it’s not just whether gn supports all of our supported platforms but by implication whether ninja support for those platforms is available.

mhdawson commented 3 years ago

Feedback from Google in the past is that they were not looking to support GN for use outside of V8/Chrome. They had other suggestions instead. I'm hesitant to bet on GN (except possibly just for V8 itself) without Google recommending/supporting it as a good choice and be willing to help if we run into issue.

mmarchini commented 3 years ago

@mhdawson yes, that's definitely going to weight in our decision. The ideal build toolchain for us is still IMO GN for V8 and insert-new-tool-but-probably-cmake for everything else. Biggest challenge is to keep defines and compiler flags in sync between the V8 build and everything else, I have some ideas and am working on a proof-of-concept for GN+GYP hybrid build with synced defines and without depot_tools. This hybrid approach might turn out to be unfeasible or too hacky, but it's hard to know without trying.

I'm also in contact with Google to come up with a solution that is good for both projects (since they also have CI bots for Node.js with updated V8), and I want to include embedders in the conversation to make sure whichever path we choose also work for them.

gocarlos commented 3 years ago

regarding v8 and cmake: I think that the people at vcpkg and conan could join forces with nodejs to maintain the cmake script...

mmarchini commented 3 years ago

Thanks @gocarlos, if we move in the direction of porting V8 to cmake we'll loop those projects in, although I'm still hopeful that we can avoid that (since porting V8 to any other build system will result in burden to maintain that port, which is quite hard considering V8's development speed).

You might be interested in https://github.com/bnoordhuis/v8-cmake, which I think already works.

devsnek commented 3 years ago

I would like to vendor getdns, which is practically impossible because we don't support cmake. Additionally, most of our deps already have cmake configs. I think it would be unfortunate if we moved to some new system and still didn't support cmake.

mmarchini commented 3 years ago

Sorry, should've been more clear: I think cmake is the way to go for everything except V8, and I'm still hopeful we can have a hybrid system that will work better for 90-99% of use cases than today.

anlexN commented 3 years ago

whether can use gradle like android?

mmarchini commented 3 years ago

whether can use gradle like android?

I think it's unlikely we would use gradle. Gradle is more popular on Java ecosystem, and it doesn't give an advantage over CMake in terms of reducing duplicate configuration for dependencies.

ryzokuken commented 3 years ago

I think if people can use the "but it's Java" argument against Bazel, then Gradle would be an even worse option.

codebytere commented 3 years ago

Speaking for Electron - we build Node.js, V8, & all other deps with GN (see this patch for our config) and will continue to do so likely regardless of what choice is ultimately made here. We recognize that GN isn't blessed outside a Google context, and as such would not try to push Node.js itself in that direction insofar as our ability to build with GN is preserved by the outcome of this issue (i can't see why it wouldn't be).

+1 for building V8 with GN though, & i would say that we've had a good experience asking Google folks for help when we run into issues and receiving feedback/assistance.

mmarchini commented 3 years ago

@codebytere that's great info thanks! I think GN is not completely out of the table yet (I've been fiddling with it more lately), but the bad experience we had with gyp does make it harder for us to have confidence to migrate to GN.

Does Electron have a plan in place in case Google drops support to GN and move the Chromium toolchain to something else?

ryzokuken commented 3 years ago

I don't think Electron has much of a choice here. It's significantly more difficult to maintain build files for the entirety of Chromium than just V8, so I think ideally Electron would always want to stick to the same build toolchain.

anlexN commented 3 years ago

we need all in one toolchain very much.

codebytere commented 3 years ago

@mmarchini yep - we'd love GN since it's what Chromium uses at present but ultimately we're fairly beholden to whatever toolchain Chromium uses even if they change it - should that happen we'd adapt other dependencies accordingly.

mhdawson commented 3 years ago

Since this is now in the list of strategic initiatives( https://github.com/nodejs/TSC/blob/master/Strategic-Initiatives.md) I think this issue could be close ?

mmarchini commented 3 years ago

IMO it makes sense to keep it open as a tracking issue (we do that for other strategic initiatives as well). I changed the title for clarity.

mhdawson commented 3 years ago

@mmarchini thanks, makes sense as tracking issue

targos commented 3 years ago

I just learned that the V8 team maintains a repo to build Node.js with GN (for their CI integration): https://chromium.googlesource.com/v8/node-ci/

bnb commented 2 years ago

Following up on this since we still use node-gyp which includes a slur and the discussion around addressing that points to this issue. Would love to see progress, especially since there was an expressed interest from multiple TSC members.

mmarchini commented 2 years ago

I haven't had much bandwidth to invest in the project lately, so it got kinda stalled (unless someone else is working on it). I might start contributing more again and would like to focus on this issue (but no promises)

bnb commented 2 years ago

are there any other @nodejs/tsc members who have the technical expertise and time to invest? Would really love to see us take a step to be more inclusive here if it's at all possible ❤️

mhdawson commented 2 years ago

@bnb I can't tell from your comment "would really love to see us take a step to be more inclusive here if it's at all possible" If you want to volunteer but don't feel you can?

mhdawson commented 2 years ago

And to clarify I mean volunteer to lead/push the effort forward?

Trott commented 2 years ago

We got rid of the requirement that strategic initiatives need to be championed by a specific TSC member, so anyone can volunteer to champion this if Mary is unable to at this time.

bnb commented 2 years ago

If you want to volunteer but don't feel you can?

That is what I'm communicating, though it's purely technical: I don't think I'm experienced enough with the kind of tooling that we're talking about (gn, cmake, etc.) to even begin to meaningfully approach this problem. I don't want to waste my time and everyone else's time 😅

mhdawson commented 2 years ago

@bnb as @Trott mentioned we can have a non TSC champion so I don't think the "inclusive" part is the problem, more that we need to find a volunteer with the time/drive to make it happen. If you have suggestions or can help on that front we'd welcome getting connected.

cjihrig commented 2 years ago

I had assumed the "inclusive" part was related to the unfortunate naming of gyp.

mmarchini commented 2 years ago

@cjihrig it is. Unfortunately no one has come up with a proposal to get rid of the naming that is not extremely disruptive to the entire ecosystem. And if disruption is inevitable we'd rather move on with changing the toolchain since that'll also be disruptive (and that way we are disruptive only once).

targos commented 2 years ago

Maybe Bazel should be considered again, as V8 now maintains a build file for it.

https://bazel.build/ https://github.com/v8/v8/blob/master/BUILD.bazel https://bugs.chromium.org/p/v8/issues/detail?id=11234

mmarchini commented 2 years ago

Interesting. The fact that Envoy uses Bazel makes me feel less concerned about using it. Although tbh I still think that decoupling V8 build toolchain from the rest is the best way to reduce chances of future breakage. But if anyone wants to give Node.js + V8 Bazel build a try I wouldn't mind it.

bnb commented 2 years ago

more that we need to find a volunteer with the time/drive to make it happen.

to clarify, if I can get someone to do this work, would the TSC accept it? 👀

bnb commented 2 years ago

Some context I've gotten from friends who are familiar with building Node.js outside of our typical build system:

Google has a design doc for building Node.js with Bazel that also raises GN. Of particular note with Bazel:

V8 will continue to maintain Bazel configs as long as V8 is used by Google internally.

This doc is from 2018, so might be out of date. Perhaps @hashseed could possibly update the doc where applicable to help us understand?

Outside of this document, it looks like Google is now maintaining a Node.js build with GN which is derived from Electron's GN patch.

It seems likely that using this tooling would be beneficial to those consumers (I recall folks from both being advocates of GN, though I may be misremembering).

Given that there's already a substantial amount of work being done to support GN builds, it might be worth seeing if someone who is doing that work would be willing to help us move to it, thus reducing their workload (and giving us the benefits outlined in the Google doc!)? I am happy to do this outreach if so.

mcollina commented 2 years ago

If I recall correctly, the reason why Bazel was discarded is that it does not support the wide range of architectures and Operating Systems we support for Node.js. We would have to build it from source for some of them and pray it all works ok.

targos commented 2 years ago

@mcollina That's the reason why GN was discarded. Bazel is written in Java, so I think we should be fine regarding supported architectures and operating systems.

ryzokuken commented 2 years ago

The reasons for which we were unenthusiastic about both GN as well as Bazel still hold for the most part, but CMake could work well with the right amount of time/effort. Any reasons for discarding CMake?

targos commented 2 years ago

Any reasons for discarding CMake?

Not saying this is a good reason, but I would certainly stop maintaining V8 in Node.js if I had to start porting GN config changes to CMake. In other words: I'm strongly -1 on CMake unless its config is maintained by someone inside the V8 repository.

ryzokuken commented 2 years ago

It's definitely a good reason, I think it's unlikely that V8 would maintain a CMake config :/

bnb commented 2 years ago

That's the reason why GN was discarded.

Does Node.js's support matrix greatly differ from that of V8? I can't imagine it's wildly different?

Trott commented 2 years ago

Does Node.js's support matrix greatly differ from that of V8? I can't imagine it's wildly different?

BUILDING.md says our supported platforms are a subset of V8's but I think that's wrong.

I'm under the impression that it is different in ways that require significant effort. For example, we support IBM's AIX operating system, M1 chips, etc.[^1]

And there's Joyent's SmartOS too.

And FreeBSD.

And Raspberry Pi.

And probably other things I'm forgetting.

I'd also guess that V8 is more aggressive about dropping support for older versions of Windows than we can reasonably be.

[^1]: Hat tip to all the amazing IBM/Red Hat folks who do work on a lot of hard things in Node.js such as releases, builds, OpenSSL support, etc.: Michael Dawson, Beth Griggs, Richard Lau, Gireesh Punathil, Ash Cripps, Dan Bevenius, and others I'm forgetting right now and I apologize!

ryzokuken commented 2 years ago

SmartOS, for example, is definitely a platform that we support and V8 doesn't. Currently people on SmartOS build V8 using a hacky script that I wrote which uses the Node.js build files for V8 and gyp.