xz-analysis-mirror/cmake/tuklib_gnu_c_attributes.cmake

65 lines
2.4 KiB
CMake

#
# tuklib_gnu_c_attributes.cmake - Checks for GNU C attributes
#
# Author: Lasse Collin
#
# This file has been put into the public domain.
# You can do whatever you want with this file.
#
include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
include(CheckCSourceCompiles)
# This is a helper function for the actual attribute tests.
function(tuklib_check_attribute CODE RESULT)
# GCC, Clang, ICC, Solaris Studio, and XLC don't exit with
# a non-zero exit status if an unknown attribute is provided.
# They only print a warning. Accept the attribute only if no
# attribute-related warnings were issued.
#
# - XLC doesn't use the lower-case string "warning".
# It might use "WARNING" on z/OS or "(W)" on AIX.
# So "warning" isn't checked.
#
# - A few XLC messages use "Attribute" instead of "attribute".
#
# - ICC doesn't use the word "ignored".
#
# The problem with this method is that the regex might become
# outdated with newer compiler versions. Using -Werror would be
# an alternative but it fails if warnings occur for reasons other
# than unsupported attribute.
#
# The first pattern is for GCC, Solaris Studio, and XLC.
# The second one is for ICC. Both patterns work with Clang.
# Matching the leading space or colon reduces chances of
# matching any unrelated messages.
check_c_source_compiles("${CODE} int main(void) { return 0; }" "${RESULT}"
FAIL_REGEX " [Aa]ttribute .* ignored"
": unknown attribute")
endfunction()
function(tuklib_check_func_attribute_always_inline RESULT)
tuklib_check_attribute("
__attribute__((__always_inline__))
static inline int my_inline_func(int x) { return x + 1; }
void my_func(void) { return my_inline_func(123); }
" "${RESULT}")
endfunction()
function(tuklib_check_func_attribute_constructor RESULT)
tuklib_check_attribute("
__attribute__((__constructor__))
void my_constructor_func(void) { return; }
" "${RESULT}")
endfunction()
function(tuklib_check_func_attribute_ifunc RESULT)
tuklib_check_attribute("
static void func(void) { return; }
static void (*resolve_func(void))(void) { return &func; }
void func_ifunc(void)
__attribute__((__ifunc__(\"resolve_func\")));
" "${RESULT}")
endfunction()