summaryrefslogtreecommitdiff
path: root/infrastructure/cmake
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2018-02-24 08:47:40 +0000
committerChris Wilson <chris+github@qwirx.com>2018-03-08 22:18:49 +0000
commitc08932c6e5e1609835219e9f42efe46bb6624a7d (patch)
tree24b8b33b8c2f83bd1fb8abe8328fef1949b45106 /infrastructure/cmake
parent6d7e9562e8485591a4888f1fc2d3c6c657dc7a01 (diff)
Fix raidfile tests on 32-bit Linux
A recent fix for Solaris (commit 81e9aa6545f7f19124c9f5e88982b867d8732965) broke support for 32-bit Linux (which wasn't spotted because we didn't have any 32-bit builders). Try a different approach: detect whether the lseek syscall takes a 64-bit integer offset, and use that if possible. CMake: reimplement autoconf tests for 64-bit lseek (cherry picked from commit 138ea5d174f146f14d91a16bf5d1ce8e479d2024)
Diffstat (limited to 'infrastructure/cmake')
-rw-r--r--infrastructure/cmake/CMakeLists.txt96
1 files changed, 96 insertions, 0 deletions
diff --git a/infrastructure/cmake/CMakeLists.txt b/infrastructure/cmake/CMakeLists.txt
index 65f59eb8..a00e10d7 100644
--- a/infrastructure/cmake/CMakeLists.txt
+++ b/infrastructure/cmake/CMakeLists.txt
@@ -363,6 +363,7 @@ target_compile_definitions(lib_common PUBLIC $<$<CONFIG:Release>:BOX_RELEASE_BUI
include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles)
+include(CheckCXXSourceRuns)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckLibraryExists)
@@ -610,6 +611,7 @@ CHECK_CXX_SOURCE_COMPILES([=[
}
]=] "HAVE_STRUCT_STATFS_F_MNTONNAME")
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_STRUCT_STATFS_F_MNTONNAME\n")
+
CHECK_CXX_SOURCE_COMPILES([=[
#include "BoxConfig.cmake.h"
#ifdef HAVE_SYS_PARAM_H
@@ -623,6 +625,7 @@ CHECK_CXX_SOURCE_COMPILES([=[
}
]=] "HAVE_STRUCT_STATVFS_F_MNTONNAME")
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_STRUCT_STATVFS_F_MNTONNAME\n")
+
if(HAVE_STRUCT_STATFS_F_MNTONNAME OR
HAVE_STRUCT_STATVFS_F_MNTONNAME OR
HAVE_STRUCT_MNTENT_MNT_DIR OR
@@ -649,6 +652,34 @@ file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_RANDOM_DEVICE\n")
# Build an intermediate version of BoxConfig.cmake.h for use in the following tests:
configure_file("${boxconfig_h_file}" "${boxconfig_cmake_h_dir}/BoxConfig.cmake.h")
+# Emulate ax_func_syscall.m4: Autoconf's AC_CHECK_FUNC (which we emulate above,
+# using check_function_exists) defines the function when testing for its
+# presence, so HAVE___SYSCALL will be true even if __syscall has no definition
+# in the system libraries, and this is precisely the case that we want to test
+# for, so now we test whether a test program compiles with no explicit
+# definition (only the system headers) and if that fails, we set
+# HAVE___SYSCALL_NEED_DEFN to 1.
+
+CHECK_CXX_SOURCE_COMPILES(
+ [=[
+ #include "BoxConfig.cmake.h"
+
+ #ifdef HAVE_SYS_SYSCALL_H
+ # include <sys/syscall.h>
+ #endif
+
+ int main()
+ {
+ __syscall(SYS_exit, 0);
+ return 0;
+ }
+ ]=] HAVE___SYSCALL_NO_DEFN)
+set(HAVE___SYSCALL_NEED_DEFN !HAVE___SYSCALL_NO_DEFN)
+file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE___SYSCALL_NEED_DEFN\n")
+
+# Build an intermediate version of BoxConfig.cmake.h for use in the following tests:
+configure_file("${boxconfig_h_file}" "${boxconfig_cmake_h_dir}/BoxConfig.cmake.h")
+
foreach(struct_member_name "struct ucred.uid" "struct ucred.cr_uid")
string(REGEX MATCH "(.*)\\.(.*)" dummy_var ${struct_member_name})
set(struct_name "${CMAKE_MATCH_1}")
@@ -684,6 +715,71 @@ foreach(struct_member_name "struct ucred.uid" "struct ucred.cr_uid")
]=] "HAVE_${platform_var_name}")
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_${platform_var_name}\n")
endforeach()
+
+function(AX_TRY_RUN_FD code var)
+ CHECK_CXX_SOURCE_RUNS([=[
+ #include "BoxConfig.cmake.h"
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <sys/types.h>
+
+ #ifdef HAVE___SYSCALL_NEED_DEFN
+ extern "C" off_t __syscall(quad_t number, ...);
+ #endif
+
+ #ifdef HAVE___SYSCALL // always use it if we have it
+ # undef syscall
+ # define syscall __syscall
+ #endif
+
+ int main()
+ {
+ int fd = creat("lseektest", 0600);
+ int res = 1;
+ if(fd>=0)
+ {
+ ${code}
+ close(fd);
+ }
+ unlink("lseektest");
+ return res;
+ }
+ ]=] ${var})
+ file(APPEND "${boxconfig_h_file}" "#cmakedefine ${var}\n")
+endfunction()
+
+AX_TRY_RUN_FD(
+ [=[
+ // This test tries first to seek to position 0, with NO "dummy
+ // argument". If lseek does actually require a dummy argument,
+ // then it will eat SEEK_SET for the offset and try to use 99
+ // as whence, which is invalid, so res will be 0, the program
+ // will return 0 and we will define HAVE_LSEEK_DUMMY_PARAM
+ // (whew! that took 1 hour to figure out) The "dummy argument"
+ // probably means that it takes a 64-bit offset.
+ res = (syscall(SYS_lseek, fd, (int32_t)10, SEEK_SET, 99) == 10) ? 2 : 0;
+ ]=] HAVE_LSEEK_DUMMY_PARAM)
+
+AX_TRY_RUN_FD(
+ [=[
+ // Try to seek to a position that requires a 64-bit
+ // representation, and check the return value, which is the
+ // current position.
+ if(syscall(SYS_lseek, fd, (int64_t)5, SEEK_SET) != 5)
+ {
+ res = 2;
+ }
+ else if(syscall(SYS_lseek, fd, (int64_t)10, SEEK_CUR) != 15)
+ {
+ res = 3;
+ }
+ else
+ {
+ res = 0;
+ }
+ ]=] HAVE_LSEEK_64_BIT)
+
set(CMAKE_REQUIRED_INCLUDES "")
# Build the final version of BoxConfig.cmake.h, as a temporary file.