10bbfda8aSnia# 20bbfda8aSnia# Compiler/stdlib feature checks for ctwm 30bbfda8aSnia# 40bbfda8aSnia 50bbfda8aSnia 60bbfda8aSnia# Expect and try to enforce a C99 capable compiler. There doesn't seem 70bbfda8aSnia# an obvious way to be sure in a fully portable way, but we probably 80bbfda8aSnia# don't work well in places that compile with something other than a 90bbfda8aSnia# program called like 'cc', and a cc that supports C99 should accept -std 100bbfda8aSnia# calls, so that's good enough. Lacking it is not (yet) a fatal error, 110bbfda8aSnia# but is a sign that it's a compiler or platform we're moving further 120bbfda8aSnia# away from. 130bbfda8aSnia# 14b18c2d1eSnia# cmake 3.1+ has C_STANDARD and related vars that seem like they'd help 15b18c2d1eSnia# with this, but it's unclear that they actually solve the whole 16b18c2d1eSnia# problem... 17b18c2d1eSnia# 180bbfda8aSnia# Known alternate spellings: 190bbfda8aSnia# -xc99 (Sun C 5.10 SunOS_i386, sunstudio12.1, OpenIndiana) 200bbfda8aSniainclude(CheckCCompilerFlag) 21b18c2d1eSniaset(MANUAL_C_STD_FLAG true) 22b18c2d1eSniaif(NOT MANUAL_C_STD_FLAG) 23b18c2d1eSnia # This is the Better Way(tm), but is disabled by default because, as 24b18c2d1eSnia # with the manual one below, the added arg doesn't apply in 25b18c2d1eSnia # check_symbol_exists(), so it screws up the tests below. I'm unable 26b18c2d1eSnia # to find a way to get info from cmake about what arg it would add 27b18c2d1eSnia # for the specified standard, so we can't pull it out manually to add 28b18c2d1eSnia # like we do our found C99_FLAG below, so... 29b18c2d1eSnia if(NOT "c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES) 30b18c2d1eSnia message(WARNING "cmake doesn't know about c99 support for this " 31b18c2d1eSnia "compiler, trying manual search...") 32b18c2d1eSnia set(MANUAL_C_STD_FLAG true) 33b18c2d1eSnia else() 34b18c2d1eSnia message(STATUS "Enabling C99 mode") 35b18c2d1eSnia set(CMAKE_C_EXTENSIONS false) 36b18c2d1eSnia set(CMAKE_C_STANDARD 99) 37b18c2d1eSnia endif() 38b18c2d1eSniaendif() 39b18c2d1eSniaif(MANUAL_C_STD_FLAG) 40b18c2d1eSnia set(c99_flag_options -std=c99 -xc99) 41b18c2d1eSnia foreach(_C99_FLAG ${c99_flag_options}) 42b18c2d1eSnia # CheckCCompilerFlag calls into CheckCSourceCompiles, which won't do 43b18c2d1eSnia # anything if the result var is already set in the cache, so we have 44b18c2d1eSnia # to unset it. Otherwise, the second and later invocations don't 45b18c2d1eSnia # actually do anything, and it'll never check any flag after the 46b18c2d1eSnia # first. 47b18c2d1eSnia unset(COMPILER_C99_FLAG CACHE) 48b18c2d1eSnia check_c_compiler_flag(${_C99_FLAG} COMPILER_C99_FLAG) 49b18c2d1eSnia if(COMPILER_C99_FLAG) 50b18c2d1eSnia set(C99_FLAG ${_C99_FLAG}) 51b18c2d1eSnia break() 52b18c2d1eSnia endif(COMPILER_C99_FLAG) 53b18c2d1eSnia endforeach(_C99_FLAG) 54b18c2d1eSnia if(C99_FLAG) 55b18c2d1eSnia message(STATUS "Enabling C99 flag: ${C99_FLAG}") 56b18c2d1eSnia add_definitions(${C99_FLAG}) 57b18c2d1eSnia else() 58b18c2d1eSnia message(WARNING "Compiler doesn't support known C99 flag, " 59b18c2d1eSnia "building without it.") 60b18c2d1eSnia endif(C99_FLAG) 61b18c2d1eSniaendif() 62b18c2d1eSnia 63b18c2d1eSnia 64b18c2d1eSnia 65b18c2d1eSnia# With -std=c99, some systems/compilers/etc enable ANSI strictness, and 66b18c2d1eSnia# so don't export symbols from headers for e.g. a lot of POSIX etc stuff. 67b18c2d1eSnia# So we may need some extra -D's. 68b18c2d1eSnia# Some refs: 69b18c2d1eSnia# https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html 70b18c2d1eSnia# https://illumos.org/man/5/standards 71b18c2d1eSnia 72b18c2d1eSnia# Somewhat irritatingly, check_symbol_exists() doesn't use the extra 73b18c2d1eSnia# flags we set above for the C standard. So we have to add it manually, 74b18c2d1eSnia# and stash up the old C_R_D. x-ref above. 75b18c2d1eSniaset(OLD_CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) 76b18c2d1eSnialist(APPEND CMAKE_REQUIRED_DEFINITIONS ${C99_FLAG}) 77b18c2d1eSnia 78b18c2d1eSnia# What might and will we add? 79b18c2d1eSniaset(AVAIL_SYM_FLAGS -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 80b18c2d1eSnia -D_GNU_SOURCE -D__EXTENSIONS__) 81b18c2d1eSniaset(EXTRA_SYM_FLAGS "") 82b18c2d1eSnia 83b18c2d1eSnia# Abstract 84b18c2d1eSniamacro(_check_func_flag FUNC HEADER) 85b18c2d1eSnia unset(_HAS_FUNC CACHE) 86b18c2d1eSnia check_symbol_exists(${FUNC} ${HEADER} _HAS_FUNC) 87b18c2d1eSnia if(NOT _HAS_FUNC) 88b18c2d1eSnia foreach(_SFLAG ${AVAIL_SYM_FLAGS}) 89b18c2d1eSnia unset(_HAS_FUNC CACHE) 90b18c2d1eSnia list(APPEND CMAKE_REQUIRED_DEFINITIONS ${_SFLAG}) 91b18c2d1eSnia check_symbol_exists(${FUNC} ${HEADER} _HAS_FUNC) 92b18c2d1eSnia list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS ${_SFLAG}) 93b18c2d1eSnia if(_HAS_FUNC) 94b18c2d1eSnia message(STATUS "${FUNC}() needs ${_SFLAG}") 95b18c2d1eSnia list(APPEND EXTRA_SYM_FLAGS ${_SFLAG}) 96b18c2d1eSnia break() 97b18c2d1eSnia endif() 98b18c2d1eSnia endforeach() 99b18c2d1eSnia if(NOT _HAS_FUNC) 100b18c2d1eSnia message(WARNING "Couldn't find def for ${FUNC}, not good...") 101b18c2d1eSnia endif() 1020bbfda8aSnia endif() 103b18c2d1eSnia unset(_HAS_FUNC CACHE) 104b18c2d1eSniaendmacro(_check_func_flag) 105b18c2d1eSnia 106b18c2d1eSnia# strdup is POSIX, so see if we have to ask for that. Probably 107b18c2d1eSnia# _POSIX_C_SOURCE. 108b18c2d1eSnia_check_func_flag(strdup string.h) 109b18c2d1eSnia 110b18c2d1eSnia# isascii falls into XOPEN on glibc, POSIX on Illumos. 111b18c2d1eSnia_check_func_flag(isascii ctype.h) 112b18c2d1eSnia 113b18c2d1eSnia# asprintf() is even weirder. glibc apparently usually uses _GNU_SOURCE, 114b18c2d1eSnia# Illumos has a pure __EXTENSIONS__ 115b18c2d1eSnia_check_func_flag(asprintf stdio.h) 116b18c2d1eSnia 117b18c2d1eSniaif(EXTRA_SYM_FLAGS) 118b18c2d1eSnia list(REMOVE_DUPLICATES EXTRA_SYM_FLAGS) 119b18c2d1eSnia message(STATUS "Adding extra visibility flags: ${EXTRA_SYM_FLAGS}") 120b18c2d1eSnia add_definitions(${EXTRA_SYM_FLAGS}) 121b18c2d1eSniaendif() 122b18c2d1eSnia 123b18c2d1eSnia# And restore 124b18c2d1eSniaset(CMAKE_REQUIRED_DEFINITIONS ${OLD_CMAKE_REQUIRED_DEFINITIONS}) 125b18c2d1eSnia 126b18c2d1eSnia 1270bbfda8aSnia 1280bbfda8aSnia 1290bbfda8aSnia# Some compilers (like Sun's) don't take -W flags for warnings. Do a 1300bbfda8aSnia# quick check with -Wall. They're mostly for devs, so we don't care THAT 1310bbfda8aSnia# much, I guess... maybe we should be more thorough about checking the 1320bbfda8aSnia# flags we use too, but worry about what when it becomes an issue. 1330bbfda8aSniacheck_c_compiler_flag("-Wall" COMPILER_TAKES_WALL) 1340bbfda8aSniaif(NOT COMPILER_TAKES_WALL) 1350bbfda8aSnia message(STATUS "Compiler doesn't like -Wall, disabling warnings.") 1360bbfda8aSnia set(NO_WARNS 1) 1370bbfda8aSniaendif(NOT COMPILER_TAKES_WALL) 1380bbfda8aSnia 1390bbfda8aSniaif(NOT NO_WARNS) 1400bbfda8aSnia add_definitions(${STD_WARNS}) 1410bbfda8aSnia message(STATUS "Enabling standard warnings.") 1420bbfda8aSniaendif(NOT NO_WARNS) 143