FreeCAD

Форк
0
/
SetupShibokenAndPyside.cmake 
268 строк · 12.5 Кб
1
macro(SetupShibokenAndPyside)
2
# -------------------------------- Shiboken/PySide ------------------------
3

4
    option(FREECAD_USE_SHIBOKEN "Links to the shiboken library at build time. If OFF its Python module is imported at runtime" ON)
5
    option(FREECAD_USE_PYSIDE "Links to the PySide libraries at build time." ON)
6

7
    if(DEFINED MACPORTS_PREFIX)
8
        find_package(Shiboken REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
9
        find_package(PySide REQUIRED HINTS "${PYTHON_LIBRARY_DIR}/cmake")
10
    endif(DEFINED MACPORTS_PREFIX)
11

12
    if(FREECAD_QT_MAJOR_VERSION EQUAL 5)
13
        set(SHIBOKEN_MAJOR_VERSION 2)
14
        set(PYSIDE_MAJOR_VERSION 2)
15
    else()
16
        set(SHIBOKEN_MAJOR_VERSION ${FREECAD_QT_MAJOR_VERSION})
17
        set(PYSIDE_MAJOR_VERSION ${FREECAD_QT_MAJOR_VERSION})
18
    endif()
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.
24
    set (SAVE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
25
    find_package(Shiboken${SHIBOKEN_MAJOR_VERSION} QUIET)
26
    set (CMAKE_BUILD_TYPE ${SAVE_BUILD_TYPE})
27
    if (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
30
        set(SHIBOKEN_PATTERN .cpython-${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR})
31

32
        file(GLOB SHIBOKEN_CONFIG "${Shiboken${SHIBOKEN_MAJOR_VERSION}_DIR}/Shiboken${SHIBOKEN_MAJOR_VERSION}Config${SHIBOKEN_PATTERN}*.cmake")
33
        if (SHIBOKEN_CONFIG)
34
            get_filename_component(SHIBOKEN_CONFIG_SUFFIX ${SHIBOKEN_CONFIG} NAME)
35
            string(SUBSTRING ${SHIBOKEN_CONFIG_SUFFIX} 15 -1 SHIBOKEN_CONFIG_SUFFIX)
36
            string(REPLACE ".cmake" "" PYTHON_CONFIG_SUFFIX ${SHIBOKEN_CONFIG_SUFFIX})
37
            message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
38
            find_package(Shiboken${SHIBOKEN_MAJOR_VERSION} QUIET)
39
        endif()
40
    endif()
41

42
    # pyside2 changed its cmake files, this is the dance we have
43
    # to dance to be compatible with the old (<5.12) and the new versions (>=5.12)
44
    if(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken)
45
        get_property(SHIBOKEN_INCLUDE_DIR TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
46
    endif(NOT SHIBOKEN_INCLUDE_DIR AND TARGET Shiboken${SHIBOKEN_MAJOR_VERSION}::libshiboken)
47

48
    if(NOT SHIBOKEN_INCLUDE_DIR)
49
        find_pip_package(Shiboken${SHIBOKEN_MAJOR_VERSION})
50
        if (Shiboken${SHIBOKEN_MAJOR_VERSION}_FOUND)
51
            set(SHIBOKEN_INCLUDE_DIR ${Shiboken${SHIBOKEN_MAJOR_VERSION}_INCLUDE_DIR})
52
            set(SHIBOKEN_LIBRARY ${Shiboken${SHIBOKEN_MAJOR_VERSION}_LIBRARY})
53
        endif()
54
    endif()
55

56
    find_package(PySide${PYSIDE_MAJOR_VERSION} QUIET)
57

58
    if(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION})
59
        get_property(PYSIDE_INCLUDE_DIR TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
60
    endif(NOT PYSIDE_INCLUDE_DIR AND TARGET PySide${PYSIDE_MAJOR_VERSION}::pyside${PYSIDE_MAJOR_VERSION})
61

62
    if(NOT PYSIDE_INCLUDE_DIR)
63
        find_pip_package(PySide${PYSIDE_MAJOR_VERSION})
64
        if (PySide${PYSIDE_MAJOR_VERSION}_FOUND)
65
            set(PYSIDE_INCLUDE_DIR ${PySide${PYSIDE_MAJOR_VERSION}_INCLUDE_DIR})
66
            set(PYSIDE_LIBRARY ${PySide${PYSIDE_MAJOR_VERSION}_LIBRARY})
67
        endif()
68
    endif()
69

70
    find_package(PySide${PYSIDE_MAJOR_VERSION}Tools QUIET) # PySide utilities (uic & rcc executables)
71
    if(NOT PYSIDE_TOOLS_FOUND)
72
        message("=======================\n"
73
                "PySide${PYSIDE_MAJOR_VERSION}Tools not found.\n"
74
                "=======================\n")
75
    endif()
76

77
    file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Ext/PySide)
78
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/__init__.py "# PySide wrapper\n"
79
                                "from PySide${PYSIDE_MAJOR_VERSION} import __version__\n"
80
                                "from PySide${PYSIDE_MAJOR_VERSION} import __version_info__\n")
81
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtCore.py "from PySide${PYSIDE_MAJOR_VERSION}.QtCore import *\n\n"
82
                                "#QCoreApplication.CodecForTr=0\n"
83
                                "#QCoreApplication.UnicodeUTF8=1\n")
84
    file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtNetwork.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtNetwork import *\n")
85
    if(BUILD_GUI)
86
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtGui.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtGui import *\n"
87
                                    "from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n"
88
                                    "QHeaderView.setResizeMode = QHeaderView.setSectionResizeMode\n")
