summaryrefslogtreecommitdiffstats
path: root/Tests/QtAutogen/CMakeLists.txt
blob: 260331b43a95ef956c016d8fcd73946052349f65 (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
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}/autorcc_depends"
  "${CMAKE_CURRENT_SOURCE_DIR}/autorcc_depends"
  autorcc_depends
  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 autorcc_depends failed. Output: ${output}")
endif()

file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/info_file.txt" qrc_files)

list(GET qrc_files 0 qrc_file1)

set(timeformat "%Y%j%H%M%S")

file(TIMESTAMP "${qrc_file1}" file1_before "${timeformat}")

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}/autorcc_depends/res1/input.txt")

execute_process(COMMAND "${CMAKE_COMMAND}" --build .
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends"
)

file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}")

if (NOT file1_step1 GREATER file1_before)
  message(SEND_ERROR "file1 (${qrc_file1}) should have changed in the first step!")
endif()

# -- Test
# Ensure a repeated build succeeds when a header containing a QObject changes
try_compile(MOC_RERUN
  "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
  "${CMAKE_CURRENT_SOURCE_DIR}/automoc_rerun"
  automoc_rerun
  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 automoc_rerun failed. Output: ${output}")
endif()

configure_file(automoc_rerun/test1.h.in2 automoc_rerun/test1.h COPYONLY)

execute_process(COMMAND "${CMAKE_COMMAND}" --build .
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun"
  RESULT_VARIABLE automoc_rerun_result
  )
if (automoc_rerun_result)
  message(SEND_ERROR "Second build of automoc_rerun failed.")
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 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(mocPluginBinDir "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin")
  find_library(style_a_file "PluginStyleA" "${mocPluginBinDir}")
  find_library(style_b_file "PluginStyleB" "${mocPluginBinDir}")
  find_library(style_c_file "PluginStyleC" "${mocPluginBinDir}")
  find_library(style_d_file "PluginStyleD" "${mocPluginBinDir}")

  file(TIMESTAMP "${style_a_file}" style_a_before "${timeformat}")
  file(TIMESTAMP "${style_b_file}" style_b_before "${timeformat}")
  file(TIMESTAMP "${style_c_file}" style_c_before "${timeformat}")
  file(TIMESTAMP "${style_d_file}" style_d_before "${timeformat}")

  # Ensure that the timestamp will change and touch the json files
  execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
  execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/StyleC.json")
  execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${mocPluginBinDir}/jsonFiles/sub/StyleD.json")

  execute_process(COMMAND "${CMAKE_COMMAND}" --build .
    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocPlugin"
  )

  file(TIMESTAMP "${style_a_file}" style_a_after "${timeformat}")
  file(TIMESTAMP "${style_b_file}" style_b_after "${timeformat}")
  file(TIMESTAMP "${style_c_file}" style_c_after "${timeformat}")
  file(TIMESTAMP "${style_d_file}" style_d_after "${timeformat}")

  if (style_a_after GREATER style_a_before)
    message(SEND_ERROR "file (${style_a_file}) should not have changed!")
  endif()
  if (style_b_after GREATER style_b_before)
    message(SEND_ERROR "file (${style_b_file}) should not have changed!")
  endif()
  if (NOT style_c_after GREATER style_c_before)
    message(SEND_ERROR "file (${style_c_file}) should have changed!")
  endif()
  if (NOT style_d_after GREATER style_d_before)
    message(SEND_ERROR "file (${style_d_file}) should have changed!")
  endif()
endif()

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