wjakob / nanobind

nanobind: tiny and efficient C++/Python bindings
BSD 3-Clause "New" or "Revised" License
2.14k stars 161 forks source link

[BUG]: importing my_ext fails with "ModuleNotFoundError: No module named 'my_ext'" on Windows #517

Closed nurpax closed 2 months ago

nurpax commented 2 months ago

Problem description

Following the docs in https://nanobind.readthedocs.io/en/latest/basics.html, I created a directory with the following files:

CMakeLists.txt
my_ext.cpp

I followed the docs to build it. It builds fine but import fails:

C:\Users\janne\dev\nbtest>cmake -S . -B build
C:\Users\janne\dev\nbtest>cmake --build build
C:\Users\janne\dev\nbtest>cd build

C:\Users\janne\dev\nbtest\build>python
Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_ext
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'my_ext'```

However, it works if I cd into build\Debug instead:

C:\Users\janne\dev\nbtest\build>cd debug

C:\Users\janne\dev\nbtest\build\Debug>python
Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_ext
>>> my_ext.add(3,5)
8
>>>

Not sure if this happens only on Windows but it wasn't immediately obvious what the problem is.

Perhaps this could be called out in the docs?

Reproducible example code

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15...3.27)
project(my_ext) # Replace 'my_project' with the name of your project
find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED)

if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

# Detect the installed nanobind package and import it into CMake
execute_process(
  COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
  OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NB_DIR)
list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")
find_package(nanobind CONFIG REQUIRED)

nanobind_add_module(my_ext my_ext.cpp)

my_ext.cpp:

#include <nanobind/nanobind.h>

int add(int a, int b) { return a + b; }

NB_MODULE(my_ext, m) {
    m.def("add", &add);
}
wjakob commented 2 months ago

This is not a nanobind issue. CMake places extensions into configuration-specific subdirectories in MSVC builds.

nurpax commented 2 months ago

I meant the issue as an enhancement idea for docs, not a bug in nanobind. But no problem, now I know where to start the Python interpreter.

wjakob commented 2 months ago

Could you make a PR with the desired change to the documentation in this case?