1*09537850SAkhilesh Sanikop# Copyright 2019 The libgav1 Authors 2*09537850SAkhilesh Sanikop# 3*09537850SAkhilesh Sanikop# Licensed under the Apache License, Version 2.0 (the "License"); 4*09537850SAkhilesh Sanikop# you may not use this file except in compliance with the License. 5*09537850SAkhilesh Sanikop# You may obtain a copy of the License at 6*09537850SAkhilesh Sanikop# 7*09537850SAkhilesh Sanikop# http://www.apache.org/licenses/LICENSE-2.0 8*09537850SAkhilesh Sanikop# 9*09537850SAkhilesh Sanikop# Unless required by applicable law or agreed to in writing, software 10*09537850SAkhilesh Sanikop# distributed under the License is distributed on an "AS IS" BASIS, 11*09537850SAkhilesh Sanikop# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*09537850SAkhilesh Sanikop# See the License for the specific language governing permissions and 13*09537850SAkhilesh Sanikop# limitations under the License. 14*09537850SAkhilesh Sanikop 15*09537850SAkhilesh Sanikopif(LIBGAV1_CMAKE_LIBGAV1_FLAGS_CMAKE_) 16*09537850SAkhilesh Sanikop return() 17*09537850SAkhilesh Sanikopendif() # LIBGAV1_CMAKE_LIBGAV1_FLAGS_CMAKE_ 18*09537850SAkhilesh Sanikopset(LIBGAV1_CMAKE_LIBGAV1_FLAGS_CMAKE_ 1) 19*09537850SAkhilesh Sanikop 20*09537850SAkhilesh Sanikopinclude(CheckCXXCompilerFlag) 21*09537850SAkhilesh Sanikopinclude(CheckCXXSourceCompiles) 22*09537850SAkhilesh Sanikop 23*09537850SAkhilesh Sanikop# Adds compiler flags specified by FLAGS to the sources specified by SOURCES: 24*09537850SAkhilesh Sanikop# 25*09537850SAkhilesh Sanikop# libgav1_set_compiler_flags_for_sources(SOURCES <sources> FLAGS <flags>) 26*09537850SAkhilesh Sanikopmacro(libgav1_set_compiler_flags_for_sources) 27*09537850SAkhilesh Sanikop unset(compiler_SOURCES) 28*09537850SAkhilesh Sanikop unset(compiler_FLAGS) 29*09537850SAkhilesh Sanikop unset(optional_args) 30*09537850SAkhilesh Sanikop unset(single_value_args) 31*09537850SAkhilesh Sanikop set(multi_value_args SOURCES FLAGS) 32*09537850SAkhilesh Sanikop cmake_parse_arguments(compiler "${optional_args}" "${single_value_args}" 33*09537850SAkhilesh Sanikop "${multi_value_args}" ${ARGN}) 34*09537850SAkhilesh Sanikop 35*09537850SAkhilesh Sanikop if(NOT (compiler_SOURCES AND compiler_FLAGS)) 36*09537850SAkhilesh Sanikop libgav1_die("libgav1_set_compiler_flags_for_sources: SOURCES and " 37*09537850SAkhilesh Sanikop "FLAGS required.") 38*09537850SAkhilesh Sanikop endif() 39*09537850SAkhilesh Sanikop 40*09537850SAkhilesh Sanikop set_source_files_properties(${compiler_SOURCES} PROPERTIES COMPILE_FLAGS 41*09537850SAkhilesh Sanikop ${compiler_FLAGS}) 42*09537850SAkhilesh Sanikop 43*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE GREATER 1) 44*09537850SAkhilesh Sanikop foreach(source ${compiler_SOURCES}) 45*09537850SAkhilesh Sanikop foreach(flag ${compiler_FLAGS}) 46*09537850SAkhilesh Sanikop message("libgav1_set_compiler_flags_for_sources: source:${source} " 47*09537850SAkhilesh Sanikop "flag:${flag}") 48*09537850SAkhilesh Sanikop endforeach() 49*09537850SAkhilesh Sanikop endforeach() 50*09537850SAkhilesh Sanikop endif() 51*09537850SAkhilesh Sanikopendmacro() 52*09537850SAkhilesh Sanikop 53*09537850SAkhilesh Sanikop# Tests compiler flags stored in list(s) specified by FLAG_LIST_VAR_NAMES, adds 54*09537850SAkhilesh Sanikop# flags to $LIBGAV1_CXX_FLAGS when tests pass. Terminates configuration if 55*09537850SAkhilesh Sanikop# FLAG_REQUIRED is specified and any flag check fails. 56*09537850SAkhilesh Sanikop# 57*09537850SAkhilesh Sanikop# ~~~ 58*09537850SAkhilesh Sanikop# libgav1_test_cxx_flag(<FLAG_LIST_VAR_NAMES <flag list variable(s)>> 59*09537850SAkhilesh Sanikop# [FLAG_REQUIRED]) 60*09537850SAkhilesh Sanikop# ~~~ 61*09537850SAkhilesh Sanikopmacro(libgav1_test_cxx_flag) 62*09537850SAkhilesh Sanikop unset(cxx_test_FLAG_LIST_VAR_NAMES) 63*09537850SAkhilesh Sanikop unset(cxx_test_FLAG_REQUIRED) 64*09537850SAkhilesh Sanikop unset(single_value_args) 65*09537850SAkhilesh Sanikop set(optional_args FLAG_REQUIRED) 66*09537850SAkhilesh Sanikop set(multi_value_args FLAG_LIST_VAR_NAMES) 67*09537850SAkhilesh Sanikop cmake_parse_arguments(cxx_test "${optional_args}" "${single_value_args}" 68*09537850SAkhilesh Sanikop "${multi_value_args}" ${ARGN}) 69*09537850SAkhilesh Sanikop 70*09537850SAkhilesh Sanikop if(NOT cxx_test_FLAG_LIST_VAR_NAMES) 71*09537850SAkhilesh Sanikop libgav1_die("libgav1_test_cxx_flag: FLAG_LIST_VAR_NAMES required") 72*09537850SAkhilesh Sanikop endif() 73*09537850SAkhilesh Sanikop 74*09537850SAkhilesh Sanikop unset(cxx_flags) 75*09537850SAkhilesh Sanikop foreach(list_var ${cxx_test_FLAG_LIST_VAR_NAMES}) 76*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 77*09537850SAkhilesh Sanikop message("libgav1_test_cxx_flag: adding ${list_var} to cxx_flags") 78*09537850SAkhilesh Sanikop endif() 79*09537850SAkhilesh Sanikop list(APPEND cxx_flags ${${list_var}}) 80*09537850SAkhilesh Sanikop endforeach() 81*09537850SAkhilesh Sanikop 82*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 83*09537850SAkhilesh Sanikop message("CXX test: all flags: ${cxx_flags}") 84*09537850SAkhilesh Sanikop endif() 85*09537850SAkhilesh Sanikop 86*09537850SAkhilesh Sanikop unset(all_cxx_flags) 87*09537850SAkhilesh Sanikop list(APPEND all_cxx_flags ${LIBGAV1_CXX_FLAGS} ${cxx_flags}) 88*09537850SAkhilesh Sanikop 89*09537850SAkhilesh Sanikop # Turn off output from check_cxx_source_compiles. Print status directly 90*09537850SAkhilesh Sanikop # instead since the logging messages from check_cxx_source_compiles can be 91*09537850SAkhilesh Sanikop # quite confusing. 92*09537850SAkhilesh Sanikop set(CMAKE_REQUIRED_QUIET TRUE) 93*09537850SAkhilesh Sanikop 94*09537850SAkhilesh Sanikop # Run the actual compile test. 95*09537850SAkhilesh Sanikop unset(libgav1_all_cxx_flags_pass CACHE) 96*09537850SAkhilesh Sanikop message("--- Running combined CXX flags test, flags: ${all_cxx_flags}") 97*09537850SAkhilesh Sanikop check_cxx_compiler_flag("${all_cxx_flags}" libgav1_all_cxx_flags_pass) 98*09537850SAkhilesh Sanikop 99*09537850SAkhilesh Sanikop if(cxx_test_FLAG_REQUIRED AND NOT libgav1_all_cxx_flags_pass) 100*09537850SAkhilesh Sanikop libgav1_die("Flag test failed for required flag(s): " 101*09537850SAkhilesh Sanikop "${all_cxx_flags} and FLAG_REQUIRED specified.") 102*09537850SAkhilesh Sanikop endif() 103*09537850SAkhilesh Sanikop 104*09537850SAkhilesh Sanikop if(libgav1_all_cxx_flags_pass) 105*09537850SAkhilesh Sanikop # Test passed: update the global flag list used by the libgav1 target 106*09537850SAkhilesh Sanikop # creation wrappers. 107*09537850SAkhilesh Sanikop set(LIBGAV1_CXX_FLAGS ${cxx_flags}) 108*09537850SAkhilesh Sanikop list(REMOVE_DUPLICATES LIBGAV1_CXX_FLAGS) 109*09537850SAkhilesh Sanikop 110*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 111*09537850SAkhilesh Sanikop message("LIBGAV1_CXX_FLAGS=${LIBGAV1_CXX_FLAGS}") 112*09537850SAkhilesh Sanikop endif() 113*09537850SAkhilesh Sanikop 114*09537850SAkhilesh Sanikop message("--- Passed combined CXX flags test") 115*09537850SAkhilesh Sanikop else() 116*09537850SAkhilesh Sanikop message("--- Failed combined CXX flags test, testing flags individually.") 117*09537850SAkhilesh Sanikop 118*09537850SAkhilesh Sanikop if(cxx_flags) 119*09537850SAkhilesh Sanikop message("--- Testing flags from $cxx_flags: " "${cxx_flags}") 120*09537850SAkhilesh Sanikop foreach(cxx_flag ${cxx_flags}) 121*09537850SAkhilesh Sanikop # Between 3.17.0 and 3.18.2 check_cxx_compiler_flag() sets a normal 122*09537850SAkhilesh Sanikop # variable at parent scope while check_cxx_source_compiles() continues 123*09537850SAkhilesh Sanikop # to set an internal cache variable, so we unset both to avoid the 124*09537850SAkhilesh Sanikop # failure / success state persisting between checks. See 125*09537850SAkhilesh Sanikop # https://gitlab.kitware.com/cmake/cmake/-/issues/21207. 126*09537850SAkhilesh Sanikop unset(cxx_flag_test_passed) 127*09537850SAkhilesh Sanikop unset(cxx_flag_test_passed CACHE) 128*09537850SAkhilesh Sanikop message("--- Testing flag: ${cxx_flag}") 129*09537850SAkhilesh Sanikop check_cxx_compiler_flag("${cxx_flag}" cxx_flag_test_passed) 130*09537850SAkhilesh Sanikop 131*09537850SAkhilesh Sanikop if(cxx_flag_test_passed) 132*09537850SAkhilesh Sanikop message("--- Passed test for ${cxx_flag}") 133*09537850SAkhilesh Sanikop else() 134*09537850SAkhilesh Sanikop list(REMOVE_ITEM cxx_flags ${cxx_flag}) 135*09537850SAkhilesh Sanikop message("--- Failed test for ${cxx_flag}, flag removed.") 136*09537850SAkhilesh Sanikop endif() 137*09537850SAkhilesh Sanikop endforeach() 138*09537850SAkhilesh Sanikop 139*09537850SAkhilesh Sanikop set(LIBGAV1_CXX_FLAGS ${cxx_flags}) 140*09537850SAkhilesh Sanikop endif() 141*09537850SAkhilesh Sanikop endif() 142*09537850SAkhilesh Sanikop 143*09537850SAkhilesh Sanikop if(LIBGAV1_CXX_FLAGS) 144*09537850SAkhilesh Sanikop list(REMOVE_DUPLICATES LIBGAV1_CXX_FLAGS) 145*09537850SAkhilesh Sanikop endif() 146*09537850SAkhilesh Sanikopendmacro() 147*09537850SAkhilesh Sanikop 148*09537850SAkhilesh Sanikop# Tests executable linker flags stored in list specified by FLAG_LIST_VAR_NAME, 149*09537850SAkhilesh Sanikop# adds flags to $LIBGAV1_EXE_LINKER_FLAGS when test passes. Terminates 150*09537850SAkhilesh Sanikop# configuration when flag check fails. libgav1_set_cxx_flags() must be called 151*09537850SAkhilesh Sanikop# before calling this macro because it assumes $LIBGAV1_CXX_FLAGS contains only 152*09537850SAkhilesh Sanikop# valid CXX flags. 153*09537850SAkhilesh Sanikop# 154*09537850SAkhilesh Sanikop# libgav1_test_exe_linker_flag(<FLAG_LIST_VAR_NAME <flag list variable)>) 155*09537850SAkhilesh Sanikopmacro(libgav1_test_exe_linker_flag) 156*09537850SAkhilesh Sanikop unset(link_FLAG_LIST_VAR_NAME) 157*09537850SAkhilesh Sanikop unset(optional_args) 158*09537850SAkhilesh Sanikop unset(multi_value_args) 159*09537850SAkhilesh Sanikop set(single_value_args FLAG_LIST_VAR_NAME) 160*09537850SAkhilesh Sanikop cmake_parse_arguments(link "${optional_args}" "${single_value_args}" 161*09537850SAkhilesh Sanikop "${multi_value_args}" ${ARGN}) 162*09537850SAkhilesh Sanikop 163*09537850SAkhilesh Sanikop if(NOT link_FLAG_LIST_VAR_NAME) 164*09537850SAkhilesh Sanikop libgav1_die("libgav1_test_link_flag: FLAG_LIST_VAR_NAME required") 165*09537850SAkhilesh Sanikop endif() 166*09537850SAkhilesh Sanikop 167*09537850SAkhilesh Sanikop libgav1_set_and_stringify(DEST linker_flags SOURCE_VARS 168*09537850SAkhilesh Sanikop ${link_FLAG_LIST_VAR_NAME}) 169*09537850SAkhilesh Sanikop 170*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 171*09537850SAkhilesh Sanikop message("EXE LINKER test: all flags: ${linker_flags}") 172*09537850SAkhilesh Sanikop endif() 173*09537850SAkhilesh Sanikop 174*09537850SAkhilesh Sanikop # Tests of $LIBGAV1_CXX_FLAGS have already passed. Include them with the 175*09537850SAkhilesh Sanikop # linker test. 176*09537850SAkhilesh Sanikop libgav1_set_and_stringify(DEST CMAKE_REQUIRED_FLAGS SOURCE_VARS 177*09537850SAkhilesh Sanikop LIBGAV1_CXX_FLAGS) 178*09537850SAkhilesh Sanikop 179*09537850SAkhilesh Sanikop # Cache the global exe linker flags. 180*09537850SAkhilesh Sanikop if(CMAKE_EXE_LINKER_FLAGS) 181*09537850SAkhilesh Sanikop set(cached_CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}) 182*09537850SAkhilesh Sanikop libgav1_set_and_stringify(DEST CMAKE_EXE_LINKER_FLAGS SOURCE 183*09537850SAkhilesh Sanikop ${linker_flags}) 184*09537850SAkhilesh Sanikop endif() 185*09537850SAkhilesh Sanikop 186*09537850SAkhilesh Sanikop libgav1_set_and_stringify(DEST CMAKE_EXE_LINKER_FLAGS SOURCE ${linker_flags} 187*09537850SAkhilesh Sanikop ${CMAKE_EXE_LINKER_FLAGS}) 188*09537850SAkhilesh Sanikop 189*09537850SAkhilesh Sanikop # Turn off output from check_cxx_source_compiles. Print status directly 190*09537850SAkhilesh Sanikop # instead since the logging messages from check_cxx_source_compiles can be 191*09537850SAkhilesh Sanikop # quite confusing. 192*09537850SAkhilesh Sanikop set(CMAKE_REQUIRED_QUIET TRUE) 193*09537850SAkhilesh Sanikop 194*09537850SAkhilesh Sanikop message("--- Running EXE LINKER test for flags: ${linker_flags}") 195*09537850SAkhilesh Sanikop 196*09537850SAkhilesh Sanikop unset(linker_flag_test_passed CACHE) 197*09537850SAkhilesh Sanikop set(libgav1_cxx_main "\nint main() { return 0; }") 198*09537850SAkhilesh Sanikop check_cxx_source_compiles("${libgav1_cxx_main}" linker_flag_test_passed) 199*09537850SAkhilesh Sanikop 200*09537850SAkhilesh Sanikop if(NOT linker_flag_test_passed) 201*09537850SAkhilesh Sanikop libgav1_die("EXE LINKER test failed.") 202*09537850SAkhilesh Sanikop endif() 203*09537850SAkhilesh Sanikop 204*09537850SAkhilesh Sanikop message("--- Passed EXE LINKER flag test.") 205*09537850SAkhilesh Sanikop 206*09537850SAkhilesh Sanikop # Restore cached global exe linker flags. 207*09537850SAkhilesh Sanikop if(cached_CMAKE_EXE_LINKER_FLAGS) 208*09537850SAkhilesh Sanikop set(CMAKE_EXE_LINKER_FLAGS ${cached_CMAKE_EXE_LINKER_FLAGS}) 209*09537850SAkhilesh Sanikop else() 210*09537850SAkhilesh Sanikop unset(CMAKE_EXE_LINKER_FLAGS) 211*09537850SAkhilesh Sanikop endif() 212*09537850SAkhilesh Sanikopendmacro() 213*09537850SAkhilesh Sanikop 214*09537850SAkhilesh Sanikop# Runs the libgav1 compiler tests. This macro builds up the list of list var(s) 215*09537850SAkhilesh Sanikop# that is passed to libgav1_test_cxx_flag(). 216*09537850SAkhilesh Sanikop# 217*09537850SAkhilesh Sanikop# Note: libgav1_set_build_definitions() must be called before this macro. 218*09537850SAkhilesh Sanikopmacro(libgav1_set_cxx_flags) 219*09537850SAkhilesh Sanikop unset(cxx_flag_lists) 220*09537850SAkhilesh Sanikop 221*09537850SAkhilesh Sanikop if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") 222*09537850SAkhilesh Sanikop list(APPEND cxx_flag_lists libgav1_base_cxx_flags) 223*09537850SAkhilesh Sanikop endif() 224*09537850SAkhilesh Sanikop 225*09537850SAkhilesh Sanikop # Append clang flags after the base set to allow -Wno* overrides to take 226*09537850SAkhilesh Sanikop # effect. Some of the base flags may enable a large set of warnings, e.g., 227*09537850SAkhilesh Sanikop # -Wall. 228*09537850SAkhilesh Sanikop if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 229*09537850SAkhilesh Sanikop list(APPEND cxx_flag_lists libgav1_clang_cxx_flags) 230*09537850SAkhilesh Sanikop endif() 231*09537850SAkhilesh Sanikop 232*09537850SAkhilesh Sanikop if(MSVC) 233*09537850SAkhilesh Sanikop list(APPEND cxx_flag_lists libgav1_msvc_cxx_flags) 234*09537850SAkhilesh Sanikop endif() 235*09537850SAkhilesh Sanikop 236*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 237*09537850SAkhilesh Sanikop if(cxx_flag_lists) 238*09537850SAkhilesh Sanikop libgav1_set_and_stringify(DEST cxx_flags SOURCE_VARS ${cxx_flag_lists}) 239*09537850SAkhilesh Sanikop message("libgav1_set_cxx_flags: internal CXX flags: ${cxx_flags}") 240*09537850SAkhilesh Sanikop endif() 241*09537850SAkhilesh Sanikop endif() 242*09537850SAkhilesh Sanikop 243*09537850SAkhilesh Sanikop if(LIBGAV1_CXX_FLAGS) 244*09537850SAkhilesh Sanikop list(APPEND cxx_flag_lists LIBGAV1_CXX_FLAGS) 245*09537850SAkhilesh Sanikop if(LIBGAV1_VERBOSE) 246*09537850SAkhilesh Sanikop message("libgav1_set_cxx_flags: user CXX flags: ${LIBGAV1_CXX_FLAGS}") 247*09537850SAkhilesh Sanikop endif() 248*09537850SAkhilesh Sanikop endif() 249*09537850SAkhilesh Sanikop 250*09537850SAkhilesh Sanikop libgav1_test_cxx_flag(FLAG_LIST_VAR_NAMES ${cxx_flag_lists}) 251*09537850SAkhilesh Sanikopendmacro() 252*09537850SAkhilesh Sanikop 253*09537850SAkhilesh Sanikop# Sets LIBGAV1_TEST_C_FLAGS and LIBGAV1_TEST_CXX_FLAGS. 254*09537850SAkhilesh Sanikop# 255*09537850SAkhilesh Sanikop# Note: libgav1_set_cxx_flags() must be called before this macro. Furthermore, 256*09537850SAkhilesh Sanikop# the call to this macro should be made after all additions to LIBGAV1_CXX_FLAGS 257*09537850SAkhilesh Sanikop# are complete. 258*09537850SAkhilesh Sanikopmacro(libgav1_set_test_flags) 259*09537850SAkhilesh Sanikop if(LIBGAV1_ENABLE_TESTS) 260*09537850SAkhilesh Sanikop set(LIBGAV1_TEST_CXX_FLAGS ${LIBGAV1_CXX_FLAGS}) 261*09537850SAkhilesh Sanikop list(FILTER LIBGAV1_TEST_CXX_FLAGS EXCLUDE REGEX "-Wframe-larger-than") 262*09537850SAkhilesh Sanikop 263*09537850SAkhilesh Sanikop if(NOT CMAKE_CXX_COMPILER_ID STREQUAL CMAKE_C_COMPILER_ID) 264*09537850SAkhilesh Sanikop message( 265*09537850SAkhilesh Sanikop FATAL_ERROR 266*09537850SAkhilesh Sanikop "C/CXX compiler mismatch (${CMAKE_C_COMPILER_ID} vs" 267*09537850SAkhilesh Sanikop " ${CMAKE_CXX_COMPILER_ID})! Compiler flags are only tested using" 268*09537850SAkhilesh Sanikop " CMAKE_CXX_COMPILER, rerun cmake with CMAKE_C_COMPILER set to the" 269*09537850SAkhilesh Sanikop " C compiler from the same package as CMAKE_CXX_COMPILER to ensure" 270*09537850SAkhilesh Sanikop " the build completes successfully.") 271*09537850SAkhilesh Sanikop endif() 272*09537850SAkhilesh Sanikop set(LIBGAV1_TEST_C_FLAGS ${LIBGAV1_TEST_CXX_FLAGS}) 273*09537850SAkhilesh Sanikop list(FILTER LIBGAV1_TEST_C_FLAGS EXCLUDE REGEX 274*09537850SAkhilesh Sanikop "-fvisibility-inlines-hidden") 275*09537850SAkhilesh Sanikop endif() 276*09537850SAkhilesh Sanikopendmacro() 277