cmake/AddCompilerFlags.cmake
authorAlan Knowles <alan@roojs.com>
Thu, 14 Feb 2019 07:56:23 +0000 (15:56 +0800)
committerAlan Knowles <alan@roojs.com>
Thu, 14 Feb 2019 07:56:23 +0000 (15:56 +0800)
CMakeLists.txt

CMakeLists.txt
cmake/AddCompilerFlags.cmake

index e3ac3bf..2bd9507 100644 (file)
@@ -2,7 +2,7 @@ project("roojspacker" C)
 
 cmake_minimum_required(VERSION 3.2)
 
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/vala)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
 
 include(FindVala)
 
index e69de29..c8e6077 100644 (file)
@@ -0,0 +1,186 @@
+# Copyright (c) 2016 Evan Nemerson <evan@nemerson.com>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# This module provides a convenient way to add C/C++ compiler flags if
+# the compiler supports them.
+
+include (CheckCCompilerFlag)
+include (CheckCXXCompilerFlag)
+
+# Depending on the settings, some compilers will accept unknown flags.
+# We try to disable this behavior by also passing these flags when we
+# check if a flag is supported.
+set (ADD_COMPILER_FLAGS_PREPEND "")
+
+if ("GNU" STREQUAL "${CMAKE_C_COMPILER_ID}")
+  set (ADD_COMPILER_FLAGS_PREPEND "-Wall -Wextra -Werror")
+elseif ("Clang" STREQUAL "${CMAKE_C_COMPILER_ID}")
+  set (ADD_COMPILER_FLAGS_PREPEND "-Werror=unknown-warning-option")
+endif ()
+
+##
+# Set a variable to different flags, depending on which compiler is in
+# use.
+#
+# Example:
+#   set_compiler_flags(VARIABLE varname MSVC /wd666 INTEL /wd1729)
+#
+#   This will set varname to /wd666 if the compiler is MSVC, and /wd1729
+#   if it is Intel.
+#
+# Possible compilers:
+#  - GCC: GNU C Compiler
+#  - GCCISH: A compiler that (tries to) be GCC-compatible on the CLI
+#    (i.e., anything but MSVC).
+#  - CLANG: clang
+#  - MSVC: Microsoft Visual C++ compiler
+#  - INTEL: Intel C Compiler
+#
+# Note: the compiler is determined based on the value of the
+# CMAKE_C_COMPILER_ID variable, not CMAKE_CXX_COMPILER_ID.
+##
+function (set_compiler_specific_flags)
+  set (oneValueArgs VARIABLE)
+  set (multiValueArgs GCC GCCISH INTEL CLANG MSVC)
+  cmake_parse_arguments(COMPILER_SPECIFIC_FLAGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+  unset (options)
+  unset (oneValueArgs)
+  unset (multiValueArgs)
+
+  set (compiler_flags)
+
+  if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+    list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_GCC})
+  elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+    list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_CLANG})
+  elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel")
+    list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_INTEL})
+  elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
+    list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_MSVC})
+  endif()
+
+  if (NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
+    list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_GCCISH})
+  endif ()
+
+  set (${COMPILER_SPECIFIC_FLAGS_VARIABLE} "${compiler_flags}" PARENT_SCOPE)
+endfunction ()
+
+function (source_file_add_compiler_flags_unchecked file)
+  set (flags ${ARGV})
+  list (REMOVE_AT flags 0)
+  get_source_file_property (sources ${file} SOURCES)
+
+  foreach (flag ${flags})
+    get_source_file_property (existing ${file} COMPILE_FLAGS)
+    if ("${existing}" STREQUAL "NOTFOUND")
+      set_source_files_properties (${file}
+        PROPERTIES COMPILE_FLAGS "${flag}")
+    else ()
+      set_source_files_properties (${file}
+        PROPERTIES COMPILE_FLAGS "${existing} ${flag}")
+    endif ()
+  endforeach (flag)
+endfunction ()
+
+function (source_file_add_compiler_flags file)
+  set (flags ${ARGV})
+  list (REMOVE_AT flags 0)
+  get_source_file_property (sources ${file} SOURCES)
+
+  foreach (flag ${flags})
+    if ("GNU" STREQUAL "${CMAKE_C_COMPILER_ID}")
+      # Because https://gcc.gnu.org/wiki/FAQ#wnowarning
+      string (REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}")
+    else ()
+      set (flag_to_test ${flag})
+    endif ()
+
+    if ("${file}" MATCHES "\\.c$")
+      string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CFLAG_${flag_to_test}")
+      CHECK_C_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name})
+    elseif ("${file}" MATCHES "\\.(cpp|cc|cxx)$")
+      string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CXXFLAG_${flag_to_test}")
+      CHECK_CXX_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name})
+    endif ()
+
+    if (${test_name})
+      source_file_add_compiler_flags_unchecked (${file} ${flag})
+    endif ()
+
+    unset (test_name)
+    unset (flag_to_test)
+  endforeach (flag)
+
+  unset (flags)
+endfunction ()
+
+function (target_add_compiler_flags target)
+  set (flags ${ARGV})
+  list (REMOVE_AT flags 0)
+  get_target_property (sources ${target} SOURCES)
+
+  foreach (source ${sources})
+    source_file_add_compiler_flags (${source} ${flags})
+  endforeach (source)
+
+  unset (flags)
+  unset (sources)
+endfunction (target_add_compiler_flags)
+
+# global_add_compiler_flags (flag1 [flag2 [flag3 ...]]):
+#
+# This just adds the requested compiler flags to
+# CMAKE_C/CXX_FLAGS variable if they work with the compiler.
+function (global_add_compiler_flags)
+  set (flags ${ARGV})
+
+  foreach (flag ${flags})
+    if ("GNU" STREQUAL "${CMAKE_C_COMPILER_ID}")
+      # Because https://gcc.gnu.org/wiki/FAQ#wnowarning
+      string (REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}")
+    else ()
+      set (flag_to_test "${flag}")
+    endif ()
+
+    string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" c_test_name "CFLAG_${flag_to_test}")
+    CHECK_C_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${c_test_name})
+    if (${c_test_name})
+      set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+    endif ()
+    unset (c_test_name)
+
+    string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" cxx_test_name "CFLAG_${flag_to_test}")
+    CHECK_CXX_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${cxx_test_name})
+    if (${cxx_test_name})
+      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+    endif ()
+    unset (cxx_test_name)
+
+    unset (flag_to_test)
+  endforeach (flag)
+
+  unset (flags)
+
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" PARENT_SCOPE)
+  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
+endfunction (global_add_compiler_flags)
\ No newline at end of file