scikit-build/scikit-build-core

Double dot added before pyd extension when building swig based python module

Closed this issue · 8 comments

When building a swig based python module that calls a library developed in C++, the following files are created inside the generated .whl file:

As a result, python cannot find _myModule..pyd due to the extra dot. Maually deleting it fixes this problem

This doesn't always happen, just occasionally. Do you know what could be causing it?

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15...3.26)
set (CMAKE_CXX_STANDARD 20)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX)

add_library(subLib STATIC IMPORTED)
set_target_properties(subLib PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/subLib/"
    IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/subLib/Build/Release/myModule_subLib.lib"
    #INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:myModule_subLib>"
)


find_package(
  Python
  COMPONENTS Interpreter Development.SABIModule ${SKBUILD_SABI_COMPONENT}
  REQUIRED)

find_package(
  SWIG
  COMPONENTS python
  REQUIRED)

find_package(OpenCV)
find_package(Boost)
find_package(easyloggingpp)
find_package(OpenCV-SWIG REQUIRED)
find_package(ssp)
find_package(vincentlaucsb-csv-parser)

include_directories(${CMAKE_SOURCE_DIR}/subLib/)

include(UseSWIG)


set_property(SOURCE interface.i PROPERTY CPLUSPLUS ON)

swig_add_library(
  myModule
  LANGUAGE python OUTPUT_DIR "${SKBUILD_PLATLIB_DIR}"
  SOURCES interface.i include/main.hpp src/main.cpp)
  set(Python_SOABI ${SKBUILD_SOABI})
set_property(TARGET myModule PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
set_property(
  TARGET myModule
  PROPERTY SWIG_INCLUDE_DIRECTORIES
    ${OpenCV-SWIG_INCLUDE_DIRS}
)
#set_property(TARGET myModule PROPERTY SWIG_COMPILE_OPTIONS -DPy_LIMITED_API)
target_include_directories(myModule PRIVATE include src ${CMAKE_CURRENT_SOURCE_DIR} ${Python_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
#set_property(TARGET myModule PROPERTY SWIG_INCLUDE_DIRECTORIES ./include/ ./src/)
if(WIN32)
  set_property(TARGET myModule PROPERTY SUFFIX ".${SKBUILD_SOSABI}.pyd")
else()
  set_property(TARGET myModule
               PROPERTY SUFFIX ".${SKBUILD_SOSABI}${CMAKE_SHARED_MODULE_SUFFIX}")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  target_link_libraries(myModule PRIVATE Python::SABIModule opencv::opencv boost::boost easyloggingpp::easyloggingpp ssp::ssp vincentlaucsb-csv-parser::vincentlaucsb-csv-parser ${PROJECT_SOURCE_DIR}/subLib/Build/Release/myModule_subLib.a tbb)
  target_compile_options(myModule PRIVATE -Wall -Wextra -Wpedantic -Werror -DPARALLEL)
else()
  target_link_libraries(myModule PRIVATE Python::SABIModule opencv::opencv boost::boost easyloggingpp::easyloggingpp ssp::ssp vincentlaucsb-csv-parser::vincentlaucsb-csv-parser ${PROJECT_SOURCE_DIR}/subLib/Build/Release/myModule_subLib.lib)
${CMAKE_SOURCE_DIR}/subLib/Build/Release/myModule_subLib
endif()
install(TARGETS myModule DESTINATION .)

pyproject.toml:

[build-system]
requires = ["scikit-build-core >= 0.9.4", "swig >= 4.2.1", "cibuildwheel"]
build-backend = "scikit_build_core.build"

[tool.scikit-build]
wheel.py-api = "cp37"
sdist.cmake = true
cmake.version = ">=3.23"
cmake.build-type = "Release"
cmake.args = ["--preset conan-release", "-G Ninja", "-DOpenCV-SWIG_ROOT=./extlibs/opencv-swig/install"]

[[tool.scikit-build.overrides]]
if.platform-system = "win32"
cmake.args = ["--preset conan-default", "-DLF=...Windows.locks", "-DOpenCV-SWIG_ROOT=./extlibs/opencv-swig/install"]

[[tool.cibuildwheel.overrides]]
select = "cp37-win_amd64"

[project]
name = "myModule"
version = "1.0.0"
requires-python = ">=3.7"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

Fixed by changing set_property(TARGET myModule PROPERTY SUFFIX ".${SKBUILD_SOSABI}.pyd") to set_property(TARGET myModule PROPERTY SUFFIX ".${SKBUILD_SOSABI}pyd").

Apparently, sometimes double dot was detected during build and corrected, while other times it failed (that line was copied from scikit-build-core documentation)

Wouldn't it be "${SKBUILD_SOSABI}.pyd"? That variable shouldn't end in a dot. Edit: Actually, it doesn't have a dot at all.

Actually, there's also a typo too, it's SKBUILD_SOABI.

It's not a typo. SKBUILD_SOSABI corresponds to python abi3 (python's limited API that ensures compatibility with future versions)

Wouldn't it be "${SKBUILD_SOSABI}.pyd"? That variable shouldn't end in a dot. Edit: Actually, it doesn't have a dot at all.

Thanks, that's another typo

There is no SKBUILD_SOSABI, though? SKBUILD_SOABI is provided since Python_SOABI isn't always correct when cross compiling. Since SKBUILD_SOSABI is always empty (undefined), that's why you have a double dot.

If you do need it, string(JOIN "." ...) would put these together properly. But there is no SKBUILD_SOSABI variable.

There is no SKBUILD_SOSABI, though? SKBUILD_SOABI is provided since Python_SOABI isn't always correct when cross compiling. Since SKBUILD_SOSABI is always empty (undefined), that's why you have a double dot.

Thanks, that line was copied from an example in which it was used. Now that double dot makes sense