summaryrefslogtreecommitdiffstats
path: root/cmake/QtHeadersClean.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtHeadersClean.cmake')
-rw-r--r--cmake/QtHeadersClean.cmake139
1 files changed, 139 insertions, 0 deletions
diff --git a/cmake/QtHeadersClean.cmake b/cmake/QtHeadersClean.cmake
new file mode 100644
index 0000000000..9719cdbaa5
--- /dev/null
+++ b/cmake/QtHeadersClean.cmake
@@ -0,0 +1,139 @@
+# Add a custom ${module_include_name}_header_check target that builds each header in
+# ${module_headers} with a custom set of defines. This makes sure our public headers
+# are self-contained, and also compile with more strict compiler options.
+function(qt_internal_add_headers_clean_target
+ module_target
+ module_include_name
+ module_headers)
+ # module_headers is a list of strings of the form
+ # <headerfile>[:feature]
+ set(hclean_headers "")
+ foreach(entry ${module_headers})
+ string(REPLACE ":" ";" entry_list ${entry})
+ list(LENGTH entry_list entry_list_length)
+ list(GET entry_list 0 entry_path)
+
+ if (${entry_list_length} EQUAL 2)
+ list(GET entry_list 1 entry_feature)
+ if (NOT QT_FEATURE_${entry_feature})
+ message(STATUS "headersclean: Ignoring header ${entry_path} because of missing feature ${entry_feature}")
+ continue()
+ endif()
+ endif()
+ list(APPEND hclean_headers ${entry_path})
+ endforeach()
+
+ # Make sure that the header compiles with our strict options
+ set(hcleanDEFS -DQT_NO_CAST_TO_ASCII
+ -DQT_NO_CAST_FROM_ASCII
+ -DQT_NO_URL_CAST_FROM_STRING
+ -DQT_NO_CAST_FROM_BYTEARRAY
+ -DQT_NO_KEYWORDS
+ -DQT_USE_QSTRINGBUILDER
+ -DQT_USE_FAST_OPERATOR_PLUS)
+
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"
+ OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"
+ OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
+ # Turn on some extra warnings not found in -Wall -Wextra.
+
+ set(hcleanFLAGS -Wall -Wextra -Werror -Woverloaded-virtual -Wshadow -Wundef -Wfloat-equal
+ -Wnon-virtual-dtor -Wpointer-arith -Wformat-security -Wno-long-long -Wno-variadic-macros
+ -pedantic-errors)
+
+ if(QT_FEATURE_reduce_relocations AND UNIX)
+ list(APPEND hcleanFLAGS -fPIC)
+ endif()
+
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
+ # these warnings are disabled because explicit constructors with zero or
+ # multiple arguments are permitted in C++11:
+ # 2304: non-explicit constructor with single argument may cause implicit type
+ # conversion
+ # 2305: declaration of 'explicit' constructor without a single argument is
+ # redundant
+ #
+ # ICC 14+ has a bug with -Wshadow, emitting it for cases where there's no
+ # shadowing (issue ID 0000698329, task DPD200245740)
+ list(APPEND hcleanFLAGS -wd2304,2305 -Wshadow)
+ else()
+ # options accepted by GCC and Clang
+ list(APPEND hcleanFLAGS -Wchar-subscripts -Wold-style-cast)
+
+ if (NOT ((TEST_architecture_arch STREQUAL arm)
+ OR (TEST_architecture_arch STREQUAL mips)))
+ list(APPEND hcleanFLAGS -Wcast-align)
+ endif()
+
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ list(APPEND hcleanFLAGS -Wzero-as-null-pointer-constant)
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.5)
+ list(APPEND hcleanFLAGS -Wdouble-promotion)
+ endif()
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.9)
+ list(APPEND hcleanFLAGS -Wfloat-conversion)
+
+ # GCC 9 has a lot of false positives relating to these
+ list(APPEND hcleanFlags -Wno-deprecated-copy -Wno-redundant-move
+ -Wno-format-overflow -Wno-init-list-lifetime)
+ endif()
+ endif()
+ endif()
+
+ # Use strict mode C++17, with no GNU extensions (see -pedantic-errors above).
+ list(APPEND hcleanFLAGS -std=c++17)
+
+ foreach(header ${hclean_headers})
+ get_filename_component(input_path "${header}" ABSOLUTE)
+ set(artifact_path "header_${header}.o")
+
+ add_custom_command(
+ OUTPUT "${artifact_path}"
+ COMMENT "headersclean: Checking header ${header}"
+ COMMAND "${CMAKE_CXX_COMPILER}" -c ${CMAKE_CXX_FLAGS} ${hcleanFLAGS}
+ -I "${QT_BUILD_DIR}/include" ${hcleanDEFS} -xc++ "${input_path}"
+ -o${artifact_path}
+ IMPLICIT_DEPENDS CXX
+ VERBATIM)
+ list(APPEND hclean_artifacts "${artifact_path}")
+ endforeach()
+
+ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
+ # 4180: qualifier applied to function type has no meaning; ignored
+ # 4458: declaration of 'identifier' hides class member
+ # 4577: 'noexcept' used with no exception handling mode specified; termination on
+ # exception is not guaranteed. Specify /EHsc
+ #
+ # -Za would enable strict standards behavior, but we can't add it because
+ # <windows.h> and <GL.h> violate the standards.
+ set(hcleanFLAGS -std:c++17 -WX -W3 -wd4180 -wd4458 -wd4577)
+
+ # cl.exe needs a source path
+ get_filename_component(source_path "${QT_MKSPECS_DIR}/features/data/dummy.cpp" REALPATH)
+
+ foreach(header ${hclean_headers})
+ # We need realpath here to make sure path starts with drive letter
+ get_filename_component(input_path "${header}" REALPATH)
+ set(artifact_path "header_${header}.o")
+
+ add_custom_command(
+ OUTPUT "${artifact_path}"
+ COMMENT "headersclean: Checking header ${header}"
+ COMMAND "${CMAKE_CXX_COMPILER}" -nologo -c ${CMAKE_CXX_FLAGS} ${hcleanFLAGS}
+ -I "${QT_BUILD_DIR}/include" ${hcleanDEFS} -FI "${input_path}"
+ -Fo${artifact_path} "${source_path}"
+ IMPLICIT_DEPENDS CXX
+ VERBATIM)
+ list(APPEND hclean_artifacts "${artifact_path}")
+ endforeach()
+ else()
+ message(ERROR "CMAKE_CXX_COMPILER_ID \"${CMAKE_CXX_COMPILER_ID}\" is not supported for the headersclean check.")
+ endif()
+
+ add_custom_target(${module_include_name}_header_check
+ COMMENT "headersclean: Checking headers in ${module_include_name}"
+ DEPENDS ${hclean_artifacts}
+ VERBATIM)
+
+ add_dependencies(${module_target} ${module_include_name}_header_check)
+endfunction()