| # COPYRIGHT (c) 2016 Obsidian Research Corporation. | |
| # Licensed under BSD (MIT variant) or GPLv2. See COPYING. | |
| # cmake does not have way to do this even slightly sanely until CMP0056 | |
| function(RDMA_CHECK_C_LINKER_FLAG FLAG CACHE_VAR) | |
| set(SAFE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") | |
| set(SAFE_CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") | |
| if (POLICY CMP0056) | |
| set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") | |
| else() | |
| set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} ${FLAG}") | |
| endif() | |
| CHECK_C_COMPILER_FLAG("" ${CACHE_VAR}) | |
| set(CMAKE_EXE_LINKER_FLAGS "${SAFE_CMAKE_EXE_LINKER_FLAGS}") | |
| set(CMAKE_REQUIRED_LIBRARIES "${SAFE_CMAKE_REQUIRED_LIBRARIES}") | |
| endfunction() | |
| # Test if the CC compiler supports the linker flag and if so add it to TO_VAR | |
| function(RDMA_AddOptLDFlag TO_VAR CACHE_VAR FLAG) | |
| RDMA_CHECK_C_LINKER_FLAG("${FLAG}" ${CACHE_VAR}) | |
| if (${CACHE_VAR}) | |
| SET(${TO_VAR} "${${TO_VAR}} ${FLAG}" PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| # Test if the CC compiler supports the flag and if so add it to TO_VAR | |
| function(RDMA_AddOptCFlag TO_VAR CACHE_VAR FLAG) | |
| CHECK_C_COMPILER_FLAG("${FLAG}" ${CACHE_VAR}) | |
| if (${CACHE_VAR}) | |
| SET(${TO_VAR} "${${TO_VAR}} ${FLAG}" PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| # Enable the minimum required gnu11 standard in the compiler | |
| # This was introduced in GCC 4.7 | |
| function(RDMA_EnableCStd) | |
| if (HAVE_SPARSE) | |
| # Sparse doesn't support gnu11, but doesn't fail if the option is present, | |
| # force gnu99 instead. | |
| SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99" PARENT_SCOPE) | |
| return() | |
| endif() | |
| if (CMAKE_VERSION VERSION_LESS "3.1") | |
| # Check for support of the usual flag | |
| CHECK_C_COMPILER_FLAG("-std=gnu11" SUPPORTS_GNU11) | |
| if (SUPPORTS_GNU11) | |
| SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11" PARENT_SCOPE) | |
| else() | |
| SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99" PARENT_SCOPE) | |
| endif() | |
| else() | |
| # Newer cmake can do this internally | |
| set(CMAKE_C_STANDARD 11 PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| function(RDMA_Check_C_Compiles TO_VAR CHECK_PROGRAM) | |
| set(CMAKE_REQUIRED_FLAGS "${ARGV2} -Werror") | |
| CHECK_C_SOURCE_COMPILES("${CHECK_PROGRAM}" ${TO_VAR}) | |
| set(${TO_VAR} ${${TO_VAR}} PARENT_SCOPE) | |
| endfunction() | |
| function(RDMA_Check_Aliasing TO_VAR) | |
| SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") | |
| RDMA_Check_C_Compiles(HAVE_WORKING_STRICT_ALIASING " | |
| struct in6_addr {unsigned int u6_addr32[4];}; | |
| struct iphdr {unsigned int daddr;}; | |
| union ibv_gid {unsigned char raw[16];}; | |
| static void map_ipv4_addr_to_ipv6(struct in6_addr *ipv6) {ipv6->u6_addr32[0] = 0;} | |
| static int set_ah_attr_by_ipv4(struct iphdr *ip4h) | |
| { | |
| union ibv_gid sgid = {}; | |
| map_ipv4_addr_to_ipv6((struct in6_addr *)&sgid); | |
| return 0; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| struct in6_addr a; | |
| struct iphdr h = {}; | |
| map_ipv4_addr_to_ipv6(&a); | |
| return set_ah_attr_by_ipv4(&h); | |
| }" | |
| ) | |
| set(${TO_VAR} "${HAVE_WORKING_STRICT_ALIASING}" PARENT_SCOPE) | |
| endfunction() | |
| function(RDMA_Check_SSE TO_VAR) | |
| set(SSE_CHECK_PROGRAM " | |
| #if defined(__i386__) | |
| #include <string.h> | |
| #include <xmmintrin.h> | |
| int __attribute__((target(\"sse\"))) main(int argc, char *argv[]) | |
| { | |
| __m128 tmp = {}; | |
| tmp = _mm_loadl_pi(tmp, (__m64 *)&main); | |
| _mm_storel_pi((__m64 *)&main, tmp); | |
| return memchr(&tmp, 0, sizeof(tmp)) == &tmp; | |
| } | |
| #else | |
| int main(int argc, char *argv[]) | |
| { | |
| return 0; | |
| } | |
| #endif | |
| ") | |
| RDMA_Check_C_Compiles(HAVE_TARGET_SSE "${SSE_CHECK_PROGRAM}") | |
| if(NOT HAVE_TARGET_SSE) | |
| # Older compiler, we can work around this by adding -msse instead of | |
| # relying on the function attribute. | |
| RDMA_Check_C_Compiles(NEED_MSSE_FLAG "${SSE_CHECK_PROGRAM}" "-msse") | |
| if(NEED_MSSE_FLAG) | |
| set(SSE_FLAGS "-msse" PARENT_SCOPE) | |
| else() | |
| message(FATAL_ERROR "Can not figure out how to turn on sse instructions for i386") | |
| endif() | |
| endif() | |
| set(${TO_VAR} "${HAVE_TARGET_SSE}" PARENT_SCOPE) | |
| endFunction() | |
| function(RDMA_Check_LS64 TO_VAR) | |
| set(LS64_CHECK_PROGRAM " | |
| #include <arm_acle.h> | |
| int main(void) | |
| { | |
| static char buf[64] __attribute__((aligned(64))); | |
| __arm_st64b(buf, *(const data512_t *)buf); | |
| return 0; | |
| } | |
| ") | |
| RDMA_Check_C_Compiles(HAVE_LS64 "${LS64_CHECK_PROGRAM}" "-march=armv8-a+ls64") | |
| if (HAVE_LS64) | |
| set(LS64_FLAGS "-march=armv8-a+ls64" PARENT_SCOPE) | |
| set(${TO_VAR} TRUE PARENT_SCOPE) | |
| else() | |
| set(${TO_VAR} FALSE PARENT_SCOPE) | |
| endif() | |
| endFunction() |