summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2016-11-18 19:42:07 +0100
committerMichal Klocek <michal.klocek@qt.io>2016-12-16 17:00:44 +0000
commite00ac03b406f7588a41b83f6d33a8306c3dd92b8 (patch)
treec66ea729f77492fb0fb6c4312817d6abd54f7822
parent794606237796b976f9cede7bfdc218e4de6a42ec (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.pro24
-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.pri6
-rw-r--r--src/core/core_gyp_config.pri5
-rw-r--r--src/src.pro2
-rw-r--r--tools/qmake/mkspecs/features/gn_generator.prf184
-rw-r--r--tools/scripts/gn_find_mocables.py68
-rw-r--r--tools/scripts/gn_run_binary.py33
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:]))