Skip to content

Commit

Permalink
Merge 79e61f8 into 76fbc4c
Browse files Browse the repository at this point in the history
  • Loading branch information
agarny committed Nov 21, 2019
2 parents 76fbc4c + 79e61f8 commit a402aa1
Show file tree
Hide file tree
Showing 148 changed files with 9,053 additions and 494 deletions.
153 changes: 153 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ option(USE_PREBUILT_OAUTH_PACKAGE "Use the pre-built version of the OAuth packag
option(USE_PREBUILT_OPENSSL_PACKAGE "Use the pre-built version of the OpenSSL package" ON)
option(USE_PREBUILT_PYTHON_PACKAGE "Use the pre-built version of the Python package" ON)
option(USE_PREBUILT_PYTHON_PACKAGES_PACKAGE "Use the pre-built version of various Python packages" ON)
option(USE_PREBUILT_PYTHONQT_PACKAGE "Use the pre-built version of the PythonQt package" ON)
option(USE_PREBUILT_QSCINTILLA_PACKAGE "Use the pre-built version of the QScintilla package" ON)
option(USE_PREBUILT_QWT_PACKAGE "Use the pre-built version of the Qwt package" ON)
option(USE_PREBUILT_SUNDIALS_PACKAGE "Use the pre-built version of the SUNDIALS package" ON)
Expand Down Expand Up @@ -617,6 +618,13 @@ set(I18N_QRC_FILENAME ${PROJECT_BUILD_DIR}/res/i18n.qrc)
configure_file(${CMAKE_SOURCE_DIR}/res/common.qrc.in ${COMMON_QRC_FILENAME})
configure_file(${CMAKE_SOURCE_DIR}/res/i18n.qrc.in ${I18N_QRC_FILENAME})

# The Python interface depends on Python headers, so we only include it if we
# are using the prebuilt version of our Python and QtWebKit packages

if(USE_PREBUILT_PYTHON_AND_QTWEBKIT_PACKAGES)
set(PYTHON_INTERFACE_FILENAME src/plugins/pythoninterface.cpp)
endif()

# Files that make up the GUI version of OpenCOR

set(SOURCES
Expand Down Expand Up @@ -645,6 +653,7 @@ set(SOURCES
src/plugins/plugininterface.cpp
src/plugins/pluginmanager.cpp
src/plugins/preferencesinterface.cpp
${PYTHON_INTERFACE_FILENAME}
src/plugins/solverinterface.cpp
src/plugins/viewinterface.cpp
src/plugins/windowinterface.cpp
Expand Down Expand Up @@ -682,6 +691,7 @@ if(WIN32)
src/plugins/plugininfo.cpp
src/plugins/plugininterface.cpp
src/plugins/pluginmanager.cpp
${PYTHON_INTERFACE_FILENAME}
src/plugins/solverinterface.cpp

src/windows/main.cpp
Expand Down Expand Up @@ -856,10 +866,19 @@ if(USE_PREBUILT_QTWEBKIT_PACKAGE)
if(USE_PREBUILT_PYTHON_PACKAGE)
# We are using the prebuilt version of our Python package, so build all
# our plugins
# Note: on Windows, it's technically very difficult, if not impossible,
# to get a debug version of our PythonConsole window, so we skip
# it in that case (see
# https://github.com/opencor/opencor/issues/1255#issuecomment-550605710)...

if(RELEASE_MODE OR NOT WIN32)
set(MISCELLANEOUS_PYTHONCONSOLEWINDOW miscellaneous/PythonConsoleWindow)
endif()

list(APPEND PLUGINS
thirdParty/libSBML
thirdParty/PythonPackages
thirdParty/PythonQt

dataStore/BioSignalMLDataStore
dataStore/CSVDataStore
Expand All @@ -877,6 +896,9 @@ if(USE_PREBUILT_QTWEBKIT_PACKAGE)
miscellaneous/Compiler
miscellaneous/Core
miscellaneous/HelpWindow
miscellaneous/JupyterKernel
${MISCELLANEOUS_PYTHONCONSOLEWINDOW}
miscellaneous/PythonShell
miscellaneous/WebBrowserWindow

organisation/FileBrowserWindow
Expand All @@ -896,6 +918,8 @@ if(USE_PREBUILT_QTWEBKIT_PACKAGE)
support/CellMLSupport
support/COMBINESupport
support/PMRSupport
support/PythonQtSupport
support/PythonSupport
support/SEDMLSupport
support/SimulationSupport
support/StandardSupport
Expand Down Expand Up @@ -953,6 +977,10 @@ if(USE_PREBUILT_QTWEBKIT_PACKAGE)
add_definitions(-DENABLE_TEST_PLUGINS)
endif()

# Let OpenCOR know that we want Python support

add_definitions(-DPYTHON_SUPPORT)

# Let OpenCOR know about the prebuilt version of our QtWebKit package
# being used

Expand Down Expand Up @@ -1018,6 +1046,7 @@ configure_clang_and_clang_tidy(${CMAKE_PROJECT_NAME})
if(WIN32)
target_link_libraries(${CMAKE_PROJECT_NAME}
${Qt5Core_QTMAIN_LIBRARIES}
${PYTHON_LIBRARY}
)
endif()

Expand All @@ -1027,6 +1056,28 @@ foreach(REQUIRED_QT_MODULE ${REQUIRED_QT_MODULES})
)
endforeach()

# We can't compile Python interface code until after the Python headers are in
# place

if(NOT "${PYTHON_DEPENDENCIES}" STREQUAL "")
add_dependencies(${CMAKE_PROJECT_NAME} ${PYTHON_DEPENDENCIES})
endif()

# On Linux, our Python package needs to be directly linked to OpenCOR otherwise
# Python extension DSOs can't find symbols
# Note: this is because the lookup scope changes for DSOs that are loaded using
# dlopen() (see https://www.akkadia.org/drepper/dsohowto.pdf)...

if(NOT WIN32 AND NOT APPLE)
include_directories(${PYTHON_INCLUDE_DIR})

target_link_libraries(${CMAKE_PROJECT_NAME}
${PYTHON_LIBRARY}
)

add_dependencies(${CMAKE_PROJECT_NAME} PythonPlugin)
endif()

# Build the CLI version of OpenCOR (Windows specific)
# Note: when it comes to WINDOWS_CLI_PROJECT_NAME, we used to have it set to
# ${CMAKE_PROJECT_NAME}.com, but Ninja found a duplicate rule (from a copy
Expand All @@ -1049,7 +1100,12 @@ if(WIN32)
target_link_libraries(${WINDOWS_CLI_PROJECT_NAME}
Qt5::Core
Qt5::Network
${PYTHON_LIBRARY}
)

if(NOT "${PYTHON_DEPENDENCIES}" STREQUAL "")
add_dependencies(${WINDOWS_CLI_PROJECT_NAME} ${PYTHON_DEPENDENCIES})
endif()
endif()

# Some post-processing specific stuff
Expand Down Expand Up @@ -1204,6 +1260,9 @@ else()
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
endif()

string(REPLACE "${PROJECT_BUILD_DIR}/" ""
RELATIVE_PYTHON_SCRIPT_DIR "${PYTHON_SCRIPT_DIR}")

if(WIN32)
# Select NSIS, if available, and ZIP as the packagers on Windows

Expand Down Expand Up @@ -1275,6 +1334,48 @@ if(WIN32)
install(FILES ${VBS_FILENAME}
DESTINATION .)

# Python runtime libraries and utilities

install(DIRECTORY ${PROJECT_BUILD_DIR}/Python
DESTINATION .)

# Batch files to setup and run Python and Jupyter
# Note: on Windows, it's technically very difficult, if not impossible, to
# get a debug version of any of our Jupyter-related scripts, so we
# skip them in that case (see
# https://github.com/opencor/opencor/issues/1255#issuecomment-550605710)...

if(RELEASE_MODE)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} ${RELATIVE_PYTHON_SCRIPT_DIR} runjupyter.bat)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} ${RELATIVE_PYTHON_SCRIPT_DIR} start_jupyter.py)

