diff options
author | Tobias Hunger <tobias.hunger@qt.io> | 2019-02-07 15:30:44 +0100 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@qt.io> | 2019-02-11 09:39:36 +0000 |
commit | 35a30c7ebbd50e8b5b1fad7c00bd6c36b0dca8b9 (patch) | |
tree | bca7a5fd7c4c3f4458e4ba76adf0c4c830e78ff0 /util/cmake | |
parent | 199cce0c20108e657d3b3555cdeacb76412fa28f (diff) |
CMake: pro2cmake.py: Expand qmake values in file names, etc.
Expand qmake values when dealing with source file names, include
directories and more. This handles cases where variables are used
to refer to sources (e.g. $$VERSIONTAGGING_SOURCES in corelib) as
well as things like $$QT_SOURCE_TREE and friends.
Note that $$PWD and $$OUT_PWD are still need hand-holding since they
refer to the scopes directory relative to the top level directory --
which pro2cmake.py does not know.
Change-Id: I011ef55416ff820053d5f844b3008836849f5075
Reviewed-by: Albert Astals Cid <albert.astals.cid@kdab.com>
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'util/cmake')
-rwxr-xr-x | util/cmake/pro2cmake.py | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index 5c804826c4..9cd1b7a542 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -77,14 +77,10 @@ def spaces(indent: int) -> str: def map_to_file(f: str, top_dir: str, current_dir: str, want_absolute_path: bool = False) -> typing.Optional[str]: - if f == '$$NO_PCH_SOURCES': - return None if f.startswith('$$PWD/') or f == '$$PWD': # INCLUDEPATH += $$PWD return os.path.join(os.path.relpath(current_dir, top_dir), f[6:]) if f.startswith('$$OUT_PWD/'): return "${CMAKE_CURRENT_BUILD_DIR}/" + f[10:] - if f.startswith('$$QT_SOURCE_TREE'): - return "${PROJECT_SOURCE_DIR}/" + f[17:] if f.startswith("./"): return os.path.join(current_dir, f) if current_dir != '.' else f[2:] if want_absolute_path and not os.path.isabs(f): @@ -102,8 +98,6 @@ def map_source_to_cmake(source: str, base_dir: str, return source[2:] if source == '.': return "${CMAKE_CURRENT_SOURCE_DIR}" - if source.startswith('$$QT_SOURCE_TREE/'): - return "${PROJECT_SOURCE_DIR}/" + source[17:] if os.path.exists(os.path.join(base_dir, source)): return source @@ -201,7 +195,10 @@ class Scope(object): parent_scope: typing.Optional[Scope], file: typing.Optional[str] = None, condition: str = '', base_dir: str = '', - operations: typing.Mapping[str, typing.List[Operation]] = {}) -> None: + operations: typing.Mapping[str, typing.List[Operation]] = { + 'QT_SOURCE_TREE': [SetOperation('${PROJECT_SOURCE_DIR}')], + 'QT_BUILD_TREE': [SetOperation('${PROJECT_BUILD_DIR}')], + }) -> None: if parent_scope: parent_scope._add_child(self) else: @@ -453,6 +450,33 @@ class Scope(object): assert len(v) == 1 return v[0] + def _expand_value(self, value: str) -> typing.List[str]: + result = value + pattern = re.compile(r'\$\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?') + match = re.search(pattern, result) + while match: + if match.group(0) == value: + return self.expand(match.group(1), '') + else: + result = result[:match.start()] \ + + self.expandString(match.group(1)) \ + + result[match.end():] + match = re.search(pattern, result) + return [result] + + def expand(self, key: str, default=None) -> typing.List[str]: + value = self.get(key, default) + result: typing.List[str] = [] + assert isinstance(value, list) + for v in value: + result += self._expand_value(v) + return result + + def expandString(self, key: str) -> str: + result = self._expand_value(self.getString(key)) + assert len(result) == 1 + return result[0] + @property def TEMPLATE(self) -> str: return self.getString('TEMPLATE', 'app') @@ -715,10 +739,10 @@ def write_sources_section(cm_fh: typing.IO[str], scope: Scope, *, if plugin_type: cm_fh.write('{} TYPE {}\n'.format(ind, plugin_type[0])) - sources = scope.get('SOURCES') + scope.get('HEADERS') \ - + scope.get('OBJECTIVE_SOURCES') + scope.get('NO_PCH_SOURCES') \ - + scope.get('FORMS') - resources = scope.get('RESOURCES') + sources = scope.expand('SOURCES') + scope.expand('HEADERS') \ + + scope.expand('OBJECTIVE_SOURCES') + scope.expand('NO_PCH_SOURCES') \ + + scope.expand('FORMS') + resources = scope.expand('RESOURCES') if resources: qrc_only = True for r in resources: @@ -731,7 +755,7 @@ def write_sources_section(cm_fh: typing.IO[str], scope: Scope, *, else: sources += resources - vpath = scope.get('VPATH') + vpath = scope.expand('VPATH') sources = [map_source_to_cmake(s, scope.basedir, vpath) for s in sources] if sources: @@ -739,26 +763,27 @@ def write_sources_section(cm_fh: typing.IO[str], scope: Scope, *, for l in sort_sources(sources): cm_fh.write('{} {}\n'.format(ind, l)) - defines = scope.get('DEFINES') + defines = scope.expand('DEFINES') if defines: cm_fh.write('{} DEFINES\n'.format(ind)) for d in defines: d = d.replace('=\\\\\\"$$PWD/\\\\\\"', '="${CMAKE_CURRENT_SOURCE_DIR}/"') cm_fh.write('{} {}\n'.format(ind, d)) - includes = scope.get('INCLUDEPATH') + includes = scope.expand('INCLUDEPATH') if includes: cm_fh.write('{} INCLUDE_DIRECTORIES\n'.format(ind)) for i in includes: i = i.rstrip('/') or ('/') + i = map_source_to_cmake(i, scope.basedir, vpath) cm_fh.write('{} {}\n'.format(ind, i)) - dependencies = [map_qt_library(q) for q in scope.get('QT') + dependencies = [map_qt_library(q) for q in scope.expand('QT') if map_qt_library(q) not in known_libraries] - dependencies += [map_qt_library(q) for q in scope.get('QT_FOR_PRIVATE') + dependencies += [map_qt_library(q) for q in scope.expand('QT_FOR_PRIVATE') if map_qt_library(q) not in known_libraries] - dependencies += scope.get('QMAKE_USE_PRIVATE') + scope.get('QMAKE_USE') \ - + scope.get('LIBS_PRIVATE') + scope.get('LIBS') + dependencies += scope.expand('QMAKE_USE_PRIVATE') + scope.expand('QMAKE_USE') \ + + scope.expand('LIBS_PRIVATE') + scope.expand('LIBS') if dependencies: cm_fh.write('{} LIBRARIES\n'.format(ind)) is_framework = False @@ -807,7 +832,8 @@ def is_simple_condition(condition: str) -> bool: def write_ignored_keys(scope: Scope, ignored_keys, indent) -> str: result = '' for k in sorted(ignored_keys): - if k == '_INCLUDED' or k == 'TARGET' or k == 'QMAKE_DOCS': + if k == '_INCLUDED' or k == 'TARGET' or k == 'QMAKE_DOCS' or k == 'QT_SOURCE_TREE' \ + or k == 'QT_BUILD_TREE': # All these keys are actually reported already continue values = scope.get(k) |