Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot open include file: 'napi.h' #309

Closed
TareHimself opened this issue Oct 10, 2023 · 7 comments
Closed

Cannot open include file: 'napi.h' #309

TareHimself opened this issue Oct 10, 2023 · 7 comments

Comments

@TareHimself
Copy link

TareHimself commented Oct 10, 2023

I am getting this error Cannot open include file: 'napi.h' in multiple source files. This is my CmakeLists

cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
# Name of the project (will be the name of the plugin)
project(nodeml_torch)

set(CMAKE_CXX_STANDARD 17)

add_definitions(-DNAPI_VERSION=4)

include_directories(${CMAKE_JS_INC})

set(PYTORCH_VERSION 2.1.0)

if(NOT EXISTS ${CMAKE_SOURCE_DIR}/deps/dynamic/libtorch)
  file(DOWNLOAD https://download.pytorch.org/libtorch/cpu/libtorch-win-shared-with-deps-${PYTORCH_VERSION}%2Bcpu.zip ${CMAKE_CURRENT_SOURCE_DIR}/torch.zip SHOW_PROGRESS)
  message(STATUS "Extracting")
  file(ARCHIVE_EXTRACT INPUT ${CMAKE_CURRENT_SOURCE_DIR}/torch.zip DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/deps/dynamic)
  message(STATUS "Done Extracting")
  file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/torch.zip)
endif()

list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/deps/dynamic/libtorch")
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/deps/dynamic/libtorch/share/cmake/Torch")


find_package(Torch REQUIRED)

# Build a shared library named after the project from the files in `src/`
file(GLOB SOURCE_FILES "src/*.cc" "src/*.h")

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})

# Gives our library file a .node extension without any "lib" prefix
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")

# Essential include files to build a node addon,
# You should add this line in every CMake.js based project
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_JS_INC})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

# message(STATUS "Using Napi At ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api")
# Include N-API wrappers
# target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api" "src" )

# Libtorch
target_link_libraries(${PROJECT_NAME} ${TORCH_LIBRARIES})


# Essential library files to link to a node addon
# You should add this line in every CMake.js based project
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})


if (MSVC)
  file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
  add_custom_command(TARGET ${PROJECT_NAME}
                     POST_BUILD
                     COMMAND ${CMAKE_COMMAND} -E copy_if_different
                     ${TORCH_DLLS}
                     $<TARGET_FILE_DIR:${PROJECT_NAME}>)
endif (MSVC)

It only works when I uncomment # target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api" "src" )
But that does not when I try to install the module elsewhere.
This is the repository https://github.com/nodeml/torch

@TareHimself
Copy link
Author

I fixed it with this

 target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/node_modules/node-addon-api" "${CMAKE_SOURCE_DIR}/../../node-addon-api" "src" )

But is there a better way to handle this ?

@TareHimself
Copy link
Author

TareHimself commented Oct 10, 2023

Also while not related to the issue, Is it possible to have Native Package B, depend on Native Package A such that B can import and use all headers and such defined in A? Like in my case I have a torch package that has basic tensor operations and another package for torchvision. but I do not want to have to redefine tensors and all that and instead want to use what I already have done in the previous package.

@Julusian
Copy link
Collaborator

cmake-js attempts to find node-addon-api, and adds it to the CMAKE_JS_INC variable if it finds it. I don't know why it wouldn't be successful in doing so

Also while not related to the issue, Is it possible to have Native Package B, depend on Native Package A such that B can import and use all headers and such defined in A?

I'm not entirely following what you are asking, but probably. It sounds like a more general cmake question than something specific to this lib

@mmomtchev
Copy link

mmomtchev commented Feb 6, 2024

cmake-js does a very unusual check for if a module is using node-addon-api - based on the presence of:

  "binary": {
    "napi_versions": [
      7
    ]
  }

in package.json

If you include this property, it will correctly add the node-addon-api directory.

AFAIK, currently there is no such requirement for node-addon-api projects - but there seem to have been such an idea in the early days - napi-build-utils and @mapbox/node-pre-gyp both mention it.

Additionally, when cmake-js detects the presence of this napi_versions, it will also disable access to the low-level API - including uv.h. Normally a node-addon-api project is not supposed to access the low-level API - except for uv.h.

My proposal is to make it a little bit less intelligent. Always include the low-level API as retrieved from the remote server. And try to simply detect the presence of node_modules/node-addon-api and node_modules/nan. This will match the behavior of node-gyp.

@mmomtchev
Copy link

@TareHimself open a separate issue with this question, and I will share my experience on this matter, which does not have a simple solution. gdal-exprtk does this.

@remyjette
Copy link

cmake-js attempts to find node-addon-api, and adds it to the CMAKE_JS_INC variable if it finds it. I don't know why it wouldn't be successful in doing so

I was hitting this too, and figured out why by enabling --log-level silly and digging through the code a bit

If --directory is set to anything other than the package.json directory, it will fail

In my project, Node is only one of the many platforms we build for. Thus we have CMakeLists.txt in the root, and electron/package.json in a subfolder. Our build calls cmake-js --directory ../ to make this work.

The README says " -d, --directory specify CMake project's directory (where CMakeLists.txt located)` - it doesn't say package.json has to be in the same directory as the CMakeLists.txt (if it did I'm not sure why this option would exist). It also doesn't say where the directory needs to be in relation to the package.json, which is why my understanding is putting CMakeLists.txt in a parent dir should work.

this.options.isNodeApi = isNodeApi(this.log, this.options.directory) passes that directory to isNodeApi

isNode Api does

const tmpRequire = require('module').createRequire(path.join(projectRoot, 'package.json'))

<projectRoot>/package.json doesnt exist for me, my package.json is in <projectRoot>/electron/package.json, so this fails

@TareHimself
Copy link
Author

TareHimself commented Mar 6, 2024

I was missing node.lib this is the fixed CMakeList https://github.com/nodeml/torch/blob/main/CMakeLists.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants