]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Reintroduce dev mode and disable problematic build flags in user mode
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 5 Dec 2020 18:17:32 +0000 (19:17 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 6 Dec 2020 07:59:51 +0000 (08:59 +0100)
In version 3.x, ccache was in “user mode” when building from release
archive sources and “dev mode” otherwise. In “dev mode”, additional
compiler flags like “-Wextra -Wpedantic -Werror” were added, but they
were not present in “user mode” in order not to break end users’ builds.
This behavior was partially lost in the conversion to CMake.

This commit tries to imitate the previous behavior by introducing a
CCACHE_DEV_MODE CMake variable and only enable potentially problematic
compiler flags when it’s set to ON.

Related to #730.

CMakeLists.txt
ci/build-and-verify-source-package
cmake/CcachePackConfig.cmake
cmake/CcacheVersion.cmake
cmake/DefaultBuildType.cmake
cmake/DevModeWarnings.cmake [new file with mode: 0644]
cmake/GenerateVersionFile.cmake
cmake/StandardWarnings.cmake
cmake/version.cpp.in
doc/CMakeLists.txt

index 39126a93b567820e8d22f2eda26402e20b798f57..b4a0ddcb9a526a23e94bb5feb04f8a31edf4197a 100644 (file)
@@ -51,6 +51,15 @@ endif()
 #
 # Settings
 #
+include(CcacheVersion)
+
+if("${CCACHE_VERSION_ORIGIN}" STREQUAL git OR DEFINED ENV{CI})
+  set(CCACHE_DEV_MODE ON)
+else()
+  set(CCACHE_DEV_MODE OFF)
+endif()
+message(STATUS "Ccache dev mode: ${CCACHE_DEV_MODE}")
+
 include(StandardSettings)
 include(StandardWarnings)
 include(CIBuildType)
index 5a212c2f46501398a0a30ad6a71f9f6a11b948b4..d74bc152c970f34b93bbfbf65322b87518d5bdb6 100755 (executable)
@@ -5,6 +5,9 @@
 
 set -eu
 
+# Unset CI variable to trigger ccache user build mode.
+unset CI
+
 # Ninja builds with relative paths so that ccache can be used to cache the build
 # without resorting to setting base_dir.
 export CMAKE_GENERATOR=Ninja
index daaca306d5f26a27019a139c7176a5f6f3116455..a35949da5224d8240d13193ff5c8ab15eb65b43e 100644 (file)
@@ -6,7 +6,7 @@ if(${CMAKE_VERSION} VERSION_LESS "3.9")
 endif()
 
 # From CcacheVersion.cmake.
-set(CPACK_PACKAGE_VERSION ${VERSION})
+set(CPACK_PACKAGE_VERSION ${CCACHE_VERSION})
 
 set(CPACK_VERBATIM_VARIABLES ON)
 
@@ -18,7 +18,7 @@ endif()
 
 set(
   CPACK_PACKAGE_FILE_NAME
-  "ccache-${VERSION}-${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}"
+  "ccache-${CCACHE_VERSION}-${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}"
 )
 
 include(CPack)
index e1cf88cabde4517ac7d26a00fd2bed58de190590..25fd7162000a4d28898f8510b0445e5ee7e43949 100644 (file)
@@ -1,3 +1,8 @@
+# This script sets two variables:
+#
+# - CCACHE_VERSION (version string)
+# - CCACHE_VERSION_ORIGIN (archive or git)
+#
 # There are three main scenarios:
 #
 # 1. Building from a source code archive generated by "git archive", e.g. the
 # 3. Building from a Git repository. In this case the version will be a proper
 #    version if building a tagged commit, otherwise "branch.hash(+dirty)". In
 #    case Git is not available, the version will be "unknown".
+#
+# CCACHE_VERSION_ORIGIN is set to "archive" in scenario 1 and "git" in scenario
+# 3.
 
 set(version_info "$Format:%H %D$")
 
 if(version_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]* (.*)")
   # Scenario 1.
+  set(CCACHE_VERSION_ORIGIN archive)
+
   set(hash "${CMAKE_MATCH_1}")
   set(ref_names "${CMAKE_MATCH_2}")
   if(ref_names MATCHES "tag: v([^,]+)")
     # Tagged commit.
-    set(VERSION "${CMAKE_MATCH_1}")
+    set(CCACHE_VERSION "${CMAKE_MATCH_1}")
   else()
     # Untagged commit.
-    set(VERSION "${hash}")
+    set(CCACHE_VERSION "${hash}")
   endif()
 elseif(EXISTS "${CMAKE_SOURCE_DIR}/.git")
   # Scenario 3.
+  set(CCACHE_VERSION_ORIGIN git)
+
   find_package(Git QUIET)
   if(NOT GIT_FOUND)
-    set(VERSION "unknown")
+    set(CCACHE_VERSION "unknown")
     message(WARNING "Could not find git")
   else()
     macro(git)
@@ -43,9 +55,9 @@ elseif(EXISTS "${CMAKE_SOURCE_DIR}/.git")
 
     git(describe --abbrev=8 --dirty)
     if(git_stdout MATCHES "^v([^-]+)(-dirty)?$")
-      set(VERSION "${CMAKE_MATCH_1}")
+      set(CCACHE_VERSION "${CMAKE_MATCH_1}")
       if(NOT "${CMAKE_MATCH_2}" STREQUAL "")
-        set(VERSION "${VERSION}+dirty")
+        set(CCACHE_VERSION "${CCACHE_VERSION}+dirty")
       endif()
     elseif(git_stdout MATCHES "^v[^-]+-[0-9]+-g([0-9a-f]+)(-dirty)?$")
       set(hash "${CMAKE_MATCH_1}")
@@ -55,12 +67,14 @@ elseif(EXISTS "${CMAKE_SOURCE_DIR}/.git")
       git(rev-parse --abbrev-ref HEAD)
       set(branch "${git_stdout}")
 
-      set(VERSION "${branch}.${hash}${dirty}")
+      set(CCACHE_VERSION "${branch}.${hash}${dirty}")
     endif() # else: fail below
   endif()
 endif()
 
-if(VERSION STREQUAL "")
+if(CCACHE_VERSION STREQUAL "")
   # Scenario 2 or unexpected error.
   message(SEND_ERROR "Cannot determine Ccache version")
 endif()
+
+message(STATUS "Ccache version: ${CCACHE_VERSION}")
index 87b76474587fd6fe02bd59b13413ef29fca91065..630ecfb8cb29240b35475e8672357ff48a513e1a 100644 (file)
@@ -6,7 +6,7 @@ endif()
 
 # Default to Release for end user builds (from source archive) and Debug for
 # development builds (in a Git repository).
-if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
+if(CCACHE_DEV_MODE)
   set(
     CMAKE_BUILD_TYPE "Debug"
     CACHE STRING "Choose the type of build." FORCE)
diff --git a/cmake/DevModeWarnings.cmake b/cmake/DevModeWarnings.cmake
new file mode 100644 (file)
index 0000000..1e3f223
--- /dev/null
@@ -0,0 +1,158 @@
+include(CheckCXXCompilerFlag)
+
+# check_cxx_compiler_flag caches the result, so a unique variable name is
+# required for every flag to be checked.
+#
+# Parameters:
+#
+# * flag [in], e.g. FLAG
+# * var_name_of_var_name [in], e.g. "TEMP". This is the variable that "HAS_FLAG"
+#   will be written to.
+function(generate_unique_has_flag_var_name flag var_name_of_var_name)
+  string(REGEX REPLACE "[=-]" "_" var_name "${flag}")
+  string(TOUPPER "${var_name}" var_name)
+  set(${var_name_of_var_name} "HAS_${var_name}" PARENT_SCOPE)
+endfunction()
+
+macro(add_compile_flag_if_supported_ex varname flag alternative_flag)
+  # has_flag will contain "HAS_$flag" so each flag gets a unique HAS variable.
+  generate_unique_has_flag_var_name("${flag}" "has_flag")
+
+  # Instead of passing "has_flag" this passes the content of has_flag.
+  check_cxx_compiler_flag("${flag}" "${has_flag}")
+
+  if(${${has_flag}})
+    list(APPEND "${varname}" "${flag}")
+  elseif("${alternative_flag}")
+    add_compile_flag_if_supported_ex("${varname}" ${alternative_flag} "")
+  endif()
+endmacro()
+
+macro(add_compile_flag_if_supported varname flag)
+  add_compile_flag_if_supported_ex("${varname}" "${flag}" "")
+endmacro()
+
+set(
+  _clang_gcc_warnings
+  -Wextra
+  -Wnon-virtual-dtor
+  -Wcast-align
+  -Wunused
+  -Woverloaded-virtual
+  -Wpedantic
+
+  # Candidates for enabling in the future:
+  # -Wshadow
+  # -Wold-style-cast
+  # -Wconversion
+  # -Wsign-conversion
+  # -Wnull-dereference
+  # -Wformat=2
+)
+
+# Tested separately as this is not supported by Clang 3.4.
+add_compile_flag_if_supported(_clang_gcc_warnings "-Wdouble-promotion")
+
+if(WARNINGS_AS_ERRORS)
+  list(APPEND _clang_gcc_warnings -Werror)
+endif()
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+  list(APPEND CCACHE_COMPILER_WARNINGS ${_clang_gcc_warnings})
+
+  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
+    list(
+      APPEND
+      CCACHE_COMPILER_WARNINGS
+      -Qunused-arguments
+      -Wno-error=unreachable-code
+    )
+  endif()
+
+  list(
+    APPEND
+    CCACHE_COMPILER_WARNINGS
+    -Weverything
+    -Wno-c++98-compat
+    -Wno-c++98-compat-pedantic
+    -Wno-constexpr-not-const
+    -Wno-conversion
+    -Wno-disabled-macro-expansion
+    -Wno-documentation-unknown-command
+    -Wno-exit-time-destructors
+    -Wno-format-nonliteral
+    -Wno-global-constructors
+    -Wno-implicit-fallthrough
+    -Wno-old-style-cast
+    -Wno-padded
+    -Wno-shadow # Warnings in fmtlib
+    -Wno-shorten-64-to-32
+    -Wno-sign-conversion
+    -Wno-signed-enum-bitfield # Warnings in fmtlib
+    -Wno-weak-vtables
+  )
+
+  # If compiler supports -Wshadow-field-in-constructor, disable only that.
+  # Otherwise disable shadow.
+  add_compile_flag_if_supported_ex(
+    CCACHE_COMPILER_WARNINGS "-Wno-shadow-field-in-constructor" "-Wno-shadow")
+
+  # Disable C++20 compatibility for now.
+  add_compile_flag_if_supported(CCACHE_COMPILER_WARNINGS "-Wno-c++2a-compat")
+
+  # If compiler supports these warnings they have to be disabled for now.
+  add_compile_flag_if_supported(
+    CCACHE_COMPILER_WARNINGS "-Wno-zero-as-null-pointer-constant")
+  add_compile_flag_if_supported(
+    CCACHE_COMPILER_WARNINGS "-Wno-undefined-func-template")
+  add_compile_flag_if_supported(
+    CCACHE_COMPILER_WARNINGS "-Wno-return-std-move-in-c++11")
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+  list(
+    APPEND
+    CCACHE_COMPILER_WARNINGS
+    ${_clang_gcc_warnings}
+
+    # Warn about logical operations being used where bitwise were probably
+    # wanted.
+    -Wlogical-op
+
+    # Candidates for enabling in the future:
+    # -Wduplicated-cond
+    # -Wduplicated-branches
+    # -Wuseless-cast
+  )
+
+  # TODO: Exact version or reason unknown, discovered in Ubuntu 14 Docker test
+  # with GCC 4.8.4
+  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8.5)
+    add_compile_flag_if_supported(
+      CCACHE_COMPILER_WARNINGS "-Wno-missing-field-initializers")
+    add_compile_flag_if_supported(
+      CCACHE_COMPILER_WARNINGS "-Wno-unused-variable")
+  endif()
+elseif(MSVC)
+  # Remove any warning level flags added by CMake.
+  string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}")
+  string(REGEX REPLACE "/W[0-4]" "" CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS}")
+  string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+
+  if(WARNINGS_AS_ERRORS)
+    list(APPEND CCACHE_COMPILER_WARNINGS /WE)
+  endif()
+
+  list(
+    APPEND
+    CCACHE_COMPILER_WARNINGS
+    /W4
+    # Ignore bad macro in winbase.h triggered by /Zc:preprocessor:
+    /wd5105
+    # Conversion warnings:
+    /wd4244
+    /wd4267
+    # Assignment in conditional:
+    /wd4706
+    # Non-underscore-prefixed POSIX functions:
+    /wd4996
+  )
+endif()
index 1517d440b5f64cf9716e52afb3c803c6fd6dadd1..7b2ad0cd4be1f318ffde5c6c121e4569b8f01de5 100644 (file)
@@ -1,6 +1,4 @@
-include(CcacheVersion)
 configure_file(
   ${CMAKE_SOURCE_DIR}/cmake/version.cpp.in
   ${CMAKE_BINARY_DIR}/src/version.cpp
   @ONLY)
