• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021-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
14# Generator of arch-dependent values for cross-compiling
15#
16# The target platforms should be specified with `create_cross_values_target(arch_name toolchain)` function.
17# Basically, the function adds an `ExternalProject` with ${PANDA_ROOT} as a source, configures it with
18# the specified toolchain and generates a header with values based on `asm_defines.def`. After that,
19# an umbrella-header `cross_values.h` is being generated (with the values included)
20#
21# Currently, only AMD64 cross-compiling is supported.
22
23# Prevent recursive generation:
24if (NOT CROSS_VALUES_CONFIG)
25    add_custom_target(cross_values_generator)
26    set(GENERATED_CROSS_VALUES_DIR "${PANDA_BINARY_ROOT}/cross_values/generated_values")
27    file(MAKE_DIRECTORY ${GENERATED_CROSS_VALUES_DIR})
28
29    include(ExternalProject)
30    function(create_cross_values_target arch toolchain)
31        set(CROSS_ASM_DEF_TARGET_NAME "cross_asm_defines_${arch}")
32        set(PANDA_AUX_PROJECT_SOURCE ${PANDA_ROOT})
33        set(PANDA_AUX_BINARY_DIR auxiliary_panda_binary_dirs/${arch})
34        set(CMAKE_VARIABLES
35            "'-G${CMAKE_GENERATOR}'
36            -DES2PANDA_PATH=${ES2PANDA_PATH}
37            -DCMAKE_TOOLCHAIN_FILE=${toolchain}
38            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
39            -DANDROID_ABI=${ANDROID_ABI}
40            -DANDROID_PLATFORM=${ANDROID_PLATFORM}
41            -DPANDA_TARGET_MOBILE_WITH_MANAGED_LIBS=${PANDA_TARGET_MOBILE_WITH_MANAGED_LIBS}
42            -DMOBILE_NATIVE_LIBS_SOURCE_PATH=${MOBILE_NATIVE_LIBS_SOURCE_PATH}
43            -DPANDA_TARGET_ARM32_ABI_HARD=${PANDA_TARGET_ARM32_ABI_HARD}
44            -DPANDA_PRODUCT_BUILD=${PANDA_PRODUCT_BUILD}
45            -DTOOLCHAIN_CLANG_ROOT=${TOOLCHAIN_CLANG_ROOT}
46            -DTOOLCHAIN_SYSROOT=${TOOLCHAIN_SYSROOT}
47            -DPANDA_WITH_TESTS=FALSE
48            -DPANDA_WITH_BENCHMARKS=FALSE
49            -DPANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER=${PANDA_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER}
50            -DPANDA_ENABLE_ADDRESS_SANITIZER=${PANDA_ENABLE_ADDRESS_SANITIZER}
51            -DCROSS_VALUES_CONFIG=TRUE
52            --no-warn-unused-cli
53            -Wno-deprecated"
54        )
55
56        foreach(plugin ${PLUGINS})
57            string(TOUPPER ${plugin} plugin_name_upper)
58            string(CONCAT PANDA_WITH_PLUGIN "PANDA_WITH_" ${plugin_name_upper})
59            string(APPEND CMAKE_VARIABLES "
60            -DPANDA_WITH_${plugin_name_upper}=${${PANDA_WITH_PLUGIN}}")
61        endforeach()
62
63        set(BUILD_COMMAND "${CMAKE_COMMAND} --build <BINARY_DIR> --target asm_defines")
64        separate_arguments(CMAKE_VARIABLES_SEP UNIX_COMMAND ${CMAKE_VARIABLES})
65        separate_arguments(BUILD_COMMAND UNIX_COMMAND ${BUILD_COMMAND})
66
67        # Configure subprojects at main project's configure step:
68        file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}")
69        message(STATUS "  Configuring subproject in ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR} via `execute_process()`")
70        set(TEMP_CMAKE_LOG_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}/cmake_log.tmp")
71        execute_process(
72            COMMAND ${CMAKE_COMMAND} ${PANDA_AUX_PROJECT_SOURCE} ${CMAKE_VARIABLES_SEP}
73            WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}"
74            RESULT_VARIABLE ret
75            OUTPUT_FILE ${TEMP_CMAKE_LOG_FILE}
76            ERROR_FILE ${TEMP_CMAKE_LOG_FILE}
77        )
78        if (NOT ret EQUAL "0")
79            file(READ ${TEMP_CMAKE_LOG_FILE} TEMP_CMAKE_LOG)
80            string(REPLACE "\n" "\n " TEMP_CMAKE_LOG ${TEMP_CMAKE_LOG})
81            string(REPLACE "\n" " " CMAKE_VARIABLES ${CMAKE_VARIABLES})
82            message(FATAL_ERROR
83                " ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR} configuration failed:\n"
84                " ${TEMP_CMAKE_LOG}\n"
85                " Reproduce:"
86                " cd ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR} && ${CMAKE_COMMAND} ${PANDA_AUX_PROJECT_SOURCE} ${CMAKE_VARIABLES}\n"
87            )
88        endif()
89
90        file(WRITE ${TEMP_CMAKE_LOG_FILE} "")
91        message(STATUS "  Building `asm_defines` in ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR} via `execute_process()`")
92        execute_process(
93            COMMAND ${CMAKE_COMMAND} --build . --target asm_defines
94            WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}"
95            RESULT_VARIABLE ret
96            OUTPUT_FILE ${TEMP_CMAKE_LOG_FILE}
97            ERROR_FILE ${TEMP_CMAKE_LOG_FILE}
98        )
99        if (NOT ret EQUAL "0")
100            file(READ ${TEMP_CMAKE_LOG_FILE} TEMP_CMAKE_LOG)
101            string(REPLACE "\n" "\n " TEMP_CMAKE_LOG ${TEMP_CMAKE_LOG})
102            message(FATAL_ERROR
103                " ${PANDA_AUX_BINARY_DIR}/runtime/asm_defines failed:\n"
104                " ${TEMP_CMAKE_LOG}\n"
105                " Reproduce:"
106                " cd ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR} && ${CMAKE_COMMAND} --build . --target asm_defines\n"
107            )
108        endif()
109
110        # Add targets to the main project:
111        ExternalProject_Add(${CROSS_ASM_DEF_TARGET_NAME}
112                SOURCE_DIR        "${PANDA_AUX_PROJECT_SOURCE}"
113                TMP_DIR           "${PANDA_AUX_BINARY_DIR}/${CROSS_ASM_DEF_TARGET_NAME}_tmp"
114                STAMP_DIR         "${PANDA_AUX_BINARY_DIR}/${CROSS_ASM_DEF_TARGET_NAME}_stamp"
115                DOWNLOAD_DIR      "${PANDA_AUX_BINARY_DIR}"
116                BINARY_DIR        "${PANDA_AUX_BINARY_DIR}"
117                INSTALL_DIR       "${PANDA_AUX_BINARY_DIR}"
118                BUILD_IN_SOURCE   FALSE
119                BUILD_ALWAYS      TRUE
120                CONFIGURE_COMMAND ""
121                BUILD_COMMAND     ${BUILD_COMMAND}
122                INSTALL_COMMAND   ""
123        )
124
125        set(ASM_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}/runtime/asm_defines")
126        set(ASM_FILE "libasm_defines.S")
127
128        add_custom_target(cross_asm_defines_${arch}_gen
129            COMMAND ${CMAKE_COMMAND} --build . --target asm_defines
130                    >${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}/cross_asm_defines.log
131                    || (cat ${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}/cross_asm_defines.log && false)
132            WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_AUX_BINARY_DIR}"
133            BYPRODUCTS ${ASM_DIR}/${ASM_FILE}
134        )
135
136        set(OUTPUT_DIR ${GENERATED_CROSS_VALUES_DIR})
137        set(OUTPUT_FILE "${arch}_values_gen.h")
138
139        add_custom_command(OUTPUT ${OUTPUT_DIR}/${OUTPUT_FILE}
140            COMMAND ruby ${CMAKE_CURRENT_SOURCE_DIR}/cross_values_generator.rb ${ASM_DIR}/${ASM_FILE} ${OUTPUT_DIR}/${OUTPUT_FILE} ${arch}
141            DEPENDS ${ASM_DIR}/${ASM_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/cross_values_generator.rb
142        )
143
144        add_custom_target(cross_values_generate_${arch}
145            DEPENDS ${OUTPUT_DIR}/${OUTPUT_FILE}
146        )
147        add_dependencies(cross_values_generator cross_values_generate_${arch})
148        set(GENERATED_CROSS_VALUES_HEADERS "${GENERATED_CROSS_VALUES_HEADERS} ${OUTPUT_DIR}/${OUTPUT_FILE}" PARENT_SCOPE)
149    endfunction()
150
151    # By default, gcc-toolchain is used:
152    set(PANDA_CROSS_X86_64_DEFAULT_TOOLCHAIN_FILE ${PANDA_ROOT}/cmake/toolchain/host_gcc_default.cmake)
153    set(PANDA_CROSS_AARCH64_DEFAULT_TOOLCHAIN_FILE ${PANDA_ROOT}/cmake/toolchain/cross-gcc-default-qemu-aarch64.cmake)
154    set(PANDA_CROSS_AARCH32_DEFAULT_TOOLCHAIN_FILE ${PANDA_ROOT}/cmake/toolchain/cross-gcc-default-qemu-arm-linux-gnueabi.cmake)
155
156    # Enable cross-target offsets for x86_64 only:
157    if (PANDA_TARGET_AMD64)
158        if (HOST_TOOLS)
159            create_cross_values_target(${PANDA_HOST_TOOLS_TARGET_ARCH} ${PANDA_HOST_TOOLS_TARGET_TOOLCHAIN})
160        else()
161            set(TARGET_CROSS_VALUES ${PANDA_BINARY_ROOT}/cross_values/generated_values/X86_64_values_gen.h)
162            set(TARGET_ARCH X86_64)
163            if (PANDA_COMPILER_TARGET_X86_64)
164                message(STATUS "Generating cross-values for X86_64")
165                if (PANDA_CROSS_X86_64_TOOLCHAIN_FILE)
166                    create_cross_values_target(X86_64 ${PANDA_CROSS_X86_64_TOOLCHAIN_FILE})
167                else()
168                    create_cross_values_target(X86_64 ${PANDA_CROSS_X86_64_DEFAULT_TOOLCHAIN_FILE})
169                endif()
170            endif()
171            if (PANDA_COMPILER_TARGET_AARCH64)
172                message(STATUS "Generating cross-values for AARCH64")
173                if (PANDA_CROSS_AARCH64_TOOLCHAIN_FILE)
174                    create_cross_values_target(AARCH64 ${PANDA_CROSS_AARCH64_TOOLCHAIN_FILE})
175                else()
176                    create_cross_values_target(AARCH64 ${PANDA_CROSS_AARCH64_DEFAULT_TOOLCHAIN_FILE})
177                endif()
178            endif()
179            if (PANDA_COMPILER_TARGET_AARCH32)
180                message(STATUS "Generating cross-values for ARM")
181                if (PANDA_CROSS_AARCH32_TOOLCHAIN_FILE)
182                    create_cross_values_target(AARCH32 ${PANDA_CROSS_AARCH32_TOOLCHAIN_FILE})
183                else()
184                    create_cross_values_target(AARCH32 ${PANDA_CROSS_AARCH32_DEFAULT_TOOLCHAIN_FILE})
185                endif()
186            endif()
187        endif()
188    elseif(PANDA_TARGET_ARM64)
189        message(STATUS "Generating cross-values for AARCH64")
190        set(TARGET_CROSS_VALUES ${PANDA_BINARY_ROOT}/cross_values/generated_values/AARCH64_values_gen.h)
191        set(TARGET_ARCH AARCH64)
192        create_cross_values_target(AARCH64 "${CMAKE_TOOLCHAIN_FILE}")
193        if(PANDA_COMPILER_TARGET_X86_64 OR PANDA_COMPILER_TARGET_AARCH32)
194            message(FATAL_ERROR "Cross-compiling is supported for AMD64 only")
195        endif()
196    elseif(PANDA_TARGET_ARM32)
197        message(STATUS "Generating cross-values for ARM")
198        set(TARGET_CROSS_VALUES ${PANDA_BINARY_ROOT}/cross_values/generated_values/AARCH32_values_gen.h)
199        set(TARGET_ARCH AARCH32)
200        create_cross_values_target(AARCH32 "${CMAKE_TOOLCHAIN_FILE}")
201        if(PANDA_COMPILER_TARGET_X86_64 OR PANDA_COMPILER_TARGET_AARCH64)
202            message(FATAL_ERROR "Cross-compiling is supported for AMD64 only")
203        endif()
204    endif()
205
206    set(OUTPUT_DIR "${PANDA_BINARY_ROOT}/cross_values")
207    set(OUTPUT_FILE "cross_values.h")
208
209    set(ASM_DEFINES_INPUT "${CMAKE_SOURCE_DIR}/runtime/asm_defines/asm_defines.def")
210    set(ASM_DEFINES_OUTPUT "${OUTPUT_DIR}/asm_defines_def.cpp")
211
212    add_custom_command(OUTPUT ${ASM_DEFINES_OUTPUT}
213        COMMAND cmake -E copy ${ASM_DEFINES_INPUT} ${ASM_DEFINES_OUTPUT}
214        DEPENDS ${ASM_DEFINES_INPUT}
215    )
216
217    panda_add_library(asm_defines_process OBJECT ${ASM_DEFINES_OUTPUT})
218    panda_target_compile_options(asm_defines_process PRIVATE -E -P)
219    panda_target_include_directories(asm_defines_process
220        PUBLIC ${CMAKE_SOURCE_DIR}
221        PUBLIC ${CMAKE_BINARY_DIR}
222        PUBLIC ${CMAKE_BINARY_DIR}/runtime/asm_defines
223    )
224
225    add_dependencies(cross_values_generator asm_defines_process)
226
227    string(REPLACE " " ";" GENERATED_CROSS_VALUES_HEADERS_LIST ${GENERATED_CROSS_VALUES_HEADERS})
228    add_custom_command(OUTPUT ${OUTPUT_DIR}/${OUTPUT_FILE}
229        COMMAND ruby ${CMAKE_CURRENT_SOURCE_DIR}/cross_values_getters_generator.rb $<TARGET_OBJECTS:asm_defines_process> ${GENERATED_CROSS_VALUES_DIR} ${OUTPUT_DIR}/${OUTPUT_FILE}
230        DEPENDS cross_values_generator ${CMAKE_CURRENT_SOURCE_DIR}/cross_values_getters_generator.rb $<TARGET_OBJECTS:asm_defines_process> ${GENERATED_CROSS_VALUES_HEADERS_LIST}
231    )
232
233    add_custom_target(cross_values
234        DEPENDS ${OUTPUT_DIR}/${OUTPUT_FILE}
235    )
236    set(GENERATED_CROSS_VALUES_HEADERS ${GENERATED_CROSS_VALUES_HEADERS} PARENT_SCOPE)
237    add_dependencies(panda_gen_files cross_values)
238
239    if (NOT (HOST_TOOLS OR PANDA_TARGET_WINDOWS))
240        # Generate `cross-values` using `asm_defines` from root-build to ensure later that they are the same as generated in `auxiliary_panda_binary_dirs`.
241        # The reason for this extra-generation is to check that `auxiliary_panda_binary_dirs` are being generated correctly, e.g. all
242        # of the `cmake`-flags are being passed correctly.
243        set(ROOT_ASM_DIR "${CMAKE_BINARY_DIR}/runtime/asm_defines")
244        set(ROOT_ASM_FILE "libasm_defines.S")
245        set(OUTPUT_DIR ${GENERATED_CROSS_VALUES_DIR}/test)
246        file(MAKE_DIRECTORY ${GENERATED_CROSS_VALUES_DIR}/test)
247        set(OUTPUT_FILE "values_root_build_gen.h")
248        set(ROOT_CROSS_VALUES ${OUTPUT_DIR}/${OUTPUT_FILE})
249        add_dependencies(cross_values asm_defines_generator)
250        add_custom_command(TARGET cross_values POST_BUILD
251            COMMAND ruby ${CMAKE_CURRENT_SOURCE_DIR}/cross_values_generator.rb ${ROOT_ASM_DIR}/${ROOT_ASM_FILE} ${ROOT_CROSS_VALUES} ${TARGET_ARCH}
252            COMMAND ${PANDA_ROOT}/cross_values/diff_check_values.sh ${TARGET_CROSS_VALUES} ${ROOT_CROSS_VALUES}
253        )
254    endif()
255else()
256    # Add mock-targets because of external dependencies on `cross_values`:
257    add_custom_target(asm_defines_process)
258    add_custom_target(cross_values)
259    add_custom_target(cross_values_generator)
260endif()
261
262if (CMAKE_CROSSCOMPILING)
263    add_dependencies(host_tools_depends cross_values)
264endif()
265