node-sass: OpenBSD でビルドエラー - 解決方法
Tags: node, sass, openbsd, troubleshooting
Published: 2022-02-23 12:40:25

## 事象

`npm install node-sass` を [OpenBSD](https://www.openbsd.org/) で実行すると、次のようなエラーが出ることがあります。

```console
> node-sass@4.12.0 postinstall $APP_DIR/node_modules/node-sass
> node scripts/build.js

Building: node $APP_DIR/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
gyp info it worked if it ends with ok
gyp info using node-gyp@3.8.0
gyp info using node@12.16.1 | openbsd | x64
gyp http GET https://nodejs.org/download/release/v12.16.1/node-v12.16.1-headers.tar.gz
gyp http 200 https://nodejs.org/download/release/v12.16.1/node-v12.16.1-headers.tar.gz
gyp http GET https://nodejs.org/download/release/v12.16.1/SHASUMS256.txt
gyp http 200 https://nodejs.org/download/release/v12.16.1/SHASUMS256.txt
gyp info spawn /usr/local/bin/python2
gyp info spawn args [
gyp info spawn args   '$APP_DIR/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '$APP_DIR/node_modules/node-sass/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '$APP_DIR/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '$HOME_DIR/.node-gyp/12.16.1/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=$HOME_DIR/.node-gyp/12.16.1',
gyp info spawn args   '-Dnode_gyp_dir=$APP_DIR/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=$HOME_DIR/.node-gyp/12.16.1/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=$APP_DIR/node_modules/node-sass',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn gmake
gyp info spawn args [ 'V=1', 'BUILDTYPE=Release', '-C', 'build' ]
gmake: Entering directory '$APP_DIR/node_modules/node-sass/build'
  g++ '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.4"' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer -std=gnu++1y -std=c++0x -fexceptions -frtti -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/ast.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/ast.o ../src/libsass/src/ast.cpp
cc1plus: error: unrecognized command line option "-std=gnu++1y"
cc1plus: error: unrecognized command line option "-std=c++0x"
gmake: *** [src/libsass.target.mk:162: Release/obj.target/libsass/src/libsass/src/ast.o] Error 1
gmake: Leaving directory '$APP_DIR/node_modules/node-sass/build'
gyp ERR! build error 
gyp ERR! stack Error: `gmake` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit ($APP_DIR/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:311:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12)
gyp ERR! System OpenBSD 6.7
gyp ERR! command "node" "$APP_DIR/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd $APP_DIR/node_modules/node-sass
gyp ERR! node -v v12.16.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
Build failed with error code: 1
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"openbsd","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.12.0 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the node-sass@4.12.0 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
```

### 環境

- OS: OpenBSD 7.0
- App: [Node.js](https://nodejs.org/) 12.22

## 解決方法

[`clang++`](https://clang.llvm.org/) が必要なところで [`g++`](https://gcc.gnu.org/) が使われるためにエラーが発生します。
そのようなわけですので、次のようにすると解決できます:

```console
$ # npm の場合:
$ env CXX=/usr/bin/clang++ npm install node-sass

$ # yarn の場合:
$ env CXX=/usr/bin/clang++ yarn install node-sass
```

以下のように出れば成功です:

```console
gypgmake: Entering directory '$APP_DIR/node_modules/node-sass/build'
 info   /usr/bin/clang++ '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.4"' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer -std=gnu++1y -std=c++0x -fexceptions -frtti -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/ast.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/ast.o ../src/libsass/src/ast.cpp
spawn gmake
gyp info spawn args [ 'V=1', 'BUILDTYPE=Release', '-C', 'build' ]
  /usr/bin/clang++ '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.4"' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer -std=gnu++1y -std=c++0x -fexceptions -frtti -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/ast_fwd_decl.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/ast_fwd_decl.o ../src/libsass/src/ast_fwd_decl.cpp
  ...
  cc '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.4"' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer  -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/cencode.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/cencode.o ../src/libsass/src/cencode.c
  /usr/bin/clang++ '-DNODE_GYP_MODULE_NAME=libsass' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DLIBSASS_VERSION="3.5.4"' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer -std=gnu++1y -std=c++0x -fexceptions -frtti -MMD -MF ./Release/.deps/Release/obj.target/libsass/src/libsass/src/check_nesting.o.d.raw   -c -o Release/obj.target/libsass/src/libsass/src/check_nesting.o ../src/libsass/src/check_nesting.cpp
  ...
  rm -f Release/obj.target/src/sass.a && ar crs Release/obj.target/src/sass.a Release/obj.target/libsass/src/libsass/src/ast.o Release/obj.target/libsass/src/libsass/src/ast_fwd_decl.o Release/obj.target/libsass/src/libsass/src/backtrace.o Release/obj.target/libsass/src/libsass/src/base64vlq.o Release/obj.target/libsass/src/libsass/src/bind.o Release/obj.target/libsass/src/libsass/src/cencode.o Release/obj.target/libsass/src/libsass/src/check_nesting.o Release/obj.target/libsass/src/libsass/src/color_maps.o Release/obj.target/libsass/src/libsass/src/constants.o Release/obj.target/libsass/src/libsass/src/context.o Release/obj.target/libsass/src/libsass/src/cssize.o Release/obj.target/libsass/src/libsass/src/emitter.o Release/obj.target/libsass/src/libsass/src/environment.o Release/obj.target/libsass/src/libsass/src/error_handling.o Release/obj.target/libsass/src/libsass/src/eval.o Release/obj.target/libsass/src/libsass/src/expand.o Release/obj.target/libsass/src/libsass/src/extend.o Release/obj.target/libsass/src/libsass/src/file.o Release/obj.target/libsass/src/libsass/src/functions.o Release/obj.target/libsass/src/libsass/src/inspect.o Release/obj.target/libsass/src/libsass/src/json.o Release/obj.target/libsass/src/libsass/src/lexer.o Release/obj.target/libsass/src/libsass/src/listize.o Release/obj.target/libsass/src/libsass/src/memory/SharedPtr.o Release/obj.target/libsass/src/libsass/src/node.o Release/obj.target/libsass/src/libsass/src/operators.o Release/obj.target/libsass/src/libsass/src/output.o Release/obj.target/libsass/src/libsass/src/parser.o Release/obj.target/libsass/src/libsass/src/plugins.o Release/obj.target/libsass/src/libsass/src/position.o Release/obj.target/libsass/src/libsass/src/prelexer.o Release/obj.target/libsass/src/libsass/src/remove_placeholders.o Release/obj.target/libsass/src/libsass/src/sass.o Release/obj.target/libsass/src/libsass/src/sass2scss.o Release/obj.target/libsass/src/libsass/src/sass_context.o Release/obj.target/libsass/src/libsass/src/sass_functions.o Release/obj.target/libsass/src/libsass/src/sass_util.o Release/obj.target/libsass/src/libsass/src/sass_values.o Release/obj.target/libsass/src/libsass/src/source_map.o Release/obj.target/libsass/src/libsass/src/subset_map.o Release/obj.target/libsass/src/libsass/src/to_c.o Release/obj.target/libsass/src/libsass/src/to_value.o Release/obj.target/libsass/src/libsass/src/units.o Release/obj.target/libsass/src/libsass/src/utf8_string.o Release/obj.target/libsass/src/libsass/src/util.o Release/obj.target/libsass/src/libsass/src/values.o
  rm -rf "Release/sass.a" && cp -pPRf "Release/obj.target/src/sass.a" "Release/sass.a"
  /usr/bin/clang++ '-DNODE_GYP_MODULE_NAME=binding' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DBUILDING_NODE_EXTENSION' -I$HOME_DIR/.node-gyp/12.16.1/include/node -I$HOME_DIR/.node-gyp/12.16.1/src -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/config -I$HOME_DIR/.node-gyp/12.16.1/deps/openssl/openssl/include -I$HOME_DIR/.node-gyp/12.16.1/deps/uv/include -I$HOME_DIR/.node-gyp/12.16.1/deps/zlib -I$HOME_DIR/.node-gyp/12.16.1/deps/v8/include -I../../nan -I../src/libsass/include  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -I/usr/local/include -O3 -fno-omit-frame-pointer -fno-rtti -fno-exceptions -std=gnu++1y -std=c++0x -MMD -MF ./Release/.deps/Release/obj.target/binding/src/binding.o.d.raw   -c -o Release/obj.target/binding/src/binding.o ../src/binding.cpp
  ...
  /usr/bin/clang++ -shared -pthread -rdynamic -m64 -Wl,-z,wxneeded  -Wl,-soname=binding.node -o Release/obj.target/binding.node -Wl,--start-group Release/obj.target/binding/src/binding.o Release/obj.target/binding/src/create_string.o Release/obj.target/binding/src/custom_function_bridge.o Release/obj.target/binding/src/custom_importer_bridge.o Release/obj.target/binding/src/sass_context_wrapper.o Release/obj.target/binding/src/sass_types/boolean.o Release/obj.target/binding/src/sass_types/color.o Release/obj.target/binding/src/sass_types/error.o Release/obj.target/binding/src/sass_types/factory.o Release/obj.target/binding/src/sass_types/list.o Release/obj.target/binding/src/sass_types/map.o Release/obj.target/binding/src/sass_types/null.o Release/obj.target/binding/src/sass_types/number.o Release/obj.target/binding/src/sass_types/string.o Release/obj.target/src/sass.a -Wl,--end-group 
  rm -rf "Release/binding.node" && cp -pPRf "Release/obj.target/binding.node" "Release/binding.node"
gmake: Leaving directory '$APP_DIR/node_modules/node-sass/build'
gyp info ok 
Installed to $APP_DIR/node_modules/node-sass/vendor/openbsd-x64-72/binding.node
```

### 補足事項

インラインで [`env`](https://man.openbsd.org/env.1) を使う代わりに、[`export`](https://man.openbsd.org/sh.1#export) や [`alias`](https://man.openbsd.org/sh.1#alias) を使うこともできます。

```console
$ # export の場合:
$ export CXX=/usr/bin/clang++
$ npm install node-sass
```

```console
$ # alias の場合:
$ alias npm='env CXX=/usr/bin/clang++ npm'
$ npm install node-sass
```

## 謝辞

[こちらの GitHub のイシュー](https://github.com/sass/node-sass/issues/2840) が大変参考になりました。


[@morgant](https://github.com/morgant)、[@qbit](https://github.com/qbit)、[@ghost](https://github.com/ghost) 方々に感謝申し上げます。