-message(STATUS "Ccache version: ${VERSION}")
index 35077376766cbe51a3d8470aa4c4bcc4357033e8..6a0ca71b504d9e58744e198e3b5ae57a14b3d09b 100644 (file)
 # be linked privately by all product and test code, but not by third party code.
 add_library(standard_warnings INTERFACE)
 
-if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git" OR DEFINED ENV{"CI"})
-  # Enabled by default for development builds and CI builds.
+if(CCACHE_DEV_MODE)
+  # Enabled by default for developer builds.
   option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" TRUE)
 else()
-  # Disabled by default for end user builds so compilation doesn't fail with new
+  # Disabled by default for user builds so compilation doesn't fail with new
   # compilers that may emit new warnings.
   option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" FALSE)
 endif()
 
-include(CheckCXXCompilerFlag)
-
-# check_cxx_compiler_flag caches the result, so a unique variable name is
-# required for every flag to be checked.
-#
-# Parameters:
-#
-# * flag [in], e.g. FLAG
-# * var_name_of_var_name [in], e.g. "TEMP". This is the variable that "HAS_FLAG"
-#   will be written to.
-function(generate_unique_has_flag_var_name flag var_name_of_var_name)
-  string(REGEX REPLACE "[=-]" "_" var_name "${flag}")
-  string(TOUPPER "${var_name}" var_name)
-  set(${var_name_of_var_name} "HAS_${var_name}" PARENT_SCOPE)
-endfunction()
-
-function(add_target_compile_flag_if_supported_ex target flag alternative_flag)
-  # has_flag will contain "HAS_$flag" so each flag gets a unique HAS variable.
-  generate_unique_has_flag_var_name("${flag}" "has_flag")
-
-  # Instead of passing "has_flag" this passes the content of has_flag.
-  check_cxx_compiler_flag("${flag}" "${has_flag}")
-
-  if(${${has_flag}})
-    target_compile_options(${target} INTERFACE "${flag}")
-  elseif("${alternative_flag}")
-    add_target_compile_flag_if_supported_ex(${target} ${alternative_flag} "")
-  endif()
-endfunction()
-
-# TODO: Is there a better way to provide an optional third argument?
-macro(add_target_compile_flag_if_supported target flag)
-  add_target_compile_flag_if_supported_ex("${target}" "${flag}" "")
-endmacro()
-
-set(CLANG_GCC_WARNINGS
-    -Wall
-    -Wextra
-    -Wnon-virtual-dtor
-    -Wcast-align
-    -Wunused
-    -Woverloaded-virtual
-    -Wpedantic
-
-    # Candidates for enabling in the future:
-    # -Wshadow
-    # -Wold-style-cast
-    # -Wconversion
-    # -Wsign-conversion
-    # -Wnull-dereference
-    # -Wformat=2
-)
-# Tested separately as this is not supported by Clang 3.4.
-add_target_compile_flag_if_supported(standard_warnings "-Wdouble-promotion")
-
-if(WARNINGS_AS_ERRORS)
-  set(CLANG_GCC_WARNINGS ${CLANG_GCC_WARNINGS} -Werror)
+if(NOT MSVC)
+  set(CCACHE_COMPILER_WARNINGS -Wall)
 endif()
 
-if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0)
-    set(
-      CLANG_GCC_WARNINGS
-      ${CLANG_GCC_WARNINGS}
-      -Qunused-arguments
-      -Wno-error=unreachable-code)
-  endif()
-
-  target_compile_options(
-    standard_warnings
-    INTERFACE
-      ${CLANG_GCC_WARNINGS}
-      -Weverything
-      -Wno-c++98-compat-pedantic
-      -Wno-c++98-compat
-      -Wno-constexpr-not-const
-      -Wno-conversion
-      -Wno-disabled-macro-expansion
-      -Wno-documentation-unknown-command
-      -Wno-exit-time-destructors
-      -Wno-format-nonliteral
-      -Wno-global-constructors
-      -Wno-implicit-fallthrough
-      -Wno-padded
-      -Wno-shadow # Warnings in fmtlib
-      -Wno-shorten-64-to-32
-      -Wno-sign-conversion
-      -Wno-signed-enum-bitfield # Warnings in fmtlib
-      -Wno-weak-vtables
-      -Wno-old-style-cast)
-
-  # If compiler supports -Wshadow-field-in-constructor, disable only that.
-  # Otherwise disable shadow.
-  add_target_compile_flag_if_supported_ex(
-    standard_warnings "-Wno-shadow-field-in-constructor" "-Wno-shadow")
-
-  # Disable C++20 compatibility for now.
-  add_target_compile_flag_if_supported(standard_warnings "-Wno-c++2a-compat")
-
-  # If compiler supports these warnings they have to be disabled for now.
-  add_target_compile_flag_if_supported(
-    standard_warnings "-Wno-zero-as-null-pointer-constant")
-  add_target_compile_flag_if_supported(
-    standard_warnings "-Wno-undefined-func-template")
-  add_target_compile_flag_if_supported(
-    standard_warnings "-Wno-return-std-move-in-c++11")
-elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
-  target_compile_options(
-    standard_warnings
-    INTERFACE ${CLANG_GCC_WARNINGS}
-    # Warn about logical operations being used where bitwise were probably
-    # wanted.
-    -Wlogical-op
-
-    # Candidates for enabling in the future:
-    # -Wduplicated-cond
-    # -Wduplicated-branches
-    # -Wuseless-cast
-  )
-
-  # TODO: Exact version or reason unknown, discovered in Ubuntu 14 Docker test
-  # with GCC 4.8.4
-  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8.5)
-    add_target_compile_flag_if_supported(
-      standard_warnings "-Wno-missing-field-initializers")
-    add_target_compile_flag_if_supported(
-      standard_warnings "-Wno-unused-variable")
-  endif()
-elseif(MSVC)
-  # Remove any warning level flags added by CMake.
-  string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}")
-  string(REGEX REPLACE "/W[0-4]" "" CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS}")
-  string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-
-  target_compile_options(
-    standard_warnings
-    INTERFACE
-    /W4
-    # Ignore bad macro in winbase.h triggered by /Zc:preprocessor
-    /wd5105
-    # Conversion warnings.
-    /wd4244
-    /wd4267
-    # Assignment in conditional.
-    /wd4706
-    # Non-underscore-prefixed POSIX functions.
-    /wd4996
-  )
+if(CCACHE_DEV_MODE)
+  include(DevModeWarnings)
 endif()
