FreeCAD
240 строк · 11.5 Кб
1macro(SetupShibokenAndPyside)
2# -------------------------------- Shiboken/PySide ------------------------
3
4option(FREECAD_USE_SHIBOKEN "Links to the shiboken library at build time. If OFF its Python module is imported at runtime" ON)
5option(FREECAD_USE_PYSIDE "Links to the PySide libraries at build time." ON)
6
7if(DEFINED MACPORTS_PREFIX)
8find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
9find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
10endif(DEFINED MACPORTS_PREFIX)
11
12if(FREECAD_QT_MAJOR_VERSION EQUAL 5)
13set(SHIBOKEN_MAJOR_VERSION 2)
14set(PYSIDE_MAJOR_VERSION 2)
15else()
16set(SHIBOKEN_MAJOR_VERSION ${FREECAD_QT_MAJOR_VERSION})
17set(PYSIDE_MAJOR_VERSION ${FREECAD_QT_MAJOR_VERSION})
18endif()
19
20
21# Shiboken2Config.cmake may explicitly set CMAKE_BUILD_TYPE to Release which causes
22# CMake to fail to create Makefiles for a debug build.
23# So as a workaround we save and restore the value after checking for Shiboken2.
24set (SAVE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
25find_package(Shiboken${SHIBOKEN_MAJOR_VERSION} QUIET)
26set (CMAKE_BUILD_TYPE ${SAVE_BUILD_TYPE})
27if (Shiboken${SHIBOKEN_MAJOR_VERSION}_FOUND)
28# Shiboken config file was found but it may use the wrong Python version
29# Try to get the matching config suffix and repeat finding the package
30set(SHIBOKEN_PATTERN .cpython-${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR})
31
32file(GLOB SHIBOKEN_CONFIG "${Shiboken${SHIBOKEN_MAJOR_VERSION}_DIR}/Shiboken${SHIBOKEN_MAJOR_VERSION}Config${SHIBOKEN_PATTERN}*.cmake")
33if (SHIBOKEN_CONFIG)
34get_filename_component(SHIBOKEN_CONFIG_SUFFIX ${SHIBOKEN_CONFIG} NAME)
35string(SUBSTRING ${SHIBOKEN_CONFIG_SUFFIX} 15 -1 SHIBOKEN_CONFIG_SUFFIX)
36string(REPLACE ".cmake" "" PYTHON_CONFIG_SUFFIX ${SHIBOKEN_CONFIG_SUFFIX})
37message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
38find_package(Shiboken${SHIBOKEN_MAJOR_VERSION} QUIET)
39endif()
40
41if(TARGET Shiboken6::libshiboken AND SHIBOKEN_MAJOR_VERSION EQUAL 6)
42set_target_properties(Shiboken6::libshiboken PROPERTIES INTERFACE_COMPILE_DEFINITIONS "NDEBUG")
43endif()
44endif()
45
46# pyside2 changed its cmake files, this is the dance we have
47# to dance to be compatible with the old (<5.12) and the new versions (>=5.12)
48if(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken)
49get_property(SHIBOKEN_INCLUDE_DIR TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
50endif(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken)
51
52if(NOT SHIBOKEN_INCLUDE_DIR)
53find_pip_package(Shiboken${SHIBOKEN_MAJOR_VERSION})
54if (Shiboken${SHIBOKEN_MAJOR_VERSION}_FOUND)
55set(SHIBOKEN_INCLUDE_DIR ${Shiboken${SHIBOKEN_MAJOR_VERSION}_INCLUDE_DIRS})
56set(SHIBOKEN_LIBRARY ${Shiboken${SHIBOKEN_MAJOR_VERSION}_LIBRARIES})
57endif()
58endif()
59
60find_package(PySide${PYSIDE_MAJOR_VERSION} QUIET)
61
62if(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION})
63get_property(PYSIDE_INCLUDE_DIR TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
64endif(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION})
65
66if(NOT PYSIDE_INCLUDE_DIR)
67find_pip_package(PySide${PYSIDE_MAJOR_VERSION})
68if (PySide${PYSIDE_MAJOR_VERSION}_FOUND)
69set(PYSIDE_INCLUDE_DIR ${PySide${PYSIDE_MAJOR_VERSION}_INCLUDE_DIRS})
70set(PYSIDE_LIBRARY ${PySide${PYSIDE_MAJOR_VERSION}_LIBRARIES})
71endif()
72endif()
73
74find_package(PySide${PYSIDE_MAJOR_VERSION}Tools QUIET) # PySide utilities (uic & rcc executables)
75if(NOT PYSIDE_TOOLS_FOUND)
76message("=======================\n"
77"PySide${PYSIDE_MAJOR_VERSION}Tools not found.\n"
78"=======================\n")
79endif()
80
81file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Ext/PySide)
82file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/__init__.py "# PySide wrapper\n"
83"from PySide${PYSIDE_MAJOR_VERSION} import __version__\n"
84"from PySide${PYSIDE_MAJOR_VERSION} import __version_info__\n")
85file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtCore.py "from PySide${PYSIDE_MAJOR_VERSION}.QtCore import *\n\n"
86"#QCoreApplication.CodecForTr=0\n"
87"#QCoreApplication.UnicodeUTF8=1\n")
88file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtNetwork.py "from PySide${PYSIDE_MAJOR_VERSION}.QtNetwork import *\n")
89if(BUILD_GUI)
90file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtGui.py "from PySide${PYSIDE_MAJOR_VERSION}.QtGui import *\n"
91"from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n"
92"QHeaderView.setResizeMode = QHeaderView.setSectionResizeMode\n")
93file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvg.py "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import *\n")
94file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtUiTools.py "from PySide${PYSIDE_MAJOR_VERSION}.QtUiTools import *\n")
95file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n")
96if(PYSIDE_MAJOR_VERSION LESS 6)
97file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QGraphicsSvgItem\n"
98"from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import QSvgWidget\n")
99file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n")
100else()
101file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvgWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtSvgWidgets import *\n")
102file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n"
103"from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineCore import QWebEnginePage\n")
104endif()
105endif()
106
107if(APPLE AND NOT BUILD_WITH_CONDA)
108install(
109DIRECTORY
110${CMAKE_BINARY_DIR}/Ext/PySide
111DESTINATION
112MacOS
113)
114else()
115install(
116DIRECTORY
117${CMAKE_BINARY_DIR}/Ext/PySide
118DESTINATION
119Ext
120)
121endif()
122
123# If shiboken cannot be found the build option will be set to OFF
124if(NOT SHIBOKEN_INCLUDE_DIR)
125message(WARNING "Shiboken${PYSIDE_MAJOR_VERSION} include files not found, FREECAD_USE_SHIBOKEN automatically set to OFF")
126set(FREECAD_USE_SHIBOKEN OFF)
127endif()
128
129# Now try to import the shiboken Python module and print a warning if it can't be loaded
130execute_process(
131COMMAND ${PYTHON_EXECUTABLE} -c "import shiboken${SHIBOKEN_MAJOR_VERSION}"
132RESULT_VARIABLE FAILURE
133OUTPUT_VARIABLE PRINT_OUTPUT
134)
135
136if(FAILURE)
137message(WARNING
138"==================================\n"
139"Shiboken${SHIBOKEN_MAJOR_VERSION} Python module not found.\n"
140"==================================\n")
141else()
142execute_process(
143COMMAND ${PYTHON_EXECUTABLE} -c "import shiboken${SHIBOKEN_MAJOR_VERSION};print(shiboken${SHIBOKEN_MAJOR_VERSION}.__version__, end='')"
144RESULT_VARIABLE FAILURE
145OUTPUT_VARIABLE Shiboken_VERSION
146)
147endif()
148
149# If PySide cannot be found the build option will be set to OFF
150if(NOT PYSIDE_INCLUDE_DIR)
151message(WARNING "PySide${PYSIDE_MAJOR_VERSION} include files not found, FREECAD_USE_PYSIDE automatically set to OFF")
152set(FREECAD_USE_PYSIDE OFF)
153endif()
154
155# Independent of the build option PySide modules must be loaded at runtime. Print a warning if it fails.
156execute_process(
157COMMAND ${PYTHON_EXECUTABLE} -c "import PySide${PYSIDE_MAJOR_VERSION};import os;print(os.path.dirname(PySide${PYSIDE_MAJOR_VERSION}.__file__), end='')"
158RESULT_VARIABLE FAILURE
159OUTPUT_VARIABLE PRINT_OUTPUT
160)
161if(FAILURE)
162message(WARNING
163"================================\n"
164"PySide${PYSIDE_MAJOR_VERSION} Python module not found.\n"
165"================================\n")
166else()
167execute_process(
168COMMAND ${PYTHON_EXECUTABLE} -c "import PySide${PYSIDE_MAJOR_VERSION};print(PySide${PYSIDE_MAJOR_VERSION}.__version__, end='')"
169RESULT_VARIABLE FAILURE
170OUTPUT_VARIABLE PySide_VERSION
171)
172message(STATUS "PySide ${PySide_VERSION} Python module found at ${PRINT_OUTPUT}.\n")
173endif()
174
175endmacro(SetupShibokenAndPyside)
176
177
178# Macros similar to FindQt4.cmake's WRAP_UI and WRAP_RC, for the automatic generation of Python
179# code from Qt4's user interface ('.ui') and resource ('.qrc') files. These macros are called:
180# - PYSIDE_WRAP_UI
181# - PYSIDE_WRAP_RC
182
183MACRO(PYSIDE_WRAP_UI outfiles)
184if (NOT PYSIDE_UIC_EXECUTABLE)
185message(FATAL_ERROR "Qt uic is required for generating ${ARGN}")
186endif()
187FOREACH(it ${ARGN})
188GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
189GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
190SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py)
191if(WIN32 OR APPLE)
192ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
193COMMAND ${PYSIDE_UIC_EXECUTABLE} ${UICOPTIONS} ${infile} -o ${outfile}
194MAIN_DEPENDENCY ${infile}
195)
196else()
197# Especially on Open Build Service we don't want changing date like
198# pyside2-uic generates in comments at beginning., which is why
199# we follow the tool command with a POSIX-friendly sed.
200ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
201COMMAND "${PYSIDE_UIC_EXECUTABLE}" ${UICOPTIONS} "${infile}" -o "${outfile}"
202COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
203MAIN_DEPENDENCY "${infile}"
204)
205endif()
206list(APPEND ${outfiles} ${outfile})
207ENDFOREACH(it)
208ENDMACRO (PYSIDE_WRAP_UI)
209
210MACRO(PYSIDE_WRAP_RC outfiles)
211if (NOT PYSIDE_RCC_EXECUTABLE)
212message(FATAL_ERROR "Qt rcc is required for generating ${ARGN}")
213endif()
214FOREACH(it ${ARGN})
215GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
216GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
217SET(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py")
218#ADD_CUSTOM_TARGET(${it} ALL
219# DEPENDS ${outfile}
220#)
221if(WIN32 OR APPLE)
222ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
223COMMAND ${PYSIDE_RCC_EXECUTABLE} ${RCCOPTIONS} ${infile} -o ${outfile}
224MAIN_DEPENDENCY ${infile}
225)
226else()
227# Especially on Open Build Service we don't want changing date like
228# pyside-rcc generates in comments at beginning, which is why
229# we follow the tool command with in-place sed.
230ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
231COMMAND "${PYSIDE_RCC_EXECUTABLE}" ${RCCOPTIONS} "${infile}" ${PY_ATTRIBUTE} -o "${outfile}"
232# The line below sometimes catches unwanted lines too - but there is no date in the file
233# anymore with Qt5 RCC, so commenting it out for now...
234#COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
235MAIN_DEPENDENCY "${infile}"
236)
237endif()
238list(APPEND ${outfiles} ${outfile})
239ENDFOREACH(it)
240ENDMACRO (PYSIDE_WRAP_RC)
241