diff options
| -rw-r--r-- | lib/recipetool/__init__.py | 3 | ||||
| -rw-r--r-- | lib/recipetool/create_qt5.py | 162 |
2 files changed, 165 insertions, 0 deletions
diff --git a/lib/recipetool/__init__.py b/lib/recipetool/__init__.py new file mode 100644 index 00000000..8eda9276 --- /dev/null +++ b/lib/recipetool/__init__.py | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | # Enable other layers to have modules in the same named directory | ||
| 2 | from pkgutil import extend_path | ||
| 3 | __path__ = extend_path(__path__, __name__) | ||
diff --git a/lib/recipetool/create_qt5.py b/lib/recipetool/create_qt5.py new file mode 100644 index 00000000..51708b40 --- /dev/null +++ b/lib/recipetool/create_qt5.py | |||
| @@ -0,0 +1,162 @@ | |||
| 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 | |||
| 18 | import re | ||
| 19 | import os | ||
| 20 | |||
| 21 | from recipetool.create import RecipeHandler | ||
| 22 | from recipetool.create_buildsys import CmakeExtensionHandler, AutotoolsExtensionHandler | ||
| 23 | |||
| 24 | |||
| 25 | class 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 | |||
| 40 | class 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 | 'qtenginio': 'Qt5Enginio', | ||
| 51 | 'qtsensors': 'Qt5Sensors', | ||
| 52 | 'qtmultimedia': 'Qt5Multimedia Qt5MultimediaWidgets', | ||
| 53 | 'qtwebchannel': 'Qt5WebChannel', | ||
| 54 | 'qtwebsockets': 'Qt5WebSockets', | ||
| 55 | 'qtserialport': 'Qt5SerialPort', | ||
| 56 | 'qtx11extras': 'Qt5X11Extras', | ||
| 57 | 'qtlocation': 'Qt5Location Qt5Positioning', | ||
| 58 | 'qt3d': 'Qt53DCollision Qt53DCore Qt53DInput Qt53DLogic Qt53DQuick Qt53DQuickRender Qt53DRender', | ||
| 59 | } | ||
| 60 | for recipe, pkgs in cmake_qt5_pkgmap.iteritems(): | ||
| 61 | if pkg in pkgs.split(): | ||
| 62 | deps.append(recipe) | ||
| 63 | return True | ||
| 64 | return False | ||
| 65 | |||
| 66 | def post_process(self, srctree, fn, pkg, deps, outlines, inherits, values): | ||
| 67 | for dep in deps: | ||
| 68 | if dep.startswith('qt'): | ||
| 69 | if 'cmake_qt5' not in inherits: | ||
| 70 | inherits.append('cmake_qt5') | ||
| 71 | break | ||
| 72 | |||
| 73 | |||
| 74 | class Qmake5RecipeHandler(RecipeHandler): | ||
| 75 | # Map of QT variable items to recipes | ||
| 76 | qt_map = {'axcontainer': '', | ||
| 77 | 'axserver': '', | ||
| 78 | 'concurrent': 'qtbase', | ||
| 79 | 'core': 'qtbase', | ||
| 80 | 'gui': 'qtbase', | ||
| 81 | 'dbus': 'qtbase', | ||
| 82 | 'declarative': 'qtquick1', | ||
| 83 | 'designer': 'qttools', | ||
| 84 | 'help': 'qttools', | ||
| 85 | 'multimedia': 'qtmultimedia', | ||
| 86 | 'multimediawidgets': 'qtmultimedia', | ||
| 87 | 'network': 'qtbase', | ||
| 88 | 'opengl': 'qtbase', | ||
| 89 | 'printsupport': 'qtbase', | ||
| 90 | 'qml': 'qtdeclarative', | ||
| 91 | 'qmltest': 'qtdeclarative', | ||
| 92 | 'x11extras': 'qtx11extras', | ||
| 93 | 'quick': 'qtdeclarative', | ||
| 94 | 'script': 'qtscript', | ||
| 95 | 'scripttools': 'qtscript', | ||
| 96 | 'sensors': 'qtsensors', | ||
| 97 | 'serialport': 'qtserialport', | ||
| 98 | 'sql': 'qtbase', | ||
| 99 | 'svg': 'qtsvg', | ||
| 100 | 'testlib': 'qtbase', | ||
| 101 | 'uitools': 'qttools', | ||
| 102 | 'webkit': 'qtwebkit', | ||
| 103 | 'webkitwidgets': 'qtwebkit', | ||
| 104 | 'widgets': 'qtbase', | ||
| 105 | 'winextras': '', | ||
| 106 | 'xml': 'qtbase', | ||
| 107 | 'xmlpatterns': 'qtxmlpatterns'} | ||
| 108 | |||
| 109 | def process(self, srctree, classes, lines_before, lines_after, handled, extravalues): | ||
| 110 | # There's not a conclusive way to tell a Qt2/3/4/5 .pro file apart, so we | ||
| 111 | # just assume that qmake5 is a reasonable default if you have this layer | ||
| 112 | # enabled | ||
| 113 | if 'buildsystem' in handled: | ||
| 114 | return False | ||
| 115 | |||
| 116 | unmappedqt = [] | ||
| 117 | files = RecipeHandler.checkfiles(srctree, ['*.pro']) | ||
| 118 | deps = [] | ||
| 119 | if files: | ||
| 120 | for fn in files: | ||
| 121 | self.parse_qt_pro(fn, deps, unmappedqt) | ||
| 122 | |||
| 123 | classes.append('qmake5') | ||
| 124 | if unmappedqt: | ||
| 125 | outlines.append('# NOTE: the following QT dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmappedqt)))) | ||
| 126 | if deps: | ||
| 127 | lines_before.append('DEPENDS = "%s"' % ' '.join(list(set(deps)))) | ||
| 128 | handled.append('buildsystem') | ||
| 129 | return True | ||
| 130 | return False | ||
| 131 | |||
| 132 | def parse_qt_pro(self, fn, deps, unmappedqt): | ||
| 133 | with open(fn, 'r') as f: | ||
| 134 | for line in f: | ||
| 135 | if re.match('^QT\s*[+=]+', line): | ||
| 136 | if '=' in line: | ||
| 137 | for item in line.split('=')[1].split(): | ||
| 138 | dep = Qmake5RecipeHandler.qt_map.get(item, None) | ||
| 139 | if dep: | ||
| 140 | deps.append(dep) | ||
| 141 | elif dep is not None: | ||
| 142 | unmappedqt.append(item) | ||
| 143 | elif re.match('^SUBDIRS\s*[+=]+', line): | ||
| 144 | if '=' in line: | ||
| 145 | for item in line.split('=')[1].split(): | ||
| 146 | subfiles = RecipeHandler.checkfiles(os.path.join(os.path.dirname(fn), item), ['*.pro']) | ||
| 147 | for subfn in subfiles: | ||
| 148 | self.parse_qt_pro(subfn, deps, unmappedqt) | ||
| 149 | elif 'qml' in line.lower(): | ||
| 150 | deps.append('qtdeclarative') | ||
| 151 | |||
| 152 | |||
| 153 | def register_recipe_handlers(handlers): | ||
| 154 | # Insert handler in front of default qmake handler | ||
| 155 | handlers.append((Qmake5RecipeHandler(), 21)) | ||
| 156 | |||
| 157 | def register_cmake_handlers(handlers): | ||
| 158 | handlers.append(Qt5CmakeHandler()) | ||
| 159 | |||
| 160 | def register_autotools_handlers(handlers): | ||
| 161 | handlers.append(Qt5AutotoolsHandler()) | ||
| 162 | |||