+
+target_compile_options(standard_warnings INTERFACE ${CCACHE_COMPILER_WARNINGS})
index 291f049646d2ee6fff64b61a480f93580c880833..3b877464c0cf35886e03ed0d099f7ce513e8ad07 100644 (file)
@@ -1,2 +1,2 @@
 extern const char CCACHE_VERSION[];
-const char CCACHE_VERSION[] = "@VERSION@";
+const char CCACHE_VERSION[] = "@CCACHE_VERSION@";
index 8f866b8818d79192c00da767deff451bf377e1c3..c5ce224d9e99ff317e45f9ccf627107169da3fa6 100644 (file)
@@ -15,7 +15,7 @@ else()
       COMMAND
         ${ASCIIDOC_EXE}
           -o "${html_file}"
-          -a revnumber="${VERSION}"
+          -a revnumber="${CCACHE_VERSION}"
           -a toc
           -b xhtml11
           "${CMAKE_SOURCE_DIR}/${adoc_file}"
@@ -46,7 +46,7 @@ else()
       COMMAND
         ${ASCIIDOC_EXE}
           -o -
-          -a revnumber=${VERSION}
+          -a revnumber=${CCACHE_VERSION}
           -d manpage
           -b docbook "${CMAKE_SOURCE_DIR}/doc/MANUAL.adoc"
         | perl -pe 's!<literal>\(.*?\)</literal>!<emphasis role="strong">\\1</emphasis>!g'