diff options
author | Chris Wilson <chris+github@qwirx.com> | 2018-02-24 08:47:40 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2018-03-08 22:18:49 +0000 |
commit | c08932c6e5e1609835219e9f42efe46bb6624a7d (patch) | |
tree | 24b8b33b8c2f83bd1fb8abe8328fef1949b45106 /infrastructure/cmake | |
parent | 6d7e9562e8485591a4888f1fc2d3c6c657dc7a01 (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.txt | 96 |
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. |