# 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 #include 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()