• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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