| load(moc) |
| load(resources) |
| |
| defineReplace(getTargetType) { |
| equals(TEMPLATE, "app"):return("executable") |
| equals(TEMPLATE, "lib") { |
| CONFIG(static): return("static_library") |
| return("shared_library") |
| } |
| return("none") |
| } |
| |
| defineReplace(filter_flag_values) { |
| value_to_check = $$1 |
| if (macos|ios):equals(value_to_check, "$(EXPORT_ARCH_ARGS)") { |
| # EXPORT_ARCH_ARGS comes from qtbase/mkspecs/features/mac/default_post.prf which is a way |
| # to figure out the architectures to pass to the compiler at Makefile time. Because this |
| # variable expansion is not supported by GN, we filter it out. GN takes care of assigning |
| # the architecture itself. |
| return("") |
| } |
| if (ios) { |
| equals(value_to_check, "$(EXPORT_QMAKE_XARCH_LFLAGS)"): return("") |
| equals(value_to_check, "$(EXPORT_QMAKE_XARCH_CFLAGS)"): return("") |
| } |
| |
| return($$value_to_check) |
| } |
| |
| 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 += " [" |
| 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 += " [" |
| 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 += "if (moc_source_h_files != []) {" |
| 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 += "}" |
| GN_CONTENTS += "if (moc_source_cpp_files != []) {" |
| 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 += " }" |
| GN_CONTENTS += "}" |
| |
| # RESOURCES SETUP |
| |
| CLEAN_QMAKE_RCC = $$clean_path($$QMAKE_RCC) |
| |
| !isEmpty(RESOURCES) { |
| 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 += "}" |
| } |
| |
| # CONFIG SETUP |
| |
| GN_CONTENTS += "config(\"$${TARGET}_config\") {" |
| !isEmpty(QMAKE_CFLAGS) { |
| GN_CONTENTS += " cflags = [" |
| for(flag, QMAKE_CFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\"," |
| GN_CONTENTS += " ]" |
| } |
| |
| !isEmpty(QMAKE_FRAMEWORKPATH) { |
| GN_CONTENTS += " cflags += [" |
| for(path, QMAKE_FRAMEWORKPATH): GN_CONTENTS += " \"-F$$path\"," |
| GN_CONTENTS += " ]" |
| } |
| |
| # Stop the barrage of unused variables warnings. |
| gcc|clang|clang_cl { |
| QMAKE_CXXFLAGS += "-Wno-unused-parameter" |
| QMAKE_CXXFLAGS += "-Wno-unused-variable" |
| } else:msvc { |
| QMAKE_CXXFLAGS += /wd4100 /wd4101 |
| } |
| |
| # Chromium activates this, but we need it off to be able to compile QFlags |
| clang_cl { |
| QMAKE_CXXFLAGS += "-fno-complete-member-pointers" |
| } |
| |
| !isEmpty(QMAKE_CXXFLAGS) { |
| GN_CONTENTS += " cflags_cc = [" |
| for(flag, QMAKE_CXXFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\"," |
| GN_CONTENTS += " ]" |
| } |
| |
| GN_CONTENTS += " defines = [" |
| # Remove single quotes around function macro defines, so that GN doesn't escape them, thus breaking |
| # the macro. |
| # Also add a layer of escaping for double quotes. |
| for (define, DEFINES): { |
| define = $$replace(define,\",\\\") |
| define = $$replace(define,\',) |
| GN_CONTENTS += " \"$$define\"," |
| } |
| GN_CONTENTS += " ]" |
| |
| GN_CONTENTS += " include_dirs = [" |
| for (path, INCLUDEPATH): GN_CONTENTS += " \"$$path\"," |
| GN_CONTENTS += " rebase_path(\"$target_gen_dir/.moc/\")," |
| GN_CONTENTS += " \"$$QMAKESPEC\"" |
| GN_CONTENTS += " ]" |
| |
| GN_CONTENTS += " ldflags = [" |
| for (flag, QMAKE_LFLAGS): GN_CONTENTS += " \"$$filter_flag_values($$flag)\"," |
| for (flag, GN_FLAGS): GN_CONTENTS += " \"$$flag\"," |
| !isEmpty(QMAKE_RPATHDIR) { |
| for (rpath, QMAKE_RPATHDIR) { |
| unix:!macos: GN_CONTENTS += " \"-Wl,-rpath=$${rpath}\"," |
| } |
| } |
| !isEmpty(QMAKE_RPATHLINKDIR): GN_CONTENTS += " \"-Wl,-rpath-link=$${QMAKE_RPATHLINKDIR}\"," |
| GN_CONTENTS += " ]" |
| |
| GN_CONTENTS += " lib_dirs = [" |
| lib_dirs = $$find(LIBS, ^-L.*) |
| lib_dirs = $$unique(lib_dirs) |
| for (lib_dir, lib_dirs): GN_CONTENTS += " \"$$replace(lib_dir, -L, )\"," |
| GN_CONTENTS += " ]" |
| |
| GN_CONTENTS += "}" |
| |
| # TARGET SETUP |
| |
| TARGET_TYPE = $$getTargetType() |
| |
| GN_CONTENTS += "$${TARGET_TYPE}(\"$$TARGET\") {" |
| !isEmpty(GN_CREATE_PRI): GN_CONTENTS += " create_pri_file = $$GN_CREATE_PRI" |
| !isEmpty(GN_IMPORTS) { |
| for (imp, GN_IMPORTS): GN_CONTENTS += " import(\"$$imp\")" |
| } |
| |
| GN_CONTENTS += " configs += [ \":$${TARGET}_config\" ]" |
| !isEmpty(GN_PRECOMPILED_HEADERS): GN_CONTENTS += " configs += [ \"//build/config:precompiled_headers\" ]" |
| |
| # 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. |
| !isEmpty(RESOURCES): GN_CONTENTS += " sources += get_target_outputs(\":generate_resources\")" |
| |
| GN_CONTENTS += " if (!defined(libs)) {"\ |
| " libs = []"\ |
| " }" |
| GN_CONTENTS += " libs += [" |
| for (lib, GN_LIBS): GN_CONTENTS += " \"$$lib\"," |
| libs = $$find(LIBS, ^-l.*) |
| libs = $$unique(libs) |
| for (lib, libs): GN_CONTENTS += " \"$$replace(lib, -l, )\"," |
| GN_CONTENTS += " ]" |
| |
| GN_CONTENTS += " if (!defined(deps)) {"\ |
| " deps = []"\ |
| " }" |
| |
| !isEmpty(RESOURCES) { |
| GN_CONTENTS += " deps += [" |
| GN_CONTENTS += " \":generate_resources\"," |
| GN_CONTENTS += " ]" |
| } |
| |
| # Remove the default no_rtti config for our own cpp files, thus leaving the decision |
| # to the compiler's defaults. This is consistent with how qtbase does it. |
| # Unless the user explicitly configured Qt with a different RTTI setting. |
| # Windows only for now, because macOS (and presumably Linux) does not support |
| # partial rtti info (e.g. rtti info present for derived class, but not base class), and the |
| # qtbase rtti feature affects only Windows. |
| win32 { |
| GN_CONTENTS += " configs -= [\"//build/config/compiler:no_rtti\"]" |
| CONFIG(rtti_off): GN_CONTENTS += " configs += [\"//build/config/compiler:no_rtti\"]" |
| CONFIG(rtti): GN_CONTENTS += " configs += [\"//build/config/compiler:rtti\"]" |
| } |
| gcc:!qtConfig(reduce_exports) { |
| GN_CONTENTS += " configs -= [\"//build/config/gcc:symbol_visibility_hidden\"]" |
| } |
| |
| GN_CONTENTS += " if (moc_source_h_files != []) {" |
| GN_CONTENTS += " deps += [" |
| GN_CONTENTS += " \":generate_h_mocs\"," |
| GN_CONTENTS += " ]" |
| # Add moc output files to compile |
| GN_CONTENTS += " sources += get_target_outputs(\":generate_h_mocs\")" |
| GN_CONTENTS += " }" |
| GN_CONTENTS += " if (moc_source_cpp_files != []) {" |
| GN_CONTENTS += " deps += [" |
| GN_CONTENTS += " \":generate_cpp_mocs\"," |
| GN_CONTENTS += " ]" |
| GN_CONTENTS += " }" |
| GN_CONTENTS += "}" |
| !isEmpty(GN_CORE_INCLUDE_DIRS) { |
| GN_CONTENTS += " if (!defined(core_include_dirs)) {"\ |
| " core_include_dirs = []"\ |
| " }" |
| GN_CONTENTS += "core_include_dirs += [" |
| for (inc, GN_CORE_INCLUDE_DIRS): GN_CONTENTS += " \"$$inc\"," |
| GN_CONTENTS += "]" |
| } |
| |
| !isEmpty(GN_INCLUDES) { |
| for (inc, GN_INCLUDES): GN_CONTENTS += $$cat($$inc,lines) |
| } |
| |
| build_pass|!debug_and_release: 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 = |
| |
| QMAKE_DISTCLEAN += $$GN_FILE |