diff options
author | Michal Klocek <michal.klocek@qt.io> | 2016-11-18 19:42:07 +0100 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2016-12-16 17:00:44 +0000 |
commit | e00ac03b406f7588a41b83f6d33a8306c3dd92b8 (patch) | |
tree | c66ea729f77492fb0fb6c4312817d6abd54f7822 | |
parent | 794606237796b976f9cede7bfdc218e4de6a42ec (diff) |
Add gn generator for pro files
Change-Id: I5f28314d79b4aad587b323b027eb6d74ad422a73
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | src/core/core.pro | 24 | ||||
-rw-r--r-- | src/core/core_generator.pro (renamed from src/core/core_gyp_generator.pro) | 13 | ||||
-rw-r--r-- | src/core/core_gn_config.pri | 6 | ||||
-rw-r--r-- | src/core/core_gyp_config.pri | 5 | ||||
-rw-r--r-- | src/src.pro | 2 | ||||
-rw-r--r-- | tools/qmake/mkspecs/features/gn_generator.prf | 184 | ||||
-rw-r--r-- | tools/scripts/gn_find_mocables.py | 68 | ||||
-rw-r--r-- | tools/scripts/gn_run_binary.py | 33 |
8 files changed, 318 insertions, 17 deletions
diff --git a/src/core/core.pro b/src/core/core.pro index 86fe838cb..e495685eb 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -9,26 +9,32 @@ core_api.file = api/core_api.pro core_module.file = core_module.pro core_module.depends = core_api -contains(WEBENGINE_CONFIG, use_gn) { +# core_generator.pro is a dummy .pro file that is used by qmake +# to generate our main .gyp/BUILD.gn file +core_generator.file = core_generator.pro +core_generator.depends = core_headers + + +use?(gn) { + gn_run.file = gn_run.pro - SUBDIRS += gn_run -} else { + gn_run.depends = core_generator - # core_gyp_generator.pro is a dummy .pro file that is used by qmake - # to generate our main .gyp file - core_gyp_generator.file = core_gyp_generator.pro - core_gyp_generator.depends = core_headers + SUBDIRS += gn_run \ + core_headers \ + core_generator +} else { # gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step. gyp_run.file = gyp_run.pro - gyp_run.depends = core_gyp_generator + gyp_run.depends = core_generator core_api.depends = gyp_run SUBDIRS += gyp_run \ core_api \ core_module \ core_headers \ - core_gyp_generator + core_generator !win32 { # gyp_configure_host.pro and gyp_configure_target.pro are phony pro files that diff --git a/src/core/core_gyp_generator.pro b/src/core/core_generator.pro index a09683ba6..223ea076e 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_generator.pro @@ -1,10 +1,9 @@ -# This is a dummy .pro file used to extract some aspects of the used configuration and feed them to gyp -# We want the gyp generation step to happen after all the other config steps. For that we need to prepend -# our gyp_generator.prf feature to the CONFIG variable since it is processed backwards -CONFIG = gyp_generator $$CONFIG -GYPFILE = $$OUT_PWD/core_generated.gyp -GYPINCLUDES += $$PWD/qtwebengine.gypi -GYPSRCDIR = $$PWD + +use?(gn) { + include(core_gn_config.pri) +} else { + include(core_gyp_config.pri) +} TEMPLATE = lib diff --git a/src/core/core_gn_config.pri b/src/core/core_gn_config.pri new file mode 100644 index 000000000..ea45977f5 --- /dev/null +++ b/src/core/core_gn_config.pri @@ -0,0 +1,6 @@ +CONFIG = gn_generator $$CONFIG +GN_SRC_DIR = $$PWD +GN_FILE = $$OUT_PWD/BUILD.gn +GN_FIND_MOCABLES_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_find_mocables.py) +GN_RUN_BINARY_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_run_binary.py) + diff --git a/src/core/core_gyp_config.pri b/src/core/core_gyp_config.pri new file mode 100644 index 000000000..999d019f9 --- /dev/null +++ b/src/core/core_gyp_config.pri @@ -0,0 +1,5 @@ +CONFIG = gyp_generator $$CONFIG +GYPFILE = $$OUT_PWD/core_generated.gyp +GYPINCLUDES += $$PWD/qtwebengine.gypi +GYPSRCDIR = $$PWD + diff --git a/src/src.pro b/src/src.pro index 3f793474f..26abd52cc 100644 --- a/src/src.pro +++ b/src/src.pro @@ -9,7 +9,7 @@ webengine_plugin.depends = webengine SUBDIRS += core -!contains(WEBENGINE_CONFIG, use_gn) { +!use?(gn) { SUBDIRS += process \ webengine \ webengine_plugin \ diff --git a/tools/qmake/mkspecs/features/gn_generator.prf b/tools/qmake/mkspecs/features/gn_generator.prf new file mode 100644 index 000000000..924297aae --- /dev/null +++ b/tools/qmake/mkspecs/features/gn_generator.prf @@ -0,0 +1,184 @@ +load(moc) +load(resources) + +defineReplace(getTargetType) { + equals(TEMPLATE, "app"):return("executable") + equals(TEMPLATE, "lib") { + CONFIG(static): return("static_library") + return("shared_library") + } + return("none") +} + +isEmpty(GN_FILE): GN_FILE = $$system_path($$_PRO_FILE_PWD_/BUILD.gn) +isEmpty(GN_RUN_BINARY_SCRIPT): GN_RUN_BINARY_SCRIPT = "//build/gn_run_binary.py" +isEmpty(GN_FIND_MOCABLES_SCRIPT): GN_FIND_MOCABLES_SCRIPT = "//build/gn_find_mocables.py" + +# MOC SETUP + +GN_CONTENTS += "moc_source_h_files = exec_script(\"$$GN_FIND_MOCABLES_SCRIPT\"," +GN_CONTENTS += " [ \"$$_PRO_FILE_PWD_\"," +for (headerfile, HEADERS): GN_CONTENTS += " \"$$GN_SRC_DIR/$$headerfile\"," +GN_CONTENTS += " ], \"list lines\", [\"$$system_path($$_PRO_FILE_)\"]"\ + ")" +GN_CONTENTS += "moc_source_cpp_files = exec_script(\"$$GN_FIND_MOCABLES_SCRIPT\"," +GN_CONTENTS += " [ \"$$_PRO_FILE_PWD_\"," +for (sourcefile, SOURCES): GN_CONTENTS += " \"$$GN_SRC_DIR/$$sourcefile\"," +GN_CONTENTS += " ], \"list lines\", [\"$$system_path($$_PRO_FILE_)\"]"\ + ")" + +DEFINES_LIST = $$join(DEFINES, " -D", "-D") +INCLUDE_LIST = $$join(INCLUDEPATH, " -I", "-I") + +# we don't generate a moc_predef file yet. +MOC_PREDEF_FILE = +MOC_COMMAND = $$clean_path($$mocCmdBase()) +MOC_COMMAND = $$replace(MOC_COMMAND, $$re_escape("$(DEFINES)"), $$DEFINES_LIST) +MOC_COMMAND = $$replace(MOC_COMMAND, $$re_escape("$(INCPATH)"), $$INCLUDE_LIST) +MOC_COMMAND = $$eval($$list($$MOC_COMMAND)) + +GN_CONTENTS += "action_foreach(\"generate_h_mocs\") {"\ + " script = \"$$GN_RUN_BINARY_SCRIPT\"" +GN_CONTENTS += " sources = moc_source_h_files" \ + " outputs = [ \"$target_gen_dir/.moc/moc_{{source_name_part}}.cpp\" ]" +GN_CONTENTS += " inputs = [ \"$$system_path($$_PRO_FILE_)\" ]" \ + " args = [" +for(token, MOC_COMMAND): GN_CONTENTS += " \"$$replace(token,\',)\"," +GN_CONTENTS += " \"{{source}}\"," \ + " \"-o\"," \ + " rebase_path(\"$target_gen_dir/.moc/moc_{{source_name_part}}.cpp\")"\ + " ]" +GN_CONTENTS += "}" +GN_CONTENTS += "action_foreach(\"generate_cpp_mocs\") {"\ + " script = \"$$GN_RUN_BINARY_SCRIPT\"" +GN_CONTENTS += " sources = moc_source_cpp_files" \ + " outputs = [ \"$target_gen_dir/.moc/{{source_name_part}}.moc\" ]" +GN_CONTENTS += " inputs = [ \"$$system_path($$_PRO_FILE_)\" ]" \ + " args = [" +for(token, MOC_COMMAND): GN_CONTENTS += " \"$$replace(token,\',)\"," +GN_CONTENTS += " \"{{source}}\"," \ + " \"-o\"," \ + " rebase_path(\"$target_gen_dir/.moc/{{source_name_part}}.moc\")"\ + " ]" +GN_CONTENTS += "}" + + + +# RESOURCES SETUP + +CLEAN_QMAKE_RCC = $$clean_path($$QMAKE_RCC) + +GN_CONTENTS += "action_foreach(\"generate_resources\") {"\ + " script = \"$$GN_RUN_BINARY_SCRIPT\"" +GN_CONTENTS += " sources = [" +for (sourcefile, RESOURCES): GN_CONTENTS += " \"$$GN_SRC_DIR/$$sourcefile\"," +GN_CONTENTS += " ]" \ + " outputs = [ \"$target_gen_dir/.rcc/qrc_{{source_name_part}}.cpp\" ]" +GN_CONTENTS += " inputs = [ \"$$system_path($$_PRO_FILE_)\" ]" \ + " args = [" \ + " \"$$replace(CLEAN_QMAKE_RCC,\',)\"," +for(resource_flag, $$QMAKE_RESOURCE_FLAGS): GN_CONTENTS += " \"$$resource_flag\"" +GN_CONTENTS += " \"-name\"," \ + " \"{{source_name_part}}\"," \ + " \"{{source}}\"," \ + " \"-o\"," \ + " rebase_path(\"$target_gen_dir/.rcc/qrc_{{source_name_part}}.cpp\")"\ + " ]" +GN_CONTENTS += "}" + +# TARGET SETUP + +TARGET_TYPE = $$getTargetType() + +GN_CONTENTS += "$${TARGET_TYPE}(\"$$TARGET\") {" + +!isEmpty(GN_IMPORTS) { +for (imp, GN_IMPORTS): GN_CONTENTS += " import(\"$$imp\")" +} + +!isEmpty(QMAKE_FRAMEWORKPATH) { + GN_CONTENTS += " mac_framework_dirs = [" + for(path, QMAKE_FRAMEWORKPATH): GN_CONTENTS += " \"$$path\"," + GN_CONTENTS += " ]" +} + +!isEmpty(QMAKE_CFLAGS) { + GN_CONTENTS += " cflags = [" + for(flag, QMAKE_CFLAGS): GN_CONTENTS += " \"$$flag\"," + GN_CONTENTS += " ]" +} +!isEmpty(QMAKE_CXXFLAGS) { + GN_CONTENTS += " cflags_cc = [" + for(flag, QMAKE_CXXFLAGS): GN_CONTENTS += " \"$$flag\"," + GN_CONTENTS += " ]" +} + +GN_CONTENTS += " defines += [" +for (define, DEFINES): GN_CONTENTS += " \"$$define\"," +!isEmpty(QMAKE_LIBDIR_EGL): + GN_CONTENTS += " \"QT_LIBDIR_EGL=\\\"$${QMAKE_DIR_SEP}$$relative_path($$QMAKE_LIBDIR_EGL, $$[QT_SYSROOT])\\\"\"," +!isEmpty(QMAKE_LIBDIR_OPENGL_ES2) + GN_CONTENTS += " \"QT_LIBDIR_GLES2=\\\"$${QMAKE_DIR_SEP}$$relative_path($$QMAKE_LIBDIR_OPENGL_ES2, $$[QT_SYSROOT])\\\"\"," +GN_CONTENTS += " ]" + +# Source files to compile +GN_CONTENTS += " sources = [" +for (sourcefile, SOURCES): GN_CONTENTS += " \"$$GN_SRC_DIR/$$sourcefile\"," +for (headerfile, HEADERS): GN_CONTENTS += " \"$$GN_SRC_DIR/$$headerfile\"," +GN_CONTENTS += " ]" + +# Add Sources generated by rcc from qrc files. +GN_CONTENTS += " sources += get_target_outputs(\":generate_resources\")" +# Add moc output files to compile +GN_CONTENTS += " sources += get_target_outputs(\":generate_h_mocs\")" + +GN_CONTENTS += " include_dirs += [" +for (path, INCLUDEPATH): GN_CONTENTS += " \"$$path\"," +GN_CONTENTS += " rebase_path(\"$target_gen_dir/.moc/\")" +GN_CONTENTS += " ]" + +GN_CONTENTS += " ldflags = [" +for (lib, LIBS): GN_CONTENTS += " \"$$lib\"," +GN_CONTENTS += " \"-Wl,-rpath=$$[QT_INSTALL_LIBS]\"," \ + " \"-Wl,-rpath-link=\"," +GN_CONTENTS += " ]" + +GN_CONTENTS += " deps += [" +!isEmpty(RESOURCES): GN_CONTENTS += " \":generate_resources\"," +GN_CONTENTS += " \":generate_h_mocs\"," +GN_CONTENTS += " \":generate_cpp_mocs\"," +GN_CONTENTS += " ]" + +!isEmpty(GN_LIBS) { + GN_CONTENTS += " libs += [" + for (lib, GN_LIBS): GN_CONTENTS += " \"$$lib\"," + GN_CONTENTS += " ]" +} + +!isEmpty(GN_STATIC_LIBS) { + GN_CONTENTS += " ldflags += [" + for (lib, GN_STATIC_LIBS) { + linux { + GN_CONTENTS += " \"-Wl,--whole-archive\"," + GN_CONTENTS += " \"$$lib\"," + GN_CONTENTS += " \"-Wl,--no-whole-archive\"," + } else: macos { + GN_CONTENTS += " \"-Wl,-force_load,$$lib\"," + } + } + GN_CONTENTS += " ]" +} + +GN_CONTENTS += "}" + +!isEmpty(GN_INCLUDES) { + for (inc, GN_INCLUDES): GN_CONTENTS += $$cat($$inc,lines) +} + +!build_pass: write_file($$GN_FILE, GN_CONTENTS) + +# The generated Makefile shouldn't build anything by itself, just re-run qmake if necessary +TEMPLATE = aux +SOURCES = +HEADERS = +RESOURCES = diff --git a/tools/scripts/gn_find_mocables.py b/tools/scripts/gn_find_mocables.py new file mode 100644 index 000000000..d97dcb534 --- /dev/null +++ b/tools/scripts/gn_find_mocables.py @@ -0,0 +1,68 @@ +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the QtWebEngine module of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import re +import sys +import os + +mocables = set() +includedMocs = set() +dir = sys.argv[1] +files = sys.argv[2:] + +for f in filter(os.path.isfile, [os.path.join(dir, f) for f in files]): + inBlockComment = False + for line in open(f).readlines(): + # Block comments handling + if "/*" in line: + inBlockComment = True + if inBlockComment and "*/" in line: + inBlockComment = False + if line.find("*/") != len(line) - 3: + line = line[line.find("*/")+2:] + else: + continue + if inBlockComment: + continue + #simple comments handling + if "//" in line: + line = line.partition("//")[0] + if re.match(".*Q_OBJECT", line): + mocables.add(f) + im = re.search('#include "(moc_\w+.cpp)"', line) + if im: + includedMocs.add(im.group(1)) + +for mocable in includedMocs: + print "Found included moc: " + mocable + +assert len(includedMocs) == 0 , "Included mocs are not supported !" + +for mocable in mocables: + print mocable +sys.exit(0) diff --git a/tools/scripts/gn_run_binary.py b/tools/scripts/gn_run_binary.py new file mode 100644 index 000000000..5debf02ab --- /dev/null +++ b/tools/scripts/gn_run_binary.py @@ -0,0 +1,33 @@ +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the QtWebEngine module of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + + +import sys +import subprocess + +sys.exit(subprocess.call(sys.argv[1:])) |