Skip to content

Commit daead75

Browse files
bryanpkcpsoni2628
andcommitted
[build] Support cross-compilation of Fortran programs
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]>
1 parent e81c9f8 commit daead75

File tree

11 files changed

+130
-33
lines changed

11 files changed

+130
-33
lines changed

CMakeLists.txt

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ if (WIN32)
2020
SET(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
2121
endif()
2222

23+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
24+
add_definitions(-DCROSS_COMPILE_TARGET_TRIPLE="${CROSS_COMPILE_TARGET_TRIPLE}")
25+
string(REGEX MATCH "^[^-]+"
26+
TARGET_ARCHITECTURE ${CROSS_COMPILE_TARGET_TRIPLE})
27+
else()
28+
set(TARGET_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Target Architecture")
29+
endif()
2330
set(TARGET_OS ${CMAKE_SYSTEM_NAME} CACHE STRING "Target OS")
24-
set(TARGET_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Target Architecture")
2531

2632
if (POLICY CMP0054)
2733
cmake_policy(SET CMP0054 NEW)
@@ -80,7 +86,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
8086
message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}")
8187
set(CONFIG_COMMAND ${LLVM_CONFIG}
8288
"--assertion-mode"
83-
"--bindir"
8489
"--libdir"
8590
"--includedir"
8691
"--prefix"
@@ -104,11 +109,17 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
104109
endif()
105110

106111
list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS)
107-
list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR)
108-
list(GET CONFIG_OUTPUT 2 LIBRARY_DIR)
109-
list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)
110-
list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)
111-
list(GET CONFIG_OUTPUT 5 LLVM_HOST_TARGET)
112+
list(GET CONFIG_OUTPUT 1 LIBRARY_DIR)
113+
list(GET CONFIG_OUTPUT 2 INCLUDE_DIR)
114+
list(GET CONFIG_OUTPUT 3 LLVM_OBJ_ROOT)
115+
list(GET CONFIG_OUTPUT 4 LLVM_HOST_TARGET)
116+
117+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
118+
set(INSTALLED_TARGET_TRIPLE ${CROSS_COMPILE_TARGET_TRIPLE})
119+
else()
120+
set(INSTALLED_TARGET_TRIPLE ${LLVM_HOST_TARGET})
121+
endif()
122+
message(STATUS "Current target triple: ${INSTALLED_TARGET_TRIPLE}")
112123

113124
if(NOT MSVC_IDE)
114125
set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
@@ -117,10 +128,10 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
117128
mark_as_advanced(LLVM_ENABLE_ASSERTIONS)
118129
endif()
119130

120-
set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin")
121131
set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib")
122132
set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
123133
set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree")
134+
set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to llvm-lit, FileCheck, etc.")
124135

125136
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib/cmake/llvm"
126137
CACHE PATH "Path to LLVM cmake modules")
@@ -160,7 +171,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
160171
endif()
161172

162173
include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}")
163-
link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}")
164174

165175
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
166176
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
@@ -180,16 +190,18 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.")
180190
endif()
181191

182192
# Check prebuilt llvm/utils.
183-
if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX}
184-
AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/count${CMAKE_EXECUTABLE_SUFFIX}
185-
AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX})
193+
if(EXISTS ${LLVM_LIT_TOOLS_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX}
194+
AND EXISTS ${LLVM_LIT_TOOLS_DIR}/count${CMAKE_EXECUTABLE_SUFFIX}
195+
AND EXISTS ${LLVM_LIT_TOOLS_DIR}/not${CMAKE_EXECUTABLE_SUFFIX})
186196
set(LLVM_UTILS_PROVIDED ON)
187197
endif()
188198

189199
if(LLVM_EXTERNAL_LIT)
190200
if(NOT LLVM_LIT)
191201
set(LLVM_LIT ${LLVM_EXTERNAL_LIT})
192202
endif()
203+
elseif(EXISTS ${LLVM_LIT_TOOLS_DIR}/llvm-lit${CMAKE_EXECUTABLE_SUFFIX})
204+
set(LLVM_LIT ${LLVM_LIT_TOOLS_DIR}/llvm-lit${CMAKE_EXECUTABLE_SUFFIX})
193205
endif()
194206

195207
if(NOT LLVM_LIT OR NOT LLVM_UTILS_PROVIDED)
@@ -362,8 +374,8 @@ macro(add_flang_library name)
362374
# link_system_libs( ${name} ) # getd of cmake warning messages
363375

