1# Copyright (c) 2021-2022 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 14# 32-bits pointers optimization in Panda for objects => addresses usage low 4GB 15# We need use linker scripts for section replacement above 4GB 16# Note: AddressSanitizer reserves (mmap) addresses for its own needs, 17# so we have difference start addresses for asan and default buildings 18function(panda_add_executable target) 19 # When using rapidcheck we should use linker scripts with 20 # definitions for exception handling sections 21 cmake_parse_arguments(ARG "RAPIDCHECK_ON" "OUTPUT_DIRECTORY" "" ${ARGN}) 22 23 if(PANDA_USE_PREBUILT_TARGETS) 24 if(NOT DEFINED ARG_OUTPUT_DIRECTORY) 25 set(ARG_OUTPUT_DIRECTORY "${PANDA_BINARY_ROOT}/bin/${target}") 26 endif() 27 28 message(VERBOSE "Use prebuilt ${target}") 29 add_executable(${target} IMPORTED GLOBAL) 30 set_property(TARGET ${target} PROPERTY 31 IMPORTED_LOCATION ${ARG_OUTPUT_DIRECTORY}) 32 return() 33 endif() 34 35 add_executable(${target} ${ARG_UNPARSED_ARGUMENTS}) 36 37 if(DEFINED ARG_OUTPUT_DIRECTORY) 38 set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${ARG_OUTPUT_DIRECTORY}") 39 endif() 40 41 if(PANDA_USE_32_BIT_POINTER AND NOT (PANDA_TARGET_MOBILE OR PANDA_TARGET_WINDOWS OR PANDA_TARGET_MACOS OR PANDA_TARGET_OHOS)) 42 if(ARG_RAPIDCHECK_ON) 43 set(LINKER_SCRIPT_ARG "-Wl,-T,${PANDA_ROOT}/ldscripts/panda_test_asan.ld") 44 else() 45 set(LINKER_SCRIPT_ARG "-Wl,-T,${PANDA_ROOT}/ldscripts/panda.ld") 46 endif() 47 if(PANDA_ENABLE_ADDRESS_SANITIZER) 48 # For cross-aarch64 with ASAN with linker script we need use additional path-link 49 # Here we use default addresses space (without ASAN flag). It is nuance of cross-building. 50 if(PANDA_TARGET_ARM64) 51 set(LINKER_SCRIPT_ARG "-Wl,-rpath-link,${PANDA_SYSROOT}/lib ${LINKER_SCRIPT_ARG}") 52 else() 53 set(LINKER_SCRIPT_ARG "-Wl,--defsym,LSFLAG_ASAN=1 ${LINKER_SCRIPT_ARG}") 54 endif() 55 endif() 56 # We need use specific options for AMD64 building with Clang compiler 57 # because it is necessary for placement of sections above 4GB 58 if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND PANDA_TARGET_AMD64) 59 set(LINKER_SCRIPT_ARG "${LINKER_SCRIPT_ARG} -pie") 60 # -mcmodel=large with clang and asan on x64 leads to bugs in rapidcheck with high-mem mappings 61 # so for rapidcheck test binaries panda_test_asan.ld is used which does not require 62 # -mcmodel=large option 63 if(NOT ARG_RAPIDCHECK_ON) 64 target_compile_options(${target} PUBLIC "-mcmodel=large") 65 endif() 66 endif() 67 target_link_libraries(${target} ${LINKER_SCRIPT_ARG}) 68 endif() 69endfunction() 70 71# This function need for non-SHARED libraries 72# It is necessary for 32-bits pointers via amd64 building with Clang compiler 73function(panda_set_lib_32bit_property target) 74 if(PANDA_USE_32_BIT_POINTER AND PANDA_TARGET_AMD64 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 75 set_property(TARGET ${target} PROPERTY POSITION_INDEPENDENT_CODE ON) 76 endif() 77endfunction() 78 79function(panda_add_library target lib_type) 80 if(NOT PANDA_USE_PREBUILT_TARGETS OR 81 NOT (lib_type STREQUAL SHARED) OR 82 NOT ARGN) 83 add_library(${ARGV}) 84 return() 85 endif() 86 87 set(RELATIVE_PATH "lib/lib${target}.so") 88 set(IMPORTED_LOCATION "${PANDA_BINARY_ROOT}/${RELATIVE_PATH}") 89 if(NOT EXISTS ${IMPORTED_LOCATION}) 90 set(IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${RELATIVE_PATH}") 91 endif() 92 93 message(VERBOSE "Use prebuilt lib${target}.so") 94 add_library(${target} ${lib_type} IMPORTED GLOBAL) 95 set_property(TARGET ${target} PROPERTY 96 IMPORTED_LOCATION ${IMPORTED_LOCATION}) 97endfunction() 98 99function(panda_target_link_libraries target) 100 get_target_property(target_is_imported ${target} IMPORTED) 101 if(NOT target_is_imported) 102 target_link_libraries(${ARGV}) 103 return() 104 endif() 105 106 cmake_parse_arguments(ARG "" "" "PUBLIC;PRIVATE;INTERFACE" ${ARGN}) 107 set(NON_PRIVATE_LIBRARIES ${ARG_PUBLIC} ${ARG_INTERFACE} ${ARG_UNPARSED_ARGUMENTS}) 108 109 foreach(lib IN LISTS NON_PRIVATE_LIBRARIES ARG_PRIVATE) 110 if(TARGET ${lib}) 111 get_target_property(lib_type ${lib} TYPE) 112 if(lib_type STREQUAL SHARED_LIBRARY) 113 add_dependencies(${target} ${lib}) 114 endif() 115 endif() 116 endforeach() 117 target_link_libraries(${target} INTERFACE ${NON_PRIVATE_LIBRARIES}) 118endfunction() 119 120function(panda_target_include_directories target) 121 get_target_property(target_is_imported ${target} IMPORTED) 122 if(NOT target_is_imported) 123 target_include_directories(${ARGV}) 124 return() 125 endif() 126 127 cmake_parse_arguments(ARG "SYSTEM" "" "PUBLIC;PRIVATE;INTERFACE" ${ARGN}) 128 if(ARG_SYSTEM) 129 set(SYSTEM_ON "SYSTEM") 130 endif() 131 132 target_include_directories(${target} ${SYSTEM_ON} INTERFACE ${ARG_PUBLIC} ${ARG_INTERFACE}) 133endfunction() 134 135function(panda_target_compile_options target) 136 get_target_property(target_is_imported ${target} IMPORTED) 137 if(NOT target_is_imported) 138 target_compile_options(${ARGV}) 139 return() 140 endif() 141 142 cmake_parse_arguments(ARG "" "" "PUBLIC;PRIVATE;INTERFACE" ${ARGN}) 143 target_compile_options(${target} INTERFACE ${ARG_PUBLIC} ${ARG_INTERFACE}) 144endfunction() 145 146function(panda_target_compile_definitions target) 147 get_target_property(target_is_imported ${target} IMPORTED) 148 if(NOT target_is_imported) 149 target_compile_definitions(${ARGV}) 150 return() 151 endif() 152 153 cmake_parse_arguments(ARG "" "" "PUBLIC;PRIVATE;INTERFACE" ${ARGN}) 154 target_compile_definitions(${target} INTERFACE ${ARG_PUBLIC} ${ARG_INTERFACE}) 155endfunction() 156 157function(panda_target_sources target) 158 get_target_property(target_is_imported ${target} IMPORTED) 159 if(NOT target_is_imported) 160 target_sources(${ARGV}) 161 endif() 162endfunction() 163