summaryrefslogtreecommitdiffstats
path: root/Tests/QtAutogen/CMakeLists.txt
blob: 86af7465f43db33f10e19ffd554337b6059bae24 (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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
cmake_minimum_required(VERSION 3.7)

project(QtAutogen)

# Tell find_package(Qt5) where to find Qt.
if(QT_QMAKE_EXECUTABLE)
  get_filename_component(Qt_BIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH)
  get_filename_component(Qt_PREFIX_DIR "${Qt_BIN_DIR}" PATH)
  set(CMAKE_PREFIX_PATH ${Qt_PREFIX_DIR})
endif()

if (QT_TEST_VERSION STREQUAL 4)
  find_package(Qt4 REQUIRED)

  # Include this directory before using the UseQt4 file.
  add_subdirectory(defines_test)

  include(UseQt4)

  set(QT_QTCORE_TARGET Qt4::QtCore)

  macro(qtx_wrap_cpp)
    qt4_wrap_cpp(${ARGN})
  endmacro()

else()
  if (NOT QT_TEST_VERSION STREQUAL 5)
    message(SEND_ERROR "Invalid Qt version specified.")
  endif()
  find_package(Qt5Widgets REQUIRED)

  set(QT_QTCORE_TARGET Qt5::Core)

  include_directories(${Qt5Widgets_INCLUDE_DIRS})
  set(QT_LIBRARIES Qt5::Widgets)

  if(Qt5_POSITION_INDEPENDENT_CODE AND CMAKE_CXX_COMPILE_OPTIONS_PIC)
    add_definitions(${CMAKE_CXX_COMPILE_OPTIONS_PIC})
  endif()

  macro(qtx_wrap_cpp)
    qt5_wrap_cpp(${ARGN})
  endmacro()

endif()

get_property(QT_COMPILE_FEATURES TARGET ${QT_QTCORE_TARGET} PROPERTY INTERFACE_COMPILE_FEATURES)

# -- Test
# RCC only
add_executable(rccOnly rccOnly.cpp rccOnlyRes.qrc)
set_property(TARGET rccOnly PROPERTY AUTORCC ON)
target_link_libraries(rccOnly ${QT_QTCORE_TARGET})

# -- Test
# RCC empty
add_executable(rccEmpty rccEmpty.cpp rccEmptyRes.qrc)
set_property(TARGET rccEmpty PROPERTY AUTORCC ON)
target_link_libraries(rccEmpty ${QT_QTCORE_TARGET})

# -- Test
# UIC only
qtx_wrap_cpp(uicOnlyMoc uicOnlySource/uiconly.h)
add_executable(uicOnly uicOnlySource/uiconly.cpp ${uicOnlyMoc})
set_property(TARGET uicOnly PROPERTY AUTOUIC ON)
target_link_libraries(uicOnly ${QT_LIBRARIES})

# -- Test
# Add not_generated_file.qrc to the source list to get the file-level
# dependency, but don't generate a c++ file from it.  Disable the AUTORCC
# feature for this target.  This tests that qrc files in the sources don't
# have an effect on generation if AUTORCC is off.
add_library(empty STATIC empty.cpp not_generated_file.qrc)
set_target_properties(empty PROPERTIES AUTORCC OFF)
set_target_properties(empty PROPERTIES AUTOMOC TRUE)
target_link_libraries(empty no_link_language)
add_library(no_link_language STATIC empty.h)
set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE)
# Pass Qt compiler features to targets that don't link against Qt
target_compile_features(no_link_language PRIVATE ${QT_COMPILE_FEATURES})
target_compile_features(empty PRIVATE ${QT_COMPILE_FEATURES})

# -- Test
# When a file listed in a .qrc file changes the target must be rebuilt
try_compile(RCC_DEPENDS
  "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
  "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends"
  rccDepends
  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
  OUTPUT_VARIABLE output
)
if (NOT RCC_DEPENDS)
  message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}")
endif()

# Get name and timestamp of the output binary
file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/target1.txt" target1List)
list(GET target1List 0 binFile)
set(timeformat "%Y%j%H%M%S")
file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")

# Touch first qrc input file and rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res1/input.txt")
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
  RESULT_VARIABLE rccDepends_result
)
if (rccDepends_result)
  message(SEND_ERROR "Second build of rccDepends failed.")
endif()
# Compare timestamps
file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
if (NOT timeStep1 GREATER timeBegin)
  message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
endif()

# Touch second qrc input file and rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change.
execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res2/input.txt")
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends"
  RESULT_VARIABLE rccDepends_result
)
if (rccDepends_result)
  message(SEND_ERROR "Third build of rccDepends failed.")
endif()
# Compare timestamps
file(TIMESTAMP "${binFile}" timeStep2 "${timeformat}")
if (NOT timeStep2 GREATER timeStep1)
  message(SEND_ERROR "File (${binFile}) should have changed in the second step!")
endif()

# -- Test
# Ensure a repeated build succeeds when a header containing a QObject changes
try_compile(MOC_RERUN
  "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
  "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun"
  mocRerun
  CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
              "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
              "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
  OUTPUT_VARIABLE output
)
if (NOT MOC_RERUN)
  message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}")
endif()

# Get name and timestamp of the output binary
file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List)
list(GET target1List 0 binFile)
set(timeformat "%Y%j%H%M%S")
file(TIMESTAMP "${binFile}" timeBegin "${timeformat}")

# Change file content and rebuild
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY)
execute_process(COMMAND "${CMAKE_COMMAND}" --build .
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun"
  RESULT_VARIABLE mocRerun_result
  )
if (mocRerun_result)
  message(SEND_ERROR "Second build of mocRerun failed.")
endif()

# Compare timestamps
file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}")
if (NOT timeStep1 GREATER timeBegin)
  message(SEND_ERROR "File (${binFile}) should have changed in the first step!")
endif()

# -- Test
# Test for SKIP_AUTOMOC and SKIP_AUTOGEN on an AUTOMOC enabled target
qtx_wrap_cpp(skipMocWrapMoc
  skipSource/qItemA.hpp
  skipSource/qItemB.hpp)
set(skipMocSources
  skipMoc.cpp
  skipSource/qItemA.cpp
  skipSource/qItemB.cpp
  skipSource/qItemC.cpp)
set_property(SOURCE skipSource/qItemA.cpp PROPERTY SKIP_AUTOMOC ON)
set_property(SOURCE skipSource/qItemB.cpp PROPERTY SKIP_AUTOGEN ON)
# AUTOMOC enabled only
add_executable(skipMocA ${skipMocSources} ${skipMocWrapMoc})
set_property(TARGET skipMocA PROPERTY AUTOMOC ON)
target_link_libraries(skipMocA ${QT_LIBRARIES})
# AUTOMOC and AUTOUIC enabled
add_executable(skipMocB ${skipMocSources} ${skipMocWrapMoc})
set_property(TARGET skipMocB PROPERTY AUTOMOC ON)
set_property(TARGET skipMocB PROPERTY AUTOUIC ON)
target_link_libraries(skipMocB ${QT_LIBRARIES})

# -- Test
# Test for SKIP_AUTOUIC and SKIP_AUTOGEN on an AUTOUIC enabled target
set(skipUicSources
  skipUic.cpp
  skipSource/skipUicGen.cpp
  skipSource/skipUicNoGen1.cpp
  skipSource/skipUicNoGen2.cpp
)
set_property(SOURCE skipSource/skipUicNoGen1.cpp PROPERTY SKIP_AUTOUIC ON)
set_property(SOURCE skipSource/skipUicNoGen2.cpp PROPERTY SKIP_AUTOGEN ON)
# AUTOUIC enabled
add_executable(skipUicA ${skipUicSources})
set_property(TARGET skipUicA PROPERTY AUTOUIC ON)
target_link_libraries(skipUicA ${QT_LIBRARIES})
# AUTOUIC and AUTOMOC enabled
add_executable(skipUicB ${skipUicSources})
set_property(TARGET skipUicB PROPERTY AUTOUIC ON)
set_property(TARGET skipUicB PROPERTY AUTOMOC ON)
target_link_libraries(skipUicB ${QT_LIBRARIES})

