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