Skip to content

Commit

Permalink
[build] Support cross-compilation of Fortran programs
Browse files Browse the repository at this point in the history
This patch changes CMakeLists.txt and build scripts to support cross-compiling
Fortran programs in the frontend, and to cross-compile all runtime libraries
for the target architecture. LLVM must support the specified target.

Co-authored-by: Prabhdeep Singh Soni <[email protected]>
  • Loading branch information
bryanpkc and psoni2628 committed Nov 29, 2024
1 parent e81c9f8 commit 35c02ae
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 33 deletions.
40 changes: 26 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"
Expand All @@ -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}
Expand All @@ -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")
Expand Down Expand Up @@ -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 )
Expand All @@ -180,16 +190,18 @@ 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()

if(LLVM_EXTERNAL_LIT)
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)
Expand Down Expand Up @@ -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)
Expand Down
51 changes: 41 additions & 10 deletions build-flang.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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=""
Expand All @@ -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";
Expand All @@ -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";;
Expand All @@ -61,18 +64,40 @@ 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 \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-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
Expand All @@ -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.
Expand All @@ -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
11 changes: 11 additions & 0 deletions runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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)

Expand Down
7 changes: 4 additions & 3 deletions runtime/flangrti/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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" )
Expand Down
23 changes: 22 additions & 1 deletion runtime/libpgmath/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
4 changes: 2 additions & 2 deletions runtime/libpgmath/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
4 changes: 3 additions & 1 deletion runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
Expand Down
2 changes: 2 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
6 changes: 6 additions & 0 deletions tools/flang1/flang1exe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
6 changes: 6 additions & 0 deletions tools/flang2/flang2exe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
9 changes: 7 additions & 2 deletions tools/flang2/flang2exe/cgmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit 35c02ae

Please sign in to comment.