aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/data/shiboken_helpers.cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2018-10-18 19:40:49 +0200
committerCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2019-02-07 08:26:31 +0000
commit97df448edbc035a2f531508a5cfe5739fb2de18d (patch)
tree732de8143e1dcb6a5b25e25eb8ec2954bf8ac87f /sources/shiboken2/data/shiboken_helpers.cmake
parent9a371088d6b8e8a0986a30a8dfb0076669275103 (diff)
Modernize cmake build
Add a CMake super project that includes the shiboken2, PySide2 and pyside2-tools subprojects, so that it's possible to build everything from Qt Creator (or any other IDE that supports CMake) with minimal set up effort, and thus inform the IDE CMake integration of all relevant files, for easier code editing, navigation and refactoring. This also lays the foundation for allowing 3rd parties to use the shiboken2 generator to generate custom modules. This is achieved by eliminating various hardcoded paths for libraries and include directories. Start using CMake targets throughout the build code to correctly propagate link flags and include dirs for libshiboken and shiboken2 executable targets. Same for the libpyside target. Generate two separate cmake config files (build-tree / install-tree) that can be used with find_package(Shiboken2), to make sure that the PySide2 project can be built as part of the super project build. This is currently the only way I've found to allow the super build to work. Note that for the build-tree find_package() to work, the CMAKE_MODULE_PATH has to be adjusted in the super project file. The generated config files contain variables and logic that allow usage of the installed shiboken package in downstream projects (PySide2). This involves things like getting the includes and libraries for the currently found python interpreter, the shiboken build type (release or debug), was shiboken built with limited api support, etc. Generate 2 separate (build-tree and install-tree) config files for PySide2, similar to how it's done for the shiboken case, for pyside2-tools to build correctly. Install shiboken2 target files using install(EXPORT) to allow building PySide2 with an installed Shiboken2 package (as opposed to one that is built as part of the super project). Same with PySide2 targets for pyside2-tools subproject. Make sure not to redefine uninstall targets if they are already defined. Add a --shorter-paths setup.py option, which would be used by the Windows CI, to circumvent creating paths that are too long, and thus avoiding build issues. Output the build characteristics / classifiers into the generated build_history/YYYY-MM-DD_AAAAAA/build_dir.txt file, so it can be used by the test runner to properly filter out blacklisted tests. This was necessary due to the shorter paths options. Fix various issues regarding target includes and library dependencies. Remove certain duplicated cmake code (like limited api check and build type checks) in PySide2, given that that information will now be present in the exported shiboken2 config file. Include a short README.cmake.md file that describes how to build the super project. References used https://rix0r.nl/blog/2015/08/13/cmake-guide/ https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/ https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1 https://cliutils.gitlab.io/modern-cmake/chapters/basics/functions.html https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html https://github.com/ComicSansMS/libstratcom/blob/master/CMakeLists.txt Abandoned approach using ExternalProject references: https://cmake.org/cmake/help/latest/module/ExternalProject.html https://stackoverflow.com/questions/44990964/how-to-perform-cmakefind-package-at-build-stage-only Fixes: PYSIDE-919 Change-Id: Iaa15d20b279a04c5e16ce2795d03f912bc44a389 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/data/shiboken_helpers.cmake')
-rw-r--r--sources/shiboken2/data/shiboken_helpers.cmake201
1 files changed, 201 insertions, 0 deletions
diff --git a/sources/shiboken2/data/shiboken_helpers.cmake b/sources/shiboken2/data/shiboken_helpers.cmake
new file mode 100644
index 000000000..c55ee89fe
--- /dev/null
+++ b/sources/shiboken2/data/shiboken_helpers.cmake
@@ -0,0 +1,201 @@
+include(CMakeParseArguments)
+
+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:
+ for lib in '${PYTHON_LIBRARIES}'.split(';'):
+ if '/' in 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 "2" AND PYTHON_VERSION_MINOR LESS "7") OR
+ (PYTHON_VERSION_MAJOR EQUAL "3" AND PYTHON_VERSION_MINOR LESS "5"))
+ message(FATAL_ERROR
+ "Shiboken requires Python 2.7+ or 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 Shiboken2::libshiboken
+ APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
+ else()
+ target_include_directories(libshiboken
+ PUBLIC $<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>)
+ endif()
+
+
+ set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${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 correpsonding 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 Shiboken2::libshiboken
+ APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES})
+ else()
+ target_link_libraries(libshiboken
+ PUBLIC $<BUILD_INTERFACE:${SHIBOKEN_PYTHON_LIBRARIES}>)
+ endif()
+
+ 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()