Subject: [PATCH] main/nodejs: enable cross-compilation

From: alpine-mips-patches <[email-masked]>
Date: Fri, 13 Sep 2019 11:21:34 +0000

- fix nodejs cross-build with shared dependencies: with GYP *all*
  bundled dependencies are set to link against nodejs 'libraries'
  (a variable filled by configure) though none of them needs it.
  This is harmless for native build because of --as-needed in the
  Alpine toolchain. The work-around semi-hardcodes all those '-lz'
  etc in the node.gypi and disables 'libraries' in the configure.py
  script completely.

- the above work-around is not complete for certain host-to-target
  combinations (e.g. x86_64 to ppc64le, s390x) because common.gypi
  adds machine-dependent cflags without the _toolset=target guard.
  Such cases are considered irrelevant wrt the problem cross-build
  tries to solve.

  And there is even stricter limitation imposed by V8 itself: only
  32-bit hosts can be used to build 32-bit targets because Alpine
  systems are not bi-arch. The same applies to 64-bit host/target
  pairs. One of V8 .gypi files was patched to make this limitation
  clearer.

  (Note: target/host in nodejs and V8 are CHOST/CBUILD in Alpine)

- remove ca-certificates from makedepends as it is not needed for
  the build (runtime ca-certificates dependency is left intact).

- remove binutils-gold from makedepends for the same reason.
---
 main/nodejs/APKBUILD                          | 25 +++++-
 ...t-link-bundled-deps-with-shared-deps.patch | 90 +++++++++++++++++++
 2 files changed, 111 insertions(+), 4 deletions(-)
 create mode 100644 main/nodejs/dont-link-bundled-deps-with-shared-deps.patch

diff --git a/main/nodejs/APKBUILD b/main/nodejs/APKBUILD
index d025612fd4..9aeebb599b 100644
--- a/main/nodejs/APKBUILD
+++ b/main/nodejs/APKBUILD
@@ -52,14 +52,15 @@ arch="all !mips64 !mips64el"
 license="MIT"
 depends="ca-certificates"
 depends_dev="libuv"
-# gold is needed for mksnapshot
-makedepends="$depends_dev python2 openssl-dev zlib-dev libuv-dev linux-headers
-	paxmark binutils-gold http-parser-dev ca-certificates c-ares-dev"
+makedepends_build="linux-headers python2 paxmark"
+makedepends_host="linux-headers
+	zlib-dev http-parser-dev c-ares-dev libuv-dev openssl-dev"
 subpackages="$pkgname-dev $pkgname-doc npm::noarch"
 provides="nodejs-lts=$pkgver"  # for backward compatibility
 replaces="nodejs-current nodejs-lts"  # nodejs-lts for backward compatibility
 source="https://nodejs.org/dist/v$pkgver/node-v$pkgver.tar.gz
 	dont-run-gyp-files-for-bundled-deps.patch
+	dont-link-bundled-deps-with-shared-deps.patch
 	link-with-libatomic-on-mips32.patch
 	"
 builddir="$srcdir/node-v$pkgver"
@@ -68,7 +69,7 @@ prepare() {
 	default_prepare
 
 	# Remove bundled dependencies that we're not using.
-	rm -rf deps/http_parser deps/openssl deps/uv deps/zlib
+	rm -rf deps/cares deps/http_parser deps/openssl deps/uv deps/zlib
 }
 
 build() {
@@ -78,6 +79,21 @@ build() {
 	mips*) _carchflags="--with-mips-arch-variant=r1 --with-mips-float-abi=soft";;
 	esac
 
+	# 32-bit hosts require 32-bit build system
+	if [ "$CBUILD" != "$CHOST" ]; then
+		export CC_host=${HOSTCC:-gcc}
+		export CXX_host=${HOSTCXX:-g++}
+		export LINK_host=${HOSTCXX:-g++}
+		case "$CARCH" in
+		aarch64) _carchflags="$_carchflags --dest-cpu=arm64";;
+		arm*) _carchflags="$_carchflags --dest-cpu=arm";;
+		mipsel*) _carchflags="$_carchflags --dest-cpu=mipsel";;
+		ppc64*) _carchflags="$_carchflags --dest-cpu=ppc64";;
+		# this covers the rest of mips* and s390x/x86/x86_64
+		*) _carchflags="$_carchflags --dest-cpu=$CARCH";;
+		esac
+	fi
+
 	./configure --prefix=/usr \
 		$_carchflags \
 		--shared-zlib \
