Skip to content

Commit

Permalink
Update cross compile checks and files (#2497)
Browse files Browse the repository at this point in the history
  • Loading branch information
byrnHDF authored Mar 2, 2023
1 parent b16ec83 commit 7b833f0
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 54 deletions.
110 changes: 56 additions & 54 deletions config/cmake/ConfigureChecks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -768,56 +768,57 @@ if (HDF5_BUILD_FORTRAN)
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)
message (VERBOSE "Detecting C ${FUNCTION_NAME}")
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)
message (VERBOSE "Detecting C ${FUNCTION_NAME}")
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})

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 "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ")

if (COMPILE_RESULT_VAR)
if (RUN_RESULT_VAR EQUAL "0")
set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}")
message (VERBOSE "Testing C ${FUNCTION_NAME} - OK")
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"
)
set (${RETURN_OUTPUT_VAR} ${OUTPUT_VAR})

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 "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ")

if (COMPILE_RESULT_VAR)
if (RUN_RESULT_VAR EQUAL "0")
set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}")
message (VERBOSE "Testing C ${FUNCTION_NAME} - OK")
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 ()
message (VERBOSE "Testing C ${FUNCTION_NAME} - Fail")
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 (VERBOSE "Testing C ${FUNCTION_NAME} - Fail")
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")
message (FATAL_ERROR "Compilation of C ${FUNCTION_NAME} - Failed")
endif ()
else ()
message (FATAL_ERROR "Compilation of C ${FUNCTION_NAME} - Failed")
endif ()
endmacro ()
endmacro ()

set (PROG_SRC
"
set (PROG_SRC
"
#include <float.h>\n\
#include <stdio.h>\n\
#define CHECK_FLOAT128 _SIZEOF___FLOAT128\n\
Expand All @@ -838,17 +839,18 @@ if (HDF5_BUILD_FORTRAN)
#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)
Expand Down
1 change: 1 addition & 0 deletions config/toolchain/aarch64.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
81 changes: 81 additions & 0 deletions release_docs/INSTALL_CMake.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

************************************************************************

Expand Down Expand Up @@ -938,6 +939,86 @@ The HDF5_ENABLE_COVERAGE option will add "-g -O0 -fprofile-arcs -ftest-coverage"
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. <toolchain_name>.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 [email protected]
========================================================================
Expand Down

0 comments on commit 7b833f0

Please sign in to comment.