364376
install(TARGETS ${name}
365-
LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
366-
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
377+
LIBRARY DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${INSTALLED_TARGET_TRIPLE}"
378+
ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${INSTALLED_TARGET_TRIPLE}"
367379
RUNTIME DESTINATION bin)
368380
set_target_properties(${name} PROPERTIES FOLDER "Flang libraries")
369381
endmacro(add_flang_library)

build-flang.sh

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ TARGET="X86"
88
BUILD_TYPE="Release"
99
BUILD_PREFIX="./build"
1010
INSTALL_PREFIX="/usr/local"
11+
CROSS_TARGET=""
1112
NPROC=1
1213
USE_LLVM_MAIN_SRC_DIR=""
13-
USE_LLVM_CONFIG=""
14+
LLVM_CONFIG_BIN=""
1415
USE_CCACHE="0"
1516
USE_SUDO="0"
1617
EXTRA_CMAKE_OPTS=""
@@ -33,6 +34,7 @@ function print_usage {
3334
echo " -d CMake build type. Default: Release";
3435
echo " -b Build prefix. Default: ./build";
3536
echo " -p Install prefix. Default: /usr/local";
37+
echo " -X Build a cross-compiler for given target triple. Default: N/A"
3638
echo " -n Number of parallel jobs. Default: 1";
3739
echo " -l Path to LLVM sources. Default: not set";
3840
echo " -o Path to llvm-config. Default: not set";
@@ -42,15 +44,16 @@ function print_usage {
4244
echo " -v Enable verbose output";
4345
}
4446

45-
while getopts "t:d:b:p:n:l:o:csx:v?" opt; do
47+
while getopts "t:X:d:b:p:n:l:o:csx:v?" opt; do
4648
case "$opt" in
4749
t) TARGET=$OPTARG;;
4850
d) BUILD_TYPE=$OPTARG;;
4951
b) BUILD_PREFIX=$OPTARG;;
5052
p) INSTALL_PREFIX=$OPTARG;;
53+
X) CROSS_TARGET=$OPTARG;;
5154
n) NPROC=$OPTARG;;
5255
l) USE_LLVM_MAIN_SRC_DIR="-DLLVM_MAIN_SRC_DIR=$OPTARG";;
53-
o) USE_LLVM_CONFIG="-DLLVM_CONFIG=$OPTARG";;
56+
o) LLVM_CONFIG_BIN="$OPTARG";;
5457
c) USE_CCACHE="1";;
5558
s) USE_SUDO="1";;
5659
x) EXTRA_CMAKE_OPTS="$OPTARG";;
@@ -61,18 +64,39 @@ done
6164

6265
CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
6366
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
64-
-DCMAKE_CXX_COMPILER=$INSTALL_PREFIX/bin/clang++ \
67+
-DCMAKE_AR=$INSTALL_PREFIX/bin/llvm-ar \
6568
-DCMAKE_C_COMPILER=$INSTALL_PREFIX/bin/clang \
69+
-DCMAKE_CXX_COMPILER=$INSTALL_PREFIX/bin/clang++ \
70+
-DCMAKE_RANLIB=$INSTALL_PREFIX/bin/llvm-ranlib \
6671
-DLLVM_TARGETS_TO_BUILD=$TARGET \
6772
$USE_LLVM_MAIN_SRC_DIR"
6873

74+
# Use lld for release_19x or newer version of classic-flang-llvm-project.
75+
set -x
76+
if [ -n "$LLVM_CONFIG_BIN" ]; then
77+
LLVM_MAJOR_VERSION=$("$LLVM_CONFIG_BIN" --version | cut -f1 -d.)
78+
if [ "$LLVM_MAJOR_VERSION" -gt 19 ]; then
79+
CMAKE_OPTIONS="$CMAKE_OPTIONS \
80+
-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld \
81+
-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld"
82+
fi
83+
fi
84+
set +x
85+
6986
if [ $USE_CCACHE == "1" ]; then
7087
echo "Build using ccache"
7188
CMAKE_OPTIONS="$CMAKE_OPTIONS \
7289
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
7390
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
7491
fi
7592