@@ -139,4 +155,5 @@ npm() {
 
 sha512sums="c3a95d8810599db8e9a17932c55ff57223cf9e66028e776088420023ab7ba393e9b60518a189fcab46ca2597d213f8a6414abba282a73c9501c294dbc7b041e6  node-v10.16.3.tar.gz
 9d09a88074bf0093f35c5b610e73ebf4c5381df2a2b29feb69da1af0b18776a683b13f1276375bbcfc60936cc27769539e1f01b4ba94b22cad2d5f4daae14c46  dont-run-gyp-files-for-bundled-deps.patch
+bf3adc95d6ddaa6f2c4a4eb784c94f50aba22052d7769aba45ee5fdf47d360e9e16a1ac09f0e84027f63816442b572b4901e67936dae9bacd4a2ca6ca4086533  dont-link-bundled-deps-with-shared-deps.patch
 4fd3f10bd82d1e851ed000169c2635c001a4a051283edf96f1efb2260e2d395199dd5843f79f1cff8f2c0c65462c44241c508ea67835dfbd9880d9196fae290a  link-with-libatomic-on-mips32.patch"
diff --git a/main/nodejs/dont-link-bundled-deps-with-shared-deps.patch b/main/nodejs/dont-link-bundled-deps-with-shared-deps.patch
new file mode 100644
index 0000000000..b2ea137122
--- /dev/null
+++ b/main/nodejs/dont-link-bundled-deps-with-shared-deps.patch
@@ -0,0 +1,90 @@
+--- a/configure.py
++++ b/configure.py
+@@ -1128,7 +1128,7 @@
+   shared_lib = 'shared_' + lib
+   output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))
+ 
+-  if getattr(options, shared_lib):
++  if getattr(options, shared_lib) and False:
+     (pkg_libs, pkg_cflags, pkg_libpath, pkg_modversion) = pkg_config(lib)
+ 
+     if options.__dict__[shared_lib + '_includes']:
+--- a/deps/v8/gypfiles/toolchain.gypi
++++ b/deps/v8/gypfiles/toolchain.gypi
+@@ -141,7 +141,7 @@
+       host_arch=="s390" or host_arch=="s390x" or \
+       clang==1', {
+       'variables': {
+-        'host_cxx_is_biarch%': 1,
++        'host_cxx_is_biarch%': 0,
+        },
+      }, {
+       'variables': {
+@@ -152,7 +152,7 @@
+       target_arch=="ppc" or target_arch=="ppc64" or target_arch=="s390" or \
+       target_arch=="s390x" or clang==1', {
+       'variables': {
+-        'target_cxx_is_biarch%': 1,
++        'target_cxx_is_biarch%': 0,
+        },
+      }, {
+       'variables': {
+--- a/node.gypi
++++ b/node.gypi
+@@ -161,14 +161,26 @@
+           ],
+         }],
+       ],
++    }, {
++      'link_settings': {
++        'libraries': [ '-lz' ],
++      },
+     }],
+ 
+     [ 'node_shared_http_parser=="false"', {
+       'dependencies': [ 'deps/http_parser/http_parser.gyp:http_parser' ],
++    }, {
++      'link_settings': {
++        'libraries': [ '-lhttp_parser' ],
++      },
+     }],
+ 
+     [ 'node_shared_cares=="false"', {
+       'dependencies': [ 'deps/cares/cares.gyp:cares' ],
++    }, {
++      'link_settings': {
++        'libraries': [ '-lcares' ],
++      },
+     }],
+ 
+     [ 'node_shared_libuv=="false"', {
+@@ -199,10 +211,18 @@
+           ],
+         }],
+       ],
++    }, {
++      'link_settings': {
++        'libraries': [ '-luv' ],
++      },
+     }],
+ 
+     [ 'node_shared_nghttp2=="false"', {
+       'dependencies': [ 'deps/nghttp2/nghttp2.gyp:nghttp2' ],
++    }, {
++      'link_settings': {
++        'libraries': [ '-lnghttp2' ],
++      },
+     }],
+ 
+     [ 'OS=="mac"', {
+@@ -351,6 +371,10 @@
+               ],
+             }],
+           ],
++        }, {
++          'link_settings': {
++            'libraries': [ '-lcrypto', '-lssl' ],
++          },
+         }]]
+ 
+     }, {
-- 
2.23.0