Skip to content
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

feat: Apple Silicon support #312

Merged
merged 4 commits into from
Nov 6, 2021
Merged

Conversation

johnwchadwick
Copy link
Contributor

@johnwchadwick johnwchadwick commented Oct 6, 2021

The goal of this PR is to get node-libcurl building properly for Apple silicon. Universal builds seem like they would be ideal, so that is my current goal. Unfortunately, this adds a decent amount of complexity to the build scripts and will necessarily increase build times :( In addition, some workaround may be needed for node-pre-gyp to be able to fetch the universal binaries.

We're working on this in the process of trying to resolve Kong/insomnia#2964.

@codecov
Copy link

codecov bot commented Oct 7, 2021

Codecov Report

Merging #312 (1ab4bc8) into develop (965733d) will increase coverage by 0.16%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #312      +/-   ##
===========================================
+ Coverage    93.17%   93.33%   +0.16%     
===========================================
  Files           43       43              
  Lines          908      930      +22     
  Branches        95       97       +2     
===========================================
+ Hits           846      868      +22     
  Misses          41       41              
  Partials        21       21              
Impacted Files Coverage Δ
lib/generated/CurlOption.ts 100.00% <ø> (ø)
lib/Curl.ts 81.49% <100.00%> (+0.62%) ⬆️
lib/enum/CurlAuth.ts 100.00% <100.00%> (ø)
lib/enum/CurlCode.ts 100.00% <100.00%> (ø)
lib/enum/CurlProtocol.ts 100.00% <100.00%> (ø)
lib/enum/CurlPush.ts 100.00% <100.00%> (ø)
lib/enum/CurlSslOpt.ts 100.00% <100.00%> (ø)
lib/enum/CurlVersion.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 938c12f...1ab4bc8. Read the comment docs.

@johnwchadwick
Copy link
Contributor Author

There are probably more ways in which this PR could be cleaned up and/or improved. However, I think it would be a good idea to solicit review at this point before putting too much more work into it, to see if this is going in a reasonable direction.

@johnwchadwick johnwchadwick marked this pull request as ready for review October 7, 2021 18:58
@JCMais
Copy link
Owner

JCMais commented Oct 7, 2021

Hi @johnwchadwick , thanks for this! I will try to review it this weekend

@johnwchadwick johnwchadwick changed the title feat: Apple Silicon support. feat: Apple Silicon support Oct 7, 2021
@johnwchadwick johnwchadwick force-pushed the m1-support branch 2 times, most recently from ca685b5 to a768f97 Compare October 8, 2021 15:33
binding.gyp Outdated
Comment on lines 159 to 167
'OTHER_LDFLAGS': [
# HACK: -framework CoreFoundation appears twice, but CoreFoundation is a singleton
# because it doesn't start with a -. We need to remove one of the instances of
# -framework CoreFoundation or GYP will break our args.
'-static',
'<!@(<(curl_config_bin) --static-libs | sed "s/-framework CoreFoundation//")',
],
Copy link
Owner

@JCMais JCMais Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this! I have stolen your workaround and merged it into a different PR as I had to fix the CI pipelines. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, I shall rebase.


build_arch x86_64
make distclean || true;
build_arch arm64
Copy link
Owner

@JCMais JCMais Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line here is not working for me on Node.js 8 and 10, I believe it would also give an error with Node.js 12 but I have not tested it.

It seems that the OpenSSL version shipped with those Node.js versions does not have the build target darwin64-arm64-cc . Could you take a look at that?

To make things easier I have enabled more tests to run in the CI for PRs, so if you rebase your changes on top of master develop you should get a build matrix that tests against multiple versions of Node.js and Electron on macOS.

As this changes the build steps for the libcurl dependencies, please make sure you bump the versioning for the libcurl-deps cache in the build-lint-test and build-and-release workflows (you can find all of them by searching for libcurl-deps-cache inside https://github.com/JCMais/node-libcurl/tree/develop/.github/workflows).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I don't think Node.js 8 or 10 support Apple Silicon; I probably need to adjust this to not attempt to build a universal binary when it isn't possible. That having been said, I've been testing on Node 12, so at least on new enough Node 12 releases it should be OK.

Copy link
Owner

@JCMais JCMais Oct 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Btw I meant develop above, not master, but it seems you got it. Sorry for that haha 😓

@johnwchadwick johnwchadwick force-pushed the m1-support branch 6 times, most recently from dd7ca2d to 88985f6 Compare October 11, 2021 18:58
@JCMais
Copy link
Owner

JCMais commented Oct 11, 2021

fyi I just pushed a new commit to develop to make sure the artifacts with the build logs are always saved.

@johnwchadwick
Copy link
Contributor Author

I think I've made most of the necessary changes now. I am not sure if openssl will wind up being the only limiting factor for universal builds, but now it is only attempted (by default) to do a universal build if openssl is >= 1.1.1i. I think this is a reasonable heuristic, but there might be other factors that should limit universal builds. That said, it sure seems like tests pass in CI with Node.js 10, which appears to be picked up as universal, so maybe some patch releases of node 10 also work.

@johnwchadwick
Copy link
Contributor Author

While universal build support is nice to have, I'm currently second-guessing if it is the right approach for the pre-built packages. For Electron, it appears electron-builder will lipo the native addons on its own, and as far as I can tell, node-pre-gyp is just not aware of universal builds at all.

This isn't too big of a deal, since most of the same things apply for cross-compiling that apply for universal builds, so realistically switching between the two approaches shouldn't be too hard.

@johnwchadwick
Copy link
Contributor Author

OK, scratch that. It's a bit hard for me to test, but I think I've finally landed on the best solution we can realistically get. It is possible to cross compile each target individually, but this ended up being a PITA, since the non-universal binaries can only be tested in the case where target_arch == host_arch. After a long spike, I stashed the effort to build separately on ARM64 and have instead simply modified the universal build to publish two separate packages, using lipo to isolate the x64 and arm64 components at the last minute. This isn't perfect, so I can understand if we want to evaluate our options more. I expect to mostly leave this PR alone pending further feedback. I understand that you are busy, so no worries if we need some more time to get this pushed through satisfactorily. Thanks!

@JCMais
Copy link
Owner

JCMais commented Oct 18, 2021

@johnwchadwick I was not able to review the recent changes this weekend, but I plan to do so this following week/weekend.

Regarding your comment about publishing the binary twice, that seems fine to me.

@JCMais
Copy link
Owner

JCMais commented Nov 6, 2021

Going to merge this and then create a pre-release version tomorrow. Thanks for all your work @johnwchadwick

the pre-release version will be created this later week, as I had some errors in the CI during the weekend, I am going to fix them all during the week.

@JCMais
Copy link
Owner

JCMais commented Nov 29, 2021

it took a while, but the pre-release version has been finally released: v2.3.4-0. The prebuilt binaries will take some time to be generated, but they should be available in the next hour or so.

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

Successfully merging this pull request may close these issues.

ARM M1 support? :)
2 participants