Unit: install unit-http on Mac OS

Created on 19 Feb 2020  ·  12Comments  ·  Source: nginx/unit

Mac OS: 10.15.3 (19D76)
NodeJS: v13.9.0
npm: 6.13.7

hi,

I'm trying to install the unit-http on Mac OS:

npm install unit-http --global --unsafe-permk

which results in:

> [email protected] install /Users/dmitrymedvedev/.nvm/versions/node/13.9.0/lib/node_modules/unit-http
> node-gyp configure build

  CXX(target) Release/obj.target/unit-http/unit.o
In file included from ../unit.cpp:6:
In file included from ../unit.h:9:
../nxt_napi.h:17:10: fatal error: 'nxt_unit.h' file not found
#include <nxt_unit.h>
         ^~~~~~~~~~~~
1 error generated.
make: *** [Release/obj.target/unit-http/unit.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:321:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System Darwin 19.3.0
gyp ERR! command "/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/bin/node" "/Users/dmitrymedvedev/.nvm/versions/node/v13.9.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "build"
gyp ERR! cwd /Users/dmitrymedvedev/.nvm/versions/node/13.9.0/lib/node_modules/unit-http
gyp ERR! node -v v13.9.0
gyp ERR! node-gyp -v v5.0.7
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: `node-gyp configure build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/dmitrymedvedev/.npm/_logs/2020-02-19T00_50_52_264Z-debug.log

The question is: is the unit-http not compatible with Mac? If that is not the case, could you please point me to a proper installation procedure?

Regards,
Dmitry

All 12 comments

Hello,

Node.js module unit-http can be used on Mac OS.

Unit header files and library required to build module. For Mac OS you need to configure and build Unit and library from sources (you need Unit to run your app anyway).

Node.js module can be configured and installed from this source tree:

./configure nodejs
make node-install

There is an option to install unit-http locally to your project.

hi @mar0x, do you have the command to build the unit with ssl support?

I do this:

./configure \
  --openssl \
  --cc-opt=-I$OPENSSL_DIR \
  --ld-opt=-L$OPENSSL_DIR \
  --prefix=$NGINX_UNIT_PREFIX

make && make install

and get errors about functions in ssl marked as deprecated like this:

src/nxt_openssl.c:1047:15: error: 'ERR_get_error_line_data' is deprecated [-Werror,-Wdeprecated-declarations]
        err = ERR_get_error_line_data(NULL, NULL, &data, &flags);

in the following snippet:

./configure nodejs \
  --local=$NGINX_UNIT_PREFIX/module

make node-local-install

the --local will not be taken into account, look:

  "dependencies": {
    "unit-http": "file:distros/unit/build/node-unit-http.tar.gz"
  }

NB: the distros is the directory for both openssl and unit sources. The node-local-install should have the module installed in the $NGINX_UNIT_PREFIX/module path instead.

hi @mar0x, do you have the command to build the unit with ssl support?
..

You may try to:

  • disable deprecations with -Wno-deprecated-declarations CFLAG or
  • build your own openssl manually or
  • use openssl from MacPorts or
  • use brew and install unit from my tap with command brew install mar0x/unit/unit, this makes unit header files and library available for npm install unit-http either local or global.

...
the --local will not be taken into account, look:
...

Could you please provide complete list of executed commands (it is hard to guess what was wrong).

hi @mar0x, please see the files I am using to build both the unit and the unit-http lib.

env.sh

#!/bin/bash

export CWD=$(pwd)

# export ADV_BUILD_DIR=$(mktemp -d)
mkdir -p "$CWD/distros"

export ADV_BUILD_DIR="$CWD/distros"
export OPENSSL_DIR="$ADV_BUILD_DIR/openssl"

export NGINX_UNIT_DIR="$ADV_BUILD_DIR/unit"
export NGINX_UNIT_PREFIX="$CWD/usr/local/unit"

export OPENSSL_GIT=https://github.com/openssl/openssl.git
export UNIT_GIT=https://github.com/nginx/unit

nginx-unit.sh

#!/bin/bash

source ./scripts/install/env.sh

NODE_UNIT_TGZ="$NGINX_UNIT_DIR/build/node-unit-http.tar.gz"

pnpm add node-gyp --global --unsafe-perm

if [[ ! -d  $NGINX_UNIT_DIR ]]
then
  echo "downloading NGINX-UNIT"

  mkdir -p $NGINX_UNIT_DIR

  cd $NGINX_UNIT_DIR

  git clone $UNIT_GIT .
else
  echo "updating NGINX-UNIT"

  cd $NGINX_UNIT_DIR

  git pull

  make clean
fi

./configure \
  --prefix=$NGINX_UNIT_PREFIX \
  --openssl \
  --cc-opt="-Wno-deprecated-declarations -I$OPENSSL_DIR"

echo "install NGINX-UNIT"
make && make install

./configure nodejs \
  --local=$NGINX_UNIT_PREFIX/module \
  --node-gyp=$(dirname $(dirname $(which node)))/lib/node_modules/npm/bin/node-gyp-bin/node-gyp

echo "install unit-http lib"
make node-install
mkdir $NGINX_UNIT_PREFIX/module
cp $NGINX_UNIT_DIR/build/node-unit-http.tar.gz $NGINX_UNIT_PREFIX/module

one more problem: the node-unit-http.tar.gz file does not contain a *.node library and when installed locally ( when there is a devDependencies generated for it in the package.json file ) cannot be installed with npm install command.

@mar0x,

using something like brew install mar0x/unit/unit is not an option since I need to be able to build the unit and the unit-http library and have complete control over them, e.g.: the unit will be invoked in a test environment as a separate process from a test script.

These two will also be distributed by a couple of other projects. So, the point is: complete control is required.

.. the node-unit-http.tar.gz file does not contain a *.node library ...

Yes, it contains only sources and can be used in npm install.

.. cannot be installed with npm install command.

You can install node module with npm install after you add extra variables to your environment:

export UNIT_SRC_PATH=$NGINX_UNIT_DIR/src
export UNIT_BUILD_PATH=$NGINX_UNIT_DIR/build
export UNIT_LIB_STATIC_PATH=$NGINX_UNIT_DIR/build/libunit.a
npm install $NGINX_UNIT_DIR/build/build/node-unit-http.tar.gz

hi @mar0x ,

the thing is: if I want to install the node module I will have to have all the sources on the target machine. Right?

what I want to achieve on the other hand, is that I establish a build routing for each OS, run the build, get the installable package for each OS used ( actuall for Mac OS and Debian ) and distribute this package among all the developers so that they are not required to rebuild it all from scratch.

Does it make sense? Is it feasible?

... have all the sources on the target machine ...

Not all sources, only 10 header files and 1 static library required to build module.

Does it make sense?

Definitely, yes.

Is it feasible?

I have no idea how to properly package binary library for Node.js module. People wants to use npm install smoothly on all platforms and only way to achieve this (as far as I know) is to distribute sources and build binary on the target host.

On Debian developers may install unit-dev and then npm install unit-http should work (yes, there will be compilation during install).
On macOS there is no standard package manager and using brew is not an option for you.

We have similar situation with Go module and we are trying to support _traditional_ ways to install modules for Go and Node.js. Please let me know if you see a more convenient/correct/smooth solution.

@mar0x, please see this repo: build-nginx-unit. Your help is greatly appreciated

Was this page helpful?
0 / 5 - 0 ratings