# -- Test
# Test for SKIP_AUTORCC and SKIP_AUTOGEN on an AUTORCC enabled target
set(skipRccSources
  skipRcc.cpp
  skipSource/skipRccBad1.qrc
  skipSource/skipRccBad2.qrc
  skipSource/skipRccGood.qrc
)
set_property(SOURCE skipSource/skipRccBad1.qrc PROPERTY SKIP_AUTORCC ON)
set_property(SOURCE skipSource/skipRccBad2.qrc PROPERTY SKIP_AUTOGEN ON)
# AUTORCC enabled
add_executable(skipRccA ${skipRccSources})
set_property(TARGET skipRccA PROPERTY AUTORCC ON)
target_link_libraries(skipRccA ${QT_LIBRARIES})
# AUTORCC, AUTOUIC and AUTOMOC enabled
add_executable(skipRccB ${skipRccSources})
set_property(TARGET skipRccB PROPERTY AUTORCC ON)
set_property(TARGET skipRccB PROPERTY AUTOUIC ON)
set_property(TARGET skipRccB PROPERTY AUTOMOC ON)
target_link_libraries(skipRccB ${QT_LIBRARIES})

# -- Test
# Source files with the same basename in different subdirectories
add_subdirectory(sameName)

# -- Test
# Tests AUTOMOC with generated sources
add_subdirectory(mocDepends)

# -- Test
# Tests various include moc patterns
add_subdirectory(mocIncludeStrict)

# -- Test
# Tests various include moc patterns
add_subdirectory(mocIncludeRelaxed)

# -- Test
# Tests Q_PLUGIN_METADATA json file change detection
if (NOT QT_TEST_VERSION STREQUAL 4)
  try_compile(MOC_PLUGIN
    "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin"
    "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin"
    mocPlugin
    CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
                "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}"
    OUTPUT_VARIABLE output
  )
  if (NOT MOC_PLUGIN)
    message(SEND_ERROR "Initial build of mocPlugin failed. Output: ${output}")
  endif()

  set(timeformat "%Y%j%H%M%S")
  set(mocPlugSrcDir "${CMAKE_CURRENT_SOURCE_DIR}/mocPlugin")
  set(mocPlugBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
  find_library(plAFile "PlugA" PATHS "${mocPlugBinDir}" NO_DEFAULT_PATH)
  find_library(plBFile "PlugB" PATHS "${mocPlugBinDir}" NO_DEFAULT_PATH)
  find_library(plCFile "PlugC" PATHS "${mocPlugBinDir}" NO_DEFAULT_PATH)
  find_library(plDFile "PlugD" PATHS "${mocPlugBinDir}" NO_DEFAULT_PATH)

  file(TIMESTAMP "${plAFile}" plABefore "${timeformat}")
  file(TIMESTAMP "${plBFile}" plBBefore "${timeformat}")
  file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
  file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")

  # Ensure that the timestamp will change and change the json files
  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
  configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC.json")
  configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD.json")
  execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")

  file(TIMESTAMP "${plAFile}" plAAfter "${timeformat}")
  file(TIMESTAMP "${plBFile}" plBAfter "${timeformat}")
  file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
  file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")

  if (plAAfter GREATER plABefore)
    message(SEND_ERROR "file (${plAFile}) should not have changed!")
  endif()
  if (plBAfter GREATER plBBefore)
    message(SEND_ERROR "file (${plBFile}) should not have changed!")
  endif()
  if (NOT plCAfter GREATER plCBefore)
    message(SEND_ERROR "file (${plCFile}) should have changed!")
  endif()
  if (NOT plDAfter GREATER plDBefore)
    message(SEND_ERROR "file (${plDFile}) should have changed!")
  endif()

  # Test custom macro
  file(TIMESTAMP "${plCFile}" plCBefore "${timeformat}")
  file(TIMESTAMP "${plDFile}" plDBefore "${timeformat}")
  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
  configure_file("${mocPlugSrcDir}/jsonIn/StyleD.json" "${mocPlugBinDir}/jsonFiles/StyleC_Custom.json")
  configure_file("${mocPlugSrcDir}/jsonIn/StyleC.json" "${mocPlugBinDir}/jsonFiles/sub/StyleD_Custom.json")
  execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${mocPlugBinDir}")
  file(TIMESTAMP "${plCFile}" plCAfter "${timeformat}")
  file(TIMESTAMP "${plDFile}" plDAfter "${timeformat}")
  if (NOT plCAfter GREATER plCBefore)
    message(SEND_ERROR "file (${plCFile}) should have changed!")
  endif()
  if (NOT plDAfter GREATER plDBefore)
    message(SEND_ERROR "file (${plDFile}) should have changed!")
  endif()

endif()

# -- Test
# Tests various .ui include directories
add_subdirectory(uicInclude)

# -- Test
# Complex test case
add_subdirectory(complex)