From 73415e134b75876d547667c6eeb7052f76750687 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 25 Oct 2021 15:41:43 +0200 Subject: CMake: Dissolve generic cmake_helpers/helpers.cmake Move PySide specific functions into a new PySideHelpers.cmake file. Keep functions used by both shiboken and pyside in a renamed ShibokHelpers.cmake file. This brings the CMake file structure more in-line with how it's structured in Qt6 itself. TODO: Ideally the pyside subproject should not include the shiboken files directly, but rather have access to those functions as a consequence of calling find_package(Shiboken6). Pick-to: 6.2 Change-Id: I954d8be0df86a45e74b6011f8e2758026f3340fa Reviewed-by: Friedemann Kleint Reviewed-by: Qt CI Bot --- sources/cmake_helpers/helpers.cmake | 265 ------------ sources/pyside6/cmake/PySideHelpers.cmake | 186 ++++++++ sources/pyside6/cmake/PySideSetup.cmake | 8 +- sources/shiboken6/cmake/ShibokenHelpers.cmake | 468 +++++++++++++++++++++ sources/shiboken6/cmake/ShibokenSetup.cmake | 4 +- sources/shiboken6/cmake/shiboken_helpers.cmake | 389 ----------------- sources/shiboken6/data/CMakeLists.txt | 2 +- .../shiboken6/data/Shiboken6Config-spec.cmake.in | 2 +- 8 files changed, 662 insertions(+), 662 deletions(-) delete mode 100644 sources/cmake_helpers/helpers.cmake create mode 100644 sources/pyside6/cmake/PySideHelpers.cmake create mode 100644 sources/shiboken6/cmake/ShibokenHelpers.cmake delete mode 100644 sources/shiboken6/cmake/shiboken_helpers.cmake diff --git a/sources/cmake_helpers/helpers.cmake b/sources/cmake_helpers/helpers.cmake deleted file mode 100644 index 3bc26f17d..000000000 --- a/sources/cmake_helpers/helpers.cmake +++ /dev/null @@ -1,265 +0,0 @@ -macro(collect_essential_modules) -# Collect all essential modules. -# note: the order of this list is relevant for dependencies. -# For instance: Qt5Printsupport must come before Qt5WebKitWidgets. -set(ALL_ESSENTIAL_MODULES - Core - Gui - Widgets - PrintSupport - Sql - Network - Test - Concurrent) -endmacro() - -macro(collect_optional_modules) -# Collect all optional modules. -set(ALL_OPTIONAL_MODULES - Designer - Xml - Help Multimedia - MultimediaWidgets - OpenGL - OpenGLWidgets - Positioning - Location - NetworkAuth - Qml - Quick - QuickControls2 - QuickWidgets - RemoteObjects - Scxml - Sensors - SerialPort - StateMachine - TextToSpeech - Charts - Svg - SvgWidgets - DataVisualization - Bluetooth) -find_package(Qt${QT_MAJOR_VERSION}UiTools) -if(Qt${QT_MAJOR_VERSION}UiTools_FOUND) - list(APPEND ALL_OPTIONAL_MODULES UiTools) -else() - set(DISABLE_QtUiTools 1) -endif() -if(WIN32) - list(APPEND ALL_OPTIONAL_MODULES AxContainer) -endif() -list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngineWidgets - WebEngineQuick WebSockets) -if(NOT WIN32 AND NOT APPLE) - list(APPEND ALL_OPTIONAL_MODULES DBus) -endif() -if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 6.0.2) - list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras) -endif() -if(WIN32) - list(APPEND ALL_OPTIONAL_MODULES WinExtras) -endif() -endmacro() - -macro(check_os) -set(ENABLE_UNIX "1") -set(ENABLE_MAC "0") -set(ENABLE_WIN "0") - -if(CMAKE_HOST_APPLE) - set(ENABLE_MAC "1") -elseif(CMAKE_HOST_WIN32) - set(ENABLE_WIN "1") - set(ENABLE_UNIX "0") -elseif(NOT CMAKE_HOST_UNIX) - message(FATAL_ERROR "OS not supported") -endif() -endmacro() - -macro(use_protected_as_public_hack) -# 2017-04-24 The protected hack can unfortunately not be disabled, because -# Clang does produce linker errors when we disable the hack. -# But the ugly workaround in Python is replaced by a shiboken change. -if(WIN32 OR DEFINED AVOID_PROTECTED_HACK) - message(STATUS "PySide6 will be generated avoiding the protected hack!") - set(GENERATOR_EXTRA_FLAGS ${GENERATOR_EXTRA_FLAGS} --avoid-protected-hack) - add_definitions(-DAVOID_PROTECTED_HACK) -else() - message(STATUS "PySide will be generated using the protected hack!") -endif() -endmacro() - -macro(remove_skipped_modules) -# Removing from the MODULES list the items that were defined with -# -DSKIP_MODULES on command line -if (SKIP_MODULES) - foreach(s ${SKIP_MODULES}) - list(REMOVE_ITEM MODULES ${s}) - endforeach() -endif() - -foreach(m ${MODULES}) - COLLECT_MODULE_IF_FOUND(${m}) - list(FIND all_module_shortnames ${m} is_module_collected) - # If the module was collected, remove it from disabled modules list. - if (NOT is_module_collected EQUAL -1) - list(REMOVE_ITEM DISABLED_MODULES ${m}) - endif() -endforeach() -endmacro() - -macro(COLLECT_MODULE_IF_FOUND shortname) - set(name "Qt${QT_MAJOR_VERSION}${shortname}") - set(_qt_module_name "${name}") - if ("${shortname}" STREQUAL "OpenGLFunctions") - set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui") - endif() - # Determine essential/optional/missing - set(module_state "missing") - list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex) - if(${essentialIndex} EQUAL -1) - list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex) - if(NOT ${optionalIndex} EQUAL -1) - set(module_state "optional") - endif() - else() - set(module_state "essential") - endif() - - # Silence warnings when optional packages are not found when doing a quiet build. - set(quiet_argument "") - if (QUIET_BUILD AND "${module_state}" STREQUAL "optional") - set(quiet_argument "QUIET") - endif() - - find_package(${_qt_module_name} ${quiet_argument}) - # If package is found, _name_found will be equal to 1 - set(_name_found "${_qt_module_name}_FOUND") - # _name_dir will keep the path to the directory where the CMake rules were found - # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Core or /usr/lib64/cmake/Qt5Core - set(_name_dir "${_qt_module_name}_DIR") - # Qt5Core will set the base path to check if all the modules are on the same - # directory, to avoid CMake looking in another path. - # This will be saved in a global variable at the beginning of the modules - # collection process. - string(FIND "${name}" "Qt${QT_MAJOR_VERSION}Core" qtcore_found) - if(("${qtcore_found}" GREATER "0") OR ("${qtcore_found}" EQUAL "0")) - get_filename_component(_core_abs_dir "${${_name_dir}}/../" ABSOLUTE) - # Setting the absolute path where the Qt5Core was found - # e.g: ~/qt5.9-install/qtbase/lib/cmake or /usr/lib64/cmake - message(STATUS "CORE_ABS_DIR:" ${_core_abs_dir}) - endif() - - # Getting the absolute path for each module where the CMake was found, to - # compare it with CORE_ABS_DIR and check if they are in the same source directory - # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Script or /usr/lib64/cmake/Qt5Script - get_filename_component(_module_dir "${${_name_dir}}" ABSOLUTE) - string(FIND "${_module_dir}" "${_core_abs_dir}" found_basepath) - - # If the module was found, and also the module path is the same as the - # Qt5Core base path, we will generate the list with the modules to be installed - set(looked_in_message ". Looked in: ${${_name_dir}}") - if("${${_name_found}}" AND (("${found_basepath}" GREATER "0") OR ("${found_basepath}" EQUAL "0"))) - message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}") - # record the shortnames for the tests - list(APPEND all_module_shortnames ${shortname}) - # Build Qt 5 compatibility variables - if(${QT_MAJOR_VERSION} GREATER_EQUAL 6 AND NOT "${shortname}" STREQUAL "OpenGLFunctions") - get_target_property(Qt6${shortname}_INCLUDE_DIRS Qt6::${shortname} - INTERFACE_INCLUDE_DIRECTORIES) - get_target_property(Qt6${shortname}_PRIVATE_INCLUDE_DIRS - Qt6::${shortname}Private - INTERFACE_INCLUDE_DIRECTORIES) - set(Qt6${shortname}_LIBRARIES Qt::${shortname}) - endif() - else() - if("${module_state}" STREQUAL "optional") - message(STATUS "optional module ${name} skipped${looked_in_message}") - elseif("${module_state}" STREQUAL "essential") - message(STATUS "skipped module ${name} is essential!\n" - " We do not guarantee that all tests are working.${looked_in_message}") - else() - message(FATAL_ERROR "module ${name} MISSING${looked_in_message}") - endif() - endif() -endmacro() - -macro(compute_config_py_values - full_version_var_name - ) - string(TIMESTAMP PACKAGE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC) - if (PACKAGE_BUILD_DATE) - set(PACKAGE_BUILD_DATE "__build_date__ = '${PACKAGE_BUILD_DATE}'") - endif() - - if (PACKAGE_SETUP_PY_PACKAGE_VERSION) - set(PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PACKAGE_SETUP_PY_PACKAGE_VERSION}'") - set(FINAL_PACKAGE_VERSION ${PACKAGE_SETUP_PY_PACKAGE_VERSION}) - else() - set(FINAL_PACKAGE_VERSION ${${full_version_var_name}}) - endif() - - if (PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP) - set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP}'") - else() - set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "") - endif() - - find_package(Git) - if(GIT_FOUND) - # Check if current source folder is inside a git repo, so that commit information can be - # queried. - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir - OUTPUT_VARIABLE PACKAGE_SOURCE_IS_INSIDE_REPO - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(PACKAGE_SOURCE_IS_INSIDE_REPO) - # Force git dates to be UTC-based. - set(ENV{TZ} UTC) - execute_process( - COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD - OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_DATE - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(PACKAGE_BUILD_COMMIT_DATE) - set(PACKAGE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PACKAGE_BUILD_COMMIT_DATE}'") - endif() - unset(ENV{TZ}) - - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse HEAD - OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(PACKAGE_BUILD_COMMIT_HASH) - set(PACKAGE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PACKAGE_BUILD_COMMIT_HASH}'") - endif() - - execute_process( - COMMAND ${GIT_EXECUTABLE} describe HEAD - OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH_DESCRIBED - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED) - set(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PACKAGE_BUILD_COMMIT_HASH_DESCRIBED}'") - endif() - - endif() - endif() - -endmacro() - -# Creates a new target called "${library_name}_generator" which -# depends on the mjb_rejected_classes.log file generated by shiboken. -# This target is added as a dependency to ${library_name} target. -# This file's timestamp informs cmake when the last generation was -# done, without force-updating the timestamps of the generated class -# cpp files. -# In practical terms this means that changing some injection code in -# an xml file that modifies only one specific class cpp file, will -# not force rebuilding all the cpp files, and thus allow for better -# incremental builds. -macro(create_generator_target library_name) - add_custom_target(${library_name}_generator DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log") - add_dependencies(${library_name} ${library_name}_generator) -endmacro() diff --git a/sources/pyside6/cmake/PySideHelpers.cmake b/sources/pyside6/cmake/PySideHelpers.cmake new file mode 100644 index 000000000..dc6fe22ce --- /dev/null +++ b/sources/pyside6/cmake/PySideHelpers.cmake @@ -0,0 +1,186 @@ +macro(collect_essential_modules) + # Collect all essential modules. + # note: the order of this list is relevant for dependencies. + # For instance: Qt5Printsupport must come before Qt5WebKitWidgets. + set(ALL_ESSENTIAL_MODULES + Core + Gui + Widgets + PrintSupport + Sql + Network + Test + Concurrent) +endmacro() + +macro(collect_optional_modules) + # Collect all optional modules. + set(ALL_OPTIONAL_MODULES + Designer + Xml + Help Multimedia + MultimediaWidgets + OpenGL + OpenGLWidgets + Positioning + Location + NetworkAuth + Qml + Quick + QuickControls2 + QuickWidgets + RemoteObjects + Scxml + Sensors + SerialPort + StateMachine + TextToSpeech + Charts + Svg + SvgWidgets + DataVisualization + Bluetooth) + find_package(Qt${QT_MAJOR_VERSION}UiTools) + if(Qt${QT_MAJOR_VERSION}UiTools_FOUND) + list(APPEND ALL_OPTIONAL_MODULES UiTools) + else() + set(DISABLE_QtUiTools 1) + endif() + if(WIN32) + list(APPEND ALL_OPTIONAL_MODULES AxContainer) + endif() + list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngineWidgets + WebEngineQuick WebSockets) + if(NOT WIN32 AND NOT APPLE) + list(APPEND ALL_OPTIONAL_MODULES DBus) + endif() + if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 6.0.2) + list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras) + endif() + if(WIN32) + list(APPEND ALL_OPTIONAL_MODULES WinExtras) + endif() +endmacro() + +macro(check_os) + set(ENABLE_UNIX "1") + set(ENABLE_MAC "0") + set(ENABLE_WIN "0") + + if(CMAKE_HOST_APPLE) + set(ENABLE_MAC "1") + elseif(CMAKE_HOST_WIN32) + set(ENABLE_WIN "1") + set(ENABLE_UNIX "0") + elseif(NOT CMAKE_HOST_UNIX) + message(FATAL_ERROR "OS not supported") + endif() +endmacro() + +macro(use_protected_as_public_hack) + # 2017-04-24 The protected hack can unfortunately not be disabled, because + # Clang does produce linker errors when we disable the hack. + # But the ugly workaround in Python is replaced by a shiboken change. + if(WIN32 OR DEFINED AVOID_PROTECTED_HACK) + message(STATUS "PySide6 will be generated avoiding the protected hack!") + set(GENERATOR_EXTRA_FLAGS ${GENERATOR_EXTRA_FLAGS} --avoid-protected-hack) + add_definitions(-DAVOID_PROTECTED_HACK) + else() + message(STATUS "PySide will be generated using the protected hack!") + endif() +endmacro() + +macro(remove_skipped_modules) + # Removing from the MODULES list the items that were defined with + # -DSKIP_MODULES on command line + if(SKIP_MODULES) + foreach(s ${SKIP_MODULES}) + list(REMOVE_ITEM MODULES ${s}) + endforeach() + endif() + + foreach(m ${MODULES}) + collect_module_if_found(${m}) + list(FIND all_module_shortnames ${m} is_module_collected) + # If the module was collected, remove it from disabled modules list. + if (NOT is_module_collected EQUAL -1) + list(REMOVE_ITEM DISABLED_MODULES ${m}) + endif() + endforeach() +endmacro() + +macro(collect_module_if_found shortname) + set(name "Qt${QT_MAJOR_VERSION}${shortname}") + set(_qt_module_name "${name}") + if ("${shortname}" STREQUAL "OpenGLFunctions") + set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui") + endif() + # Determine essential/optional/missing + set(module_state "missing") + list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex) + if(${essentialIndex} EQUAL -1) + list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex) + if(NOT ${optionalIndex} EQUAL -1) + set(module_state "optional") + endif() + else() + set(module_state "essential") + endif() + + # Silence warnings when optional packages are not found when doing a quiet build. + set(quiet_argument "") + if (QUIET_BUILD AND "${module_state}" STREQUAL "optional") + set(quiet_argument "QUIET") + endif() + + find_package(${_qt_module_name} ${quiet_argument}) + # If package is found, _name_found will be equal to 1 + set(_name_found "${_qt_module_name}_FOUND") + # _name_dir will keep the path to the directory where the CMake rules were found + # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Core or /usr/lib64/cmake/Qt5Core + set(_name_dir "${_qt_module_name}_DIR") + # Qt5Core will set the base path to check if all the modules are on the same + # directory, to avoid CMake looking in another path. + # This will be saved in a global variable at the beginning of the modules + # collection process. + string(FIND "${name}" "Qt${QT_MAJOR_VERSION}Core" qtcore_found) + if(("${qtcore_found}" GREATER "0") OR ("${qtcore_found}" EQUAL "0")) + get_filename_component(_core_abs_dir "${${_name_dir}}/../" ABSOLUTE) + # Setting the absolute path where the Qt5Core was found + # e.g: ~/qt5.9-install/qtbase/lib/cmake or /usr/lib64/cmake + message(STATUS "CORE_ABS_DIR:" ${_core_abs_dir}) + endif() + + # Getting the absolute path for each module where the CMake was found, to + # compare it with CORE_ABS_DIR and check if they are in the same source directory + # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Script or /usr/lib64/cmake/Qt5Script + get_filename_component(_module_dir "${${_name_dir}}" ABSOLUTE) + string(FIND "${_module_dir}" "${_core_abs_dir}" found_basepath) + + # If the module was found, and also the module path is the same as the + # Qt5Core base path, we will generate the list with the modules to be installed + set(looked_in_message ". Looked in: ${${_name_dir}}") + if("${${_name_found}}" AND (("${found_basepath}" GREATER "0") OR ("${found_basepath}" EQUAL "0"))) + message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}") + # record the shortnames for the tests + list(APPEND all_module_shortnames ${shortname}) + # Build Qt 5 compatibility variables + if(${QT_MAJOR_VERSION} GREATER_EQUAL 6 AND NOT "${shortname}" STREQUAL "OpenGLFunctions") + get_target_property(Qt6${shortname}_INCLUDE_DIRS Qt6::${shortname} + INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(Qt6${shortname}_PRIVATE_INCLUDE_DIRS + Qt6::${shortname}Private + INTERFACE_INCLUDE_DIRECTORIES) + set(Qt6${shortname}_LIBRARIES Qt::${shortname}) + endif() + else() + if("${module_state}" STREQUAL "optional") + message(STATUS "optional module ${name} skipped${looked_in_message}") + elseif("${module_state}" STREQUAL "essential") + message(STATUS "skipped module ${name} is essential!\n" + " We do not guarantee that all tests are working.${looked_in_message}") + else() + message(FATAL_ERROR "module ${name} MISSING${looked_in_message}") + endif() + endif() +endmacro() diff --git a/sources/pyside6/cmake/PySideSetup.cmake b/sources/pyside6/cmake/PySideSetup.cmake index 0b7138f48..b46d09b57 100644 --- a/sources/pyside6/cmake/PySideSetup.cmake +++ b/sources/pyside6/cmake/PySideSetup.cmake @@ -3,12 +3,14 @@ cmake_policy(SET CMP0046 NEW) set(QT_MAJOR_VERSION 6) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake_helpers") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Macros") -include(helpers) -include(shiboken_helpers) +# TODO: Don't directly include, ShibokenHelpers but rather pick it up from the installed Shiboken +# package. Needs to support top-level build as well (Shiboken is not yet installed in that case). +include(ShibokenHelpers) +include(PySideHelpers) # Don't display "up-to-date / install" messages when installing, to reduce visual clutter. if(QUIET_BUILD) diff --git a/sources/shiboken6/cmake/ShibokenHelpers.cmake b/sources/shiboken6/cmake/ShibokenHelpers.cmake new file mode 100644 index 000000000..c17401ccc --- /dev/null +++ b/sources/shiboken6/cmake/ShibokenHelpers.cmake @@ -0,0 +1,468 @@ +include(CMakeParseArguments) + +macro(set_limited_api) + if (WIN32 AND NOT EXISTS "${PYTHON_LIMITED_LIBRARIES}") + message(FATAL_ERROR "The Limited API was enabled, but ${PYTHON_LIMITED_LIBRARIES} was not found!") + endif() + message(STATUS "******************************************************") + message(STATUS "** Limited API enabled ${PYTHON_LIMITED_LIBRARIES}") + message(STATUS "******************************************************") +endmacro() + +macro(set_debug_build) + set(SHIBOKEN_BUILD_TYPE "Debug") + + if(NOT PYTHON_DEBUG_LIBRARIES) + message(WARNING "Python debug shared library not found; \ + assuming python was built with shared library support disabled.") + endif() + + if(NOT PYTHON_WITH_DEBUG) + message(WARNING "Compiling shiboken6 with debug enabled, \ + but the python executable was not compiled with debug support.") + else() + set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION " -DPy_DEBUG") + endif() + + if (PYTHON_WITH_COUNT_ALLOCS) + set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION "${SBK_PKG_CONFIG_PY_DEBUG_DEFINITION} -DCOUNT_ALLOCS") + endif() +endmacro() + +macro(setup_sanitize_address) + # Currently this does not check that the clang / gcc version used supports Address sanitizer, + # so once again, use at your own risk. + add_compile_options("-fsanitize=address" "-g" "-fno-omit-frame-pointer") + # We need to add the sanitize address option to all linked executables / shared libraries + # so that proper sanitizer symbols are linked in. + # + # Note that when running tests, you may need to set an additional environment variable + # in set_tests_properties for shiboken6 / pyside tests, or exported in your shell. Address + # sanitizer will tell you what environment variable needs to be exported. For example: + # export DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/ + # ./XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_STANDARD_LIBRARIES} -fsanitize=address") +endmacro() + +macro(set_cmake_cxx_flags) +if(MSVC) + # Qt5: this flag has changed from /Zc:wchar_t- in Qt4.X + set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") + #set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DNOCOLOR /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") # XXX +else() + if(CMAKE_HOST_UNIX AND NOT CYGWIN) + add_definitions(-fPIC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fvisibility=hidden -Wno-strict-aliasing") + endif() + set(CMAKE_CXX_FLAGS_DEBUG "-g") + option(ENABLE_GCC_OPTIMIZATION "Enable specific GCC flags to optimization library \ + size and performance. Only available on Release Mode" 0) + if(ENABLE_GCC_OPTIMIZATION) + set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Os -Wl,-O1") + if(NOT CMAKE_HOST_APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--hash-style=gnu") + endif() + endif() + if(CMAKE_HOST_APPLE) + # ALTERNATIVE_QT_INCLUDE_DIR is deprecated, because CMake takes care of finding the proper + # include folders using the qmake found in the environment. Only use it for now in case + # something goes wrong with the cmake process. + if(ALTERNATIVE_QT_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) + set(QT_INCLUDE_DIR ${ALTERNATIVE_QT_INCLUDE_DIR}) + endif() + endif() +endif() + +endmacro() + +macro(set_python_site_packages) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} -c "if True: + from distutils import sysconfig + from os.path import sep + print(sysconfig.get_python_lib(1, 0, prefix='${CMAKE_INSTALL_PREFIX}').replace(sep, '/')) + " + OUTPUT_VARIABLE PYTHON_SITE_PACKAGES + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT PYTHON_SITE_PACKAGES) + message(FATAL_ERROR "Could not detect Python module installation directory.") + elseif (APPLE) + message(STATUS "!!! The generated bindings will be installed on ${PYTHON_SITE_PACKAGES}, \ + is it right!?") + endif() +endmacro() + +macro(set_python_config_suffix) + if (PYTHON_LIMITED_API) + if(WIN32) + set(PYTHON_EXTENSION_SUFFIX "") + else() + set(PYTHON_EXTENSION_SUFFIX ".abi3") + endif() + set(PYTHON_CONFIG_SUFFIX ".abi3") + else() + set(PYTHON_CONFIG_SUFFIX "${PYTHON_EXTENSION_SUFFIX}") + endif() +endmacro() + +macro(setup_clang) + # Find libclang using the environment variables LLVM_INSTALL_DIR, + # CLANG_INSTALL_DIR using standard cmake. + # Use CLANG_INCLUDE_DIRS and link to libclang. + if(DEFINED ENV{LLVM_INSTALL_DIR}) + list(PREPEND CMAKE_PREFIX_PATH "$ENV{LLVM_INSTALL_DIR}") + list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{LLVM_INSTALL_DIR}") + elseif(DEFINED ENV{CLANG_INSTALL_DIR}) + list(PREPEND CMAKE_PREFIX_PATH "$ENV{CLANG_INSTALL_DIR}") + list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{CLANG_INSTALL_DIR}") + endif() + + find_package(Clang CONFIG REQUIRED) + # CLANG_LIBRARY is read out from the cmake cache to deploy libclang + get_target_property(CLANG_BUILD_TYPE libclang IMPORTED_CONFIGURATIONS) + get_target_property(CLANG_LIBRARY_NAME libclang IMPORTED_LOCATION_${CLANG_BUILD_TYPE}) + set(CLANG_LIBRARY "${CLANG_LIBRARY_NAME}" CACHE FILEPATH "libclang") + message(STATUS "CLANG: ${Clang_DIR}, ${CLANG_LIBRARY} detected") +endmacro() + +macro(set_quiet_build) + # Don't display "up-to-date / install" messages when installing, to reduce visual clutter. + set(CMAKE_INSTALL_MESSAGE NEVER) + # Override message not to display info messages when doing a quiet build. + function(message) + list(GET ARGV 0 MessageType) + if (MessageType STREQUAL FATAL_ERROR OR + MessageType STREQUAL SEND_ERROR OR + MessageType STREQUAL WARNING OR + MessageType STREQUAL AUTHOR_WARNING) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${ARGV}") + endif() + endfunction() +endmacro() + +macro(get_python_extension_suffix) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} -c "if True: + import re + import sysconfig + suffix = sysconfig.get_config_var('EXT_SUFFIX') + res = re.search(r'^(.+)\\.', suffix) + if res: + suffix = res.group(1) + else: + suffix = '' + print(suffix) + " + OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX}) +endmacro() + +macro(shiboken_parse_all_arguments prefix type flags options multiopts) + cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN}) + if(DEFINED ${prefix}_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).") + endif() +endmacro() + +macro(shiboken_check_if_limited_api) + # On Windows, PYTHON_LIBRARIES can be a list. Example: + # optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib + # On other platforms, this result is not used at all. + execute_process( + COMMAND ${PYTHON_EXECUTABLE} -c "if True: + import os + for lib in '${PYTHON_LIBRARIES}'.split(';'): + if '/' in lib and os.path.isfile(lib): + prefix, py = lib.rsplit('/', 1) + if py.startswith('python3'): + print(prefix + '/python3.lib') + break + " + OUTPUT_VARIABLE PYTHON_LIMITED_LIBRARIES + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(FORCE_LIMITED_API STREQUAL "yes") + if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4) + # GREATER_EQUAL is available only from cmake 3.7 on. We mean python 3.5 . + set(PYTHON_LIMITED_API 1) + endif() + if(WIN32) + if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4) + # PYSIDE-560: XXX maybe add an option to setup.py as override + set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIMITED_LIBRARIES}) + endif() + endif() + endif() +endmacro() + + +macro(shiboken_find_required_python) + if(${ARGC} GREATER 0) + find_package(PythonInterp ${ARGV0} REQUIRED) + find_package(PythonLibs ${ARGV0} REQUIRED) + else() + # If no version is specified, just use any interpreter that can be found (from PATH). + # This is useful for super-project builds, so that the default system interpeter + # gets picked up (e.g. /usr/bin/python and not /usr/bin/python2.7). + find_package(PythonInterp REQUIRED) + find_package(PythonLibs REQUIRED) + endif() + shiboken_validate_python_version() + + set(SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}") + set_property(GLOBAL PROPERTY SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}") +endmacro() + +macro(shiboken_validate_python_version) + if(PYTHON_VERSION_MAJOR EQUAL "3" AND PYTHON_VERSION_MINOR LESS "5") + message(FATAL_ERROR + "Shiboken requires Python 3.5+.") + endif() +endmacro() + +macro(shiboken_compute_python_includes) + shiboken_parse_all_arguments( + "SHIBOKEN_COMPUTE_INCLUDES" "shiboken_compute_python_includes" + "IS_CALLED_FROM_EXPORT" "" "" ${ARGN}) + + + # If the installed shiboken config file is used, + # append the found Python include dirs as an interface property on the libshiboken target. + # This needs to be dynamic because the user of the library might have python installed + # in a different path than when shiboken was originally built. + # Otherwise if shiboken is currently being built itself (either as standalone, or super project + # build) append the include dirs as PUBLIC. + if (SHIBOKEN_COMPUTE_INCLUDES_IS_CALLED_FROM_EXPORT) + #TODO target_include_directories works on imported targets only starting with v3.11.0. + set_property(TARGET Shiboken6::libshiboken + APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS}) + else() + target_include_directories(libshiboken + PUBLIC $) + endif() + + + set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}") + + set_property(GLOBAL PROPERTY shiboken_python_include_dirs "${SHIBOKEN_PYTHON_INCLUDE_DIRS}") + + message(STATUS + "SHIBOKEN_PYTHON_INCLUDE_DIRS computed to value: '${SHIBOKEN_PYTHON_INCLUDE_DIRS}'") +endmacro() + +# Given a list of the following form: +# optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib +# choose the corresponding library to use, based on the current configuration type. +function(shiboken_get_library_for_current_config library_list current_config out_var) + list(FIND library_list "optimized" optimized_found) + list(FIND library_list "general" general_found) + list(FIND library_list "debug" debug_found) + + if (optimized_found OR general_found OR debug_found) + # Iterate over library list to find the most appropriate library. + foreach(token ${library_list}) + if(token STREQUAL "optimized" OR token STREQUAL "general") + set(is_debug 0) + set(token1 1) + set(lib "") + elseif(token STREQUAL "debug") + set(is_debug 1) + set(token1 1) + set(lib "") + elseif(EXISTS ${token}) + set(lib ${token}) + set(token2 1) + else() + set(token1 0) + set(token2 0) + set(lib "") + endif() + + if(token1 AND token2) + if((is_debug AND lib AND current_config STREQUAL "Debug") + OR (NOT is_debug AND lib AND (NOT current_config STREQUAL "Debug"))) + set(${out_var} ${lib} PARENT_SCOPE) + return() + endif() + endif() + endforeach() + else() + # No configuration specific libraries found, just set the original value. + set(${out_var} "${library_list}" PARENT_SCOPE) + endif() + +endfunction() + +macro(shiboken_compute_python_libraries) + shiboken_parse_all_arguments( + "SHIBOKEN_COMPUTE_LIBS" "shiboken_compute_python_libraries" + "IS_CALLED_FROM_EXPORT" "" "" ${ARGN}) + + if (NOT SHIBOKEN_PYTHON_LIBRARIES) + set(SHIBOKEN_PYTHON_LIBRARIES "") + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES) + set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_DEBUG_LIBRARIES}) + endif() + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Release") + if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES) + set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIBRARIES}) + endif() + endif() + + # If the resulting variable + # contains a "debug;X;optimized;Y" list like described in shiboken_check_if_limited_api, + # make sure to pick just one, so that the final generator expressions are valid. + shiboken_get_library_for_current_config("${SHIBOKEN_PYTHON_LIBRARIES}" "${CMAKE_BUILD_TYPE}" "SHIBOKEN_PYTHON_LIBRARIES") + + if(APPLE) + set(SHIBOKEN_PYTHON_LIBRARIES "-undefined dynamic_lookup") + endif() + + # If the installed shiboken config file is used, + # append the computed Python libraries as an interface property on the libshiboken target. + # This needs to be dynamic because the user of the library might have python installed + # in a different path than when shiboken was originally built. + # Otherwise if shiboken is currently being built itself (either as standalone, or super project + # build) append the libraries as PUBLIC. + if (SHIBOKEN_COMPUTE_LIBS_IS_CALLED_FROM_EXPORT) + #TODO target_link_libraries works on imported targets only starting with v3.11.0. + set_property(TARGET Shiboken6::libshiboken + APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES}) + else() + target_link_libraries(libshiboken + PUBLIC $) + endif() + + set_property(GLOBAL PROPERTY shiboken_python_libraries "${SHIBOKEN_PYTHON_LIBRARIES}") + + message(STATUS "SHIBOKEN_PYTHON_LIBRARIES computed to value: '${SHIBOKEN_PYTHON_LIBRARIES}'") +endmacro() + +function(shiboken_check_if_built_and_target_python_are_compatible) + if(NOT SHIBOKEN_PYTHON_VERSION_MAJOR STREQUAL PYTHON_VERSION_MAJOR) + message(FATAL_ERROR "The detected Python major version is not \ +compatible with the Python major version which was used when Shiboken was built. +Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \ +Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'") + else() + if(NOT SHIBOKEN_PYTHON_LIMITED_API + AND NOT SHIBOKEN_PYTHON_VERSION_MINOR STREQUAL PYTHON_VERSION_MINOR) + message(FATAL_ERROR + "The detected Python minor version is not compatible with the Python minor \ +version which was used when Shiboken was built. Consider building shiboken with \ +FORCE_LIMITED_API set to '1', so that only the Python major version matters. +Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \ +Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'") + endif() + endif() +endfunction() + +function(shiboken_internal_disable_pkg_config) + # Disable pkg-config by setting an empty executable path. There's no documented way to + # mark the package as not found, but we can force all pkg_check_modules calls to do nothing + # by setting the variable to an empty value. + set(PKG_CONFIG_EXECUTABLE "" CACHE STRING "Disabled pkg-config usage." FORCE) +endfunction() + +function(shiboken_internal_disable_pkg_config_if_needed) + if(SHIBOKEN_SKIP_PKG_CONFIG_ADJUSTMENT) + return() + endif() + + # pkg-config should not be used by default on Darwin platforms. + if(APPLE) + set(pkg_config_enabled OFF) + else() + set(pkg_config_enabled ON) + endif() + + if(NOT pkg_config_enabled) + shiboken_internal_disable_pkg_config() + endif() +endfunction() + +macro(compute_config_py_values + full_version_var_name + ) + string(TIMESTAMP PACKAGE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC) + if (PACKAGE_BUILD_DATE) + set(PACKAGE_BUILD_DATE "__build_date__ = '${PACKAGE_BUILD_DATE}'") + endif() + + if (PACKAGE_SETUP_PY_PACKAGE_VERSION) + set(PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PACKAGE_SETUP_PY_PACKAGE_VERSION}'") + set(FINAL_PACKAGE_VERSION ${PACKAGE_SETUP_PY_PACKAGE_VERSION}) + else() + set(FINAL_PACKAGE_VERSION ${${full_version_var_name}}) + endif() + + if (PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP) + set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP}'") + else() + set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "") + endif() + + find_package(Git) + if(GIT_FOUND) + # Check if current source folder is inside a git repo, so that commit information can be + # queried. + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir + OUTPUT_VARIABLE PACKAGE_SOURCE_IS_INSIDE_REPO + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(PACKAGE_SOURCE_IS_INSIDE_REPO) + # Force git dates to be UTC-based. + set(ENV{TZ} UTC) + execute_process( + COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_DATE) + set(PACKAGE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PACKAGE_BUILD_COMMIT_DATE}'") + endif() + unset(ENV{TZ}) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_HASH) + set(PACKAGE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PACKAGE_BUILD_COMMIT_HASH}'") + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH_DESCRIBED + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED) + set(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PACKAGE_BUILD_COMMIT_HASH_DESCRIBED}'") + endif() + + endif() + endif() + +endmacro() + +# Creates a new target called "${library_name}_generator" which +# depends on the mjb_rejected_classes.log file generated by shiboken. +# This target is added as a dependency to ${library_name} target. +# This file's timestamp informs cmake when the last generation was +# done, without force-updating the timestamps of the generated class +# cpp files. +# In practical terms this means that changing some injection code in +# an xml file that modifies only one specific class cpp file, will +# not force rebuilding all the cpp files, and thus allow for better +# incremental builds. +macro(create_generator_target library_name) + add_custom_target(${library_name}_generator DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log") + add_dependencies(${library_name} ${library_name}_generator) +endmacro() diff --git a/sources/shiboken6/cmake/ShibokenSetup.cmake b/sources/shiboken6/cmake/ShibokenSetup.cmake index cb6264a16..c5ab582c3 100644 --- a/sources/shiboken6/cmake/ShibokenSetup.cmake +++ b/sources/shiboken6/cmake/ShibokenSetup.cmake @@ -1,10 +1,8 @@ include(CheckIncludeFileCXX) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../../cmake_helpers") -include(helpers) -include(shiboken_helpers) +include(ShibokenHelpers) option(BUILD_TESTS "Build tests." TRUE) option(USE_PYTHON_VERSION "Use specific python version to build shiboken6." "") diff --git a/sources/shiboken6/cmake/shiboken_helpers.cmake b/sources/shiboken6/cmake/shiboken_helpers.cmake deleted file mode 100644 index 2e4a23867..000000000 --- a/sources/shiboken6/cmake/shiboken_helpers.cmake +++ /dev/null @@ -1,389 +0,0 @@ -include(CMakeParseArguments) - -macro(set_limited_api) - if (WIN32 AND NOT EXISTS "${PYTHON_LIMITED_LIBRARIES}") - message(FATAL_ERROR "The Limited API was enabled, but ${PYTHON_LIMITED_LIBRARIES} was not found!") - endif() - message(STATUS "******************************************************") - message(STATUS "** Limited API enabled ${PYTHON_LIMITED_LIBRARIES}") - message(STATUS "******************************************************") -endmacro() - -macro(set_debug_build) - set(SHIBOKEN_BUILD_TYPE "Debug") - - if(NOT PYTHON_DEBUG_LIBRARIES) - message(WARNING "Python debug shared library not found; \ - assuming python was built with shared library support disabled.") - endif() - - if(NOT PYTHON_WITH_DEBUG) - message(WARNING "Compiling shiboken6 with debug enabled, \ - but the python executable was not compiled with debug support.") - else() - set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION " -DPy_DEBUG") - endif() - - if (PYTHON_WITH_COUNT_ALLOCS) - set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION "${SBK_PKG_CONFIG_PY_DEBUG_DEFINITION} -DCOUNT_ALLOCS") - endif() -endmacro() - -macro(setup_sanitize_address) - # Currently this does not check that the clang / gcc version used supports Address sanitizer, - # so once again, use at your own risk. - add_compile_options("-fsanitize=address" "-g" "-fno-omit-frame-pointer") - # We need to add the sanitize address option to all linked executables / shared libraries - # so that proper sanitizer symbols are linked in. - # - # Note that when running tests, you may need to set an additional environment variable - # in set_tests_properties for shiboken6 / pyside tests, or exported in your shell. Address - # sanitizer will tell you what environment variable needs to be exported. For example: - # export DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/ - # ./XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib - set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_STANDARD_LIBRARIES} -fsanitize=address") -endmacro() - -macro(set_cmake_cxx_flags) -if(MSVC) - # Qt5: this flag has changed from /Zc:wchar_t- in Qt4.X - set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") - #set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DNOCOLOR /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") # XXX -else() - if(CMAKE_HOST_UNIX AND NOT CYGWIN) - add_definitions(-fPIC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fvisibility=hidden -Wno-strict-aliasing") - endif() - set(CMAKE_CXX_FLAGS_DEBUG "-g") - option(ENABLE_GCC_OPTIMIZATION "Enable specific GCC flags to optimization library \ - size and performance. Only available on Release Mode" 0) - if(ENABLE_GCC_OPTIMIZATION) - set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Os -Wl,-O1") - if(NOT CMAKE_HOST_APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--hash-style=gnu") - endif() - endif() - if(CMAKE_HOST_APPLE) - # ALTERNATIVE_QT_INCLUDE_DIR is deprecated, because CMake takes care of finding the proper - # include folders using the qmake found in the environment. Only use it for now in case - # something goes wrong with the cmake process. - if(ALTERNATIVE_QT_INCLUDE_DIR AND NOT QT_INCLUDE_DIR) - set(QT_INCLUDE_DIR ${ALTERNATIVE_QT_INCLUDE_DIR}) - endif() - endif() -endif() - -endmacro() - -macro(set_python_site_packages) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "if True: - from distutils import sysconfig - from os.path import sep - print(sysconfig.get_python_lib(1, 0, prefix='${CMAKE_INSTALL_PREFIX}').replace(sep, '/')) - " - OUTPUT_VARIABLE PYTHON_SITE_PACKAGES - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT PYTHON_SITE_PACKAGES) - message(FATAL_ERROR "Could not detect Python module installation directory.") - elseif (APPLE) - message(STATUS "!!! The generated bindings will be installed on ${PYTHON_SITE_PACKAGES}, \ - is it right!?") - endif() -endmacro() - -macro(set_python_config_suffix) - if (PYTHON_LIMITED_API) - if(WIN32) - set(PYTHON_EXTENSION_SUFFIX "") - else() - set(PYTHON_EXTENSION_SUFFIX ".abi3") - endif() - set(PYTHON_CONFIG_SUFFIX ".abi3") - else() - set(PYTHON_CONFIG_SUFFIX "${PYTHON_EXTENSION_SUFFIX}") - endif() -endmacro() - -macro(setup_clang) - # Find libclang using the environment variables LLVM_INSTALL_DIR, - # CLANG_INSTALL_DIR using standard cmake. - # Use CLANG_INCLUDE_DIRS and link to libclang. - if(DEFINED ENV{LLVM_INSTALL_DIR}) - list(PREPEND CMAKE_PREFIX_PATH "$ENV{LLVM_INSTALL_DIR}") - list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{LLVM_INSTALL_DIR}") - elseif(DEFINED ENV{CLANG_INSTALL_DIR}) - list(PREPEND CMAKE_PREFIX_PATH "$ENV{CLANG_INSTALL_DIR}") - list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{CLANG_INSTALL_DIR}") - endif() - - find_package(Clang CONFIG REQUIRED) - # CLANG_LIBRARY is read out from the cmake cache to deploy libclang - get_target_property(CLANG_BUILD_TYPE libclang IMPORTED_CONFIGURATIONS) - get_target_property(CLANG_LIBRARY_NAME libclang IMPORTED_LOCATION_${CLANG_BUILD_TYPE}) - set(CLANG_LIBRARY "${CLANG_LIBRARY_NAME}" CACHE FILEPATH "libclang") - message(STATUS "CLANG: ${Clang_DIR}, ${CLANG_LIBRARY} detected") -endmacro() - -macro(set_quiet_build) - # Don't display "up-to-date / install" messages when installing, to reduce visual clutter. - set(CMAKE_INSTALL_MESSAGE NEVER) - # Override message not to display info messages when doing a quiet build. - function(message) - list(GET ARGV 0 MessageType) - if (MessageType STREQUAL FATAL_ERROR OR - MessageType STREQUAL SEND_ERROR OR - MessageType STREQUAL WARNING OR - MessageType STREQUAL AUTHOR_WARNING) - list(REMOVE_AT ARGV 0) - _message(${MessageType} "${ARGV}") - endif() - endfunction() -endmacro() - -macro(get_python_extension_suffix) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "if True: - import re - import sysconfig - suffix = sysconfig.get_config_var('EXT_SUFFIX') - res = re.search(r'^(.+)\\.', suffix) - if res: - suffix = res.group(1) - else: - suffix = '' - print(suffix) - " - OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX - OUTPUT_STRIP_TRAILING_WHITESPACE) - message(STATUS "PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX}) -endmacro() - -macro(shiboken_parse_all_arguments prefix type flags options multiopts) - cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN}) - if(DEFINED ${prefix}_UNPARSED_ARGUMENTS) - message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).") - endif() -endmacro() - -macro(shiboken_check_if_limited_api) - # On Windows, PYTHON_LIBRARIES can be a list. Example: - # optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib - # On other platforms, this result is not used at all. - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "if True: - import os - for lib in '${PYTHON_LIBRARIES}'.split(';'): - if '/' in lib and os.path.isfile(lib): - prefix, py = lib.rsplit('/', 1) - if py.startswith('python3'): - print(prefix + '/python3.lib') - break - " - OUTPUT_VARIABLE PYTHON_LIMITED_LIBRARIES - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(FORCE_LIMITED_API STREQUAL "yes") - if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4) - # GREATER_EQUAL is available only from cmake 3.7 on. We mean python 3.5 . - set(PYTHON_LIMITED_API 1) - endif() - if(WIN32) - if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4) - # PYSIDE-560: XXX maybe add an option to setup.py as override - set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIMITED_LIBRARIES}) - endif() - endif() - endif() -endmacro() - - -macro(shiboken_find_required_python) - if(${ARGC} GREATER 0) - find_package(PythonInterp ${ARGV0} REQUIRED) - find_package(PythonLibs ${ARGV0} REQUIRED) - else() - # If no version is specified, just use any interpreter that can be found (from PATH). - # This is useful for super-project builds, so that the default system interpeter - # gets picked up (e.g. /usr/bin/python and not /usr/bin/python2.7). - find_package(PythonInterp REQUIRED) - find_package(PythonLibs REQUIRED) - endif() - shiboken_validate_python_version() - - set(SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}") - set_property(GLOBAL PROPERTY SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}") -endmacro() - -macro(shiboken_validate_python_version) - if(PYTHON_VERSION_MAJOR EQUAL "3" AND PYTHON_VERSION_MINOR LESS "5") - message(FATAL_ERROR - "Shiboken requires Python 3.5+.") - endif() -endmacro() - -macro(shiboken_compute_python_includes) - shiboken_parse_all_arguments( - "SHIBOKEN_COMPUTE_INCLUDES" "shiboken_compute_python_includes" - "IS_CALLED_FROM_EXPORT" "" "" ${ARGN}) - - - # If the installed shiboken config file is used, - # append the found Python include dirs as an interface property on the libshiboken target. - # This needs to be dynamic because the user of the library might have python installed - # in a different path than when shiboken was originally built. - # Otherwise if shiboken is currently being built itself (either as standalone, or super project - # build) append the include dirs as PUBLIC. - if (SHIBOKEN_COMPUTE_INCLUDES_IS_CALLED_FROM_EXPORT) - #TODO target_include_directories works on imported targets only starting with v3.11.0. - set_property(TARGET Shiboken6::libshiboken - APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS}) - else() - target_include_directories(libshiboken - PUBLIC $) - endif() - - - set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}") - - set_property(GLOBAL PROPERTY shiboken_python_include_dirs "${SHIBOKEN_PYTHON_INCLUDE_DIRS}") - - message(STATUS - "SHIBOKEN_PYTHON_INCLUDE_DIRS computed to value: '${SHIBOKEN_PYTHON_INCLUDE_DIRS}'") -endmacro() - -# Given a list of the following form: -# optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib -# choose the corresponding library to use, based on the current configuration type. -function(shiboken_get_library_for_current_config library_list current_config out_var) - list(FIND library_list "optimized" optimized_found) - list(FIND library_list "general" general_found) - list(FIND library_list "debug" debug_found) - - if (optimized_found OR general_found OR debug_found) - # Iterate over library list to find the most appropriate library. - foreach(token ${library_list}) - if(token STREQUAL "optimized" OR token STREQUAL "general") - set(is_debug 0) - set(token1 1) - set(lib "") - elseif(token STREQUAL "debug") - set(is_debug 1) - set(token1 1) - set(lib "") - elseif(EXISTS ${token}) - set(lib ${token}) - set(token2 1) - else() - set(token1 0) - set(token2 0) - set(lib "") - endif() - - if(token1 AND token2) - if((is_debug AND lib AND current_config STREQUAL "Debug") - OR (NOT is_debug AND lib AND (NOT current_config STREQUAL "Debug"))) - set(${out_var} ${lib} PARENT_SCOPE) - return() - endif() - endif() - endforeach() - else() - # No configuration specific libraries found, just set the original value. - set(${out_var} "${library_list}" PARENT_SCOPE) - endif() - -endfunction() - -macro(shiboken_compute_python_libraries) - shiboken_parse_all_arguments( - "SHIBOKEN_COMPUTE_LIBS" "shiboken_compute_python_libraries" - "IS_CALLED_FROM_EXPORT" "" "" ${ARGN}) - - if (NOT SHIBOKEN_PYTHON_LIBRARIES) - set(SHIBOKEN_PYTHON_LIBRARIES "") - endif() - - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES) - set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_DEBUG_LIBRARIES}) - endif() - endif() - - if(CMAKE_BUILD_TYPE STREQUAL "Release") - if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES) - set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIBRARIES}) - endif() - endif() - - # If the resulting variable - # contains a "debug;X;optimized;Y" list like described in shiboken_check_if_limited_api, - # make sure to pick just one, so that the final generator expressions are valid. - shiboken_get_library_for_current_config("${SHIBOKEN_PYTHON_LIBRARIES}" "${CMAKE_BUILD_TYPE}" "SHIBOKEN_PYTHON_LIBRARIES") - - if(APPLE) - set(SHIBOKEN_PYTHON_LIBRARIES "-undefined dynamic_lookup") - endif() - - # If the installed shiboken config file is used, - # append the computed Python libraries as an interface property on the libshiboken target. - # This needs to be dynamic because the user of the library might have python installed - # in a different path than when shiboken was originally built. - # Otherwise if shiboken is currently being built itself (either as standalone, or super project - # build) append the libraries as PUBLIC. - if (SHIBOKEN_COMPUTE_LIBS_IS_CALLED_FROM_EXPORT) - #TODO target_link_libraries works on imported targets only starting with v3.11.0. - set_property(TARGET Shiboken6::libshiboken - APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES}) - else() - target_link_libraries(libshiboken - PUBLIC $) - endif() - - set_property(GLOBAL PROPERTY shiboken_python_libraries "${SHIBOKEN_PYTHON_LIBRARIES}") - - message(STATUS "SHIBOKEN_PYTHON_LIBRARIES computed to value: '${SHIBOKEN_PYTHON_LIBRARIES}'") -endmacro() - -function(shiboken_check_if_built_and_target_python_are_compatible) - if(NOT SHIBOKEN_PYTHON_VERSION_MAJOR STREQUAL PYTHON_VERSION_MAJOR) - message(FATAL_ERROR "The detected Python major version is not \ -compatible with the Python major version which was used when Shiboken was built. -Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \ -Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'") - else() - if(NOT SHIBOKEN_PYTHON_LIMITED_API - AND NOT SHIBOKEN_PYTHON_VERSION_MINOR STREQUAL PYTHON_VERSION_MINOR) - message(FATAL_ERROR - "The detected Python minor version is not compatible with the Python minor \ -version which was used when Shiboken was built. Consider building shiboken with \ -FORCE_LIMITED_API set to '1', so that only the Python major version matters. -Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \ -Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'") - endif() - endif() -endfunction() - -function(shiboken_internal_disable_pkg_config) - # Disable pkg-config by setting an empty executable path. There's no documented way to - # mark the package as not found, but we can force all pkg_check_modules calls to do nothing - # by setting the variable to an empty value. - set(PKG_CONFIG_EXECUTABLE "" CACHE STRING "Disabled pkg-config usage." FORCE) -endfunction() - -function(shiboken_internal_disable_pkg_config_if_needed) - if(SHIBOKEN_SKIP_PKG_CONFIG_ADJUSTMENT) - return() - endif() - - # pkg-config should not be used by default on Darwin platforms. - if(APPLE) - set(pkg_config_enabled OFF) - else() - set(pkg_config_enabled ON) - endif() - - if(NOT pkg_config_enabled) - shiboken_internal_disable_pkg_config() - endif() -endfunction() diff --git a/sources/shiboken6/data/CMakeLists.txt b/sources/shiboken6/data/CMakeLists.txt index fb650f74c..6dedb139f 100644 --- a/sources/shiboken6/data/CMakeLists.txt +++ b/sources/shiboken6/data/CMakeLists.txt @@ -53,7 +53,7 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/install/Shiboken6Config${PYTHON_CONFI install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Shiboken6ConfigVersion.cmake" DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}") -install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/shiboken_helpers.cmake" +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ShibokenHelpers.cmake" DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/shiboken6${shiboken6_SUFFIX}.pc" diff --git a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in index 06518d253..077601f8a 100644 --- a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in +++ b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in @@ -14,7 +14,7 @@ set(SHIBOKEN_PYTHON_LIMITED_API "@PYTHON_LIMITED_API@") # file (so not during a regular shiboken build, or during a super project build). if (NOT TARGET Shiboken6::shiboken6) include("${CMAKE_CURRENT_LIST_DIR}/Shiboken6Targets.cmake") - include("${CMAKE_CURRENT_LIST_DIR}/shiboken_helpers.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/ShibokenHelpers.cmake") # Compute the python include and libraries path if needed (aka not part of super project build). shiboken_find_required_python(@PYTHON_VERSION_MAJOR@) -- cgit v1.2.3