Repository navigation
Closed
Labels
buildIssues and PRs related to Node.js builds or CI infrastructure.Issues and PRs related to Node.js builds or CI infrastructure.
Description
I'm building io.sj v2.3.4 on linux/64.
I've built & installed a local instance of openssl
openssl version
OpenSSL 1.0.2d 9 Jul 2015
in
tree -d /usr/local/ssl
/usr/local/ssl
├── bin
├── certs
├── include
│ └── openssl
├── lib64
│ ├── engines
│ └── pkgconfig
├── man
│ ├── man1
│ ├── man3
│ ├── man5
│ └── man7
├── misc
└── private
I want to build io.js against that ^^ instance, ensuring proper RUNTIME-linking against the provided libs, NOT system-defaults in other locations, therefore necessitating rpath.
Currently, for io.js,
./configure --help
...
--shared-openssl link to a shared OpenSSl DLL instead of static linking
--shared-openssl-includes=SHARED_OPENSSL_INCLUDES
directory containing OpenSSL header files
--shared-openssl-libname=SHARED_OPENSSL_LIBNAME
alternative lib name to link to [default: crypto,ssl]
--shared-openssl-libpath=SHARED_OPENSSL_LIBPATH
a directory to search for the shared OpenSSL DLLs
...
Configuring with
./configure \
--prefix=/usr/local/io.js \
--dest-cpu=x64 \
--dest-os=linux \
--shared-openssl \
--shared-openssl-includes=/usr/local/ssl/include \
--shared-openssl-libpath=/usr/local/ssl/lib64 \
--shared-openssl-libname=crypto,ssl
--shared-zlib
returns
creating ./icu_config.gypi
{ 'target_defaults': { 'cflags': [],
'default_configuration': 'Release',
'defines': [],
'include_dirs': ['/usr/local/ssl/include'],
'libraries': [ '-I/usr/local/ssl/include',
'-lssl',
'-lcrypto']},
'variables': { 'host_arch': 'x64',
'icu_small': 'false',
'node_install_npm': 'true',
'node_prefix': '/usr/local/io.js',
'node_shared_http_parser': 'false',
'node_shared_libuv': 'false',
'node_shared_openssl': 'true',
'node_shared_zlib': 'false',
'node_tag': '',
'node_use_dtrace': 'false',
'node_use_etw': 'false',
'node_use_lttng': 'false',
'node_use_openssl': 'true',
'node_use_perfctr': 'false',
'openssl_fips': '',
'openssl_no_asm': 0,
'python': '/usr/bin/python',
'target_arch': 'x64',
'uv_parent_path': '/deps/uv/',
'uv_use_dtrace': 'false',
'v8_enable_gdbjit': 0,
'v8_enable_i18n_support': 0,
'v8_no_strict_aliasing': 1,
'v8_optimized_debug': 0,
'v8_random_seed': 0,
'v8_use_snapshot': 1,
'want_separate_host_toolset': 0}}
creating ./config.gypi
creating ./config.mk
which appears to
(1) neglect the "-I" flag for 'include_dirs'
...
'include_dirs': ['/usr/local/ssl/include'],
...
and
(2) incorrectly reference CFLAGS
'-I/usr/local/ssl/include'
rather than the correct/typical LDFLAGS addition,
'-L/usr/local/ssl/lib64'
as per above at
...
'libraries': [ '-I/usr/local/ssl/include',
'-lssl',
'-lcrypto']},
...
Which, of course, causes a build FAIL
./configre ...
make -C out BUILDTYPE=Release V=1 -j
...
/usr/bin/g++-5 -pthread -rdynamic -m64 -Wl,-z,noexecstack -Wl,--whole-archive /usr/local/src/io.js/out/Release/obj.target/deps/v8/tools/gyp/libv8_base.a -Wl,--no-whole-archive -pthread -o /usr/local/src/io.js/out/Release/iojs -Wl,--start-group /usr/local/src/io.js/out/Release/obj.target/iojs/src/debug-agent.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/async-wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/env.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/fs_event_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/cares_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/handle_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/js_stream.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_buffer.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_constants.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_contextify.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_file.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_http_parser.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_javascript.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_main.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_os.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_v8.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_stat_watcher.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_watchdog.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_zlib.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_i18n.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/pipe_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/signal_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/smalloc.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/spawn_sync.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/string_bytes.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/stream_base.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/stream_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/tcp_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/timer_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/tty_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/process_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/udp_wrap.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/uv.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/util.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto_bio.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto_clienthello.o /usr/local/src/io.js/out/Release/obj.target/iojs/src/tls_wrap.o /usr/local/src/io.js/out/Release/obj.target/deps/cares/libcares.a /usr/local/src/io.js/out/Release/obj.target/deps/v8/tools/gyp/libv8_libplatform.a /usr/local/src/io.js/out/Release/obj.target/deps/zlib/libzlib.a /usr/local/src/io.js/out/Release/obj.target/deps/http_parser/libhttp_parser.a /usr/local/src/io.js/out/Release/obj.target/deps/uv/libuv.a /usr/local/src/io.js/out/Release/obj.target/deps/v8/tools/gyp/libv8_base.a /usr/local/src/io.js/out/Release/obj.target/deps/v8/tools/gyp/libv8_libbase.a /usr/local/src/io.js/out/Release/obj.target/deps/v8/tools/gyp/libv8_nosnapshot.a -Wl,--end-group -I/usr/local/ssl/include -lssl -lcrypto -lrt -lm -ldl
/usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto.o: In function `node::crypto::VerifyCallback(int, x509_store_ctx_st*)':
node_crypto.cc:(.text._ZN4node6crypto14VerifyCallbackEiP17x509_store_ctx_st[_ZN4node6crypto14VerifyCallbackEiP17x509_store_ctx_st]+0x73): undefined reference to `SSL_is_server'
/usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto.o: In function `node::crypto::Connection::New(v8::FunctionCallbackInfo<v8::Value> const&)':
node_crypto.cc:(.text._ZN4node6crypto10Connection3NewERKN2v820FunctionCallbackInfoINS2_5ValueEEE+0x347): undefined reference to `SSL_set_cert_cb'
node_crypto.cc:(.text._ZN4node6crypto10Connection3NewERKN2v820FunctionCallbackInfoINS2_5ValueEEE+0x48e): undefined reference to `SSL_set_cert_cb'
/usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto.o: In function `node::crypto::SSLWrap<node::crypto::Connection>::CertCbDone(v8::FunctionCallbackInfo<v8::Value> const&)':
node_crypto.cc:(.text._ZN4node6crypto7SSLWrapINS0_10ConnectionEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE[_ZN4node6crypto7SSLWrapINS0_10ConnectionEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE]+0xf0): undefined reference to `SSL_CTX_get0_certificate'
node_crypto.cc:(.text._ZN4node6crypto7SSLWrapINS0_10ConnectionEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE[_ZN4node6crypto7SSLWrapINS0_10ConnectionEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE]+0xfc): undefined reference to `SSL_CTX_get0_privatekey'
/usr/local/src/io.js/out/Release/obj.target/iojs/src/node_crypto.o: In function `node::crypto::SSLWrap<node::TLSWrap>::CertCbDone(v8::FunctionCallbackInfo<v8::Value> const&)':
node_crypto.cc:(.text._ZN4node6crypto7SSLWrapINS_7TLSWrapEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE[_ZN4node6crypto7SSLWrapINS_7TLSWrapEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE]+0xf0): undefined reference to `SSL_CTX_get0_certificate'
node_crypto.cc:(.text._ZN4node6crypto7SSLWrapINS_7TLSWrapEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE[_ZN4node6crypto7SSLWrapINS_7TLSWrapEE10CertCbDoneERKN2v820FunctionCallbackInfoINS4_5ValueEEE]+0xfc): undefined reference to `SSL_CTX_get0_privatekey'
/usr/local/src/io.js/out/Release/obj.target/iojs/src/tls_wrap.o: In function `node::TLSWrap::InitSSL()':
tls_wrap.cc:(.text._ZN4node7TLSWrap7InitSSLEv+0xf3): undefined reference to `SSL_set_cert_cb'
collect2: error: ld returned 1 exit status
iojs.target.mk:196: recipe for target '/usr/local/src/io.js/out/Release/iojs' failed
make: *** [/usr/local/src/io.js/out/Release/iojs] Error 1
make: Leaving directory '/usr/local/src/io.js/out'
Further, there's no obvious mechanism for adding the necessary rpath'ing flags to ensure the aforementioned linking.
For node.js 0.12.x, a simple src patch does the trick
cat ./nodejs-openssl-rpath.patch
--- configure.ORIG 2015-03-03 19:37:28.534636561 -0800
+++ configure 2015-03-03 19:43:53.517334786 -0800
@@ -695,7 +695,15 @@
o['include_dirs'] += [options.shared_openssl_includes]
else:
o['cflags'] += cflags.split()
-
+ o['ldflags'] = [ '-L/usr/local/ssl/lib64',
+ '-Wl,-rpath,/usr/local/ssl/lib64',
+ '-lssl',
+ '-lcrypto',
+ '-L/usr/local/lib64',
+ '-Wl,-rpath,/usr/local/lib64',
+ '-lpcre',
+ ]
+
def configure_fullystatic(o):
if options.fully_static:
patch -p0 < ./nodejs-openssl-rpath.patch
so that node's built & properly runtime-linked,
node -v
v0.12.6
ldd `which node` | egrep -i "crypto|ssl"
libssl.so.1.0.0 => /usr/local/ssl/lib64/libssl.so.1.0.0 (0x00007f688cd14000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib64/libcrypto.so.1.0.0 (0x00007f688c8ca000)
Looking through io.js' ./configure, it's clearly a departure from node.js', and it's not at all clear, atm, how/where to make a similar patch.
Metadata
Metadata
Assignees
Labels
buildIssues and PRs related to Node.js builds or CI infrastructure.Issues and PRs related to Node.js builds or CI infrastructure.
Activity
rvagg commentedon Jul 10, 2015
/cc @nodejs/build @jbergstroem you've been working in this area haven't you?
[-]io.js v2.3.3 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/-][+]io.js v2.3.4 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/+]jbergstroem commentedon Jul 10, 2015
Yeah, this is up my alley. I'll have a look.
jbergstroem commentedon Jul 20, 2015
I swear I posted a diff here last week. Gah - I'll find it.
jbergstroem commentedon Jul 20, 2015
Quick question; @pgnd: do you have pkg-config installed in your system? At the moment iojs prefers that before anything else.
jbergstroem commentedon Jul 21, 2015
Yeah, just wanted to make it clear that you will have to either unset pkg-config from path or similar ($i_know_what_im_doing) if you want to make this work. I'll post you a diff for testing shortly.
jbergstroem commentedon Jul 21, 2015
@pgnd we already allow override with flags (so, not 100% autoconf) so that'd be good enough. The behaviour for overridden flags has just changed recently which needs to be adjusted. Finally, I don't think we'll override
pkg-configoutput from flags, rather suggest these selected few just pass/dev/nulltoPKG_CONFIGor similar. Thanks for your elaborate input, btw.2 remaining items
jbergstroem commentedon Jul 23, 2015
@pgnd passing flags through configure line would only override the default (through optparse). We need to reintroduce that logic. I'm starting to feel that the only way to really solve this is either moving closer to how autoconf works (i.e, juggling environment variables, pkg-config, default and override flags) or perhaps exposing further configuration through
config.mk/config.gypiso people can edit the files post-configuration (we're probably talking <1% of users).[-]io.js v2.3.4 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/-][+]io.js v2.5.0 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/+]rvagg commentedon Jul 29, 2015
Bringing in @bnoordhuis to this discussion as he may have some interest in helping resolve this. I believe @jbergstroem is a little busy with other things atm.
jbergstroem commentedon Jul 30, 2015
Sorry, just travelling at the moment.
@pgnd I didn't have any problems editing
config.gypibetween compiles (I tried switching shared flags). Did you? If not, I'd suggest thats how we move forward for more exotic combinations which would require better documentation.jbergstroem commentedon Jul 30, 2015
Ok, I'll create a PR.
[-]io.js v2.5.0 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/-][+]io.js all v2.3.4 - v3.0.0 (1) configures incorrect external-openssl flags, (2) FAILs build, (3) lacks rpath mechanism (&/or docs)[/+]fazalmajid commentedon Sep 30, 2015
I am encountering the same issue with 4.0.0 and 4.1.1.
cephasjohnson commentedon Nov 11, 2015
Short version: I'm making node from 5.0.0 source on Ubuntu 14.04.3 LTS (GNU/Linux 3.10.53-1.1.0_ga-wandboard-06034-g13bb184-dirty armv7l). Configure options --shared-openssl-includes, --shared-openssl-libpath and --shared-openssl and the same options for zlib don't work as advertised. This may be due to --start-group and --end-group options used in the command that links node. The same failure occurs when building from 4.2.2 source.
The command that links node in 4.2.2 and 5.0.0 source differs from the command that links node in 0.12.x source.
Longer version:
which results in:
The "libraries" stanza in above is wrong. It should be:
ldd then shows out/Release/node uses these libraries:
whereas the desired ldd output should show references to locally installed libraries (note I have /usr/local/ssl/lib linked to /usr/local/ssl-1.0.2d/lib):
nm shows the undefined symbol isn't in the system version of libssl.so (which was linked into node) but is in the locally installed version of libssl.so (which wasn't, but should have been, linked into node):
g++ -pthread -rdynamic -Wl,-z,noexecstack -Wl,--whole-archive /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_base.a -Wl,--no-whole-archive -pthread -o /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/node -Wl,--start-group /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/node/src/debug-agent.o ... <LOTS MORE REFERENCES TO .o AND .a FILES> ... /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_nosnapshot.a -Wl,--end-group -L/usr/local/lib -lz -L/usr/local/ssl-1.0.2d/lib -lssl -lcrypto -ldl -lrt -lm
which SEEMS to mean -lcrypto -lssl -lz -ldl -lrt -lm that occur after --end-group will never be searched to resolve undefined references in all the archives listed between --start-group and --end-group. In turn the node executable includes undefined symbols (one of which is SSL_set_cert_cb). Subsequently the runtime linker can't resolve the undefineds cause it hasn't been told to look in /usr/local/ssl/lib/.
g++ -pthread -rdynamic -Wl,-z,noexecstack -Wl,--whole-archive /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_base.a -Wl,--no-whole-archive -pthread -o /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/node -L/usr/local/lib -L/usr/local/ssl-1.0.2d/lib -Wl,--start-group /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/node/src/debug-agent.o ... <LOTS MORE REFERENCES TO .o AND .a FILES> ... /home/ubuntu/src/nodejs/node-v5.0.0/out/Release/obj.target/deps/v8/tools/gyp/libv8_nosnapshot.a -lz -lssl -lcrypto -ldl -lrt -lm -Wl,--end-group
cephasjohnson commentedon Nov 19, 2015
Making node from 5.0.0 source using locally installed openssl and zlib works if config.gypi and Makefile are edited. For example, configure node with:
./configure --prefix=/usr/local/node-5.0.0 --shared-openssl-includes=/usr/local/ssl/include --shared-openssl-libpath=/usr/local/ssl/lib --shared-openssl --shared-zlib-includes=/usr/local/include --shared-zlib-libpath=/usr/local/lib --shared-zlib
After running above configure command, and with node-v5.0.0 as the current directory, edit:
A. config.gypi
replace:
with:
Note on this machine I've made /usr/local/ssl/lib a soft link to /usr/local/ssl-1.0.2d/lib.
B. out/Makefile
replace:
cmd_link =$(LINK.$ (TOOLSET)) $(GYP_LDFLAGS) $ (LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $ (LD_INPUTS) -Wl,--end-group $(LIBS)
with:
cmd_link =$(LINK.$ (TOOLSET)) $(GYP_LDFLAGS) $ (LDFLAGS.$(TOOLSET)) -o $@ -Wl,-rpath=/usr/local/lib -Wl,-rpath=/usr/local/ssl/lib -L/usr/local/lib -L/usr/local/ssl/lib -Wl,--start-group $ (LD_INPUTS) $(LIBS) -Wl,--end-group
Subsequently continue to make node from source as usual.