89
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtSvg.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtSvg import *\n")
90
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtUiTools.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtUiTools import *\n")
91
        file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWidgets import *\n")
92
        if(PYSIDE_MAJOR_VERSION LESS 6)
93
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n")
94
        else()
95
            file(WRITE ${CMAKE_BINARY_DIR}/Ext/PySide/QtWebEngineWidgets.py  "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineWidgets import *\n"
96
                                                                             "from PySide${PYSIDE_MAJOR_VERSION}.QtWebEngineCore import QWebEnginePage\n")
97
        endif()
98
    endif()
99

100
    if(APPLE AND NOT BUILD_WITH_CONDA)
101
        install(
102
        DIRECTORY
103
            ${CMAKE_BINARY_DIR}/Ext/PySide
104
        DESTINATION
105
            MacOS
106
        )
107
    else()
108
        install(
109
        DIRECTORY
110
            ${CMAKE_BINARY_DIR}/Ext/PySide
111
        DESTINATION
112
            Ext
113
        )
114
    endif()
115

116
    # If shiboken cannot be found the build option will be set to OFF
117
    if(NOT SHIBOKEN_INCLUDE_DIR)
118
        message(WARNING "Shiboken${PYSIDE_MAJOR_VERSION} include files not found, FREECAD_USE_SHIBOKEN automatically set to OFF")
119
        set(FREECAD_USE_SHIBOKEN OFF)
120
    endif()
121

122
    # Now try to import the shiboken Python module and print a warning if it can't be loaded
123
    execute_process(
124
        COMMAND ${PYTHON_EXECUTABLE} -c "import shiboken${SHIBOKEN_MAJOR_VERSION}"
125
        RESULT_VARIABLE FAILURE
126
        OUTPUT_VARIABLE PRINT_OUTPUT
127
    )
128

129
    if(FAILURE)
130
        message(WARNING
131
                "==================================\n"
132
                "Shiboken${SHIBOKEN_MAJOR_VERSION} Python module not found.\n"
133
                "==================================\n")
134
    else()
135
        execute_process(
136
            COMMAND ${PYTHON_EXECUTABLE} -c "import shiboken${SHIBOKEN_MAJOR_VERSION};print(shiboken${SHIBOKEN_MAJOR_VERSION}.__version__, end='')"
137
            RESULT_VARIABLE FAILURE
138
            OUTPUT_VARIABLE Shiboken_VERSION
139
        )
140
    endif()
141

142
    # If PySide cannot be found the build option will be set to OFF
143
    if(NOT PYSIDE_INCLUDE_DIR)
144
        message(WARNING "PySide${PYSIDE_MAJOR_VERSION} include files not found, FREECAD_USE_PYSIDE automatically set to OFF")
145
        set(FREECAD_USE_PYSIDE OFF)
146
    endif()
147

148
    # Independent of the build option PySide modules must be loaded at runtime. Print a warning if it fails.
149
    execute_process(
150
        COMMAND ${PYTHON_EXECUTABLE} -c "import PySide${PYSIDE_MAJOR_VERSION};import os;print(os.path.dirname(PySide${PYSIDE_MAJOR_VERSION}.__file__), end='')"
151
        RESULT_VARIABLE FAILURE
152
        OUTPUT_VARIABLE PRINT_OUTPUT
153
    )
154
    if(FAILURE)
155
        message(WARNING
156
                "================================\n"
157
                "PySide${PYSIDE_MAJOR_VERSION} Python module not found.\n"
158
                "================================\n")
159
    else()
160
        execute_process(
161
            COMMAND ${PYTHON_EXECUTABLE} -c "import PySide${PYSIDE_MAJOR_VERSION};print(PySide${PYSIDE_MAJOR_VERSION}.__version__, end='')"
162
            RESULT_VARIABLE FAILURE
163
            OUTPUT_VARIABLE PySide_VERSION
164
        )
165
        message(STATUS "PySide ${PySide_VERSION} Python module found at ${PRINT_OUTPUT}.\n")
166
    endif()
167

168
endmacro(SetupShibokenAndPyside)
169

170
# Locate the include directory for a pip-installed package -- uses pip show to find the base pip
171
# install directory, and then appends the package name and  "/include" to the end
172
macro(find_pip_package PACKAGE)
173
    execute_process(
174
        COMMAND ${PYTHON_EXECUTABLE} -m pip show ${PACKAGE}
175
        RESULT_VARIABLE FAILURE
176
        OUTPUT_VARIABLE PRINT_OUTPUT
177
    )
