diff options
Diffstat (limited to 'examples/scriptableapplication/CMakeLists.txt')
-rw-r--r-- | examples/scriptableapplication/CMakeLists.txt | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt new file mode 100644 index 000000000..40e29346a --- /dev/null +++ b/examples/scriptableapplication/CMakeLists.txt @@ -0,0 +1,187 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Enable policy to run automoc on generated files. +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +project(scriptableapplication) + +# Set CPP standard to C++11 minimum. +set(CMAKE_CXX_STANDARD 11) + +# Find required Qt packages. +find_package(Qt5 5.9 REQUIRED COMPONENTS Core Gui Widgets) + +# Macro to get various pyside / python include / link flags. +macro(pyside2_config option output_var) + if(${ARGC} GREATER 2) + set(is_list ${ARGV2}) + else() + set(is_list "") + endif() + + execute_process( + COMMAND python "${CMAKE_SOURCE_DIR}/pyside2_config.py" ${option} + OUTPUT_VARIABLE ${output_var} + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if ("${${output_var}}" STREQUAL "") + message(FATAL_ERROR "Got empty string when running: pyside2_config.py ${option}") + endif() + if(is_list) + string (REPLACE " " ";" ${output_var} "${${output_var}}") + endif() +endmacro() + +# Get relevant general paths, include paths and linker flags. +pyside2_config(--pyside2 PYSIDE2_PATH) +set(SHIBOKEN_PATH "${PYSIDE2_PATH}/shiboken2") + +if(NOT EXISTS ${SHIBOKEN_PATH}) + message(FATAL_ERROR "Shiboken executable not found at path: ${SHIBOKEN_PATH}") +endif() + +pyside2_config(--python-include PYTHON_INCLUDE_DIR) +pyside2_config(--pyside2-include PYSIDE2_INCLUDE_DIR 1) +pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 1) +pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 1) + +# Get all relevant Qt include dirs, to pass them on to shiboken. +get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_GUI_INCLUDE_DIRS TARGET Qt5::Gui PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt5::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +set(QT_INCLUDE_DIRS ${QT_CORE_INCLUDE_DIRS} ${QT_GUI_INCLUDE_DIRS} ${QT_WIDGETS_INCLUDE_DIRS}) +set(INCLUDES "") +foreach(INCLUDE_DIR ${QT_INCLUDE_DIRS}) + list(APPEND INCLUDES "-I${INCLUDE_DIR}") +endforeach() + +# Set up the options to pass to shiboken. +set(WRAPPED_HEADER ${CMAKE_SOURCE_DIR}/wrappedclasses.h) +set(TYPESYSTEM_FILE ${CMAKE_SOURCE_DIR}/scriptableapplication.xml) + +set(SHIBOKEN_OPTIONS --generator-set=shiboken --enable-parent-ctor-heuristic + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --avoid-protected-hack + ${INCLUDES} + -I${CMAKE_SOURCE_DIR} + -T${CMAKE_SOURCE_DIR} + -T${PYSIDE2_PATH}/typesystems + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ) + +# Specify which sources will be generated by shiboken, and their dependencies. +set(GENERATED_SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/AppLib/applib_module_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/AppLib/mainwindow_wrapper.cpp) + +set(GENERATED_SOURCES_DEPENDENCIES + ${WRAPPED_HEADER} + ${TYPESYSTEM_FILE} + ) + +# Add custom target to run shiboken. +add_custom_command(OUTPUT ${GENERATED_SOURCES} + COMMAND ${SHIBOKEN_PATH} + ${SHIBOKEN_OPTIONS} ${WRAPPED_HEADER} ${TYPESYSTEM_FILE} + DEPENDS ${GENERATED_SOURCES_DEPENDENCIES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running generator for ${TYPESYSTEM_FILE}.") + +# Set the CPP files. +set(SOURCES + mainwindow.cpp + pythonutils.cpp + ${GENERATED_SOURCES} + ) + +# We need to include the headers for the module bindings that we use. +set(PYSIDE2_ADDITIONAL_INCLUDES "") +foreach(INCLUDE_DIR ${PYSIDE2_INCLUDE_DIR}) + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtCore") + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtGui") + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtWidgets") +endforeach() + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Enable rpaths so that the example can be executed from the build dir. +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +SET(CMAKE_INSTALL_RPATH "") +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= + +# Declare executable so we can enable automoc. +add_executable(${PROJECT_NAME} main.cpp) + +# Enable automoc. +set_property(TARGET ${PROJECT_NAME} PROPERTY AUTOMOC 1) + +# Add the rest of the sources. +target_sources(${PROJECT_NAME} PUBLIC ${SOURCES}) + +# Apply relevant include and link flags. +target_include_directories(${PROJECT_NAME} PRIVATE ${PYTHON_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_ADDITIONAL_INCLUDES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}) + +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE2_SHARED_LIBRARIES}) + +# Find and link to the python library. +list(GET PYTHON_LINKING_DATA 0 PYTHON_LIBDIR) +list(GET PYTHON_LINKING_DATA 1 PYTHON_LIB) +find_library(PYTHON_LINK_FLAGS ${PYTHON_LIB} HINTS ${PYTHON_LIBDIR}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PYTHON_LINK_FLAGS}) + +# Same as CONFIG += no_keywords to avoid syntax errors in object.h due to the usage of the word Slot +target_compile_definitions(${PROJECT_NAME} PRIVATE QT_NO_KEYWORDS) + +if(WIN32) + # ============================================================================================= + # !!! (The section below is deployment related, so in a real world application you will want to + # take care of this properly (this is simply to eliminate errors that users usually encounter. + # ============================================================================================= + # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link + # against a wrong python shared library. + + set(PYTHON_VERSIONS_LIST 3 32 33 34 35 36 37 38) + set(PYTHON_ADDITIONAL_LINK_FLAGS "") + foreach(VER ${PYTHON_VERSIONS_LIST}) + set(PYTHON_ADDITIONAL_LINK_FLAGS + "${PYTHON_ADDITIONAL_LINK_FLAGS} /NODEFAULTLIB:\"python${VER}_d.lib\"") + set(PYTHON_ADDITIONAL_LINK_FLAGS + "${PYTHON_ADDITIONAL_LINK_FLAGS} /NODEFAULTLIB:\"python${VER}.lib\"") + endforeach() + + set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${PYTHON_ADDITIONAL_LINK_FLAGS}") + + # Add custom target to hard link PySide2 shared libraries (just like in qmake example), so you + # don't have to set PATH manually to point to the PySide2 package. + foreach(LIBRARY_PATH ${PYSIDE2_SHARED_LIBRARIES}) + string(REGEX REPLACE ".lib$" ".dll" LIBRARY_PATH ${LIBRARY_PATH}) + get_filename_component(BASE_NAME ${LIBRARY_PATH} NAME) + file(TO_NATIVE_PATH ${LIBRARY_PATH} SOURCE_PATH) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}" DEST_PATH) + add_custom_command(OUTPUT "${BASE_NAME}" + COMMAND mklink /H "${DEST_PATH}" "${SOURCE_PATH}" + DEPENDS ${LIBRARY_PATH} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Creating hardlink to PySide2 shared library ${BASE_NAME}") + + # Fake target that depends on the previous one, but has special ALL keyword, which means + # it will always be executed. + add_custom_target("fake_${BASE_NAME}" ALL DEPENDS ${BASE_NAME}) + endforeach() + # ============================================================================================= + # !!! End of dubious section. + # ============================================================================================= +endif() |