1# Copyright (c) 2023-2024 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14if (NOT PANDA_BUILD_LLVM_BACKEND) 15 message(FATAL_ERROR "PANDA_BUILD_LLVM_BACKEND must be true") 16endif() 17 18if (CROSS_VALUES_CONFIG) 19 message(FATAL_ERROR "LLVM_BACKEND must be disabled in cross_values") 20endif() 21 22# Build our own llvm libraries 23if (PANDA_BUILD_LLVM_BINARIES) 24 25 if (NOT DEFINED PANDA_BUILD_LLVM_BINARIES_PATH_ROOT) 26 message(FATAL_ERROR 27 "PANDA_BUILD_LLVM_BINARIES_PATH_ROOT variable should be set, when PANDA_BUILD_LLVM_BINARIES is set" 28 ) 29 endif() 30 31 include(libllvmbackend/cmake/CommonDefines.cmake) 32 include(ExternalProject) 33 34 set(LLVM_SOURCES_DIR ${PANDA_THIRD_PARTY_SOURCES_DIR}/llvm-project) 35 set(LLVM_SOURCES_SUBDIR ${LLVM_SOURCES_DIR}/llvm) 36 37 set(GIT_CLONE_URL "https://gitee.com/openharmony/third_party_llvm-project.git") 38 set(GIT_CLONE_BRANCH "2024_1127_llvm_ark_aot") 39 # Even though ExternalProject_Add knows how to do "git clone" 40 # there is problems with cloning because of 41 # multiple simultaneously running configurations, so we have to do it manually 42 if (NOT EXISTS ${LLVM_SOURCES_DIR}) 43 message(STATUS "Cloning llvm-project into ${LLVM_SOURCES_DIR}") 44 execute_process( 45 COMMAND git clone --depth 1 -b ${GIT_CLONE_BRANCH} ${GIT_CLONE_URL} ${LLVM_SOURCES_DIR} 46 ) 47 endif() 48 49 ExternalProject_Add(llvm-project 50 PREFIX LLVMExternal 51 52 USES_TERMINAL_CONFIGURE ON 53 USES_TERMINAL_BUILD ON 54 USES_TERMINAL_INSTALL ON 55 56 EXCLUDE_FROM_ALL ON 57 58 SOURCE_DIR ${LLVM_SOURCES_DIR} 59 ) 60 61 set(LLVM_CMAKE_COMMON_VARIABLES -G${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} 62 -DPACKAGE_VERSION=${REQUIRED_LLVM_VERSION} 63 -DLLVM_ENABLE_FFI=OFF 64 -DLLVM_ENABLE_TERMINFO=OFF 65 -DLLVM_INCLUDE_BENCHMARKS=OFF 66 -DLLVM_INCLUDE_EXAMPLES=OFF 67 -DLLVM_INCLUDE_TESTS=OFF 68 -DLLVM_BUILD_TOOLS=ON 69 -DLLVM_BUILD_LLVM_DYLIB=ON 70 -DLLVM_ENABLE_ZLIB=OFF 71 -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} 72 -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} 73 ) 74 set(COMMON_LLVM_COMPONENTS "cmake-exports;llvm-headers;LLVM") 75 set(LLVM_COMMON_BUILD_PREFIX "${PANDA_BUILD_LLVM_BINARIES_PATH_ROOT}/BUILD") 76 set(LLVM_COMMON_INSTALL_PREFIX "${PANDA_BUILD_LLVM_BINARIES_PATH_ROOT}/INSTALL") 77 set(COMMON_RESULT_DIR_NAME_PREFIX "llvm-${REQUIRED_LLVM_VERSION}-${CMAKE_BUILD_TYPE}") 78 79 # HACK: have to add this, because if this target not exist 80 # LLVMExports.cmake file (which is imported in LLVMConfig.cmake) 81 # trying to check that all packages are built. But we are trying to 82 # use LLVMConfig.cmake at config time, and therefore there is nothing build yet 83 if(NOT TARGET LLVMSupport) 84 add_custom_target(LLVMSupport) 85 endif() 86 87 function(llvm_project_create_target_steps) 88 set(oneValueArgs STEPS_NAME STEPS_BUILD_DIR) 89 set(multiValueArgs STEPS_BUILD_DEPENDEES) 90 cmake_parse_arguments(PARSE_ARGV 0 OPT "" "${oneValueArgs}" "${multiValueArgs}") 91 92 ExternalProject_Add_Step(llvm-project ${OPT_STEPS_NAME}-build-distribution 93 EXCLUDE_FROM_MAIN ON 94 USES_TERMINAL ON 95 DEPENDEES ${OPT_STEPS_BUILD_DEPENDEES} 96 COMMAND ${CMAKE_COMMAND} --build ${OPT_STEPS_BUILD_DIR} --target distribution 97 ) 98 ExternalProject_Add_Step(llvm-project ${OPT_STEPS_NAME}-install-distribution 99 EXCLUDE_FROM_MAIN ON 100 USES_TERMINAL ON 101 DEPENDEES ${OPT_STEPS_NAME}-build-distribution 102 BYPRODUCTS ${LIB_LLVM} 103 COMMAND ${CMAKE_COMMAND} --build ${OPT_STEPS_BUILD_DIR} --target install-distribution 104 ) 105 ExternalProject_Add_StepTargets(llvm-project ${OPT_STEPS_NAME}-install-distribution) 106 endfunction(llvm_project_create_target_steps) 107 108 function(config_llvm_and_install_package) 109 set(oneValueArgs BUILD_DIR TARGET_NAME) 110 set(multiValueArgs CMAKE_VARIABLES CMAKE_LLVM_COMPONENTS CMAKE_LLVM_TARGETS_TO_BUILD) 111 cmake_parse_arguments(PARSE_ARGV 0 OPT "" "${oneValueArgs}" "${multiValueArgs}") 112 if(EXISTS ${OPT_BUILD_DIR}/configuring_done) 113 # Do not reconfigure projects on subprojects build 114 # since some parameters might be changed and though 115 # new parameters doesn't matter for us, our config will be broken 116 message(STATUS "Configuring for ${OPT_TARGET_NAME} already done. Skip.") 117 return() 118 endif() 119 message(STATUS "Configuring LLVM and installing LLVMConfig.cmake file for ${OPT_TARGET_NAME}") 120 execute_process( 121 COMMAND ${CMAKE_COMMAND} -B ${OPT_BUILD_DIR} ${OPT_CMAKE_VARIABLES} 122 -DLLVM_DISTRIBUTION_COMPONENTS=${OPT_CMAKE_LLVM_COMPONENTS} 123 -DLLVM_TARGETS_TO_BUILD=${OPT_CMAKE_LLVM_TARGETS_TO_BUILD} 124 ${LLVM_SOURCES_SUBDIR} 125 COMMAND_ECHO STDOUT 126 COMMAND_ERROR_IS_FATAL ANY 127 ) 128 execute_process( 129 COMMAND ${CMAKE_COMMAND} --build ${OPT_BUILD_DIR} --target install-cmake-exports 130 COMMAND_ECHO STDOUT 131 COMMAND_ERROR_IS_FATAL ANY 132 ) 133 file(TOUCH ${OPT_BUILD_DIR}/configuring_done) 134 endfunction(config_llvm_and_install_package) 135 136 # x86_64-linux-gnu (expected to be host) 137 # Always register - no special dependencies, but it have parts, 138 # that other configuration depends on 139 set(X86_64_RESULT_DIR ${COMMON_RESULT_DIR_NAME_PREFIX}-x86_64) 140 config_llvm_and_install_package( 141 BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${X86_64_RESULT_DIR} 142 TARGET_NAME x86_64 143 CMAKE_VARIABLES ${LLVM_CMAKE_COMMON_VARIABLES} 144 -DCMAKE_INSTALL_PREFIX=${LLVM_COMMON_INSTALL_PREFIX}/${X86_64_RESULT_DIR} 145 CMAKE_LLVM_COMPONENTS "${COMMON_LLVM_COMPONENTS};llvm-link" 146 CMAKE_LLVM_TARGETS_TO_BUILD "X86;AArch64" 147 ) 148 if (PANDA_COMPILER_TARGET_X86_64) 149 set(libllvm-dependency llvm-project-x86_64-install-distribution) 150 set(LLVM_TARGET_PATH ${LLVM_COMMON_INSTALL_PREFIX}/${X86_64_RESULT_DIR}) 151 set(LIB_LLVM ${LLVM_TARGET_PATH}/lib/libLLVM.so) 152 endif() 153 llvm_project_create_target_steps( 154 STEPS_NAME x86_64 155 STEPS_BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${X86_64_RESULT_DIR} 156 ) 157 ExternalProject_Add_Step(llvm-project x86_64-install-llvm-link 158 EXCLUDE_FROM_MAIN ON 159 USES_TERMINAL ON 160 COMMAND ${CMAKE_COMMAND} --build ${LLVM_COMMON_BUILD_PREFIX}/${X86_64_RESULT_DIR} --target install-llvm-link 161 ) 162 ExternalProject_Add_StepTargets(llvm-project x86_64-install-llvm-link) 163 # add simple alias 164 add_custom_target(x86_64-llvm-link DEPENDS llvm-project-x86_64-install-llvm-link) 165 set(LLVM_LINK ${LLVM_COMMON_INSTALL_PREFIX}/${X86_64_RESULT_DIR}/bin/llvm-link) 166 167 ExternalProject_Add_Step(llvm-project x86_64-install-llvm-tblgen 168 EXCLUDE_FROM_MAIN ON 169 USES_TERMINAL ON 170 COMMAND ${CMAKE_COMMAND} --build ${LLVM_COMMON_BUILD_PREFIX}/${X86_64_RESULT_DIR} --target install-llvm-tblgen 171 ) 172 # used for aarch64-linux-gnu 173 ExternalProject_Add_StepTargets(llvm-project x86_64-install-llvm-tblgen) 174 175 if (PANDA_TARGET_LINUX AND PANDA_TARGET_ARM64) 176 # aarch64-linux-gnu 177 set(RESULT_DIR ${COMMON_RESULT_DIR_NAME_PREFIX}-aarch64) 178 set(AARCH64_CMAKE_C_FLAGS "--target=aarch64-linux-gnu\ -I/usr/aarch64-linux-gnu/include") 179 set(AARCH64_CMAKE_CXX_FLAGS 180 "--target=aarch64-linux-gnu\ -I/usr/aarch64-linux-gnu/include/c++/8/aarch64-linux-gnu\ -I/usr/aarch64-linux-gnu/include") 181 set(LLVM_TARGET_PATH ${LLVM_COMMON_INSTALL_PREFIX}/${RESULT_DIR}) 182 set(LLVM_CMAKE_TARGET_VARIABLES 183 -DCMAKE_INSTALL_PREFIX=${LLVM_TARGET_PATH} 184 -DCMAKE_CROSSCOMPILING=ON 185 -DLLVM_TARGET_ARCH=AArch64 186 -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu 187 -DCMAKE_C_FLAGS=${AARCH64_CMAKE_C_FLAGS} 188 -DCMAKE_CXX_FLAGS=${AARCH64_CMAKE_CXX_FLAGS} 189 -DLLVM_TABLEGEN=${LLVM_COMMON_INSTALL_PREFIX}/${X86_64_RESULT_DIR}/bin/llvm-tblgen 190 ) 191 set(libllvm-dependency llvm-project-aarch64-install-distribution) 192 set(LIB_LLVM ${LLVM_TARGET_PATH}/lib/libLLVM.so) 193 llvm_project_create_target_steps( 194 STEPS_NAME aarch64 195 STEPS_BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${RESULT_DIR} 196 STEPS_BUILD_DEPENDEES x86_64-install-llvm-tblgen 197 ) 198 config_llvm_and_install_package( 199 BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${RESULT_DIR} 200 TARGET_NAME aarch64 201 CMAKE_VARIABLES ${LLVM_CMAKE_COMMON_VARIABLES} ${LLVM_CMAKE_TARGET_VARIABLES} 202 CMAKE_LLVM_COMPONENTS "${COMMON_LLVM_COMPONENTS};llvm-link" 203 CMAKE_LLVM_TARGETS_TO_BUILD AArch64 204 ) 205 endif() 206 207 if (PANDA_TARGET_OHOS AND PANDA_TARGET_ARM64) 208 # aarch64-linux-ohos 209 if (NOT DEFINED ENV{OHOS_SDK_NATIVE}) 210 message(FATAL_ERROR "OHOS_SDK_NATIVE environment variable should be set to build LLVM for OHOS") 211 endif() 212 set(RESULT_DIR ${COMMON_RESULT_DIR_NAME_PREFIX}-ohos) 213 set(LLVM_TARGET_PATH ${LLVM_COMMON_INSTALL_PREFIX}/${RESULT_DIR}) 214 set(LLVM_CMAKE_TARGET_VARIABLES 215 -DCMAKE_TOOLCHAIN_FILE=$ENV{OHOS_SDK_NATIVE}/build/cmake/ohos.toolchain.cmake 216 -DOHOS_ALLOW_UNDEFINED_SYMBOLS=ON 217 -DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-ohos 218 -DCMAKE_INSTALL_PREFIX=${LLVM_TARGET_PATH} 219 ) 220 set(libllvm-dependency llvm-project-ohos-install-distribution) 221 set(LIB_LLVM ${LLVM_TARGET_PATH}/lib/libLLVM.so) 222 llvm_project_create_target_steps( 223 STEPS_NAME ohos 224 STEPS_BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${RESULT_DIR} 225 ) 226 config_llvm_and_install_package( 227 BUILD_DIR ${LLVM_COMMON_BUILD_PREFIX}/${RESULT_DIR} 228 TARGET_NAME ohos 229 CMAKE_VARIABLES ${LLVM_CMAKE_COMMON_VARIABLES} ${LLVM_CMAKE_TARGET_VARIABLES} 230 CMAKE_LLVM_COMPONENTS "${COMMON_LLVM_COMPONENTS}" 231 CMAKE_LLVM_TARGETS_TO_BUILD AArch64 232 ) 233 endif() 234 message(STATUS "libLLVM depends on \"${libllvm-dependency}\"") 235endif() 236 237find_package(LLVM 15 REQUIRED CONFIG NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH PATHS ${LLVM_TARGET_PATH}) 238message(STATUS "LLVM backend:") 239message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 240message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 241 242# use prebuilds 243if (NOT PANDA_BUILD_LLVM_BINARIES) 244 find_library(LIB_LLVM LLVM REQUIRED NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH PATHS ${LLVM_LIBRARY_DIR}) 245 246 if (NOT CMAKE_CROSSCOMPILING AND PANDA_LLVM_INTERPRETER_INLINING) 247 find_program(LLVM_LINK NAMES llvm-link REQUIRED NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH PATHS "${LLVM_BINARY_DIR}/bin") 248 endif() 249endif() 250 251message(STATUS "LLVM_LINK ${LLVM_LINK}") 252message(STATUS "LIB_LLVM ${LIB_LLVM}") 253set(LLVM_COPY_NAME "libLLVM-${LLVM_VERSION_MAJOR}.so") 254add_custom_target(copy-libLLVM.so 255 COMMENT "Copying ${LIB_LLVM} into ${PANDA_BINARY_ROOT}/lib/${LLVM_COPY_NAME}" 256 COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LIB_LLVM}" "${PANDA_BINARY_ROOT}/lib/${LLVM_COPY_NAME}" 257 DEPENDS ${libllvm-dependency}) 258