93+
if [ -n "$CROSS_TARGET" ]; then
94+
CMAKE_OPTIONS="$CMAKE_OPTIONS \
95+
-DCROSS_COMPILE_TARGET_TRIPLE=$CROSS_TARGET \
96+
-DLLVM_DEFAULT_TARGET_TRIPLE=$CROSS_TARGET \
97+
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON"
98+
fi
99+
76100
if [ -n "$EXTRA_CMAKE_OPTS" ]; then
77101
CMAKE_OPTIONS="$CMAKE_OPTIONS $EXTRA_CMAKE_OPTS"
78102
fi
@@ -88,15 +112,22 @@ mkdir -p $BUILD_PREFIX/libpgmath && cd $BUILD_PREFIX/libpgmath
88112
if [ -n "$VERBOSE" ]; then
89113
set -x
90114
fi
91-
cmake $CMAKE_OPTIONS $TOPDIR/runtime/libpgmath
115+
if [ -n "$CROSS_TARGET" ]; then
116+
cmake $CMAKE_OPTIONS \
117+
-DCMAKE_C_COMPILER_TARGET=$CROSS_TARGET \
118+
-DCMAKE_CXX_COMPILER_TARGET=$CROSS_TARGET \
119+
$TOPDIR/runtime/libpgmath
120+
else
121+
cmake $CMAKE_OPTIONS $TOPDIR/runtime/libpgmath
122+
fi
92123
set +x
93124
make -j$NPROC VERBOSE=$VERBOSE
94125
if [ $USE_SUDO == "1" ]; then
95126
echo "Install with sudo"
96-
sudo make install
127+
sudo make install VERBOSE=$VERBOSE
97128
else
98129
echo "Install without sudo"
99-
make install
130+
make install VERBOSE=$VERBOSE
100131
fi
101132

102133
# Build and install flang.
@@ -110,14 +141,14 @@ cmake $CMAKE_OPTIONS \
110141
-DFLANG_INCLUDE_DOCS=ON \
111142
-DFLANG_LLVM_EXTENSIONS=ON \
112143
-DWITH_WERROR=ON \
113-
$USE_LLVM_CONFIG \
144+
-DLLVM_CONFIG="$LLVM_CONFIG_BIN" \
114145
$TOPDIR
115146
set +x
116147
make -j$NPROC VERBOSE=$VERBOSE
117148
if [ $USE_SUDO == "1" ]; then
118149
echo "Install with sudo"
119-
sudo make install
150+
sudo make install VERBOSE=$VERBOSE
120151
else
121152
echo "Install without sudo"
122-
make install
153+
make install VERBOSE=$VERBOSE
123154
fi

runtime/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
#
66

7+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
8+
set(CMAKE_C_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}")
9+
set(CMAKE_CXX_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}")
10+
set(CMAKE_Fortran_FLAGS "-target ${CROSS_COMPILE_TARGET_TRIPLE}")
11+
endif()
12+
713
set (RUNTIME_SHARED_DIR ${CMAKE_CURRENT_SOURCE_DIR}/shared)
814

915
add_definitions(
@@ -39,6 +45,11 @@ elseif( ${TARGET_ARCHITECTURE} STREQUAL "ppc64le" )
3945
endif()
4046

4147
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
48+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
49+
link_directories("${LLVM_LIBRARY_DIR}/${CROSS_COMPILE_TARGET_TRIPLE}")
50+
else()
51+
link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}")
52+
endif()
4253

4354
add_subdirectory(ompstub)
4455

runtime/flangrti/CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,20 @@ if (CMAKE_THREAD_LIBS_INIT)
103103
target_link_libraries(flangrti_shared PRIVATE "${CMAKE_THREAD_LIBS_INIT}")
104104
endif()
105105

106-
# Import OpenMP
106+
# Import OpenMP.
107107
if (NOT DEFINED LIBOMP_EXPORT_DIR)
108108
find_library(
109109
FLANG_LIBOMP
110110
NAMES omp libomp
111-
HINTS "${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}")
111+
HINTS ${LLVM_LIBRARY_DIR}/${INSTALLED_TARGET_TRIPLE})
112112
target_link_libraries(flangrti_shared PUBLIC ${FLANG_LIBOMP})
113113
endif()
114114

115+
# Import libpgmath.
115116
find_library(
116117
LIBPGMATH
117118
NAMES pgmath libpgmath
118-
HINTS ${CMAKE_BINARY_DIR}/lib)
119+
HINTS ${LLVM_LIBRARY_DIR}/${INSTALLED_TARGET_TRIPLE})
119120
target_link_libraries(flangrti_shared PUBLIC ${LIBPGMATH})
120121

121122
if( ${TARGET_ARCHITECTURE} STREQUAL "aarch64" )

runtime/libpgmath/CMakeLists.txt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,28 @@ if ("${LIBPGMATH_SYSTEM_NAME}" STREQUAL "OpenBSD")
4646
set(LIBPGMATH_SYSTEM_NAME "Linux")
4747
endif ()
4848

