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_LLVM_IRTOC) 15 message(FATAL_ERROR "LLVMInlineModules must be included before Definitions.cmake") 16endif () 17 18if (NOT DEFINED PANDA_LLVM_INTERPRETER_INLINING) 19 set(PANDA_LLVM_INTERPRETER_INLINING true) 20endif () 21 22if (NOT PANDA_LLVM_INTERPRETER_INLINING) 23 message(STATUS "LLVM IR inlining disabled manually, PANDA_LLVM_INTERPRETER_INLINING = '${PANDA_LLVM_INTERPRETER_INLINING}'") 24endif () 25 26if (PANDA_LLVM_INTERPRETER_INLINING 27 AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" 28 # HostTools build, compiler does not matter. Parent project built bitcode files for inlining, and set 29 # IRTOC_INT_LLVM_INL_MODULE_FILES_LIST, the file has list of bitcode files which we'll link later and use as an inline 30 # module 31 AND "${IRTOC_INT_LLVM_INL_MODULE_FILES_LIST}" STREQUAL "") 32 message(STATUS "LLVM IR inlining disabled because compiler is not 'Clang' but = '${CMAKE_CXX_COMPILER_ID}'") 33 message(STATUS "and IRTOC_INT_LLVM_INL_MODULE_FILES_LIST = '${IRTOC_INT_LLVM_INL_MODULE_FILES_LIST}'") 34 set(PANDA_LLVM_INTERPRETER_INLINING false) 35endif () 36 37if (PANDA_LLVM_INTERPRETER_INLINING) 38 message(STATUS "LLVM IR inlining enabled") 39endif () 40 41if (NOT "${IRTOC_INT_LLVM_INL_MODULE_FILES_LIST}" STREQUAL "") 42 # Parent project set it using -DIRTOC_INT_LLVM_INL_MODULE_FILES_LIST 43 # The file contains list of paths of bitcode files delimited by ';' 44 # Example /tmp/a.o;/tmp/b.o 45 # Read the file 46 file(READ ${IRTOC_INT_LLVM_INL_MODULE_FILES_LIST} IRTOC_INT_LLVM_INL_MODULE) 47 # Split the contents into a list 48 string(REPLACE "\\;" ";" "${IRTOC_INT_LLVM_INL_MODULE}" IRTOC_INT_LLVM_INL_MODULE) 49elseif (NOT PANDA_LLVM_INTERPRETER_INLINING) 50 # Must be unused outside 51 set(IRTOC_INT_LLVM_INL_MODULE "") 52else () 53 # Pre-define the path for a file with a list of bitcode files for inlining. 54 # Define the path here to configure HostTools 55 set(IRTOC_INT_LLVM_INL_MODULE_FILES_LIST "${CMAKE_BINARY_DIR}/irtoc/irtoc_interpreter/interpreter_inline_files.txt") 56endif () 57 58# Produce a list of llvm bitcode files for given sources 59# 60# Parameters: 61# 62# TARGET - name of cmake target 63# OUTPUT_VARIABLE - name of the variable in parent scope to set paths to bitcode files 64# SOURCES - source files to build the module 65# INCLUDES - paths to includes when compiling SOURCES 66# DEPENDS - dependencies of the TARGET 67function(panda_add_llvm_bc_lib) 68 set(prefix ARG) 69 set(singleValues TARGET OUTPUT_VARIABLE) 70 set(multiValues SOURCES INCLUDES DEPENDS) 71 cmake_parse_arguments(${prefix} 72 "${noValues}" 73 "${singleValues}" 74 "${multiValues}" 75 ${ARGN}) 76 if (NOT PANDA_LLVM_INTERPRETER_INLINING) 77 add_custom_target(${ARG_TARGET} COMMENT "Do not generate llvm inline module because NOT PANDA_LLVM_INTERPRETER_INLINING") 78 return() 79 endif () 80 if (NOT DEFINED ARG_SOURCES) 81 message(FATAL_ERROR "Mandatory SOURCES argument is not defined.") 82 endif () 83 if (NOT DEFINED ARG_TARGET) 84 message(FATAL_ERROR "Mandatory TARGET argument is not defined.") 85 endif () 86 if (NOT DEFINED ARG_OUTPUT_VARIABLE) 87 message(FATAL_ERROR "Mandatory OUTPUT_VARIABLE argument is not defined.") 88 endif () 89 if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 90 message(FATAL_ERROR "Compiler must be clang but CMAKE_CXX_COMPILER_ID = '${CMAKE_CXX_COMPILER_ID}'") 91 endif () 92 93 add_custom_target("${ARG_TARGET}") 94 if (HOST_TOOLS) 95 message(STATUS "Skipping 'panda_add_llvm_bc_lib'. Reason: HOST_TOOLS") 96 return() 97 endif () 98 99 # Form bitcode files as an object library 100 set(BITCODE_OBJECTS "${ARG_TARGET}_bitcode") 101 panda_add_library(${BITCODE_OBJECTS} OBJECT ${ARG_SOURCES}) 102 # Mark all includes as SYSTEM and PRIVATE. 103 # SYSTEM because passed INCLUDES contain third party headers 104 # PRIVATE because we do not expect anyone to link against the bitcode file 105 foreach (include IN LISTS ARG_INCLUDES) 106 panda_target_include_directories(${BITCODE_OBJECTS} SYSTEM PRIVATE ${include}) 107 endforeach () 108 add_dependencies(${BITCODE_OBJECTS} ${ARG_DEPENDS}) 109 set_property(TARGET ${BITCODE_OBJECTS} PROPERTY POSITION_INDEPENDENT_CODE ON) 110 set(optimization_options -O1 "SHELL:-mllvm -disable-llvm-optzns") 111 if (PANDA_SANITIZERS_LIST) 112 # -disable-llvm-optzns disables ASan 113 set(optimization_options -O1) 114 endif () 115 panda_target_compile_options(${BITCODE_OBJECTS} PUBLIC -Wno-invalid-offsetof -emit-llvm ${optimization_options}) 116 panda_add_sanitizers(TARGET ${BITCODE_OBJECTS} SANITIZERS ${PANDA_SANITIZERS_LIST}) 117 set(${ARG_OUTPUT_VARIABLE} $<TARGET_OBJECTS:${BITCODE_OBJECTS}> PARENT_SCOPE) 118 add_dependencies(${ARG_TARGET} ${BITCODE_OBJECTS}) 119 120 if (TARGET host_tools_depends) 121 add_dependencies(host_tools_depends ${ARG_TARGET}) 122 endif () 123 124endfunction() 125