178
    if(NOT FAILURE)
179
        # Extract Name: and Location: lines and use them to construct the include directory
180
        string(REPLACE "\n" ";" PIP_OUTPUT_LINES ${PRINT_OUTPUT})
181
        foreach(LINE IN LISTS PIP_OUTPUT_LINES)
182
            STRING(FIND "${LINE}" "Name: " NAME_STRING_LOCATION)
183
            STRING(FIND "${LINE}" "Location: " LOCATION_STRING_LOCATION)
184
            if(${NAME_STRING_LOCATION} EQUAL 0)
185
                STRING(SUBSTRING "${LINE}" 6 -1 PIP_PACKAGE_NAME)
186
            elseif(${LOCATION_STRING_LOCATION} EQUAL 0)
187
                STRING(SUBSTRING "${LINE}" 10 -1 PIP_PACKAGE_LOCATION)
188
            endif()
189
        endforeach()
190
        message(STATUS "Found pip-installed ${PACKAGE} in ${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}")
191
        file(TO_NATIVE_PATH "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/include" INCLUDE_DIR)
192
        file(TO_NATIVE_PATH "${PIP_PACKAGE_LOCATION}/${PIP_PACKAGE_NAME}/lib" LIBRARY)
193
        if(EXISTS ${INCLUDE_DIR})
194
            set(${PACKAGE}_INCLUDE_DIR ${INCLUDE_DIR})
195
        else()
196
            message(STATUS "${PACKAGE} include directory '${INCLUDE_DIR}' does not exist")
197
        endif()
198
        if(EXISTS ${LIBRARY})
199
            set(${PACKAGE}_LIBRARY ${LIBRARY})
200
        else()
201
            message(STATUS "${PACKAGE} library directory '${LIBRARY}' does not exist")
202
        endif()
203
        set(${PACKAGE}_FOUND TRUE)
204
    endif()
205
endmacro()
206

207

208
# Macros similar to FindQt4.cmake's WRAP_UI and WRAP_RC, for the automatic generation of Python
209
# code from Qt4's user interface ('.ui') and resource ('.qrc') files. These macros are called:
210
# - PYSIDE_WRAP_UI
211
# - PYSIDE_WRAP_RC
212

213
MACRO(PYSIDE_WRAP_UI outfiles)
214
  if (NOT PYSIDE_UIC_EXECUTABLE)
215
    message(FATAL_ERROR "Qt uic is required for generating ${ARGN}")
216
  endif()
217
  FOREACH(it ${ARGN})
218
    GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
219
    GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
220
    SET(outfile ${CMAKE_CURRENT_BINARY_DIR}/ui_${outfile}.py)
221
    if(WIN32 OR APPLE)
222
        ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
223
          COMMAND ${PYSIDE_UIC_EXECUTABLE} ${UICOPTIONS} ${infile} -o ${outfile}
224
          MAIN_DEPENDENCY ${infile}
225
        )
226
    else()
227
        # Especially on Open Build Service we don't want changing date like
228
        # pyside2-uic generates in comments at beginning., which is why
229
        # we follow the tool command with a POSIX-friendly sed.
230
        ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
231
          COMMAND "${PYSIDE_UIC_EXECUTABLE}" ${UICOPTIONS} "${infile}" -o "${outfile}"
232
          COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
233
          MAIN_DEPENDENCY "${infile}"
234
        )
235
    endif()
236
    list(APPEND ${outfiles} ${outfile})
237
  ENDFOREACH(it)
238
ENDMACRO (PYSIDE_WRAP_UI)
239

240
MACRO(PYSIDE_WRAP_RC outfiles)
241
  if (NOT PYSIDE_RCC_EXECUTABLE)
242
    message(FATAL_ERROR "Qt rcc is required for generating ${ARGN}")
243
  endif()
244
  FOREACH(it ${ARGN})
245
    GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
246
    GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
247
    SET(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}_rc.py")
248
    #ADD_CUSTOM_TARGET(${it} ALL
249
    #  DEPENDS ${outfile}
250
    #)
251
    if(WIN32 OR APPLE)
252
        ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
253
          COMMAND ${PYSIDE_RCC_EXECUTABLE} ${RCCOPTIONS} ${infile} -o ${outfile}
254
          MAIN_DEPENDENCY ${infile}
255
        )
256
    else()
257
        # Especially on Open Build Service we don't want changing date like
258
        # pyside-rcc generates in comments at beginning, which is why
259
        # we follow the tool command with in-place sed.
260
        ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
261
          COMMAND "${PYSIDE_RCC_EXECUTABLE}" ${RCCOPTIONS} "${infile}" ${PY_ATTRIBUTE} -o "${outfile}"
262
          COMMAND sed "/^# /d" "${outfile}" >"${outfile}.tmp" && mv "${outfile}.tmp" "${outfile}"
263
          MAIN_DEPENDENCY "${infile}"
264
        )
265
    endif()
266
    list(APPEND ${outfiles} ${outfile})
267
  ENDFOREACH(it)
268
ENDMACRO (PYSIDE_WRAP_RC)
269

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.