49-
set(LIBPGMATH_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
49+
# Find the default (host) target triple from Clang.
50+
execute_process(
51+
COMMAND "${CMAKE_C_COMPILER}" "-v"
52+
RESULT_VARIABLE HAD_ERROR
53+
ERROR_VARIABLE DASHV_OUTPUT
54+
)
55+
if(NOT HAD_ERROR)
56+
string(REGEX REPLACE ".*Target: ([^ \r\n]+).*" "\\1" LLVM_HOST_TARGET "${DASHV_OUTPUT}")
57+
endif()
58+
if(NOT LLVM_HOST_TARGET)
59+
message(FATAL_ERROR "Could not parse host target triple from '${CMAKE_C_COMPILER} -v' output")
60+
endif()
61+
62+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
63+
string(REGEX REPLACE "-.*$" "" LIBPGMATH_SYSTEM_PROCESSOR ${CROSS_COMPILE_TARGET_TRIPLE})
64+
message(STATUS "Cross-compiling for ${LIBPGMATH_SYSTEM_PROCESSOR}")
65+
set(INSTALLED_TARGET_TRIPLE ${CROSS_COMPILE_TARGET_TRIPLE})
66+
else()
67+
set(LIBPGMATH_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
68+
set(INSTALLED_TARGET_TRIPLE ${LLVM_HOST_TARGET})
69+
endif()
70+
5071
if ("${LIBPGMATH_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR
5172
"${LIBPGMATH_SYSTEM_PROCESSOR}" STREQUAL "amd64" )
5273
set(LIBPGMATH_SYSTEM_PROCESSOR "x86_64")

runtime/libpgmath/lib/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,6 @@ else()
266266
set_target_properties(${LIBPGMATH_LIBRARY_NAME}_static PROPERTIES OUTPUT_NAME ${LIBPGMATH_LIBRARY_NAME})
267267
endif()
268268
install(TARGETS ${LIBPGMATH_LIBRARY_NAME}
269-
LIBRARY DESTINATION lib)
269+
LIBRARY DESTINATION lib/${INSTALLED_TARGET_TRIPLE})
270270
install(TARGETS ${LIBPGMATH_LIBRARY_NAME}_static
271-
ARCHIVE DESTINATION lib)
271+
ARCHIVE DESTINATION lib/${INSTALLED_TARGET_TRIPLE})

runtime/libpgmath/lib/generic/math_tables/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ if (DEFINED DEFINITIONS)
5353
set(DEFINITIONS "-D${DEFINITIONS}")
5454
endif()
5555
string(REPLACE ";" " " SRCS "${SRCS}")
56-
#orig list(APPEND PREPROCESSOR "${CMAKE_C_COMPILER} -E ${DEFINITIONS} ${FLAGS} ${SRCS}")
56+
if(DEFINED CMAKE_C_COMPILER_TARGET)
57+
list(APPEND PREPROCESSOR " -target ${CMAKE_C_COMPILER_TARGET}")
58+
endif()
5759
list(APPEND PREPROCESSOR " -E ${DEFINITIONS} -DPGFLANG ${FLAGS} ${SRCS}")
5860
separate_arguments(PREPROCESSOR UNIX_COMMAND "${PREPROCESSOR}")
5961
list(INSERT PREPROCESSOR 0 "${CMAKE_C_COMPILER}")

tools/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ if( ${TARGET_ARCHITECTURE} STREQUAL "aarch64" )
1515
add_definitions(-DLLVM_ENABLE_FFI=false)
1616
endif()
1717

18+
link_directories("${LLVM_LIBRARY_DIR}/${LLVM_HOST_TARGET}")
19+
1820
add_subdirectory(shared)
1921
add_subdirectory(flang1)
2022
add_subdirectory(flang2)

tools/flang1/flang1exe/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ add_flang_executable(flang1
121121
${SOURCES} ${SHARED_SOURCES}
122122
)
123123

124+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
125+
set_target_properties(flang1
126+
PROPERTIES OUTPUT_NAME
127+
"${CROSS_COMPILE_TARGET_TRIPLE}-flang1")
128+
endif()
129+
124130
target_compile_definitions(flang1
125131
PRIVATE
126132
${COMMON_DEFS}

tools/flang2/flang2exe/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ add_flang_executable(flang2
117117
${SOURCES} ${SHARED_CPP_SOURCES}
118118
)
119119

120+
if(DEFINED CROSS_COMPILE_TARGET_TRIPLE)
121+
set_target_properties(flang2
122+
PROPERTIES OUTPUT_NAME
123+
"${CROSS_COMPILE_TARGET_TRIPLE}-flang2")
124+
endif()
125+
120126
target_compile_definitions(flang2
121127
PRIVATE
122128
${COMMON_DEFS}

0 commit comments

Comments
 (0)