install(FILES ${PLATFORM_DISTRIB_DIR}/runjupyter.bat
${PLATFORM_DISTRIB_DIR}/start_jupyter.py
DESTINATION ${RELATIVE_PYTHON_SCRIPT_DIR})

set(JUPYTER_CONSOLE_FILENAME "${PROJECT_BUILD_DIR}/jupyterconsole.bat")

configure_file(${PLATFORM_DISTRIB_DIR}/jupyterconsole.bat.in ${JUPYTER_CONSOLE_FILENAME})
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyterlab.bat)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyterlab.vbs)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyternotebook.bat)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyternotebook.vbs)

install(FILES ${JUPYTER_CONSOLE_FILENAME}
${PLATFORM_DISTRIB_DIR}/jupyterlab.bat
${PLATFORM_DISTRIB_DIR}/jupyterlab.vbs
${PLATFORM_DISTRIB_DIR}/jupyternotebook.bat
${PLATFORM_DISTRIB_DIR}/jupyternotebook.vbs
DESTINATION .)
endif()

set(PYTHON_SHELL_FILENAME "${PROJECT_BUILD_DIR}/pythonshell.bat")

configure_file(${PLATFORM_DISTRIB_DIR}/pythonshell.bat.in ${PYTHON_SHELL_FILENAME})

