diff --git a/CMakeLists.txt b/CMakeLists.txt index 84b5bf5454..04586dd05c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,9 @@ cmake_policy(SET CMP0077 NEW) # ``option()`` honors normal variables. cmake_policy(SET CMP0080 NEW) # ``BundleUtilities`` cannot be included at configure time. # The ``FindPythonInterp`` and ``FindPythonLibs`` modules are removed. -# if(CMAKE_VERSION VERSION_GREATER "3.27.0") -# cmake_policy(SET CMP0148 NEW) -# endif() +if(CMAKE_VERSION VERSION_GREATER "3.27.0") + cmake_policy(SET CMP0148 NEW) +endif() # resolves symlinks before collapsing ../ components. if(CMAKE_VERSION VERSION_GREATER "3.28.0") @@ -18,9 +18,9 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/cmake/Utility.cmake) # ------------------------------------------------------------------------------ -# Is this a commercial or Free build +# Are we embedding Python # ------------------------------------------------------------------------------ -option(SIMPLNX_BUILD_PYTHON "Enable building Python building" OFF) +option(SIMPLNX_BUILD_PYTHON "Enable building Python bindings" OFF) include(CMakeDependentOption) cmake_dependent_option(SIMPLNX_EMBED_PYTHON "Embeds python interpreter in nxrunner" ON "SIMPLNX_BUILD_PYTHON" OFF) enable_vcpkg_manifest_feature(TEST_VAR SIMPLNX_BUILD_PYTHON FEATURE "python") @@ -178,6 +178,20 @@ else() set(SIMPLNX_PIPELINE_INSTALL_DIR "pipelines") endif() +# ------------------------------------------------------------------------------ +# Find Python if needed +# ------------------------------------------------------------------------------ +if(SIMPLNX_BUILD_PYTHON) + message(STATUS "/***************** Finding Python 3 Interpreter ${CMAKE_CURRENT_LIST_FILE}/") + find_package(Python3 REQUIRED COMPONENTS Interpreter Development) + message(STATUS "/**************************************************************/") + + message(STATUS "/***************** Finding PyBind11 ${CMAKE_CURRENT_LIST_FILE}/") + find_package(pybind11 2.10.0 CONFIG REQUIRED) + message(STATUS "/**************************************************************/") +endif() + + # ----------------------------------------------------------------------- # Find dependent libraries # ----------------------------------------------------------------------- @@ -816,7 +830,7 @@ list(APPEND SIMPLNX_GENERATED_HEADERS # Generate Python-Bindings Supporting Files set(SIMPLNX_GENERATED_PYTHON_HEADER ${SIMPLNX_GENERATED_HEADER_DIR}/SimplnxPython.hpp) set(SIMPLNX_PYTHON_MODULE "simplnx") -configure_file(${simplnx_SOURCE_DIR}/wrapping/python/CxPybind/SimplnxPython.hpp.in ${SIMPLNX_GENERATED_PYTHON_HEADER}) +configure_file(${simplnx_SOURCE_DIR}/wrapping/python/NxPybind/SimplnxPython.hpp.in ${SIMPLNX_GENERATED_PYTHON_HEADER}) list(APPEND SIMPLNX_GENERATED_HEADERS ${SIMPLNX_GENERATED_PYTHON_HEADER} diff --git a/cmake/Summary.cmake b/cmake/Summary.cmake index cee7d72b39..7ff278255d 100644 --- a/cmake/Summary.cmake +++ b/cmake/Summary.cmake @@ -76,7 +76,7 @@ message(STATUS "* DREAM3D_DATA_DIR: ${DREAM3D_DATA_DIR}") message(STATUS "* -------------- Simplnx Python Configuration Options -------------------------------------") message(STATUS "* Pybind11 (${pybind11_VERSION}) ${pybind11_DIR}") message(STATUS "* Python3_EXECUTABLE: ${Python3_EXECUTABLE}") -message(STATUS "* PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}") +# message(STATUS "* PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}") message(STATUS "* SIMPLNX_BUILD_PYTHON: ${SIMPLNX_BUILD_PYTHON}") message(STATUS "* SIMPLNX_BUILD_PYTHON_DOCS: ${SIMPLNX_BUILD_PYTHON_DOCS}") message(STATUS "* SIMPLNX_BUILD_PYTHON_TESTS: ${SIMPLNX_BUILD_PYTHON_TESTS}") diff --git a/cmake/Utility.cmake b/cmake/Utility.cmake index fbe032d09a..c2f7359b7b 100644 --- a/cmake/Utility.cmake +++ b/cmake/Utility.cmake @@ -493,7 +493,8 @@ function(AddPythonTest) PROPERTY ENVIRONMENT "PYTHON_TEST_FILE=${ARGS_FILE}" - "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" + # "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" + "Python3_EXECUTABLE=${Python3_EXECUTABLE}" ) else() add_test(NAME ${ARGS_NAME} diff --git a/src/Plugins/ITKImageProcessing/CMakeLists.txt b/src/Plugins/ITKImageProcessing/CMakeLists.txt index 239bda2a10..2ab2885e02 100644 --- a/src/Plugins/ITKImageProcessing/CMakeLists.txt +++ b/src/Plugins/ITKImageProcessing/CMakeLists.txt @@ -49,7 +49,7 @@ if(NOT GENERATOR_IS_MULTI_CONFIG) set_property(GLOBAL PROPERTY SIMPLNX_EXTRA_LIBRARY_DIRS ${SIMPLNX_EXTRA_LIBRARY_DIRS} ${ITK_LIB_DIR}) endif() -message(STATUS "* ITK (${ITK_VERSION}) ${ITK_DIR}") +message(STATUS "ITK (${ITK_VERSION}) ${ITK_DIR}") include("${simplnx_SOURCE_DIR}/cmake/Plugin.cmake") diff --git a/src/Plugins/ITKImageProcessing/wrapping/python/itkimageprocessing.cpp b/src/Plugins/ITKImageProcessing/wrapping/python/itkimageprocessing.cpp index 9b02688cb1..6b82e7cbc8 100644 --- a/src/Plugins/ITKImageProcessing/wrapping/python/itkimageprocessing.cpp +++ b/src/Plugins/ITKImageProcessing/wrapping/python/itkimageprocessing.cpp @@ -1,10 +1,10 @@ -#include +#include #include "ITKImageProcessing/ITKImageProcessingFilterBinding.hpp" #include "ITKImageProcessing/ITKImageProcessingPlugin.hpp" using namespace nx::core; -using namespace nx::core::CxPybind; +using namespace nx::core::NxPybind; namespace py = pybind11; PYBIND11_MODULE(itkimageprocessing, mod) diff --git a/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp b/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp index 7a1e0f0ada..3cfb55a5fc 100644 --- a/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp +++ b/src/Plugins/OrientationAnalysis/wrapping/python/orientationanalysis.cpp @@ -1,4 +1,4 @@ -#include +#include #include @@ -8,7 +8,7 @@ #include "OrientationAnalysis/OrientationAnalysisFilterBinding.hpp" using namespace nx::core; -using namespace nx::core::CxPybind; +using namespace nx::core::NxPybind; namespace py = pybind11; using namespace pybind11::literals; diff --git a/src/Plugins/SimplnxCore/wrapping/python/simplnxpy.cpp b/src/Plugins/SimplnxCore/wrapping/python/simplnxpy.cpp index 666528edaa..d243ec4613 100644 --- a/src/Plugins/SimplnxCore/wrapping/python/simplnxpy.cpp +++ b/src/Plugins/SimplnxCore/wrapping/python/simplnxpy.cpp @@ -1,4 +1,4 @@ -#include +#include #include @@ -92,7 +92,7 @@ #include using namespace nx::core; -using namespace nx::core::CxPybind; +using namespace nx::core::NxPybind; namespace py = pybind11; namespace fs = std::filesystem; diff --git a/src/nxrunner/CMakeLists.txt b/src/nxrunner/CMakeLists.txt index 4f093386ab..82bb5e658c 100644 --- a/src/nxrunner/CMakeLists.txt +++ b/src/nxrunner/CMakeLists.txt @@ -31,8 +31,6 @@ target_link_libraries(nxrunner PRIVATE simplnx::simplnx) source_group("nxrunner" FILES ${CLI_HDRS} ${CLI_SRCS}) if(SIMPLNX_EMBED_PYTHON) - find_package(pybind11 2.10.0 CONFIG REQUIRED) - target_link_libraries(nxrunner PRIVATE NxPythonEmbed diff --git a/wrapping/python/CMakeLists.txt b/wrapping/python/CMakeLists.txt index 1747bce751..9d3749f142 100644 --- a/wrapping/python/CMakeLists.txt +++ b/wrapping/python/CMakeLists.txt @@ -1,10 +1,8 @@ -find_package(pybind11 2.10.0 CONFIG REQUIRED) +add_library(NxPybind INTERFACE) -add_library(CxPybind INTERFACE) +target_include_directories(NxPybind INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/NxPybind) -target_include_directories(CxPybind INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/CxPybind) - -target_link_libraries(CxPybind +target_link_libraries(NxPybind INTERFACE simplnx pybind11::headers @@ -56,7 +54,7 @@ endif() target_link_libraries(simplnxpy PUBLIC SimplnxCore - CxPybind + NxPybind ) target_compile_options(simplnxpy @@ -236,7 +234,7 @@ function(simplnx_add_python_plugin) target_link_libraries(${PYTHON_MODULE_NAME} PUBLIC ${ARGS_PLUGIN_NAME} - CxPybind + NxPybind ) target_compile_definitions(${PYTHON_MODULE_NAME} PUBLIC PYBIND11_DETAILED_ERROR_MESSAGES) diff --git a/wrapping/python/CxPybind/CxPybind/CxPybind.hpp b/wrapping/python/NxPybind/NxPybind/NxPybind.hpp similarity index 96% rename from wrapping/python/CxPybind/CxPybind/CxPybind.hpp rename to wrapping/python/NxPybind/NxPybind/NxPybind.hpp index 90e183e01d..59bc7ca40c 100644 --- a/wrapping/python/CxPybind/CxPybind/CxPybind.hpp +++ b/wrapping/python/NxPybind/NxPybind/NxPybind.hpp @@ -1,29 +1,32 @@ #pragma once -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include +#if PYBIND11_HAS_NATIVE_ENUM +#include +#endif + #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -34,7 +37,7 @@ #define SIMPLNX_PY_BIND_CLASS_VARIADIC(scope, className, ...) pybind11::class_(scope, #className) #define SIMPLNX_PY_BIND_PARAMETER(scope, className) SIMPLNX_PY_BIND_CLASS_VARIADIC(scope, className, nx::core::IParameter) -namespace nx::core::CxPybind +namespace nx::core::NxPybind { namespace py = pybind11; @@ -111,11 +114,25 @@ std::string GetFixedPythonTypeCasterName() template std::string GetFullPythonName() { + using CasterT = py::detail::make_caster; // Use py::type::of for registered C++ types otherwise use py::detail::type_caster::name - if constexpr(std::is_base_of_v>) + if constexpr(std::is_base_of_v) { return GetRegisteredPythonTypeName(); } +#if PYBIND11_HAS_NATIVE_ENUM + else if constexpr(std::is_base_of_v, CasterT>) // Is registered enum + { + const std::type_info& typeInfo = typeid(T); + py::handle nativeEnumHandle = py::detail::global_internals_native_enum_type_map_get_item(typeInfo); + if(nativeEnumHandle) + { + return GetFullPythonNameFromType(nativeEnumHandle); + } + py::handle handle = py::detail::get_type_handle(typeInfo, true); + return GetFullPythonNameFromType(handle); + } +#endif else { return GetFixedPythonTypeCasterName(); @@ -751,4 +768,4 @@ void BindParameterConstructor(py::class_& object) object.def(py::init(), "name"_a, "human_name"_a, "help_text"_a, "default_value"_a); } -} // namespace nx::core::CxPybind +} // namespace nx::core::NxPybind diff --git a/wrapping/python/CxPybind/SimplnxPython.hpp.in b/wrapping/python/NxPybind/SimplnxPython.hpp.in similarity index 100% rename from wrapping/python/CxPybind/SimplnxPython.hpp.in rename to wrapping/python/NxPybind/SimplnxPython.hpp.in diff --git a/wrapping/python/ReadMe.md b/wrapping/python/ReadMe.md index 87b0f531fc..4da26da1e4 100644 --- a/wrapping/python/ReadMe.md +++ b/wrapping/python/ReadMe.md @@ -7,7 +7,7 @@ are developing new python bindings for `simplnx`. - cmake This directory holds various files used by CMake during the configuration of the python bindings -- CxPybind +- NxPybind This directory holds C++ implementation details for the python bindings - docs This directory holds the entirety of the python binding documentation diff --git a/wrapping/python/cmake/FilterBinding.cpp.in b/wrapping/python/cmake/FilterBinding.cpp.in index 5f30b2a9df..f62f3d5867 100644 --- a/wrapping/python/cmake/FilterBinding.cpp.in +++ b/wrapping/python/cmake/FilterBinding.cpp.in @@ -4,9 +4,9 @@ namespace nx::core::@PLUGIN_NAME@ { -void BindFilters(pybind11::handle scope, const nx::core::CxPybind::Internals& internals) +void BindFilters(pybind11::handle scope, const nx::core::NxPybind::Internals& internals) { - using namespace CxPybind; + using namespace NxPybind; @FILTER_BINDING_CODE@ } } // namespace nx::core diff --git a/wrapping/python/cmake/FilterBinding.hpp.in b/wrapping/python/cmake/FilterBinding.hpp.in index 73bbb31ebf..be690184d8 100644 --- a/wrapping/python/cmake/FilterBinding.hpp.in +++ b/wrapping/python/cmake/FilterBinding.hpp.in @@ -1,8 +1,8 @@ #pragma once -#include "CxPybind/CxPybind.hpp" +#include "NxPybind/NxPybind.hpp" namespace nx::core::@PLUGIN_NAME@ { -void BindFilters(pybind11::handle scope, const nx::core::CxPybind::Internals& internals); +void BindFilters(pybind11::handle scope, const nx::core::NxPybind::Internals& internals); } // namespace nx::core diff --git a/wrapping/python/testing/anaconda_test.bat b/wrapping/python/testing/anaconda_test.bat index a78040bd14..63c16617d9 100644 --- a/wrapping/python/testing/anaconda_test.bat +++ b/wrapping/python/testing/anaconda_test.bat @@ -4,7 +4,8 @@ :: echo "complex_CONDA_ENV: %complex_CONDA_ENV%" echo "PYTHON_TEST_FILE: %PYTHON_TEST_FILE%" echo "PYTHONPATH: %PYTHONPATH%" -echo "PYTHON_EXECUTABLE: %PYTHON_EXECUTABLE%" +:: echo "PYTHON_EXECUTABLE: %PYTHON_EXECUTABLE%" +echo "Python3_EXECUTABLE: %Python3_EXECUTABLE%" :: CALL "%complex_CONDA_EXECUTABLE%" activate "%complex_CONDA_ENV%" @@ -12,7 +13,7 @@ echo "PATH: %PATH%" :: echo "Where is Python: " :: where python.exe echo "Python Version: " -%PYTHON_EXECUTABLE% --version +%Python3_EXECUTABLE% --version if %errorlevel% neq 0 exit 1 -%PYTHON_EXECUTABLE% "%PYTHON_TEST_FILE%" +%Python3_EXECUTABLE% "%PYTHON_TEST_FILE%" diff --git a/wrapping/python/testing/anaconda_test.sh b/wrapping/python/testing/anaconda_test.sh index 4fc57f69d9..2fa7897e3d 100755 --- a/wrapping/python/testing/anaconda_test.sh +++ b/wrapping/python/testing/anaconda_test.sh @@ -4,7 +4,8 @@ # echo "complex_CONDA_ENV: $complex_CONDA_ENV" echo "PYTHON_TEST_FILE: $PYTHON_TEST_FILE" echo "PYTHONPATH: $PYTHONPATH" -echo "PYTHON_EXECUTABLE: $PYTHON_EXECUTABLE" +# echo "PYTHON_EXECUTABLE: $PYTHON_EXECUTABLE" +echo "Python3_EXECUTABLE: $Python3_EXECUTABLE" # echo "Sourcing $complex_ANACONDA_DIR/etc/profile.d/conda.sh" # source "$complex_ANACONDA_DIR"/etc/profile.d/conda.sh @@ -19,4 +20,4 @@ echo "PATH: $PATH" #PYTHONEXE=`which python` #echo "Python Version: " `${PYTHONEXE} --version` -${PYTHON_EXECUTABLE} "$PYTHON_TEST_FILE" +${Python3_EXECUTABLE} "$PYTHON_TEST_FILE"