mirror of
https://github.com/python-LimeReport/python-LimeReport.git
synced 2025-09-04 17:12:22 +03:00
271 lines
11 KiB
CMake
271 lines
11 KiB
CMake
cmake_minimum_required(VERSION 3.16)
|
|
cmake_policy(VERSION 3.16)
|
|
|
|
# Enable policy to run automoc on generated files.
|
|
if(POLICY CMP0071)
|
|
cmake_policy(SET CMP0071 NEW)
|
|
endif()
|
|
|
|
|
|
# ================================ General configuration ======================================
|
|
|
|
project(LimeReport)
|
|
|
|
set(USE_QT6 ON)
|
|
if (NOT DEFINED ENABLE_ZINT)
|
|
set(ENABLE_ZINT OFF)
|
|
endif()
|
|
#
|
|
set(LIMEREPORT_STATIC ON)
|
|
|
|
# Find Python
|
|
find_package (Python3 COMPONENTS Interpreter)
|
|
if(NOT Python3_Interpreter_FOUND)
|
|
message(FATAL_ERROR "Python3 not found")
|
|
endif()
|
|
message(STATUS "Using python: ${Python3_EXECUTABLE}")
|
|
|
|
|
|
find_package(QT REQUIRED NAMES Qt6)
|
|
# Find the required Qt packages
|
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Sql Network Xml Svg Qml PrintSupport)
|
|
|
|
# Set CPP standard to C++11 minimum.
|
|
set(CMAKE_CXX_STANDARD 11)
|
|
|
|
# The C++ project library for which we will create bindings.
|
|
set(qtads_subdir "LimeReport")
|
|
set(qtads_dir ${CMAKE_CURRENT_SOURCE_DIR}/${qtads_subdir})
|
|
add_subdirectory(${qtads_subdir} EXCLUDE_FROM_ALL)
|
|
set(project_library limereport-qt${QT_VERSION_MAJOR})
|
|
|
|
# The name of the generated bindings module (as imported in Python).
|
|
set(bindings_library "LimeReport")
|
|
|
|
# The header file with all the types and functions for which bindings will be generated.
|
|
# Usually it simply includes other headers of the library you are creating bindings for.
|
|
set(wrapped_header ${CMAKE_CURRENT_SOURCE_DIR}/bindings.h)
|
|
|
|
# The typesystem xml file which defines the relationships between the C++ types / functions
|
|
# and the corresponding Python equivalents.
|
|
set(typesystem_file ${CMAKE_CURRENT_SOURCE_DIR}/bindings.xml)
|
|
|
|
# Specify which C++ files will be generated by shiboken. This includes the module wrapper
|
|
# and a '.cpp' file per C++ type. These are needed for generating the module shared
|
|
# library.
|
|
set(generated_sources
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_module_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_enums_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_reportengine_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_icallbackdatasource_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_idatasource_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_idatasourceholder_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_idatasourcemanager_wrapper.cpp
|
|
${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/limereport_idbcredentialsprovider_wrapper.cpp
|
|
)
|
|
|
|
|
|
# ================================== Shiboken detection ======================================
|
|
|
|
|
|
# Macro to get various pyside / python include / link flags and paths.
|
|
# Uses the not entirely supported utils/pyside_config.py file.
|
|
macro(pyside_config option output_var)
|
|
if(${ARGC} GREATER 2)
|
|
set(is_list ${ARGV2})
|
|
else()
|
|
set(is_list "")
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/pyside_config.py"
|
|
${option}
|
|
OUTPUT_VARIABLE ${output_var}
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
|
|
if ("${${output_var}}" STREQUAL "")
|
|
message(FATAL_ERROR "Error: Calling ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/pyside_config.py ${option} returned no output.")
|
|
endif()
|
|
if(is_list)
|
|
string (REPLACE " " ";" ${output_var} "${${output_var}}")
|
|
endif()
|
|
endmacro()
|
|
|
|
# Query for the shiboken generator path, Python path, include paths and linker flags.
|
|
pyside_config(--shiboken-module-path shiboken_module_path)
|
|
pyside_config(--shiboken-generator-path shiboken_generator_path)
|
|
pyside_config(--pyside-path pyside_path)
|
|
pyside_config(--pyside-include-path pyside_include_dir 1)
|
|
pyside_config(--python-include-path python_include_dir)
|
|
pyside_config(--shiboken-generator-include-path shiboken_include_dir 1)
|
|
pyside_config(--shiboken-module-shared-libraries-cmake shiboken_shared_libraries 0)
|
|
pyside_config(--python-link-flags-cmake python_linking_data 0)
|
|
pyside_config(--pyside-shared-libraries-cmake pyside_shared_libraries 0)
|
|
|
|
set(shiboken_path "${shiboken_generator_path}/shiboken6${CMAKE_EXECUTABLE_SUFFIX}")
|
|
if(NOT EXISTS ${shiboken_path})
|
|
message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}")
|
|
endif()
|
|
|
|
|
|
# ==================================== RPATH configuration ====================================
|
|
|
|
if(UNIX AND NOT APPLE)
|
|
set(CMAKE_BUILD_RPATH "$ORIGIN/lib:$ORIGIN/../PySide6/:$ORIGIN/../PySide6/Qt/lib:$ORIGIN/../shiboken6")
|
|
endif()
|
|
|
|
if(APPLE)
|
|
set(CMAKE_BUILD_RPATH "@loader_path/lib;@loader_path/../PySide6/;@loader_path/../PySide6/Qt/lib;@loader_path/../shiboken6")
|
|
set(MACOSX_RPATH TRUE)
|
|
endif()
|
|
|
|
# ============================== Qt Includes for project_library ==============================
|
|
|
|
# Get the relevant Qt include dirs, to pass them on to shiboken.
|
|
set(QT_INCLUDE_DIR "")
|
|
get_target_property(QT_INCLUDE_DIR_LIST Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(_Q ${QT_INCLUDE_DIR_LIST})
|
|
if(NOT "${_Q}" MATCHES "QtCore$")
|
|
set(QT_INCLUDE_DIR "${_Q}")
|
|
endif()
|
|
endforeach()
|
|
if(QT_INCLUDE_DIR STREQUAL "")
|
|
message(FATAL_ERROR "Unable to obtain the Qt include directory")
|
|
endif()
|
|
|
|
set(QT_INCLUDES "")
|
|
list(APPEND QT_INCLUDES "-I${QT_INCLUDE_DIR}")
|
|
|
|
get_property(QT_CORE_INCLUDE_DIRS TARGET Qt6::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_CORE_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt6::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_WIDGETS_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_SQL_INCLUDE_DIRS TARGET Qt6::Sql PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_SQL_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_NETWORK_INCLUDE_DIRS TARGET Qt6::Network PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_NETWORK_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_XML_INCLUDE_DIRS TARGET Qt6::Xml PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_XML_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_SVG_INCLUDE_DIRS TARGET Qt6::Svg PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_SVG_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_QML_INCLUDE_DIRS TARGET Qt6::Qml PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_QML_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
get_property(QT_PRINTSUPPORT_INCLUDE_DIRS TARGET Qt6::PrintSupport PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
|
foreach(INCLUDE_DIR ${QT_PRINTSUPPORT_INCLUDE_DIRS})
|
|
list(APPEND QT_INCLUDES "-I${INCLUDE_DIR}")
|
|
endforeach()
|
|
|
|
# Check if Qt is a framework build on macOS. This affects how include paths should be handled.
|
|
get_target_property(QtCore_is_framework Qt6::Core FRAMEWORK)
|
|
if (QtCore_is_framework)
|
|
# Get the path to the Qt framework dir.
|
|
set(QT_FRAMEWORK_INCLUDE_DIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS}")
|
|
message(STATUS "*** QT_FRAMEWORK_INCLUDE_DIR is ${QT_FRAMEWORK_INCLUDE_DIR}")
|
|
list(APPEND QT_INCLUDES "--framework-include-paths=${QT_FRAMEWORK_INCLUDE_DIR}")
|
|
endif()
|
|
|
|
# We need to include the headers for the module bindings that we use
|
|
set(pyside_additional_includes "")
|
|
foreach(INCLUDE_DIR ${pyside_include_dir})
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtCore")
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtGui")
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtWidgets")
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtQml")
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtNetwork")
|
|
list(APPEND pyside_additional_includes "${INCLUDE_DIR}/QtPrintSupport")
|
|
endforeach()
|
|
|
|
|
|
# ====================== Shiboken target for generating binding C++ files ====================
|
|
|
|
set(implicit_includes)
|
|
foreach(_current ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
|
|
set(implicit_includes ${implicit_includes} "-I${_current}")
|
|
endforeach()
|
|
|
|
# Set up the options to pass to shiboken.
|
|
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
|
|
${QT_INCLUDES}
|
|
${implicit_includes}
|
|
-I${qtads_dir}/include
|
|
-T${CMAKE_CURRENT_SOURCE_DIR}
|
|
-T${pyside_path}/typesystems
|
|
--output-directory=${CMAKE_CURRENT_BINARY_DIR}
|
|
)
|
|
|
|
set(generated_sources_dependencies ${wrapped_header} ${typesystem_file})
|
|
|
|
# Add custom target to run shiboken to generate the binding cpp files.
|
|
add_custom_command(OUTPUT ${generated_sources}
|
|
COMMAND ${shiboken_path}
|
|
${shiboken_options} ${wrapped_header} ${typesystem_file}
|
|
DEPENDS ${generated_sources_dependencies}
|
|
IMPLICIT_DEPENDS CXX ${wrapped_header}
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Running generator for ${typesystem_file}.")
|
|
|
|
|
|
# =============================== CMake target - bindings_library =============================
|
|
|
|
# Set the cpp files which will be used for the bindings library.
|
|
set(${bindings_library}_sources ${generated_sources})
|
|
|
|
# Define and build the bindings library.
|
|
add_library(${bindings_library} MODULE ${${bindings_library}_sources})
|
|
|
|
# Apply relevant include and link flags.
|
|
target_include_directories(${bindings_library} PRIVATE ${pyside_additional_includes})
|
|
target_include_directories(${bindings_library} PRIVATE ${pyside_include_dir})
|
|
target_include_directories(${bindings_library} PRIVATE ${python_include_dir})
|
|
target_include_directories(${bindings_library} PRIVATE ${shiboken_include_dir})
|
|
target_include_directories(${bindings_library} PRIVATE "${CMAKE_SOURCE_DIR}/src")
|
|
|
|
target_link_libraries(${bindings_library} PRIVATE Qt6::Widgets)
|
|
target_link_libraries(${bindings_library} PRIVATE ${project_library})
|
|
target_link_libraries(${bindings_library} PRIVATE ${pyside_shared_libraries})
|
|
target_link_libraries(${bindings_library} PRIVATE ${shiboken_shared_libraries})
|
|
|
|
target_compile_options(limereport-qt${QT_VERSION_MAJOR} PRIVATE -Og)
|
|
target_compile_options(${bindings_library} PRIVATE -Og)
|
|
target_compile_definitions(${bindings_library} PRIVATE "-DPy_LIMITED_API=0x03070000")
|
|
|
|
# Adjust the name of generated module.
|
|
set_property(TARGET ${bindings_library} PROPERTY PREFIX "")
|
|
set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME
|
|
"${bindings_library}${PYTHON_EXTENSION_SUFFIX}")
|
|
if(WIN32)
|
|
set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd")
|
|
endif()
|
|
|
|
# Make sure the linker doesn't complain about not finding Python symbols on macOS.
|
|
if(APPLE)
|
|
set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
|
endif(APPLE)
|
|
|
|
if (WIN32)
|
|
list(GET python_linking_data 0 python_libdir)
|
|
target_link_directories(${bindings_library} PRIVATE ${python_libdir})
|
|
endif()
|