install(FILES ${PYTHON_SHELL_FILENAME}
DESTINATION .)

# File type association
# Note: the calls to SHChangeNotify are to ensure that Windows refreshes
# file icons (so that it is clear to the user that an extension has
Expand Down Expand Up @@ -1320,6 +1421,29 @@ elseif(APPLE)
DESTINATION .
RENAME ${CMAKE_PROJECT_NAME}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

# Shell scripts to setup and run Python and Jupyter

set(RUN_JUPYTER_FILENAME ${PYTHON_SCRIPT_DIR}/runjupyter)

configure_file(${PLATFORM_DISTRIB_DIR}/runjupyter.in ${RUN_JUPYTER_FILENAME} @ONLY)

set(JUPYTER_CONSOLE_FILENAME ${PROJECT_BUILD_DIR}/jupyterconsole)
set(JUPYTER_LAB_FILENAME ${PROJECT_BUILD_DIR}/jupyterlab)
set(JUPYTER_NOTEBOOK_FILENAME ${PROJECT_BUILD_DIR}/jupyternotebook)
set(PYTHON_SHELL_FILENAME ${PROJECT_BUILD_DIR}/pythonshell)

configure_file(${PLATFORM_DISTRIB_DIR}/jupyterconsole.in ${JUPYTER_CONSOLE_FILENAME} @ONLY)
configure_file(${PLATFORM_DISTRIB_DIR}/jupyterlab.in ${JUPYTER_LAB_FILENAME} @ONLY)
configure_file(${PLATFORM_DISTRIB_DIR}/jupyternotebook.in ${JUPYTER_NOTEBOOK_FILENAME} @ONLY)
configure_file(${PLATFORM_DISTRIB_DIR}/pythonshell.in ${PYTHON_SHELL_FILENAME} @ONLY)

