Skip to content

Commit

Permalink
Add Python (#1268)
Browse files Browse the repository at this point in the history
* Add Python

* Python packaging fix for Windows
  • Loading branch information
fcollot authored Dec 19, 2024
1 parent 9f9b988 commit fca1145
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 6 deletions.
4 changes: 4 additions & 0 deletions packaging/apple/mac_packager.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ done

@dtk_DIR@/bin/dtkDeploy medInria.app $injectDirs &>/dev/null

@CMAKE_COMMAND@ --install @pyncpp_ROOT@ --prefix . --component Runtime
mkdir medInria.app/Contents/Resources/lib
mv lib/python@PYTHON_VERSION_MAJOR@.@PYTHON_VERSION_MINOR@ medInria.app/Contents/Resources/lib

#Run fancy packaging apple script

\cp -f @medInria_SOURCE_DIR@/utils/osx_packaging/BaseMedinriaPackage.sparseimage.gz @PROJECT_BINARY_DIR@/MedinriaPackage.sparseimage.gz
Expand Down
15 changes: 10 additions & 5 deletions packaging/linux/LinuxPackaging.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,16 @@ set(backup_CPACK_INSTALL_CMAKE_PROJECTS ${CPACK_INSTALL_CMAKE_PROJECTS} ${CMAKE_

#clear it
set(CPACK_INSTALL_CMAKE_PROJECTS "")
foreach(external_project ${external_projects})
if(NOT USE_SYSTEM_${external_project} AND BUILD_SHARED_LIBS_${external_project})
ExternalProject_Get_Property(${external_project} binary_dir)
set(CPACK_INSTALL_CMAKE_PROJECTS ${CPACK_INSTALL_CMAKE_PROJECTS} ${binary_dir} ${external_project} ALL "/")
endif()
foreach(external_project ${external_projects})
if(NOT USE_SYSTEM_${external_project}
AND BUILD_SHARED_LIBS_${external_project}
AND DEFINED ${external_project}_ROOT)
install(CODE "
execute_process(
COMMAND ${CMAKE_COMMAND} --install ${${external_project}_ROOT} --prefix \"\${CMAKE_INSTALL_PREFIX}\"
)
")
endif()
endforeach()

foreach(dir ${PRIVATE_PLUGINS_DIRS})
Expand Down
6 changes: 5 additions & 1 deletion packaging/windows/WindowsPackaging.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ list(APPEND
${DCMTK_ROOT}/bin/${CONFIG_MODE}
)


install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} --install ${pyncpp_ROOT} --prefix \"\${CMAKE_INSTALL_PREFIX}\" --component Runtime)" COMPONENT Runtime)

install(CODE "
file(GLOB_RECURSE itk_files LIST_DIRECTORIES true \"${ITK_ROOT}/bin/*.dll\")
Expand All @@ -139,6 +142,7 @@ endforeach()
file(INSTALL ${MEDINRIA_FILES}/ DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/ FILES_MATCHING PATTERN \"*${CMAKE_EXECUTABLE_SUFFIX}\")
file(INSTALL ${MEDINRIA_FILES}/ DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/ FILES_MATCHING PATTERN \"*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
file(INSTALL ${MEDINRIA_FILES}/ DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/ FILES_MATCHING PATTERN \"*.pyd\")
file(INSTALL ${QT_PLUGINS_DIR}/imageformats/qgif.dll DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/imageformats/ FILES_MATCHING PATTERN \"*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
file(INSTALL ${QT_PLUGINS_DIR}/imageformats/qicns.dll DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/imageformats/ FILES_MATCHING PATTERN \"*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
file(INSTALL ${QT_PLUGINS_DIR}/imageformats/qico.dll DESTINATION \${CMAKE_INSTALL_PREFIX}/bin/imageformats/ FILES_MATCHING PATTERN \"*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
Expand Down Expand Up @@ -206,4 +210,4 @@ if(${SDK_PACKAGING} )
else()
message("No folder ${SDK_DIR} exists. SDK will not be installed.")
endif()
endif()
endif()
9 changes: 9 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ option(USE_FFmpeg
)
endif()

option(USE_Python
"Build with Python support"
ON
)

## #############################################################################
## Find package
## #############################################################################
Expand All @@ -103,6 +108,10 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS

find_package(dtk REQUIRED)

if(USE_Python)
find_package(pyncpp REQUIRED COMPONENTS CPP_API Qt5)
endif()

## #############################################################################
## enable c++ 17
## #############################################################################
Expand Down
35 changes: 35 additions & 0 deletions src/app/medInria/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,41 @@ target_link_libraries(${TARGET_NAME} PRIVATE
med::CoreGui
)

## #############################################################################
## Python
## #############################################################################

if(USE_Python)
target_link_libraries(${TARGET_NAME} PUBLIC ${pyncpp_CPP_API_LIBRARY})

if(APPLE)
set(python_home "../Resources")
else()
set(python_home "..")
endif()

set(python_home "${python_home}/${pyncpp_PYTHON_INSTALL_DESTINATION}")

if(APPLE)
set(python_plugin_path "../Plugins/python")
else()
set(python_plugin_path "python_plugins")
endif()

target_compile_definitions(${TARGET_NAME} PUBLIC
USE_PYTHON
PYTHON_HOME="${python_home}"
PYTHON_PLUGIN_PATH="${python_plugin_path}"
BUILD_PYTHON_HOME="${pyncpp_PYTHON_DIR}"
BUILD_PYTHON_PLUGIN_PATH="${CMAKE_BINARY_DIR}/bin/python_plugins"
)

if(WIN32)
target_compile_definitions(${TARGET_NAME} PUBLIC
PLUGINS_LEGACY_PATH="plugins_legacy"
)
endif()
endif()

## #############################################################################
## install
Expand Down
95 changes: 95 additions & 0 deletions src/app/medInria/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@

#include<medFirstStart.h>

#ifdef USE_PYTHON
#include <pyncpp.h>
#endif

void forceShow(medMainWindow &mainwindow)
{
// Idea and code taken from the OpenCOR project, Thanks Allan for the code!
Expand Down Expand Up @@ -181,6 +185,89 @@ int main(int argc, char *argv[])
if (runningMedInria)
return 0;

#ifdef USE_PYTHON
pyncpp::Manager pythonManager;
QString pythonHomePath = PYTHON_HOME;
QDir applicationPath = qApp->applicationDirPath();
QDir pythonHome = applicationPath;
QDir pythonPluginPath = pythonHome;
bool pythonHomeFound = false;
bool pythonPluginsFound = false;
QString pythonErrorMessage;

if (pythonHome.cd(PYTHON_HOME))
{
pythonHomeFound = true;
pythonPluginsFound = pythonPluginPath.cd(PYTHON_PLUGIN_PATH);
}
else
{
if (pythonHome.cd(BUILD_PYTHON_HOME))
{
pythonHomeFound = true;
pythonPluginsFound = pythonPluginPath.cd(BUILD_PYTHON_PLUGIN_PATH);
}
}

if (!pythonHomeFound)
{
pythonErrorMessage = "The embedded Python could not be found ";
}
else
{
if(!pythonManager.initialize(qUtf8Printable(pythonHome.absolutePath())))
{
pythonErrorMessage = "Initialization of the embedded Python failed.";
}
else
{
if (pythonPluginsFound)
{
try
{
pyncpp::Module sysModule = pyncpp::Module::import("sys");
pyncpp::Object sysPath = sysModule.attribute("path");
sysPath.append(pyncpp::Object(pythonPluginPath.absolutePath()));
qInfo() << "Added Python plugin path: " << pythonPluginPath.path();

#ifdef Q_OS_WIN
QDir sitePackages = pythonHome;

if (sitePackages.cd("lib/site-packages"))
{
sysPath.append(pyncpp::Object(sitePackages.absolutePath()));
}
else
{
pythonErrorMessage = "Cannot find site directory.";
}

pyncpp::Module osModule = pyncpp::Module::import("os");
osModule.callMethod("add_dll_directory", applicationPath.absolutePath());
qInfo() << "Added Python DLL path: " << applicationPath.path();

QDir pluginsLegacyPath = applicationPath;

if (pluginsLegacyPath.cd(PLUGINS_LEGACY_PATH))
{
osModule.callMethod("add_dll_directory", pluginsLegacyPath.absolutePath());
qInfo() << "Added Python DLL path: " << pluginsLegacyPath.path();
}
else
{
pythonErrorMessage = "Could not find legacy plugins path.";
}
#endif // Q_OS_WIN
}
catch (pyncpp::Exception& e)
{
pythonErrorMessage = e.what();
}
}
}
}
#endif // USE_PYTHON

QNetworkAccessManager *qnam = new QNetworkAccessManager(&application);
medFirstStart firstStart(qnam);
firstStart.pushPathToCheck(medSourcesLoader::path(), ":/configs/DataSourcesDefault.json", "dataSourceLoader", "", medSourcesLoader::initSourceLoaderCfg);
Expand Down Expand Up @@ -291,6 +378,14 @@ int main(int argc, char *argv[])
QGLFormat::setDefaultFormat(format);
}

#ifdef USE_PYTHON
if(!pythonErrorMessage.isEmpty())
{
qWarning() << "(Python error) " << pythonErrorMessage;
QMessageBox::warning(mainwindow, "Python error", pythonErrorMessage);
}
#endif

if (medPluginManager::instance()->plugins().isEmpty())
{
QMessageBox::warning(
Expand Down
18 changes: 18 additions & 0 deletions superbuild/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#
################################################################################

option(USE_Python "Build with Python support" ON)

## #############################################################################
## Add packages
## #############################################################################
Expand All @@ -28,6 +30,16 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS
Quick
)

if (USE_Python AND UNIX)
if(APPLE)
set(default_root_dir "/usr/local/opt/openssl")
else()
set(default_root_dir)
endif()
set(OPENSSL_ROOT_DIR ${default_root_dir} CACHE PATH "Root directory of OpenSSL.")
find_package(OpenSSL COMPONENTS SSL)
endif()

## #############################################################################
## Add exteral projects
## #############################################################################
Expand Down Expand Up @@ -71,6 +83,12 @@ if (USE_DTKIMAGING)
)
endif()

if (USE_Python)
list(APPEND external_projects
pyncpp
)
endif()

list(APPEND external_projects
medInria
)
Expand Down
12 changes: 12 additions & 0 deletions superbuild/projects_modules/medInria.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ if (USE_DTKIMAGING)
dtkImaging
)
endif()

if (USE_Python)
list(APPEND ${ep}_dependencies
pyncpp
)
endif()

## #############################################################################
## Prepare the project
Expand Down Expand Up @@ -107,6 +113,12 @@ if (USE_DTKIMAGING)
-DdtkImaging_DIR:PATH=${dtkImaging_DIR}
)
endif()

if (USE_Python)
list(APPEND cmake_cache_args
-Dpyncpp_ROOT:PATH=${pyncpp_ROOT}
)
endif()

## #############################################################################
## Add external-project
Expand Down
78 changes: 78 additions & 0 deletions superbuild/projects_modules/pyncpp.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
################################################################################
#
# medInria
#
# Copyright (c) INRIA 2024. All rights reserved.
# See LICENSE.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.
#
################################################################################

set(PYTHON_VERSION_MAJOR 3 CACHE STRING "Python major version")
set(PYTHON_VERSION_MINOR 10 CACHE STRING "Python minor version")
set(PYTHON_VERSION_PATCH 10 CACHE STRING "Python patch version")

function(pyncpp_project)

set(ep pyncpp)

EP_Initialisation(${ep}
USE_SYSTEM OFF
BUILD_SHARED_LIBS ON
REQUIRED_FOR_PLUGINS ON
)

if(NOT USE_SYSTEM_${ep})

epComputPath(${ep})

set(project_args
GIT_REPOSITORY ${GITHUB_PREFIX}LIRYC-IHU/pyncpp.git
GIT_TAG 0.1.x
GIT_SHALLOW True
GIT_PROGRESS True
)

set(cmake_args
${ep_common_cache_args}
-D "PYNCPP_PYTHON_VERSION_MAJOR:STRING=${PYTHON_VERSION_MAJOR}"
-D "PYNCPP_PYTHON_VERSION_MINOR:STRING=${PYTHON_VERSION_MINOR}"
-D "PYNCPP_PYTHON_VERSION_PATCH:STRING=${PYTHON_VERSION_PATCH}"
-D "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE_ExtProjs}"
)

if(UNIX)
list(APPEND cmake_args
-D Qt5_DIR:PATH=${Qt5_DIR}
-D OPENSSL_ROOT_DIR:PATH=${OPENSSL_ROOT_DIR}
)
endif()

## #####################################################################
## Add external project
## #####################################################################

ExternalProject_Add(${ep}
PREFIX ${EP_PATH_SOURCE}
SOURCE_DIR ${EP_PATH_SOURCE}/${ep}
BINARY_DIR ${build_path}
TMP_DIR ${tmp_path}
STAMP_DIR ${stamp_path}
DEPENDS ${${ep}_dependencies}
CMAKE_ARGS ${cmake_args}
INSTALL_COMMAND ""
"${project_args}"
)

## #####################################################################
## Export variables
## #####################################################################

set(${ep}_ROOT "${build_path}" PARENT_SCOPE)

endif()

endfunction()

0 comments on commit fca1145

Please sign in to comment.