# Custom compiler for qface: # # If building a module, use load(ivigenerator_qt_module) instead # # Example input: # QFACE_SOURCES += my.foo.qface [required] # QFACE_MODULE_NAME = my_module_name # QFACE_FORMAT = frontend (or backend, simulator... -- defaults to "frontend") # QFACE_OUTPUT_DIR = my_output_dir (defaults to current build dir) # isEmpty(QFACE_FORMAT): QFACE_FORMAT = frontend isEmpty(QFACE_OUTPUT_DIR): QFACE_OUTPUT_DIR = $$OUT_PWD isEmpty(QFACE_SOURCES): error("QFACE_SOURCES must be set!") !contains(QFACE_SOURCES, .+\\.qface$) { error("Invalid qface file provided: The file needs to end with .qface") } # See the win32 section, why this is needed win32:!contains(CONFIG, debug_and_release) { error("The ivigenerator works only in the debug_and_release configuration on windows") } QFACE_PWD = $$dirname(QFACE_SOURCES) QFACE_ABS_PWD = $$absolute_path($$QFACE_PWD, $$_PRO_FILE_PWD_) QFACE_FILE = $$basename(QFACE_SOURCES) QFACE_BASE_NAME = $$replace(QFACE_FILE, .qface, ) QFACE_YAML = $$QFACE_ABS_PWD/$${QFACE_BASE_NAME}.yaml OTHER_FILES += $$QFACE_FILE # Detect whether we are using the feature inside the qtivi repository VIRTUALENV_PATH = $$[QT_HOST_BINS]/ivigenerator/qtivi_qface_virtualenv INTERNAL_VIRTUALENV_PATH = $$QTIVI_BUILD_ROOT/src/tools/ivigenerator/qtivi_qface_virtualenv IVI_GENERATOR_PATH = $$[QT_HOST_BINS]/ivigenerator QTEST_ENVIRONMENT = $$upper($$(QTEST_ENVIRONMENT)) # Try to use the internal virtualenv when building qtivi # Because of the two stage build of COIN, it might not exist, but the installed version should still be there !isEmpty(QTIVI_BUILD_ROOT):!equals(QTEST_ENVIRONMENT, CI) { VIRTUALENV_PATH = $$INTERNAL_VIRTUALENV_PATH } !isEmpty(QTIVI_BUILD_ROOT):!equals(QTEST_ENVIRONMENT, CI) { IVI_GENERATOR_PATH = $$QTIVI_ROOT/src/tools/ivigenerator } win32: VIRTUALENV_PYTHON = $$VIRTUALENV_PATH/Scripts/python.exe else: VIRTUALENV_PYTHON = $$VIRTUALENV_PATH/bin/python IVI_GENERATOR = $$VIRTUALENV_PYTHON $$IVI_GENERATOR_PATH/generate.py # The 'click' library used by the generator needs to have a utf8 locale setup. win32: ENV = chcp 65001 && else: ENV = LC_ALL="en_US.UTF-8" # TODO make this work with multiple input files, or only support one QFACE_SOURCE # Although this could be extra_compiler it is a normal EXTRA_TARGET for a reason. # In the debug_and_release configuration, we want to have the generator executed # during the run of the meta Makefile to only generate the code once. PRI = $$QFACE_OUTPUT_DIR/$$lower($${QFACE_BASE_NAME}).pri IVI_GENERATOR_OPTIONS = --format=$$QFACE_FORMAT !isEmpty(QFACE_MODULE_NAME): IVI_GENERATOR_OPTIONS += --module=$$QFACE_MODULE qface_sources.target = $$relative_path($$PRI, $$OUT_PWD) qface_sources.commands = $$ENV $$shell_path($$IVI_GENERATOR) $$IVI_GENERATOR_OPTIONS $$shell_path($$QFACE_ABS_PWD/$${QFACE_FILE}) $$shell_path($$QFACE_OUTPUT_DIR) qface_sources.depends = $$IVI_GENERATOR_PATH/generate.py # Add all templates of the generator format as dependency QFACE_TEMPLATE_PWD = $$IVI_GENERATOR_PATH/templates_$${QFACE_FORMAT} exists($$QFACE_TEMPLATE_PWD) { qface_sources.depends += $$files($${QFACE_TEMPLATE_PWD}/*) } # Add the configuration yaml as dependency and to other files exists($$QFACE_YAML) { qface_sources.depends += $$QFACE_YAML OTHER_FILES += $$QFACE_YAML } !isEmpty(QFACE_HEADERS_OUTPUT_DIR) { QFACE_HEADERS_OUTPUT_TARGET = $${QFACE_HEADERS_OUTPUT_DIR}/$$lower($${QFACE_MODULE_NAME})module.h qface_headers.target = $$relative_path($$QFACE_HEADERS_OUTPUT_TARGET, $$OUT_PWD) qface_headers.commands = $${QMAKE_COPY_FILE} $${QFACE_OUTPUT_DIR}/*.h $${QFACE_HEADERS_OUTPUT_DIR} qface_headers.depends = $$relative_path($$PRI, $$OUT_PWD) $$IVI_GENERATOR_PATH/generate.py } # Reevaluate the Makefile after the generation has finished Makefile.target = Makefile # The relative_path is needed here as qmake will use a relative_path for the output files # when using a QMAKE_EXTRA_COMPILER Makefile.depends = $$relative_path($$PRI, $$OUT_PWD) # Make the qmake_all target work for usage inside QtCreator # Because of the Makefile target the generator is called before the actual Makefile # is evaluated. This is a problem if the virtualenv is not created yet. # In this case we create the target with a dependency to the forceRebuild file. # This file is created during the qmake run and updated once the virtualenv is ready # and will then cause a rerun of qmake !isEmpty(QTIVI_BUILD_ROOT):!exists($$VIRTUALENV_PATH): { Makefile.depends = $$shadowed($$IVI_GENERATOR_PATH)/forceRebuild } else { !isEmpty(QFACE_HEADERS_OUTPUT_TARGET) { Makefile.depends += $$relative_path($$QFACE_HEADERS_OUTPUT_TARGET, $$OUT_PWD) QMAKE_EXTRA_TARGETS += qface_headers } } # After the generation, this should exists and qmake can create the correct build tree exists($$PRI) { # save the state and reset for SOURCES, HEADERS and OTHER_FILES # Afterwards add all autogenerated files to the 'make clean' target SOURCES_ORIG = $$SOURCES SOURCES = HEADERS_ORIG = $$HEADERS HEADERS = OTHER_FILES_ORIG = $$OTHER_FILES OTHER_FILES = include($$PRI) QMAKE_CLEAN += $$SOURCES QMAKE_CLEAN += $$HEADERS QMAKE_CLEAN += $$OTHER_FILES QMAKE_CLEAN += $$PRI SOURCES += $$SOURCES_ORIG HEADERS += $$HEADERS_ORIG OTHER_FILES += $$OTHER_FILES_ORIG } QMAKE_EXTRA_TARGETS += Makefile qface_sources # NMAKE doesn't support the Makefile target to call qmake and reevaluate itself # Because of that, the autogeneration is not started at all and if started # qmake is not run and the Makefile revaluated... # To workaround this, we depend on debug_and_release as a meta Makefile is generated # where we can envorce the run of the generator and qmake. # Afterwards the sub makefiles are read (Makefile.debug/release), which have been # regenerated before starting NMAKE on them. win32 { qmake.depends = $$relative_path($$PRI, $$OUT_PWD) debug.depends = qmake debug-make_first.depends = qmake debug-all.depends = qmake release.depends = qmake release-make_first.depends = qmake release-all.depends = qmake QMAKE_EXTRA_TARGETS += debug debug-make_first debug-all \ release release-make_first release-all \ qmake }