xref: /OK3568_Linux_fs/yocto/meta-qt5/lib/recipetool/create_qt5.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1# Recipe creation tool - Qt5 support plugin
2#
3# Copyright (C) 2016 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18import re
19import os
20
21from recipetool.create import RecipeHandler
22from recipetool.create_buildsys import CmakeExtensionHandler, AutotoolsExtensionHandler
23
24
25class Qt5AutotoolsHandler(AutotoolsExtensionHandler):
26    def process_macro(self, srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values):
27        if keyword == 'AX_HAVE_QT':
28            # We don't know specifically which modules it needs, but let's assume it's covered by qtbase
29            deps.append('qtbase')
30            return True
31        return False
32
33    def extend_keywords(self, keywords):
34        keywords.append('AX_HAVE_QT')
35
36    def process_prog(self, srctree, keyword, value, prog, deps, outlines, inherits, values):
37        return False
38
39
40class Qt5CmakeHandler(CmakeExtensionHandler):
41    def process_findpackage(self, srctree, fn, pkg, deps, outlines, inherits, values):
42        return False
43        cmake_qt5_pkgmap = {'qtbase': 'Qt5 Qt5Concurrent Qt5Core Qt5DBus Qt5Gui Qt5Network Qt5OpenGL Qt5OpenGLExtensions Qt5PrintSupport Qt5Sql Qt5Test Qt5Widgets Qt5Xml',
44                            'qtsvg': 'Qt5Svg',
45                            'qtdeclarative': 'Qt5Qml Qt5Quick Qt5QuickWidgets Qt5QuickTest',
46                            'qtxmlpatterns': 'Qt5XmlPatterns',
47                            'qtsystems': 'Qt5PublishSubscribe Qt5ServiceFramework Qt5SystemInfo',
48                            'qtscript': 'Qt5Script Qt5ScriptTools',
49                            'qttools': 'Qt5Designer Qt5Help Qt5LinguistTools Qt5UiPlugin Qt5UiTools',
50                            'qtsensors': 'Qt5Sensors',
51                            'qtmultimedia': 'Qt5Multimedia Qt5MultimediaWidgets',
52                            'qtwebchannel': 'Qt5WebChannel',
53                            'qtwebsockets': 'Qt5WebSockets',
54                            'qtserialport': 'Qt5SerialPort',
55                            'qtx11extras': 'Qt5X11Extras',
56                            'qtlocation': 'Qt5Location Qt5Positioning',
57                            'qt3d': 'Qt53DCollision Qt53DCore Qt53DInput Qt53DLogic Qt53DQuick Qt53DQuickRender Qt53DRender',
58                            }
59        for recipe, pkgs in cmake_qt5_pkgmap.iteritems():
60            if pkg in pkgs.split():
61                deps.append(recipe)
62                return True
63        return False
64
65    def post_process(self, srctree, fn, pkg, deps, outlines, inherits, values):
66        for dep in deps:
67            if dep.startswith('qt'):
68                if 'cmake_qt5' not in inherits:
69                    inherits.append('cmake_qt5')
70                break
71
72
73class Qmake5RecipeHandler(RecipeHandler):
74    # Map of QT variable items to recipes
75    qt_map = {'axcontainer': '',
76              'axserver': '',
77              'concurrent': 'qtbase',
78              'core': 'qtbase',
79              'gui': 'qtbase',
80              'dbus': 'qtbase',
81              'designer': 'qttools',
82              'help': 'qttools',
83              'multimedia': 'qtmultimedia',
84              'multimediawidgets': 'qtmultimedia',
85              'network': 'qtbase',
86              'opengl': 'qtbase',
87              'printsupport': 'qtbase',
88              'qml': 'qtdeclarative',
89              'qmltest': 'qtdeclarative',
90              'x11extras': 'qtx11extras',
91              'quick': 'qtdeclarative',
92              'script': 'qtscript',
93              'scripttools': 'qtscript',
94              'sensors': 'qtsensors',
95              'serialport': 'qtserialport',
96              'sql': 'qtbase',
97              'svg': 'qtsvg',
98              'testlib': 'qtbase',
99              'uitools': 'qttools',
100              'webkit': 'qtwebkit',
101              'webkitwidgets': 'qtwebkit',
102              'widgets': 'qtbase',
103              'winextras': '',
104              'xml': 'qtbase',
105              'xmlpatterns': 'qtxmlpatterns'}
106
107    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
108        # There's not a conclusive way to tell a Qt2/3/4/5 .pro file apart, so we
109        # just assume that qmake5 is a reasonable default if you have this layer
110        # enabled
111        if 'buildsystem' in handled:
112            return False
113
114        unmappedqt = []
115        files = RecipeHandler.checkfiles(srctree, ['*.pro'])
116        deps = []
117        if files:
118            for fn in files:
119                self.parse_qt_pro(fn, deps, unmappedqt)
120
121            classes.append('qmake5')
122            if unmappedqt:
123                outlines.append('# NOTE: the following QT dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmappedqt))))
124            if deps:
125                lines_before.append('DEPENDS = "%s"' % ' '.join(list(set(deps))))
126            handled.append('buildsystem')
127            return True
128        return False
129
130    def parse_qt_pro(self, fn, deps, unmappedqt):
131        with open(fn, 'r') as f:
132            for line in f:
133                if re.match('^QT\s*[+=]+', line):
134                    if '=' in line:
135                        for item in line.split('=')[1].split():
136                            dep = Qmake5RecipeHandler.qt_map.get(item, None)
137                            if dep:
138                                deps.append(dep)
139                            elif dep is not None:
140                                unmappedqt.append(item)
141                elif re.match('^SUBDIRS\s*[+=]+', line):
142                    if '=' in line:
143                        for item in line.split('=')[1].split():
144                            subfiles = RecipeHandler.checkfiles(os.path.join(os.path.dirname(fn), item), ['*.pro'])
145                            for subfn in subfiles:
146                                self.parse_qt_pro(subfn, deps, unmappedqt)
147                elif 'qml' in line.lower():
148                    deps.append('qtdeclarative')
149
150
151def register_recipe_handlers(handlers):
152    # Insert handler in front of default qmake handler
153    handlers.append((Qmake5RecipeHandler(), 21))
154
155def register_cmake_handlers(handlers):
156    handlers.append(Qt5CmakeHandler())
157
158def register_autotools_handlers(handlers):
159    handlers.append(Qt5AutotoolsHandler())
160
161