install(FILES ${JUPYTER_CONSOLE_FILENAME}
${JUPYTER_LAB_FILENAME}
${JUPYTER_NOTEBOOK_FILENAME}
${PYTHON_SHELL_FILENAME}
DESTINATION .
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
else()
# Select TGZ as the packager on Linux

Expand Down Expand Up @@ -1385,6 +1509,35 @@ else()
DESTINATION .
RENAME ${CMAKE_PROJECT_NAME}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

# Python runtime libraries and utilities

install(DIRECTORY ${PROJECT_BUILD_DIR}/python
DESTINATION .
USE_SOURCE_PERMISSIONS)

# Shell scripts to setup and run Python and Jupyter

copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} ${RELATIVE_PYTHON_SCRIPT_DIR} runjupyter)

install(FILES ${PLATFORM_DISTRIB_DIR}/runjupyter
DESTINATION ${RELATIVE_PYTHON_SCRIPT_DIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

set(JUPYTER_CONSOLE_FILENAME ${PROJECT_BUILD_DIR}/jupyterconsole)
set(PYTHON_SHELL_FILENAME ${PROJECT_BUILD_DIR}/pythonshell)

configure_file(${PLATFORM_DISTRIB_DIR}/jupyterconsole.in ${JUPYTER_CONSOLE_FILENAME} @ONLY)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyterlab)
copy_file_to_build_dir(DIRECT ${PLATFORM_DISTRIB_DIR} . jupyternotebook)
configure_file(${PLATFORM_DISTRIB_DIR}/pythonshell.in ${PYTHON_SHELL_FILENAME} @ONLY)

install(FILES ${JUPYTER_CONSOLE_FILENAME}
${PLATFORM_DISTRIB_DIR}/jupyterlab
${PLATFORM_DISTRIB_DIR}/jupyternotebook
${PYTHON_SHELL_FILENAME}
DESTINATION .
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()

# Specify the package file name, depending on whether we are generating a
Expand Down
14 changes: 11 additions & 3 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ macro(build_documentation DOCUMENTATION_NAME)
${PROJECT_BUILD_DIR}/doc/${DOCUMENTATION_NAME}
)

# Make our local target depend on having Python fully installed

add_dependencies(${DOCUMENTATION_BUILD} ${PYTHON_DEPENDENCIES})

# Make our local target depend on our project build target and make our
# documentation build target depend on our local target

Expand Down Expand Up @@ -187,6 +191,7 @@ macro(add_plugin PLUGIN_NAME)
EXTERNAL_BINARIES
SYSTEM_BINARIES
DEPENDS_ON
BYPRODUCTS
TESTS
)

Expand Down Expand Up @@ -276,8 +281,10 @@ macro(add_plugin PLUGIN_NAME)
endforeach()

# Create a custom target for copying external binaries
# Note: this is to prevent Ninja from getting confused with circular
# references...
# Note #1: this is to prevent Ninja from getting confused with circular
# references...
# Note #2: we use this target in the PythonQt build script when setting the
# PYTHON_DEPENDENCIES list...

