diff --git a/CMakeLists.txt b/CMakeLists.txt index 896e04583ee..6dbf1f187f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,14 @@ if (WIN32) SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1) endif() +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + add_definitions(-DCROSS_COMPILE_TARGET_TRIPLE="${CROSS_COMPILE_TARGET_TRIPLE}") + string(REGEX MATCH "^[^-]+" + TARGET_ARCHITECTURE ${CROSS_COMPILE_TARGET_TRIPLE}) +else() + set(TARGET_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Target Architecture") +endif() set(TARGET_OS ${CMAKE_SYSTEM_NAME} CACHE STRING "Target OS") -set(TARGET_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Target Architecture") if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) @@ -80,7 +86,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}") set(CONFIG_COMMAND ${LLVM_CONFIG} "--assertion-mode" - "--bindir" "--libdir" "--includedir" "--prefix" @@ -104,11 +109,17 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) endif() list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS) - list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR) - list(GET CONFIG_OUTPUT 2 LIBRARY_DIR) - list(GET CONFIG_OUTPUT 3 INCLUDE_DIR) - list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT) - list(GET CONFIG_OUTPUT 5 LLVM_HOST_TARGET) + list(GET CONFIG_OUTPUT 1 LIBRARY_DIR) + list(GET CONFIG_OUTPUT 2 INCLUDE_DIR) + list(GET CONFIG_OUTPUT 3 LLVM_OBJ_ROOT) + list(GET CONFIG_OUTPUT 4 LLVM_HOST_TARGET) + + if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + set(INSTALLED_TARGET_TRIPLE ${CROSS_COMPILE_TARGET_TRIPLE}) + else() + set(INSTALLED_TARGET_TRIPLE ${LLVM_HOST_TARGET}) + endif() + message(STATUS "Current target triple: ${INSTALLED_TARGET_TRIPLE}") if(NOT MSVC_IDE) set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} @@ -117,10 +128,10 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) mark_as_advanced(LLVM_ENABLE_ASSERTIONS) endif() - set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin") set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib") set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") + set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to llvm-lit, FileCheck, etc.") set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib/cmake/llvm" CACHE PATH "Path to LLVM cmake modules") @@ -160,7 +171,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) endif() include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}") - link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}") set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) @@ -180,9 +190,9 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") endif() # Check prebuilt llvm/utils. - if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} - AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/count${CMAKE_EXECUTABLE_SUFFIX} - AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}) + if(EXISTS ${LLVM_LIT_TOOLS_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX} + AND EXISTS ${LLVM_LIT_TOOLS_DIR}/count${CMAKE_EXECUTABLE_SUFFIX} + AND EXISTS ${LLVM_LIT_TOOLS_DIR}/not${CMAKE_EXECUTABLE_SUFFIX}) set(LLVM_UTILS_PROVIDED ON) endif() @@ -190,6 +200,8 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") if(NOT LLVM_LIT) set(LLVM_LIT ${LLVM_EXTERNAL_LIT}) endif() + elseif(EXISTS ${LLVM_LIT_TOOLS_DIR}/llvm-lit${CMAKE_EXECUTABLE_SUFFIX}) + set(LLVM_LIT ${LLVM_LIT_TOOLS_DIR}/llvm-lit${CMAKE_EXECUTABLE_SUFFIX}) endif() if(NOT LLVM_LIT OR NOT LLVM_UTILS_PROVIDED) @@ -362,8 +374,8 @@ macro(add_flang_library name) # link_system_libs( ${name} ) # getd of cmake warning messages install(TARGETS ${name} - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + LIBRARY DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${INSTALLED_TARGET_TRIPLE}" + ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${INSTALLED_TARGET_TRIPLE}" RUNTIME DESTINATION bin) set_target_properties(${name} PROPERTIES FOLDER "Flang libraries") endmacro(add_flang_library) diff --git a/build-flang.sh b/build-flang.sh index 09e77bfadca..334fa308059 100755 --- a/build-flang.sh +++ b/build-flang.sh @@ -8,9 +8,10 @@ TARGET="X86" BUILD_TYPE="Release" BUILD_PREFIX="./build" INSTALL_PREFIX="/usr/local" +CROSS_TARGET="" NPROC=1 USE_LLVM_MAIN_SRC_DIR="" -USE_LLVM_CONFIG="" +LLVM_CONFIG_BIN="" USE_CCACHE="0" USE_SUDO="0" EXTRA_CMAKE_OPTS="" @@ -33,6 +34,7 @@ function print_usage { echo " -d CMake build type. Default: Release"; echo " -b Build prefix. Default: ./build"; echo " -p Install prefix. Default: /usr/local"; + echo " -X Build a cross-compiler for given target triple. Default: N/A" echo " -n Number of parallel jobs. Default: 1"; echo " -l Path to LLVM sources. Default: not set"; echo " -o Path to llvm-config. Default: not set"; @@ -42,15 +44,16 @@ function print_usage { echo " -v Enable verbose output"; } -while getopts "t:d:b:p:n:l:o:csx:v?" opt; do +while getopts "t:X:d:b:p:n:l:o:csx:v?" opt; do case "$opt" in t) TARGET=$OPTARG;; d) BUILD_TYPE=$OPTARG;; b) BUILD_PREFIX=$OPTARG;; p) INSTALL_PREFIX=$OPTARG;; + X) CROSS_TARGET=$OPTARG;; n) NPROC=$OPTARG;; l) USE_LLVM_MAIN_SRC_DIR="-DLLVM_MAIN_SRC_DIR=$OPTARG";; - o) USE_LLVM_CONFIG="-DLLVM_CONFIG=$OPTARG";; + o) LLVM_CONFIG_BIN="$OPTARG";; c) USE_CCACHE="1";; s) USE_SUDO="1";; x) EXTRA_CMAKE_OPTS="$OPTARG";; @@ -61,11 +64,26 @@ done CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ - -DCMAKE_CXX_COMPILER=$INSTALL_PREFIX/bin/clang++ \ + -DCMAKE_AR=$INSTALL_PREFIX/bin/llvm-ar \ -DCMAKE_C_COMPILER=$INSTALL_PREFIX/bin/clang \ + -DCMAKE_CXX_COMPILER=$INSTALL_PREFIX/bin/clang++ \ + -DCMAKE_RANLIB=$INSTALL_PREFIX/bin/llvm-ranlib \ -DLLVM_TARGETS_TO_BUILD=$TARGET \ $USE_LLVM_MAIN_SRC_DIR" +# Use lld for release_19x or newer version of classic-flang-llvm-project. +set -x +if [ -n "$LLVM_CONFIG_BIN" ]; then + CMAKE_OPTIONS="$CMAKE_OPTIONS -DLLVM_CONFIG=$LLVM_CONFIG_BIN" + LLVM_MAJOR_VERSION=$("$LLVM_CONFIG_BIN" --version | cut -f1 -d.) + if [ "$LLVM_MAJOR_VERSION" -gt 19 ]; then + CMAKE_OPTIONS="$CMAKE_OPTIONS \ + -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld \ + -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld" + fi +fi +set +x + if [ $USE_CCACHE == "1" ]; then echo "Build using ccache" CMAKE_OPTIONS="$CMAKE_OPTIONS \ @@ -73,6 +91,13 @@ if [ $USE_CCACHE == "1" ]; then -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" fi +if [ -n "$CROSS_TARGET" ]; then + CMAKE_OPTIONS="$CMAKE_OPTIONS \ + -DCROSS_COMPILE_TARGET_TRIPLE=$CROSS_TARGET \ + -DLLVM_DEFAULT_TARGET_TRIPLE=$CROSS_TARGET \ + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON" +fi + if [ -n "$EXTRA_CMAKE_OPTS" ]; then CMAKE_OPTIONS="$CMAKE_OPTIONS $EXTRA_CMAKE_OPTS" fi @@ -88,15 +113,22 @@ mkdir -p $BUILD_PREFIX/libpgmath && cd $BUILD_PREFIX/libpgmath if [ -n "$VERBOSE" ]; then set -x fi -cmake $CMAKE_OPTIONS $TOPDIR/runtime/libpgmath +if [ -n "$CROSS_TARGET" ]; then + cmake $CMAKE_OPTIONS \ + -DCMAKE_C_COMPILER_TARGET=$CROSS_TARGET \ + -DCMAKE_CXX_COMPILER_TARGET=$CROSS_TARGET \ + $TOPDIR/runtime/libpgmath +else + cmake $CMAKE_OPTIONS $TOPDIR/runtime/libpgmath +fi set +x make -j$NPROC VERBOSE=$VERBOSE if [ $USE_SUDO == "1" ]; then echo "Install with sudo" - sudo make install + sudo make install VERBOSE=$VERBOSE else echo "Install without sudo" - make install + make install VERBOSE=$VERBOSE fi # Build and install flang. @@ -110,14 +142,13 @@ cmake $CMAKE_OPTIONS \ -DFLANG_INCLUDE_DOCS=ON \ -DFLANG_LLVM_EXTENSIONS=ON \ -DWITH_WERROR=ON \ - $USE_LLVM_CONFIG \ $TOPDIR set +x make -j$NPROC VERBOSE=$VERBOSE if [ $USE_SUDO == "1" ]; then echo "Install with sudo" - sudo make install + sudo make install VERBOSE=$VERBOSE else echo "Install without sudo" - make install + make install VERBOSE=$VERBOSE fi diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 44f01d77b24..8552e8c333e 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -4,6 +4,12 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + set(CMAKE_C_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}") + set(CMAKE_CXX_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}") + set(CMAKE_Fortran_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}") +endif() + set (RUNTIME_SHARED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/shared) add_definitions( @@ -39,6 +45,11 @@ elseif( ${TARGET_ARCHITECTURE} STREQUAL "ppc64le" ) endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + link_directories("${LLVM_LIBRARY_DIR}/${CROSS_COMPILE_TARGET_TRIPLE}") +else() + link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}") +endif() add_subdirectory(ompstub) diff --git a/runtime/flangrti/CMakeLists.txt b/runtime/flangrti/CMakeLists.txt index b9a02999159..51c10719ab7 100644 --- a/runtime/flangrti/CMakeLists.txt +++ b/runtime/flangrti/CMakeLists.txt @@ -103,19 +103,20 @@ if (CMAKE_THREAD_LIBS_INIT) target_link_libraries(flangrti_shared PRIVATE "${CMAKE_THREAD_LIBS_INIT}") endif() -# Import OpenMP +# Import OpenMP. if (NOT DEFINED LIBOMP_EXPORT_DIR) find_library( FLANG_LIBOMP NAMES omp libomp - HINTS "${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}") + HINTS ${LLVM_LIBRARY_DIR}/${INSTALLED_TARGET_TRIPLE}) target_link_libraries(flangrti_shared PUBLIC ${FLANG_LIBOMP}) endif() +# Import libpgmath. find_library( LIBPGMATH NAMES pgmath libpgmath - HINTS ${CMAKE_BINARY_DIR}/lib) + HINTS ${LLVM_LIBRARY_DIR}/${INSTALLED_TARGET_TRIPLE}) target_link_libraries(flangrti_shared PUBLIC ${LIBPGMATH}) if( ${TARGET_ARCHITECTURE} STREQUAL "aarch64" ) diff --git a/runtime/libpgmath/CMakeLists.txt b/runtime/libpgmath/CMakeLists.txt index 166662333e4..ffa5ab274e4 100644 --- a/runtime/libpgmath/CMakeLists.txt +++ b/runtime/libpgmath/CMakeLists.txt @@ -46,7 +46,28 @@ if ("${LIBPGMATH_SYSTEM_NAME}" STREQUAL "OpenBSD") set(LIBPGMATH_SYSTEM_NAME "Linux") endif () -set(LIBPGMATH_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}") +# Find the default (host) target triple from Clang. +execute_process( + COMMAND "${CMAKE_C_COMPILER}" "-v" + RESULT_VARIABLE HAD_ERROR + ERROR_VARIABLE DASHV_OUTPUT +) +if(NOT HAD_ERROR) + string(REGEX REPLACE ".*Target: ([^ \r\n]+).*" "\\1" LLVM_HOST_TARGET "${DASHV_OUTPUT}") +endif() +if(NOT LLVM_HOST_TARGET) + message(FATAL_ERROR "Could not parse host target triple from '${CMAKE_C_COMPILER} -v' output") +endif() + +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + string(REGEX REPLACE "-.*$" "" LIBPGMATH_SYSTEM_PROCESSOR ${CROSS_COMPILE_TARGET_TRIPLE}) + message(STATUS "Cross-compiling for ${LIBPGMATH_SYSTEM_PROCESSOR}") + set(INSTALLED_TARGET_TRIPLE ${CROSS_COMPILE_TARGET_TRIPLE}) +else() + set(LIBPGMATH_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}") + set(INSTALLED_TARGET_TRIPLE ${LLVM_HOST_TARGET}) +endif() + if ("${LIBPGMATH_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${LIBPGMATH_SYSTEM_PROCESSOR}" STREQUAL "amd64" ) set(LIBPGMATH_SYSTEM_PROCESSOR "x86_64") diff --git a/runtime/libpgmath/lib/CMakeLists.txt b/runtime/libpgmath/lib/CMakeLists.txt index c43b315137f..8e494207f1a 100644 --- a/runtime/libpgmath/lib/CMakeLists.txt +++ b/runtime/libpgmath/lib/CMakeLists.txt @@ -266,6 +266,6 @@ else() set_target_properties(${LIBPGMATH_LIBRARY_NAME}_static PROPERTIES OUTPUT_NAME ${LIBPGMATH_LIBRARY_NAME}) endif() install(TARGETS ${LIBPGMATH_LIBRARY_NAME} - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib/${INSTALLED_TARGET_TRIPLE}) install(TARGETS ${LIBPGMATH_LIBRARY_NAME}_static - ARCHIVE DESTINATION lib) + ARCHIVE DESTINATION lib/${INSTALLED_TARGET_TRIPLE}) diff --git a/runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt b/runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt index 2fbe53cafa2..6ab283a6444 100644 --- a/runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt +++ b/runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt @@ -53,7 +53,9 @@ if (DEFINED DEFINITIONS) set(DEFINITIONS "-D${DEFINITIONS}") endif() string(REPLACE ";" " " SRCS "${SRCS}") -#orig list(APPEND PREPROCESSOR "${CMAKE_C_COMPILER} -E ${DEFINITIONS} ${FLAGS} ${SRCS}") +if(DEFINED CMAKE_C_COMPILER_TARGET) + list(APPEND PREPROCESSOR " -target ${CMAKE_C_COMPILER_TARGET}") +endif() list(APPEND PREPROCESSOR " -E ${DEFINITIONS} -DPGFLANG ${FLAGS} ${SRCS}") separate_arguments(PREPROCESSOR UNIX_COMMAND "${PREPROCESSOR}") list(INSERT PREPROCESSOR 0 "${CMAKE_C_COMPILER}") diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5ecf7b0dc6c..940e3f767d6 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -15,6 +15,8 @@ if( ${TARGET_ARCHITECTURE} STREQUAL "aarch64" ) add_definitions(-DLLVM_ENABLE_FFI=false) endif() +link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}") + add_subdirectory(shared) add_subdirectory(flang1) add_subdirectory(flang2) diff --git a/tools/flang1/flang1exe/CMakeLists.txt b/tools/flang1/flang1exe/CMakeLists.txt index a3367870013..dab8b9b8e7e 100644 --- a/tools/flang1/flang1exe/CMakeLists.txt +++ b/tools/flang1/flang1exe/CMakeLists.txt @@ -121,6 +121,12 @@ add_flang_executable(flang1 ${SOURCES} ${SHARED_SOURCES} ) +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + set_target_properties(flang1 + PROPERTIES OUTPUT_NAME + "${CROSS_COMPILE_TARGET_TRIPLE}-flang1") +endif() + target_compile_definitions(flang1 PRIVATE ${COMMON_DEFS} diff --git a/tools/flang2/flang2exe/CMakeLists.txt b/tools/flang2/flang2exe/CMakeLists.txt index 5aeeb04807b..4639757c0fe 100644 --- a/tools/flang2/flang2exe/CMakeLists.txt +++ b/tools/flang2/flang2exe/CMakeLists.txt @@ -117,6 +117,12 @@ add_flang_executable(flang2 ${SOURCES} ${SHARED_CPP_SOURCES} ) +if(DEFINED CROSS_COMPILE_TARGET_TRIPLE) + set_target_properties(flang2 + PROPERTIES OUTPUT_NAME + "${CROSS_COMPILE_TARGET_TRIPLE}-flang2") +endif() + target_compile_definitions(flang2 PRIVATE ${COMMON_DEFS} diff --git a/tools/flang2/flang2exe/cgmain.cpp b/tools/flang2/flang2exe/cgmain.cpp index 9b102aca3c1..fba726be951 100644 --- a/tools/flang2/flang2exe/cgmain.cpp +++ b/tools/flang2/flang2exe/cgmain.cpp @@ -14040,10 +14040,15 @@ cg_llvm_init(void) CHECK(TARGET_PTRSIZE == size_of(DT_CPTR)); - if (flg.llvm_target_triple) + if (flg.llvm_target_triple) { triple = flg.llvm_target_triple; - else + } else { +#ifdef CROSS_COMPILE_TARGET_TRIPLE + triple = CROSS_COMPILE_TARGET_TRIPLE; +#else triple = LLVM_DEFAULT_TARGET_TRIPLE; +#endif + } ir_version = get_llvm_version();