summaryrefslogtreecommitdiff
path: root/mkspecs/features/ivigenerator.prf
blob: e94d981626f1b58293651d3bff93b10d23360ee4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# 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)
#
QT_FOR_CONFIG += ivicore-private

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-msvc*:!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

# The 'click' library used by the generator needs to have a utf8 locale setup.
equals(QMAKE_HOST.os, Windows): ENV = chcp 65001 &&
else: ENV = LC_ALL="en_US.UTF-8"

# 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
QT_FOR_CONFIG *= ivicore-private
!isEmpty(QTIVI_BUILD_ROOT):!equals(QTEST_ENVIRONMENT, CI):!qtConfig(system-ivigenerator) {
    VIRTUALENV_PATH = $$INTERNAL_VIRTUALENV_PATH
    IVI_GENERATOR_PATH = $$QTIVI_ROOT/src/tools/ivigenerator
    equals(QMAKE_HOST.os, Windows): ENV += set IVIGENERATOR_CONFIG="$$shell_path($$QTIVI_BUILD_ROOT/src/tools/ivigenerator/.config)" &&
    else: ENV += IVIGENERATOR_CONFIG="$$shell_path($$QTIVI_BUILD_ROOT/src/tools/ivigenerator/.config)"
}

equals(QMAKE_HOST.os, Windows) {
    VIRTUALENV_PYTHON = $$VIRTUALENV_PATH/Scripts/python.exe
} else {
    VIRTUALENV_PYTHON = $$VIRTUALENV_PATH/bin/python
    ENV += LD_LIBRARY_PATH="$$shell_path($$VIRTUALENV_PATH/bin)"
}
IVI_GENERATOR = $$VIRTUALENV_PYTHON $$IVI_GENERATOR_PATH/generate.py

# 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

# Windows doesn't offer any other way to sleep for a time inside non-interactive scripts
equals(QMAKE_HOST.os, Windows): SLEEP = ping -n 2 127.0.0.1 >nul
else: SLEEP = sleep 1

qface_sources.target = $$relative_path($$PRI, $$OUT_PWD)
qface_sources.commands = $$SLEEP && $$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-msvc* {
    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
}