From ab1af79798985b57401596677f7db8eb186f55a1 Mon Sep 17 00:00:00 2001 From: Allen Byrne <50328838+byrnHDF@users.noreply.github.com> Date: Wed, 29 Mar 2023 09:37:52 -0500 Subject: Update cross compile checks and files #2497 (#2565) --- config/cmake/ConfigureChecks.cmake | 179 +++++++++++++++++++------------------ config/toolchain/aarch64.cmake | 1 + release_docs/INSTALL_CMake.txt | 81 +++++++++++++++++ 3 files changed, 174 insertions(+), 87 deletions(-) diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 472f144..27eb93f 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -210,83 +210,85 @@ if (HDF5_ENABLE_MIRROR_VFD) endif() #----------------------------------------------------------------------------- -# Check if C has __float128 extension +# Check if C has __float128 extension (used for Fortran only) #----------------------------------------------------------------------------- -HDF_CHECK_TYPE_SIZE(__float128 _SIZEOF___FLOAT128) -if (${_SIZEOF___FLOAT128}) - set (${HDF_PREFIX}_HAVE_FLOAT128 1) - set (${HDF_PREFIX}_SIZEOF___FLOAT128 ${_SIZEOF___FLOAT128}) -else () - set (${HDF_PREFIX}_HAVE_FLOAT128 0) - set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) -endif () +if (HDF5_BUILD_FORTRAN) + HDF_CHECK_TYPE_SIZE(__float128 _SIZEOF___FLOAT128) + if (${_SIZEOF___FLOAT128}) + set (${HDF_PREFIX}_HAVE_FLOAT128 1) + set (${HDF_PREFIX}_SIZEOF___FLOAT128 ${_SIZEOF___FLOAT128}) + else () + set (${HDF_PREFIX}_HAVE_FLOAT128 0) + set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) + endif () -HDF_CHECK_TYPE_SIZE(_Quad _SIZEOF__QUAD) -if (NOT ${_SIZEOF__QUAD}) - set (${HDF_PREFIX}_SIZEOF__QUAD 0) -else () - set (${HDF_PREFIX}_SIZEOF__QUAD ${_SIZEOF__QUAD}) -endif () + HDF_CHECK_TYPE_SIZE(_Quad _SIZEOF__QUAD) + if (NOT ${_SIZEOF__QUAD}) + set (${HDF_PREFIX}_SIZEOF__QUAD 0) + else () + set (${HDF_PREFIX}_SIZEOF__QUAD ${_SIZEOF__QUAD}) + endif () -#----------------------------------------------------------------------------- -# The provided CMake C macros don't provide a general compile/run function -# so this one is used. -#----------------------------------------------------------------------------- -set (RUN_OUTPUT_PATH_DEFAULT ${CMAKE_BINARY_DIR}) -macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR RETURN_OUTPUT_VAR) - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Detecting C ${FUNCTION_NAME}") - endif () - file (WRITE - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler1.c - ${SOURCE_CODE} - ) - TRY_RUN (RUN_RESULT_VAR COMPILE_RESULT_VAR - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler1.c - COMPILE_DEFINITIONS "-D_SIZEOF___FLOAT128=${H5_SIZEOF___FLOAT128};-D_HAVE_QUADMATH_H=${H5_HAVE_QUADMATH_H}" - COMPILE_OUTPUT_VARIABLE COMPILEOUT - RUN_OUTPUT_VARIABLE OUTPUT_VAR - ) + if (NOT CMAKE_CROSSCOMPILING) + #----------------------------------------------------------------------------- + # The provided CMake C macros don't provide a general compile/run function + # so this one is used. + #----------------------------------------------------------------------------- + set (RUN_OUTPUT_PATH_DEFAULT ${CMAKE_BINARY_DIR}) + macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR RETURN_OUTPUT_VAR) + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "Detecting C ${FUNCTION_NAME}") + endif () + file (WRITE + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler1.c + ${SOURCE_CODE} + ) + TRY_RUN (RUN_RESULT_VAR COMPILE_RESULT_VAR + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler1.c + COMPILE_DEFINITIONS "-D_SIZEOF___FLOAT128=${H5_SIZEOF___FLOAT128};-D_HAVE_QUADMATH_H=${H5_HAVE_QUADMATH_H}" + COMPILE_OUTPUT_VARIABLE COMPILEOUT + RUN_OUTPUT_VARIABLE OUTPUT_VAR + ) - set (${RETURN_OUTPUT_VAR} ${OUTPUT_VAR}) + set (${RETURN_OUTPUT_VAR} ${OUTPUT_VAR}) - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") - message (VERBOSE "Test COMPILE_RESULT_VAR ${COMPILE_RESULT_VAR} ") - message (VERBOSE "Test COMPILE_OUTPUT ${COMPILEOUT} ") - message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") - message (VERBOSE "Test RUN_RESULT_VAR ${RUN_RESULT_VAR} ") - message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") - endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") + message (VERBOSE "Test COMPILE_RESULT_VAR ${COMPILE_RESULT_VAR} ") + message (VERBOSE "Test COMPILE_OUTPUT ${COMPILEOUT} ") + message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") + message (VERBOSE "Test RUN_RESULT_VAR ${RUN_RESULT_VAR} ") + message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") + endif () - if (COMPILE_RESULT_VAR) - if (RUN_RESULT_VAR EQUAL "0") - set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Testing C ${FUNCTION_NAME} - OK") + if (COMPILE_RESULT_VAR) + if (RUN_RESULT_VAR EQUAL "0") + set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "Testing C ${FUNCTION_NAME} - OK") + endif () + file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the C ${FUNCTION_NAME} exists passed with the following output:\n" + "${OUTPUT_VAR}\n\n" + ) + else () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "Testing C ${FUNCTION_NAME} - Fail") + endif () + set (${RETURN_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the C ${FUNCTION_NAME} exists failed with the following output:\n" + "${OUTPUT_VAR}\n\n") endif () - file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Determining if the C ${FUNCTION_NAME} exists passed with the following output:\n" - "${OUTPUT_VAR}\n\n" - ) else () - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Testing C ${FUNCTION_NAME} - Fail") - endif () - set (${RETURN_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") - file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log - "Determining if the C ${FUNCTION_NAME} exists failed with the following output:\n" - "${OUTPUT_VAR}\n\n") - endif () - else () message (FATAL_ERROR "Compilation of C ${FUNCTION_NAME} - Failed") - endif () -endmacro () + endif () + endmacro () -set (PROG_SRC - " + set (PROG_SRC + " #include \n\ #include \n\ #define CHECK_FLOAT128 _SIZEOF___FLOAT128\n\ @@ -307,31 +309,34 @@ set (PROG_SRC #else\n\ #define C_LDBL_DIG LDBL_DIG\n\ #endif\n\nint main() {\nprintf(\"\\%d\\\;\\%d\\\;\", C_LDBL_DIG, C_FLT128_DIG)\\\;\n\nreturn 0\\\;\n}\n - " -) + " + ) -C_RUN ("maximum decimal precision for C" ${PROG_SRC} PROG_RES PROG_OUTPUT4) -message (STATUS "Testing maximum decimal precision for C - ${PROG_OUTPUT4}") + C_RUN ("maximum decimal precision for C" ${PROG_SRC} PROG_RES PROG_OUTPUT4) + message (STATUS "Testing maximum decimal precision for C - ${PROG_OUTPUT4}") -# dnl The output from the above program will be: -# dnl -- long double decimal precision -- __float128 decimal precision + # dnl The output from the above program will be: + # dnl -- long double decimal precision -- __float128 decimal precision -list (GET PROG_OUTPUT4 0 H5_LDBL_DIG) -list (GET PROG_OUTPUT4 1 H5_FLT128_DIG) + list (GET PROG_OUTPUT4 0 H5_LDBL_DIG) + list (GET PROG_OUTPUT4 1 H5_FLT128_DIG) + endif () -if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL "0" OR FLT128_DIG EQUAL "0") - set (${HDF_PREFIX}_HAVE_FLOAT128 0) - set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) - set (_PAC_C_MAX_REAL_PRECISION ${H5_LDBL_DIG}) -else () - set (_PAC_C_MAX_REAL_PRECISION ${H5_FLT128_DIG}) -endif () -if (NOT ${_PAC_C_MAX_REAL_PRECISION}) - set (${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION 0) -else () - set (${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION ${_PAC_C_MAX_REAL_PRECISION}) -endif () -message (STATUS "maximum decimal precision for C var - ${${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION}") + if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL "0" OR FLT128_DIG EQUAL "0") + set (${HDF_PREFIX}_HAVE_FLOAT128 0) + set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) + set (_PAC_C_MAX_REAL_PRECISION ${H5_LDBL_DIG}) + else () + set (_PAC_C_MAX_REAL_PRECISION ${H5_FLT128_DIG}) + endif () + if (NOT ${_PAC_C_MAX_REAL_PRECISION}) + set (${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION 0) + else () + set (${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION ${_PAC_C_MAX_REAL_PRECISION}) + endif () + message (STATUS "maximum decimal precision for C var - ${${HDF_PREFIX}_PAC_C_MAX_REAL_PRECISION}") + +endif() #----------------------------------------------------------------------------- # Macro to determine the various conversion capabilities diff --git a/config/toolchain/aarch64.cmake b/config/toolchain/aarch64.cmake index 03f4e5e..6996833 100644 --- a/config/toolchain/aarch64.cmake +++ b/config/toolchain/aarch64.cmake @@ -11,6 +11,7 @@ set (CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set (CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set (CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64) include_directories(/usr/${TOOLCHAIN_PREFIX}/include) diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 9113af7..66bd732 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -13,6 +13,7 @@ Section V: Options for building HDF5 Libraries with CMake command line Section VI: CMake option defaults for HDF5 Section VII: User Defined Options for HDF5 Libraries with CMake Section VIII: User Defined Compile Flags for HDF5 Libraries with CMake +Section IX: Considerations for cross-compiling ************************************************************************ @@ -940,6 +941,86 @@ to CMAKE_C_FLAGS. ======================================================================== +IX: Considerations for cross-compiling +======================================================================== + +Cross-compiling has several consequences for CMake: + CMake cannot automatically detect the target platform. + CMake cannot find libraries and headers in the default system directories. + Executables built during cross compiling cannot be executed. + +Cross-compiling support means that CMake separates information about the +build platform and target platform and gives the user mechanisms to solve +cross-compiling issues without additional requirements such as running +virtual machines, etc. + +CMake uses a toolchain of utilities to compile, link libraries and create +archives, and other tasks to drive the build. The toolchain utilities +available are determined by the languages enabled. + +CMake stores info about the current toolchain in the following variables: + CMAKE_C_COMPILER, + CMAKE_CXX_COMPILER. +They contain paths to the C and C++ compilers respectively. This is usually +enough on desktop platforms. In the case of embedded systems, a custom +linker and assembler setting may be needed. In more complex projects +you may need to additionally specify binaries to other parts of the toolchain +(size, ranlib, objcopy…). All these tools should be set in the corresponding +variables: + CMAKE_AR, + CMAKE_ASM_COMPILER, + CMAKE_LINKER, + CMAKE_OBJCOPY, + CMAKE_RANLIB + +As for the host and target operating systems, CMake stores their names in the +following variables: + CMAKE_HOST_SYSTEM_NAME – name of the platform, on which CMake is running (host platform). + On major operating systems this is set to the Linux, Windows or + Darwin (MacOS) value. + CMAKE_SYSTEM_NAME – name of the platform, for which we are building (target platform). + By default, this value is the same as CMAKE_HOST_SYSTEM_NAME, which + means that we are building for the local platform (no cross-compilation). + +Put the toolchain variables into a separate file (e.g. .cmake) +and set CMAKE_TOOLCHAIN_FILE variable to the path of that file. +If cmake is invoked with the command line parameter: + --toolchain path/to/file +or + -DCMAKE_TOOLCHAIN_FILE=path/to/file +the file will be loaded early to set values for the compilers. The +CMAKE_CROSSCOMPILING variable is set to true when CMake is cross-compiling. + +Structure of the toolchain file +------------------------------- +In fact, the toolchain file doesn’t have any structure. You can put anything you +want there. But the best practice is to define at least these settings: +path to the toolchain binaries (C compiler, C++ compiler, linker, etc.) +name of the target platform (and optionally target processor architecture) +required compilation and linking flags on that particular platform +toolchain sysroot settings + +It is recommended that you set the CMAKE_FIND_ROOT_PATH variable to a path where +you have an exact copy of the root filesystem you have on your target device (with +libraries and binaries pre-compiled for the target processor). + +References: + https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html + https://gitlab.com/embeddedlinux/libs/platform + https://discourse.cmake.org/t/cross-compile-for-aarch64-on-ubuntu/2161/10 + https://stackoverflow.com/questions/54539682/how-to-set-up-cmake-to-cross-compile-with-clang-for-arm-embedded-on-windows?rq=1 + https://developer.android.com/ndk/guides/cmake + +Predefine H5Tinit.c file +------------------------------- +The one file that needs to be pre-generated is the H5Tinit.c file. The variables +indicated in the error log (see above) are the variables that need to match the target system. + +The HDF5 CMake variables; + HDF5_USE_PREGEN: set this to true + HDF5_USE_PREGEN_DIR: set this path to the preset H5Tinit.c file + +======================================================================== For further assistance, send email to help@hdfgroup.org ======================================================================== -- cgit v0.12