Skip to content

Commit

Permalink
build: Updates for AIX npm support - part 1
Browse files Browse the repository at this point in the history
This PR is the first step enabling support for native modules
for AIX.  The main issue is that unlike linux where all
symbols within the Node executable are available to the shared
library for a native module (npm), on AIX the symbols must
be explicitly exported.  In addition, when the shared library is
built it must be linked using a list of the available symbols.

This patch covers the changes need to:

 1) Export the symbols when building the node executable
 2) Generate the file listing the symbols that can be used when
    building the shared library.

For AIX, it breaks the build process into 2 steps.  The first builds
a static library and then generates a node.exp file which contains
the symbols from that library.  The second builds the node executable
and uses the node.exp file to specify which symbols should be
exported.  In addition, it save the node.exp file so that it can
later be used in the creation of the shared library when building
a native module.

The following additional steps will be required in dependent projects
to fully enable AIX for native modules and are being worked
separately:

 - Updates to node-gyp to use node.exp when creating the
   shared library for a native module
 - Fixes to gyp related to copying files as covered in
      https://codereview.chromium.org/1368133002/patch/1/10001
 - Pulling in updated gyp versions to Node and node-gyp
 - Pulling latest libuv

These changes were done to minimize the change to other platforms
by working within the existing structure to add the 2 step process
for AIX without changing the process for other platforms.

PR-URL: #3114
Reviewed-By: Ben Noordhuis <[email protected]>
  • Loading branch information
mhdawson authored and Myles Borins committed Jan 19, 2016
1 parent 8a9869e commit 80b4ba2
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 2 deletions.
4 changes: 4 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,10 @@ def configure_node(o):
elif target_arch in ('mips', 'mipsel'):
configure_mips(o)

if flavor == 'aix':
o['variables']['node_core_target_name'] = 'node_base'
o['variables']['node_target_type'] = 'static_library'

if flavor in ('solaris', 'mac', 'linux', 'freebsd'):
use_dtrace = not options.without_dtrace
# Don't enable by default on linux and freebsd
Expand Down
53 changes: 51 additions & 2 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
'node_shared_openssl%': 'false',
'node_v8_options%': '',
'node_target_type%': 'executable',
'node_core_target_name%': 'node',
'library_files': [
'src/node.js',
'lib/_debug_agent.js',
Expand Down Expand Up @@ -81,7 +82,7 @@

'targets': [
{
'target_name': 'node',
'target_name': '<(node_core_target_name)',
'type': '<(node_target_type)',

'dependencies': [
Expand Down Expand Up @@ -673,5 +674,53 @@
'test/cctest/util.cc',
],
}
] # end targets
], # end targets

'conditions': [
['OS=="aix"', {
'targets': [
{
'target_name': 'node',
'type': 'executable',
'dependencies': ['<(node_core_target_name)', 'node_exp'],

'include_dirs': [
'src',
'deps/v8/include',
],

'sources': [
'src/node_main.cc',
'<@(library_files)',
# node.gyp is added to the project by default.
'common.gypi',
],

'ldflags': ['-Wl,-bbigtoc,-bE:<(PRODUCT_DIR)/node.exp'],
},
{
'target_name': 'node_exp',
'type': 'none',
'dependencies': [
'<(node_core_target_name)',
],
'actions': [
{
'action_name': 'expfile',
'inputs': [
'<(OBJ_DIR)'
],
'outputs': [
'<(PRODUCT_DIR)/node.exp'
],
'action': [
'sh', 'tools/create_expfile.sh',
'<@(_inputs)', '<@(_outputs)'
],
}
]
}
], # end targets
}], # end aix section
], # end conditions block
}
48 changes: 48 additions & 0 deletions tools/create_expfile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/sh
# This script writes out all the exported symbols to a file
# AIX needs this as sybmols are not exported by an
# executable by default and we need to list
# them specifically in order to export them
# so that they can be used by native add-ons
#
# The raw symbol data is objtained by using nm on
# the .a files which make up the node executable
#
# -Xany makes sure we get symbols on both
# 32 bit and 64 bit as by default we'd only get those
# for 32 bit
#
# -g selects only exported symbols
#
# -C, -B and -p ensure the output is in a format we
# can easily parse and convert into the symbol we need
#
# -C suppresses the demangling of C++ names
# -B gives us output in BSD format
# -p displays the info in a standard portable output format
#
# We only include symbols if they are of the
# following types and don't start with a dot.
#
# T - Global text symbol
# D - Global data symbol
# B - Gobal bss symbol.
#
# the final sort allows us to remove any duplicates
#
# We need to exclude gtest libraries as they are not
# linked into the node executable
#
echo "Searching $1 to write out expfile to $2"

# this special sequence must be at the start of the exp file
echo "#!." > $2

# pull the symbols from the .a files
find $1 -name "*.a" | grep -v gtest \
| xargs nm -Xany -BCpg \
| awk '{
if ((($2 == "T") || ($2 == "D") || ($2 == "B")) &&
(substr($3,1,1) != ".")) { print $3 }
}' \
| sort -u >> $2
4 changes: 4 additions & 0 deletions tools/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ def headers(action):
'src/node_version.h',
], 'include/node/')

# Add the expfile that is created on AIX
if sys.platform.startswith('aix'):
action(['out/Release/node.exp'], 'include/node/')

subdir_files('deps/cares/include', 'include/node/', action)
subdir_files('deps/v8/include', 'include/node/', action)

Expand Down

0 comments on commit 80b4ba2

Please sign in to comment.