RobotWebTools / rclnodejs

Node.js version of ROS 2.0 client
https://docs.ros.org/en/humble/Concepts/Basic/About-Client-Libraries.html?highlight=rclnodejs#community-maintained
Apache License 2.0
311 stars 70 forks source link

Support Node 19 #883

Closed wayneparrott closed 1 year ago

wayneparrott commented 1 year ago

I was curious how rclnodejs would perform on node19. Here's my experience so far:

  1. used node 19.1.0, rclnodejs 0.21.3, ros2 humble distro, ubuntu 22
  2. encountered compilation errors with nan.h.
  3. Changing from -std=c++14 to -std=c++17 in binding.gyp resolved the compilation errors.
  4. test suite runs successfully.
  5. I also ran the same config on ros2 galactic, ubuntu 20 with no issues.

@minggangw thoughts on adding support for Node 19?

minggangw commented 1 year ago

I tried with nodejs 19 and met the failure, not sure it's the same with https://github.com/RobotWebTools/rclnodejs/issues/876, will take a deep investigation tomorrow, thanks! @wayneparrott

minggangw commented 1 year ago

Paste the error below

make: Entering directory '/home/minggang/proj/rclnodejs/build'
  CXX(target) Release/obj.target/rclnodejs/src/addon.o
In file included from /home/minggang/.cache/node-gyp/19.1.0/include/node/v8-object.h:9,
                 from /home/minggang/.cache/node-gyp/19.1.0/include/node/v8-array-buffer.h:13,
                 from /home/minggang/.cache/node-gyp/19.1.0/include/node/v8.h:24,
                 from /home/minggang/.cache/node-gyp/19.1.0/include/node/node.h:73,
                 from ../node_modules/nan/nan.h:58,
                 from ../src/addon.cpp:15:
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:106:45: error: ‘is_lvalue_reference_v’ is not a member of ‘std’; did you mean ‘is_lvalue_reference’?
  106 |   template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
      |                                             ^~~~~~~~~~~~~~~~~~~~~
      |                                             is_lvalue_reference
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:106:66: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
  106 |   template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
      |                                                                  ^
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:106:67: error: template argument 1 is invalid
  106 |   template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
      |                                                                   ^
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:106:71: error: expected unqualified-id before ‘>’ token
  106 |   template <class U, std::enable_if_t<!std::is_lvalue_reference_v<U>>*>
      |                                                                       ^
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:123:43: error: ‘is_lvalue_reference_v’ is not a member of ‘std’; did you mean ‘is_lvalue_reference’?
  123 | template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
      |                                           ^~~~~~~~~~~~~~~~~~~~~
      |                                           is_lvalue_reference
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:123:64: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
  123 | template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
      |                                                                ^
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:123:65: error: template argument 1 is invalid
  123 | template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
      |                                                                 ^
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-maybe.h:123:70: error: expected unqualified-id before ‘=’ token
  123 | template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
      |                                                                      ^
In file included from ../node_modules/nan/nan.h:178,
                 from ../src/addon.cpp:15:
../node_modules/nan/nan_callbacks.h:55:23: error: ‘AccessorSignature’ is not a member of ‘v8’
   55 | typedef v8::Local<v8::AccessorSignature> Sig;
      |                       ^~~~~~~~~~~~~~~~~
../node_modules/nan/nan_callbacks.h:55:23: error: ‘AccessorSignature’ is not a member of ‘v8’
../node_modules/nan/nan_callbacks.h:55:40: error: template argument 1 is invalid
   55 | typedef v8::Local<v8::AccessorSignature> Sig;
      |                                        ^
In file included from ../src/addon.cpp:15:
../node_modules/nan/nan.h: In function ‘void Nan::SetAccessor(v8::Local<v8::ObjectTemplate>, v8::Local<v8::String>, Nan::GetterCallback, Nan::SetterCallback, v8::Local<v8::Value>, v8::AccessControl, v8::PropertyAttribute, Nan::imp::Sig)’:
../node_modules/nan/nan.h:2544:19: error: no matching function for call to ‘v8::ObjectTemplate::SetAccessor(v8::Local<v8::String>&, void (*&)(v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&), void (*&)(v8::Local<v8::Name>, v8::Local<v8::Value>, const v8::PropertyCallbackInfo<void>&), v8::Local<v8::Object>&, v8::AccessControl&, v8::PropertyAttribute&, Nan::imp::Sig&)’
 2544 |   tpl->SetAccessor(
      |   ~~~~~~~~~~~~~~~~^
 2545 |       name
      |       ~~~~
 2546 |     , getter_
      |     ~~~~~~~~~
 2547 |     , setter_
      |     ~~~~~~~~~
 2548 |     , obj
      |     ~~~~~
 2549 |     , settings
      |     ~~~~~~~~~~
 2550 |     , attribute
      |     ~~~~~~~~~~~
 2551 |     , signature);
      |     ~~~~~~~~~~~~
In file included from /home/minggang/.cache/node-gyp/19.1.0/include/node/v8-function.h:15,
                 from /home/minggang/.cache/node-gyp/19.1.0/include/node/v8.h:33,
                 from /home/minggang/.cache/node-gyp/19.1.0/include/node/node.h:73,
                 from ../node_modules/nan/nan.h:58,
                 from ../src/addon.cpp:15:
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-template.h:807:8: note: candidate: ‘void v8::ObjectTemplate::SetAccessor(v8::Local<v8::String>, v8::AccessorGetterCallback, v8::AccessorSetterCallback, v8::Local<v8::Value>, v8::AccessControl, v8::PropertyAttribute, v8::SideEffectType, v8::SideEffectType)’
  807 |   void SetAccessor(
      |        ^~~~~~~~~~~
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-template.h:812:22: note:   no known conversion for argument 7 from ‘Nan::imp::Sig’ {aka ‘int’} to ‘v8::SideEffectType’
  812 |       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
      |       ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-template.h:814:8: note: candidate: ‘void v8::ObjectTemplate::SetAccessor(v8::Local<v8::Name>, v8::AccessorNameGetterCallback, v8::AccessorNameSetterCallback, v8::Local<v8::Value>, v8::AccessControl, v8::PropertyAttribute, v8::SideEffectType, v8::SideEffectType)’
  814 |   void SetAccessor(
      |        ^~~~~~~~~~~
/home/minggang/.cache/node-gyp/19.1.0/include/node/v8-template.h:819:22: note:   no known conversion for argument 7 from ‘Nan::imp::Sig’ {aka ‘int’} to ‘v8::SideEffectType’
  819 |       SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
      |       ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [rclnodejs.target.mk:162: Release/obj.target/rclnodejs/src/addon.o] Error 1
minggangw commented 1 year ago

After investigating, nodejs 19.1.0 does use a c++17 feature, std::is_lvalue_reference_v, which explains why passing -std=c++17 can compile successfully. So, I suggest making the change -std=c++14 to -std=c++17, considering GCC > 8.x can fully support the c++17 now (ubuntu 20.04 with GCC 9.4 , ubuntu 22.04 with GCC 11.3 as day of 11/16/2022), thus rclnodejs can support nodejs 19 too.

What do you think? @wayneparrott

minggangw commented 1 year ago

Close it due to #884