Skip to content

Targeting multiple Python versions at once #748

Description

@thorink

Hi guys, I want to build a Python extension for different Python versions (2.7 and 3.5 for the moment) in one CMake run. The goal is to have multiple targets, one for each Python version.

In the main CMakeLists.txt I have the following:

set(bindings_python_version 2.7)
add_subdirectory(pythonbindingpythonbindings27)
set(bindings_python_version 3.5)
add_subdirectory(pythonbindingpythonbindings35)

I include my pythonbindings source directory two times. Inside I unset some cache variables, include pybind11 and add the extension target:

unset(PYTHONINTERP_FOUND CACHE)
unset(PYTHON_EXECUTABLE CACHE)
unset(PYTHON_VERSION_STRING CACHE)
unset(PYTHON_VERSION_MAJOR CACHE)
unset(PYTHON_VERSION_MINOR CACHE)
unset(PYTHON_VERSION_PATCH CACHE)
find_package(PythonInterp${preonpy_python_version})
unset(PYBIND11_INCLUDE_DIR CACHE)
unset(PYTHON_INCLUDE_DIRS CACHE)
unset(PYTHON_LIBRARIES CACHE)
unset(PYTHON_MODULE_PREFIX CACHE)
unset(PYTHON_MODULE_EXTENSION CACHE)
unset(PYTHON_LIBRARY CACHE)
set(PYBIND11_PYTHON_VERSION ${preonpy_python_version}CACHESTRING""FORCE)
add_subdirectory(pybind11${CMAKE_CURRENT_BINARY_DIR}/pybind11)
set(_target_name "_pyexttarget${bindings_python_version}")
add_library(${_target_name}MODULEmain.cpp)
target_include_directories(${_target_name}PRIVATE${PYBIND11_INCLUDE_DIR})
target_include_directories(${_target_name}PRIVATE${PYTHON_INCLUDE_DIRS})
set_target_properties(${_target_name} PROPERTIES PREFIX"${PYTHON_MODULE_PREFIX}"SUFFIX"${PYTHON_MODULE_EXTENSION}"OUTPUT_NAME"_pyexttarget")

For this to work I changed some code in the CMakeLists.txt of pybind11:

if (NOT (CMAKE_VERSIONVERSION_LESS 3.0)) # CMake >= 3.0set(target_name "module${PYBIND11_PYTHON_VERSION}")
# Build an interface library target:add_library(${target_name}INTERFACE)
target_include_directories(${target_name}INTERFACE $<BUILD_INTERFACE:${PYBIND11_INCLUDE_DIR}>
$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if (WIN32ORCYGWIN)
target_link_libraries(${target_name}INTERFACE $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
elseif (APPLE)
target_link_libraries(${target_name}INTERFACE"-undefined dynamic_lookup")
 endif ()
target_compile_options(${target_name}INTERFACE $<BUILD_INTERFACE:${PYBIND11_CPP_STANDARD}>)
add_library(pybind11::moduleALIAS${target_name}) # to match exported targetendif ()

Instead of creating a target named module I name it module2.7 or module3.5, depending on the targeted Python version.

This allows me to build my extension two times with a single make.

It now works for me, but actually I don't like it very much. I would like to have your opinions on this. Do you know some better ideas to archive the same? Would you like to have support for this use case in pybind11?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions