diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index bf7ecb65..260264b8 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -11,6 +11,31 @@ if(HDE_COMPILE_PYTHON_BINDINGS) "Do you want HDE to detect and use the active site-package directory? (it could be a system dir)" FALSE) + # Function to generate __init__.py file for both hde and wearables + # It contains logic to ensure that it works fine on Windows when installing in arbitrary folders, + # See https://docs.python.org/3.8/library/os.html#os.add_dll_directory + function(hde_generate_init_py_file GENERATION_LOCATION_OF_INIT_PY_FILE INSTALLATION_LOCATION_OF_INIT_PY_FILE) + file(WRITE ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "") + if(WIN32 AND BUILD_SHARED_LIBS) + if(IS_ABSOLUTE ${INSTALLATION_LOCATION_OF_INIT_PY_FILE}) + set(PYTHON_FULL_INSTDIR "${INSTALLATION_LOCATION_OF_INIT_PY_FILE}") + else() + set(PYTHON_FULL_INSTDIR "${CMAKE_INSTALL_PREFIX}/${INSTALLATION_LOCATION_OF_INIT_PY_FILE}") + endif() + file(RELATIVE_PATH RELATIVE_PATH_BETWEEN_INIT_PY_AND_DLL_DIRECTORY ${PYTHON_FULL_INSTDIR} ${CMAKE_INSTALL_FULL_BINDIR}) + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "import os\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "library_dll_path = os.path.join(os.path.dirname(__file__),'${RELATIVE_PATH_BETWEEN_INIT_PY_AND_DLL_DIRECTORY}')\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "# Avoid to call add_dll_directory if not necessary,\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "# for example if the library to find are already found in the proper location in a conda\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "if(library_dll_path != os.path.join(os.environ.get('CONDA_PREFIX', ''),'Library','bin') and library_dll_path != os.path.join(os.environ.get('CONDA_PREFIX', ''),'bin')):\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py " if(os.path.exists(library_dll_path)):\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py " os.add_dll_directory(library_dll_path)$\n") + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "\n") + endif() + + file(APPEND ${GENERATION_LOCATION_OF_INIT_PY_FILE}/__init__.py "from .bindings import *\n") + endfunction() + # Install the resulting Python package for the active interpreter if(NOT DEFINED HDE_PYTHON_INSTALL_DIR) if(HDE_DETECT_ACTIVE_PYTHON_SITEPACKAGES) diff --git a/bindings/python-hde/CMakeLists.txt b/bindings/python-hde/CMakeLists.txt index 601ba94e..a4adc190 100644 --- a/bindings/python-hde/CMakeLists.txt +++ b/bindings/python-hde/CMakeLists.txt @@ -40,9 +40,7 @@ set_target_properties(pybind11_hde PROPERTIES install(TARGETS pybind11_hde DESTINATION ${PYTHON_INSTDIR}) # Create the __init__.py file -file(GENERATE - OUTPUT "${HDE_PYTHON_PACKAGE}/__init__.py" - CONTENT "from .bindings import *\n") +hde_generate_init_py_file("${HDE_PYTHON_PACKAGE}" "${PYTHON_INSTDIR}") # Install the __init__.py file install(FILES "${HDE_PYTHON_PACKAGE}/__init__.py" DESTINATION ${PYTHON_INSTDIR}) diff --git a/bindings/python-wearables/CMakeLists.txt b/bindings/python-wearables/CMakeLists.txt index b6ebb756..6fbe792a 100644 --- a/bindings/python-wearables/CMakeLists.txt +++ b/bindings/python-wearables/CMakeLists.txt @@ -39,9 +39,7 @@ set_target_properties(pybind11_wearables PROPERTIES install(TARGETS pybind11_wearables DESTINATION ${PYTHON_INSTDIR}) -file(GENERATE - OUTPUT "${WEARABLES_PYTHON_PACKAGE}/__init__.py" - CONTENT "from .bindings import *\n") +hde_generate_init_py_file("${WEARABLES_PYTHON_PACKAGE}" "${PYTHON_INSTDIR}") # Install the __init__.py file install(FILES "${WEARABLES_PYTHON_PACKAGE}/__init__.py" DESTINATION ${PYTHON_INSTDIR})