if( NOT "${ARG_EXTERNAL_BINARIES_DIR}" STREQUAL ""
OR ( NOT "${ARG_EXTERNAL_SOURCE_DIR}" STREQUAL ""
Expand Down Expand Up @@ -380,7 +387,8 @@ macro(add_plugin PLUGIN_NAME)

add_custom_command(TARGET ${COPY_EXTERNAL_BINARIES_TARGET}
COMMAND ${CMAKE_COMMAND} -E copy_directory ${ARG_EXTERNAL_SOURCE_DIR}
${ARG_EXTERNAL_DESTINATION_DIR})
${ARG_EXTERNAL_DESTINATION_DIR}
BYPRODUCTS ${ARG_BYPRODUCTS})
endif()

# System binaries
Expand Down
3 changes: 3 additions & 0 deletions distrib/linux/jupyterconsole.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/python/bin/runjupyter" console --kernel @CMAKE_PROJECT_NAME@ $*
3 changes: 3 additions & 0 deletions distrib/linux/jupyterlab
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/python/bin/runjupyter" lab --ip 127.0.0.1 $*
3 changes: 3 additions & 0 deletions distrib/linux/jupyternotebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/python/bin/runjupyter" notebook --ip 127.0.0.1 $*
3 changes: 3 additions & 0 deletions distrib/linux/pythonshell.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/bin/@CMAKE_PROJECT_NAME@" -c PythonShell $*
9 changes: 9 additions & 0 deletions distrib/linux/runjupyter
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

appDir="$(cd "$(dirname "$0")"; pwd)/../.."

export PATH="${appDir}/bin":$PATH

"${appDir}/python/bin/python" "${appDir}/python/bin/set_python_path.py" "${appDir}/python" -s

"${appDir}/python/bin/jupyter" $*
3 changes: 3 additions & 0 deletions distrib/macos/jupyterconsole.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/runjupyter" console --kernel @CMAKE_PROJECT_NAME@ $*
3 changes: 3 additions & 0 deletions distrib/macos/jupyterlab.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/runjupyter" lab --ip 127.0.0.1 $*
3 changes: 3 additions & 0 deletions distrib/macos/jupyternotebook.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/runjupyter" notebook --ip 127.0.0.1 $*
3 changes: 3 additions & 0 deletions distrib/macos/pythonshell.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

"$(cd "$(dirname "$0")"; pwd)/@CMAKE_PROJECT_NAME@.app/Contents/MacOS/@CMAKE_PROJECT_NAME@" -c PythonShell $*
12 changes: 12 additions & 0 deletions distrib/macos/runjupyter.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

appDir="$(cd "$(dirname "$0")"; pwd)/../../../../.."

export PATH="${appDir}/@CMAKE_PROJECT_NAME@.app/Contents/MacOS":$PATH

"${appDir}/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/python" \
"${appDir}/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/set_python_path.py" \
"${appDir}/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python" \
-s

"${appDir}/@CMAKE_PROJECT_NAME@.app/Contents/Frameworks/Python/bin/jupyter" $*
5 changes: 5 additions & 0 deletions distrib/windows/jupyterconsole.bat.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@ECHO OFF

TITLE Running the Jupyter Lab environment...

CALL "%~dp0Python\Scripts\runjupyter.bat" console --kernel ${CMAKE_PROJECT_NAME} %*
5 changes: 5 additions & 0 deletions distrib/windows/jupyterlab.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@ECHO OFF

TITLE Running the Jupyter Lab environment...

CALL "%~dp0Python\Scripts\runjupyter.bat" lab --ip 127.0.0.1 %*
9 changes: 9 additions & 0 deletions distrib/windows/jupyterlab.vbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Set shell = CreateObject("WScript.Shell")
appDir = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)
updatePythonPath = """"&appDir&"\Python\bin\Python.exe"" """&appDir&"\Python\Scripts\set_python_path.py"" """&appDir&"\Python"" -s"

shell.Run updatePythonPath, 0, True

cmd = """"&appDir&"\Python\bin\Python.exe"" """&appDir&"\Python\Scripts\start_jupyter.py"" lab --ip 127.0.0.1"

shell.Run cmd, 1, False
5 changes: 5 additions & 0 deletions distrib/windows/jupyternotebook.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@ECHO OFF

TITLE Running the Jupyter Notebook environment...

CALL "%~dp0Python\Scripts\runjupyter.bat" notebook --ip 127.0.0.1 %*
9 changes: 9 additions & 0 deletions distrib/windows/jupyternotebook.vbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Set shell = CreateObject("WScript.Shell")
appDir = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)
updatePythonPath = """"&appDir&"\Python\bin\Python.exe"" """&appDir&"\Python\Scripts\set_python_path.py"" """&appDir&"\Python"" -s"

shell.Run updatePythonPath, 0, True

cmd = """"&appDir&"\Python\bin\Python.exe"" """&appDir&"\Python\Scripts\start_jupyter.py"" notebook --ip 127.0.0.1"

shell.Run cmd, 1, False

0 comments on commit a402aa1

Please sign in to comment.