| # Copyright 2018 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations under the License. |
| # This contains a set of functions to make working with different targets a lot easier. The idea is that you can now set |
| # properties that define your lib/executable through variables that follow the following naming conventions |
| # |
| if(INCLUDE_ANDROID_CMAKE) |
| return() |
| endif() |
| |
| set(INCLUDE_ANDROID_CMAKE 1) |
| |
| include(bazel) |
| include(prebuilts) |
| include(symbols) |
| |
| # We want to make sure all the cross targets end up in a unique location |
| set(ANDROID_CROSS_BUILD_DIRECTORY ${CMAKE_BINARY_DIR}/build/${ANDROID_HOST_TAG}) |
| |
| set(ANDROID_XCODE_SIGN_ADHOC FALSE) |
| |
| if(APPLE) |
| set(ANDROID_XCODE_SIGN_ADHOC TRUE) |
| endif() |
| |
| # Checks to make sure the TAG is valid. |
| function(_check_target_tag TAG) |
| set(VALID_TARGETS |
| windows |
| windows_msvc-x86_64 |
| linux |
| linux-x86_64 |
| linux-aarch64 |
| darwin |
| darwin-x86_64 |
| darwin-aarch64 |
| all |
| Clang) |
| if(NOT (TAG IN_LIST VALID_TARGETS)) |
| message( |
| FATAL_ERROR |
| "The target ${TAG} does not exist, has to be one of: ${VALID_TARGETS}") |
| endif() |
| endfunction() |
| |
| # Cross compiles the given cmake project if needed. |
| # |
| # EXE the name of the target we are interested in. This is the main build |
| # product you want to use. SOURCE the location of the CMakeList.txt describing |
| # the project. OUT_PATH Name of the variable that will contain the resulting |
| # executable. |
| function(android_compile_for_host EXE SOURCE OUT_PATH) |
| if(NOT CROSSCOMPILE) |
| # We can add this project without any translation.. |
| if(NOT TARGET ${EXE}) |
| add_subdirectory(${SOURCE} ${EXE}_ext) |
| endif() |
| set(${OUT_PATH} "$<TARGET_FILE:${EXE}>" PARENT_SCOPE) |
| else() |
| include(ExternalProject) |
| |
| # If we are cross compiling we will need to build it for our actual OS we |
| # are currently running on. |
| get_filename_component( |
| BUILD_PRODUCT |
| ${ANDROID_CROSS_BUILD_DIRECTORY}/${EXE}_ext_cross/src/${EXE}_ext_cross-build/${EXE} |
| ABSOLUTE) |
| if(NOT TARGET ${EXE}_ext_cross) |
| message(STATUS "Cross compiling ${EXE} for host ${ANDROID_HOST_TAG}") |
| externalproject_add( |
| ${EXE}_ext_cross |
| PREFIX ${ANDROID_CROSS_BUILD_DIRECTORY}/${EXE}_ext_cross |
| DOWNLOAD_COMMAND "" |
| SOURCE_DIR ${SOURCE} |
| CMAKE_ARGS |
| "-DCMAKE_TOOLCHAIN_FILE=${ANDROID_QEMU2_TOP_DIR}/android/build/cmake/toolchain-${ANDROID_HOST_TAG}.cmake" |
| "-DBREAKPAD_API_KEY=${BREAKPAD_API_KEY}" |
| "-DBREAKPAD_API_URL=${BREAKPAD_API_URL}" |
| "-DOPTION_TEST_LOGS=${OPTION_TEST_LOGS}" |
| "-DOPTION_BAZEL=TRUE" |
| "-DANDROID_SYMBOL_DIR=${ANDROID_SYMBOL_DIR}" |
| "-DPython_EXECUTABLE=${Python_EXECUTABLE}" |
| BUILD_BYPRODUCTS ${BUILD_PRODUCT} |
| TEST_BEFORE_INSTALL True |
| LOG_BUILD ON |
| LOG_INSTALL ON |
| LOG_OUTPUT_ON_FAILURE TRUE |
| INSTALL_COMMAND "") |
| endif() |
| set(${OUT_PATH} ${BUILD_PRODUCT} PARENT_SCOPE) |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Enable the compilation of .l / .ll files using flex. This relies on |
| # ./external/flex being available |
| # |
| # The following parameters are accepted |
| # |
| # ``GENERATED`` The set of generated files |
| # ``SRC`` List of source files to be compiled. |
| # ``OUTPUT_DIR`` |
| # Directory where the generated sources will be placed, defaults to CMAKE_CURRENT_BINARY_DIR/flex |
| # ``SOURCE_DIR`` |
| # Root directory where sources can be found, defaults to CMAKE_CURRENT_SOURCE_DIR |
| # ~~~ |
| function(android_flex_compile) |
| # Parse arguments |
| set(options) |
| set(oneValueArgs OUTPUT_DIR GENERATED SOURCE_DIR) |
| set(multiValueArgs SRC) |
| cmake_parse_arguments(flex "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| |
| if(NOT flex_OUTPUT_DIR) |
| set(flex_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/flex) |
| endif() |
| if(NOT flex_SOURCE_DIR) |
| set(flex_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| endif() |
| if(NOT flex_SRC) |
| message( |
| SEND_ERROR "Error: android_flex_compile() called without any .l/.ll files" |
| ) |
| return() |
| endif() |
| |
| # Configure flex |
| android_compile_for_host( |
| flex ${ANDROID_QEMU2_TOP_DIR}/android/third_party/flex flex_EXECUTABLE) |
| |
| set(FLEX_GEN "") |
| file(MAKE_DIRECTORY ${flex_OUTPUT_DIR}) |
| foreach(FIL ${flex_SRC}) |
| get_filename_component(ABS_FIL ${FIL} ABSOLUTE) |
| get_filename_component(FIL_WE ${FIL} NAME_WE) |
| file(RELATIVE_PATH REL_FIL ${flex_SOURCE_DIR} ${ABS_FIL}) |
| get_filename_component(REL_DIR ${REL_FIL} DIRECTORY) |
| set(RELFIL_WE "${REL_DIR}/${FIL_WE}") |
| add_custom_command( |
| OUTPUT "${flex_OUTPUT_DIR}/${RELFIL_WE}.cpp" |
| COMMAND ${flex_EXECUTABLE} -o ${flex_OUTPUT_DIR}/${RELFIL_WE}.cpp |
| ${ABS_FIL} |
| COMMENT "Lexing ${ABS_FIL} with flex" |
| WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
| VERBATIM |
| DEPENDS ${flex_EXECUTABLE} ${ABS_FIL}) |
| list(APPEND FLEX_GEN ${flex_OUTPUT_DIR}/${RELFIL_WE}.cpp) |
| set_source_files_properties(${flex_OUTPUT_DIR}/${RELFIL_WE}.cpp |
| PROPERTIES GENERATED TRUE) |
| endforeach() |
| |
| # Make the library available |
| if(flex_GENERATED) |
| set(${flex_GENERATED} "${FLEX_GEN}" PARENT_SCOPE) |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Enable the compilation of .yy files using bison. This relies on |
| # ./external/bison |
| # |
| # The following parameters are accepted |
| # |
| # ''TYPE`` Generate c or cpp, defaults to cpp |
| # ``TARGET`` The library target to generate. |
| # ``SRC`` List of source files to be compiled. |
| # ``OUTPUT_DIR`` |
| # Directory where the generated sources will be placed, defaults to CMAKE_CURRENT_BINARY_DIR/gens |
| # ``SOURCE_DIR`` |
| # Root directory where sources can be found, defaults to CMAKE_CURRENT_SOURCE_DIR |
| # ~~~ |
| function(android_yacc_compile) |
| # Parse arguments |
| set(options) |
| set(oneValueArgs OUTPUT_DIR GENERATED SOURCE_DIR EXT) |
| set(multiValueArgs SRC) |
| cmake_parse_arguments(yacc "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| |
| if(NOT yacc_EXT) |
| set(yacc_EXT "cpp") |
| endif() |
| if(NOT yacc_OUTPUT_DIR) |
| set(yacc_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/yacc) |
| endif() |
| if(NOT yacc_SOURCE_DIR) |
| set(yacc_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
| endif() |
| if(NOT yacc_SRC) |
| message( |
| SEND_ERROR "Error: android_yacc_compile() called without any .yy files") |
| return() |
| endif() |
| |
| set(BISON_DIR ${ANDROID_QEMU2_TOP_DIR}/../bison) |
| # Configure bison & m4 |
| android_compile_for_host( |
| bison ${ANDROID_QEMU2_TOP_DIR}/android/third_party/bison bison_EXECUTABLE) |
| android_compile_for_host(m4 ${ANDROID_QEMU2_TOP_DIR}/android/third_party/m4 |
| m4_EXECUTABLE) |
| |
| if(MSVC AND WINDOWS_MSVC_X86_64) |
| set(PKG_DIR "set BISON_PKGDATADIR=${BISON_DIR}/data &") |
| else() |
| set(PKG_DIR "BISON_PKGDATADIR=${BISON_DIR}/data") |
| set(M4 "M4=${m4_EXECUTABLE}") |
| endif() |
| |
| set(YACC_GEN "") |
| file(MAKE_DIRECTORY ${yacc_OUTPUT_DIR}) |
| foreach(FIL ${yacc_SRC}) |
| get_filename_component(ABS_FIL ${FIL} ABSOLUTE) |
| get_filename_component(FIL_WE ${FIL} NAME_WE) |
| get_filename_component(FIL_EX ${FIL} EXT) |
| file(RELATIVE_PATH REL_FIL ${yacc_SOURCE_DIR} ${ABS_FIL}) |
| get_filename_component(REL_DIR ${REL_FIL} DIRECTORY) |
| set(RELFIL_WE "${REL_DIR}/${FIL_WE}") |
| add_custom_command( |
| OUTPUT "${yacc_OUTPUT_DIR}/${RELFIL_WE}.h" |
| "${yacc_OUTPUT_DIR}/${RELFIL_WE}.${yacc_EXT}" |
| COMMAND |
| ${PKG_DIR} ${M4} ${bison_EXECUTABLE} -d |
| --defines=${yacc_OUTPUT_DIR}/${RELFIL_WE}.h -o |
| ${yacc_OUTPUT_DIR}/${RELFIL_WE}.${yacc_EXT} ${ABS_FIL} |
| COMMENT "Yacc'ing ${ABS_FIL} with a bison" |
| WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
| VERBATIM |
| DEPENDS ${bison_EXECUTABLE} ${ABS_FIL} ${m4_EXECUTABLE}) |
| list(APPEND YACC_GEN ${yacc_OUTPUT_DIR}/${RELFIL_WE}.h) |
| list(APPEND YACC_GEN ${yacc_OUTPUT_DIR}/${RELFIL_WE}.${yacc_EXT}) |
| set_source_files_properties( |
| ${yacc_OUTPUT_DIR}/${RELFIL_WE}.h |
| ${yacc_OUTPUT_DIR}/${RELFIL_WE}.${yacc_EXT} PROPERTIES GENERATED TRUE) |
| endforeach() |
| |
| # Make the library available |
| if(yacc_GENERATED) |
| set(${yacc_GENERATED} "${YACC_GEN}" PARENT_SCOPE) |
| message(STATUS "These were the generated files: ${YACC_GEN}") |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Enable the compilation of .asm files using nasm. This will include the nasm project if needed to compile the assembly |
| # files. |
| # |
| # The following parameters are accepted |
| # |
| # ``TARGET`` The library target to generate. |
| # ``FLAGS`` Additional flags to pass to nasm |
| # ``INCLUDES`` Optional list of include paths to pass to nasm |
| # ``SRC`` List of source files to be compiled. |
| # |
| # For example: |
| # android_nasm_compile(TARGET foo_asm INCLUDES /tmp/foo /tmp/more_foo SOURCES /tmp/bar /tmp/z) |
| # |
| # nasm will be compiled for the HOST platform if needed. |
| # ~~~ |
| function(android_nasm_compile) |
| _register_target(${ARGN}) |
| # Parse arguments |
| set(options) |
| set(oneValueArgs TARGET) |
| set(multiValueArgs INCLUDES SRC FLAGS) |
| cmake_parse_arguments(android_nasm_compile "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| |
| # Configure nasm |
| android_compile_for_host( |
| nasm ${ANDROID_QEMU2_TOP_DIR}/android/third_party/nasm nasm_EXECUTABLE) |
| |
| # Setup the includes. |
| set(LIBNAME ${android_nasm_compile_TARGET}) |
| set(ASM_INC "") |
| foreach(INCLUDE ${android_nasm_compile_INCLUDES}) |
| set(ASM_INC ${ASM_INC} -I ${INCLUDE}) |
| endforeach() |
| |
| if(LINUX OR APPLE) |
| # Asan can report leaks in nasm.. |
| set(NO_ASAN "ASAN_OPTIONS=detect_leaks=0") |
| endif() |
| |
| # Configure the nasm compile command. |
| foreach(asm ${REGISTERED_SRC}) |
| get_filename_component(asm_base ${asm} NAME_WE) |
| set(DST ${CMAKE_CURRENT_BINARY_DIR}/${asm_base}.o) |
| add_custom_command( |
| OUTPUT ${DST} |
| COMMAND ${NO_ASAN} ${nasm_EXECUTABLE} ${android_nasm_compile_FLAGS} -f |
| ${ANDROID_ASM_TYPE} -o ${DST} ${asm} ${ASM_INC} |
| WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
| VERBATIM |
| DEPENDS ${nasm_EXECUTABLE} ${asm} |
| COMMENT |
| "nasm ${android_nasm_compile_FLAGS} -f ${ANDROID_ASM_TYPE} -o ${DST} ${asm} ${ASM_INC}" |
| ) |
| list(APPEND ${LIBNAME}_asm_o ${DST}) |
| endforeach() |
| |
| # Make the library available |
| add_library(${LIBNAME} ${${LIBNAME}_asm_o}) |
| set_target_properties(${LIBNAME} PROPERTIES LINKER_LANGUAGE CXX) |
| endfunction() |
| |
| # This function is the same as target_compile_definitions |
| # (https://cmake.org/cmake/help/v3.5/command/target_compile_definitions.html) |
| # The only difference is that the definitions will only be applied if the OS |
| # parameter matches the ANDROID_TARGET_TAG or compiler variable. |
| function(android_target_compile_definitions TGT OS MODIFIER ITEMS) |
| _check_target_tag(${OS}) |
| if(ANDROID_TARGET_TAG MATCHES "${OS}.*" OR OS STREQUAL "all" |
| OR OS MATCHES "${CMAKE_CXX_COMPILER_ID}") |
| target_compile_definitions(${TGT} ${MODIFIER} ${ITEMS}) |
| foreach(DEF ${ARGN}) |
| target_compile_definitions(${TGT} ${MODIFIER} ${DEF}) |
| endforeach() |
| endif() |
| endfunction() |
| |
| function(android_target_link_libraries2) |
| set(options DARWIN WINDOWS POSIX LINUX) |
| set(oneValueArgs TARGET) |
| set(multiValueArgs PRIVATE PUBLIC) |
| cmake_parse_arguments(lnk "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| if(LINUX AND (lnk_LINUX OR lnk_POSIX)) |
| target_link_libraries(${lnk_TARGET} PRIVATE ${lnk_PRIVATE} |
| PUBLIC ${lnk_PUBLIC}) |
| elseif((DARWIN_X86_64 OR DARWIN_AARCH64) AND (lnk_DARWIN OR lnk_POSIX)) |
| target_link_libraries(${lnk_TARGET} PRIVATE ${lnk_PRIVATE} |
| PUBLIC ${lnk_PUBLIC}) |
| |
| elseif(WINDOWS_MSVC_X86_64 AND (lnk_MSVC OR lnk_WINDOWS)) |
| target_link_libraries(${lnk_TARGET} PRIVATE ${lnk_PRIVATE} |
| PUBLIC ${lnk_PUBLIC}) |
| |
| endif() |
| endfunction() |
| |
| # This function is the same as target_link_libraries |
| # (https://cmake.org/cmake/help/v3.5/command/target_link_libraries.html) T he |
| # only difference is that the definitions will only be applied if the OS |
| # parameter matches the ANDROID_TARGET_TAG or Compiler variable. |
| function(android_target_link_libraries TGT OS MODIFIER ITEMS) |
| if(ARGC GREATER "49") |
| message( |
| FATAL_ERROR |
| "Currently cannot link more than 49 dependecies due to some weirdness with calling target_link_libs" |
| ) |
| endif() |
| _check_target_tag(${OS}) |
| if(ANDROID_TARGET_TAG MATCHES "${OS}.*" OR OS STREQUAL "all" |
| OR OS MATCHES "${CMAKE_CXX_COMPILER_ID}") |
| # HACK ATTACK! We cannot properly expand unknown linker args as they are |
| # treated in a magical fashion. Some arguments need to be "grouped" together |
| # somehow (for example optimized;lib) since we cannot resolve this properly |
| # we just pass on the individual arguments.. |
| # cmake-format: off |
| target_link_libraries(${TGT} ${MODIFIER} ${ARGV3} ${ARGV4} ${ARGV5} ${ARGV6} ${ARGV7} ${ARGV8} ${ARGV9} |
| ${ARGV10} ${ARGV11} ${ARGV12} ${ARGV13} ${ARGV14} ${ARGV15} ${ARGV16} ${ARGV17} ${ARGV18} ${ARGV19} |
| ${ARGV20} ${ARGV21} ${ARGV22} ${ARGV23} ${ARGV24} ${ARGV25} ${ARGV26} ${ARGV27} ${ARGV28} ${ARGV29} |
| ${ARGV30} ${ARGV31} ${ARGV32} ${ARGV33} ${ARGV34} ${ARGV35} ${ARGV36} ${ARGV37} ${ARGV38} ${ARGV39} |
| ${ARGV40} ${ARGV41} ${ARGV42} ${ARGV43} ${ARGV44} ${ARGV45} ${ARGV46} ${ARGV47} ${ARGV48} ${ARGV49}) |
| # cmake-format: on |
| endif() |
| endfunction() |
| |
| # This function is the same as target_include_directories |
| # (https://cmake.org/cmake/help/v3.5/command/target_include_directories.html) |
| # The only difference is that the definitions will only be applied if the OS |
| # parameter matches the ANDROID_TARGET_TAG variable. |
| function(android_target_include_directories TGT OS MODIFIER ITEMS) |
| _check_target_tag(${OS}) |
| if(ANDROID_TARGET_TAG MATCHES "${OS}.*" OR OS STREQUAL "all" |
| OR OS MATCHES "${CMAKE_CXX_COMPILER_ID}") |
| target_include_directories(${TGT} ${MODIFIER} ${ITEMS}) |
| foreach(DIR ${ARGN}) |
| target_include_directories(${TGT} ${MODIFIER} ${DIR}) |
| endforeach() |
| endif() |
| endfunction() |
| |
| # This function is the same as target_compile_options |
| # (https://cmake.org/cmake/help/v3.5/command/target_compile_options.html) The |
| # only difference is that the definitions will only be applied if the OS |
| # parameter matches the ANDROID_TARGET_TAG variable. |
| function(android_target_compile_options TGT OS MODIFIER ITEMS) |
| _check_target_tag(${OS}) |
| if(ANDROID_TARGET_TAG MATCHES "${OS}.*" OR OS STREQUAL "all" |
| OR OS MATCHES "${CMAKE_CXX_COMPILER_ID}") |
| target_compile_options(${TGT} ${MODIFIER} "${ITEMS};${ARGN}") |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Prefix the given prefix path to a source file that is not absolute sets. |
| # |
| # ``OUT`` The variable containing the transformed paths. |
| # ``PREFIX`` The relative prefix path. |
| # ``SRC `` List of source files to be prefixed |
| # ~~~ |
| function(prefix_sources) |
| set(oneValueArgs OUT PREFIX) |
| set(multiValueArgs SRC) |
| cmake_parse_arguments(pre "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| message("Prefix: ${pre_PREFIX} -> ${pre_OUT}") |
| if(NOT "${pre_PREFIX}" STREQUAL "") |
| set(ABSOLUTE_SOURCES "") |
| foreach(FIL ${pre_SRC}) |
| if(IS_ABSOLUTE ${FIL}) |
| list(APPEND ABSOLUTE_SOURCES "${FIL}") |
| else() |
| list(APPEND ABSOLUTE_SOURCES "${pre_PREFIX}/${FIL}") |
| endif() |
| endforeach() |
| set(${pre_OUT} ${ABSOLUTE_SOURCES} PARENT_SCOPE) |
| else() |
| set(${pre_OUT} ${pre_SRC} PARENT_SCOPE) |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Registers the given target, by calculating the source set and setting |
| # licenses. |
| # |
| # ``TARGET`` The library/executable target. For example emulatory-libyuv |
| # ``LIBNAME`` Public library name, this is how it is known in the world. |
| # For example libyuv. |
| # ``SRC`` List of source files to be compiled, part of every target. |
| # ``LINUX`` LINUX_X86_64 only sources. |
| # ``DARWIN`` DARWIN_X86_64 only sources. |
| # ``WINDOWS`` WINDOWS_MSVC_X86_64 only sources. |
| # ``MSVC`` WINDOWS_MSVC_X86_64 only sources. |
| # ``URL`` URL where the source code can be found. |
| # ``REPO`` Internal location where the, where the notice can be found. |
| # `LICENSE`` SPDX License identifier. |
| # ``NOTICE`` Location where the NOTICE can be found |
| # ``SOURCE_DIR`` Root source directory. This will be prepended to every source |
| # ~~~ |
| function(_register_target) |
| set(options NODISTRIBUTE) |
| set(oneValueArgs |
| TARGET |
| LICENSE |
| LIBNAME |
| REPO |
| URL |
| NOTICE |
| SOURCE_DIR) |
| set(multiValueArgs |
| INCLUDES |
| DEPS |
| SRC |
| LINUX |
| MSVC |
| WINDOWS |
| DARWIN |
| POSIX) |
| cmake_parse_arguments(build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| if(NOT DEFINED build_TARGET) |
| message(FATAL_ERROR "Undefined target for library.") |
| endif() |
| |
| set(src ${build_SRC}) |
| if(LINUX AND (build_LINUX OR build_POSIX)) |
| list(APPEND src ${build_LINUX} ${build_POSIX}) |
| elseif((DARWIN_X86_64 OR DARWIN_AARCH64) AND (build_DARWIN OR build_POSIX)) |
| list(APPEND src ${build_DARWIN} ${build_POSIX}) |
| elseif(WINDOWS_MSVC_X86_64 AND (build_MSVC OR build_WINDOWS)) |
| list(APPEND src ${build_MSVC} ${build_WINDOWS}) |
| endif() |
| |
| if(build_SOURCE_DIR) |
| set(ABSOLUTE_SOURCES "") |
| foreach(FIL ${src}) |
| if(IS_ABSOLUTE ${FIL}) |
| list(APPEND ABSOLUTE_SOURCES "${FIL}") |
| else() |
| list(APPEND ABSOLUTE_SOURCES "${build_SOURCE_DIR}/${FIL}") |
| endif() |
| endforeach() |
| set(REGISTERED_SRC ${ABSOLUTE_SOURCES} PARENT_SCOPE) |
| else() |
| set(REGISTERED_SRC ${src} PARENT_SCOPE) |
| endif() |
| |
| if(build_NODISTRIBUTE) |
| return() |
| endif() |
| |
| if(NOT DEFINED build_LIBNAME) |
| set(build_LIBNAME ${build_TARGET}) |
| endif() |
| |
| if(NOT DEFINED build_LICENSE) |
| message( |
| FATAL_ERROR |
| "You must set a license for ${build_TARGET}, or declare NODISTRIBUTE") |
| endif() |
| |
| if(NOT DEFINED build_NOTICE) |
| set(build_URL |
| "https://android.googlesource.com/platform/external/qemu.git/+/refs/heads/emu-master-dev" |
| ) |
| set(build_REPO "INTERNAL") |
| set(build_NOTICE "REPO/LICENSES/LICENSE.APACHE2") |
| endif() |
| |
| if(NOT DEFINED build_URL OR NOT DEFINED build_REPO OR NOT DEFINED |
| build_NOTICE) |
| message( |
| FATAL_ERROR |
| "You must set a notice/url/repo for ${build_TARGET}, or declare NODISTRIBUTE" |
| ) |
| endif() |
| if(DEFINED build_NOTICE AND NOT ${build_NODISTRIBUTE}) |
| string(REPLACE "REPO" "${build_URL}" REMOTE_LICENSE ${build_NOTICE}) |
| string(REPLACE "REPO" "${build_REPO}" LOCAL_LICENSE ${build_NOTICE}) |
| android_license( |
| TARGET ${build_TARGET} URL ${build_URL} LIBNAME ${build_LIBNAME} |
| SPDX ${build_LICENSE} LICENSE ${REMOTE_LICENSE} LOCAL ${LOCAL_LICENSE}) |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Sign the given binary when using MacOS. This signs the binary |
| # wtih the entitlements.plist, which is needed to get HVF access. |
| # |
| # Entitlements can be find in ${ANDROID_QEMU2_TOP_DIR}/entitlements.plist |
| # |
| # ``INSTALL`` Sign the given path during the installation step. |
| # ``TARGET` Sign the given target as a post build step. |
| # ~~~ |
| function(android_sign) |
| if(NOT APPLE) |
| return() |
| endif() |
| set(options "") |
| set(oneValueArgs INSTALL TARGET) |
| set(multiValueArgs "") |
| cmake_parse_arguments(sign "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| if(sign_INSTALL) |
| install( |
| CODE "message(STATUS \"Signing : ${sign_INSTALL}\") |
| execute_process(COMMAND codesign --deep -s - --entitlements ${ANDROID_QEMU2_TOP_DIR}/entitlements.plist ${sign_INSTALL})" |
| ) |
| else() |
| # Code signing cannot be done when cross compiling, unless we port something |
| # like https://github.com/thefloweringash/sigtool |
| if(DARWIN_X86_64 AND CROSSCOMPILE) |
| return() |
| endif() |
| if(DARWIN_AARCH64 AND CROSSCOMPILE) |
| return() |
| endif() |
| add_custom_command( |
| TARGET ${sign_TARGET} |
| POST_BUILD |
| COMMAND |
| codesign --deep -s - --entitlements |
| ${ANDROID_QEMU2_TOP_DIR}/entitlements.plist |
| $<TARGET_FILE:${sign_TARGET}> |
| COMMENT "Signing ${sign_TARGET}") |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Registers the given library, by calculating the source set and setting licenses. |
| # |
| # ``SHARED`` Option indicating that this is a shared library. |
| # ``ALIAS`` The library is an alias for another |
| # ``TARGET`` The library/executable target. For example emulatory-libyuv |
| # ``BAZEL`` The bazel target name for example "@zlib//:z", or none if this is not a bazel target |
| # ``INCLUDES`` The public includes that should be added |
| # ``LIBNAME`` Public library name, this is how it is known in the world. For example libyuv. |
| # ``SRC`` List of source files to be compiled, part of every target. |
| # ``LINUX`` List of source files to be compiled if the current target is LINUX_X86_64 |
| # ``DARWIN`` List of source files to be compiled if the current target is DARWIN_X86_64 |
| # ``WINDOWS`` List of source files to be compiled if the current target is WINDOWS_MSVC_X86_64 |
| # ``MSVC`` List of source files to be compiled if the current target is WINDOWS_MSVC_X86_64 |
| # ``URL`` URL where the source code can be found. |
| # ``REPO`` Internal location where the, where the notice can be found. |
| # ``LICENSE`` SPDX License identifier. |
| # ``NOTICE`` Location where the NOTICE can be found |
| # ``DEPS`` Set of private dependencies |
| # ~~~ |
| function(android_add_library) |
| set(options SHARED) |
| set(oneValueArgs TARGET ALIAS BAZEL) |
| set(multiValueArgs DEPS INCLUDES) |
| cmake_parse_arguments(build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| |
| # Check if this is a bazel target, if so, we will compile it with |
| if(OPTION_BAZEL AND DEFINED build_BAZEL AND NOT WINDOWS_MSVC_X86_64 |
| AND NOT LINUX_AARCH64) |
| android_add_bazel_lib(TARGET ${build_TARGET} BAZEL ${build_BAZEL} INCLUDE |
| ${build_INCLUDES}) |
| _register_target(${ARGN}) |
| return() |
| endif() |
| |
| if(${build_SHARED}) |
| add_library(${build_TARGET} SHARED "") |
| elseif((DEFINED build_ALIAS)) |
| set_property(GLOBAL APPEND PROPERTY ALIAS_LST |
| "${build_TARGET}|${build_ALIAS}\n") |
| add_library(${build_TARGET} ALIAS ${build_ALIAS}) |
| return() |
| else() |
| add_library(${build_TARGET} "") |
| endif() |
| |
| _register_target(${ARGN}) |
| |
| if(LINUX) |
| target_link_options(${build_TARGET} PRIVATE "LINKER:--build-id=sha1") |
| endif() |
| |
| target_sources(${build_TARGET} PRIVATE ${REGISTERED_SRC}) |
| target_link_libraries(${build_TARGET} PRIVATE ${build_DEPS}) |
| if(WINDOWS_MSVC_X86_64 AND NOT ${build_TARGET} STREQUAL "msvc-posix-compat") |
| target_link_libraries(${build_TARGET} PRIVATE msvc-posix-compat) |
| endif() |
| android_clang_tidy(${build_TARGET}) |
| # Clang on mac os does not get properly recognized by cmake |
| if(NOT DARWIN_X86_64 AND NOT DARWIN_AARCH64) |
| target_compile_features(${build_TARGET} PRIVATE cxx_std_17) |
| endif() |
| |
| if(${build_SHARED}) |
| # We don't want cmake to binplace the shared libraries into the bin |
| # directory As this can make them show up in unexpected places! |
| if(ANDROID_TARGET_TAG MATCHES "windows.*") |
| set_target_properties( |
| ${build_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY |
| ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) |
| endif() |
| if(CROSSCOMPILE AND WINDOWS_MSVC_X86_64) |
| # For windows-msvc build (on linux), this generates a dll and a lib |
| # (import library) file. The files are being placed at |
| # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} which is correct for the dll, but the |
| # lib file needs to be in the ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} or we |
| # can't link to it. Most windows compilers, including clang, don't allow |
| # you to directly link to a dll (unlike mingw), and instead, need to link |
| # to it's import library. |
| # |
| # Another headache: it seems we attach a prefix to some of our shared |
| # libraries, which make cmake unable to locate the import library later on |
| # to whoever tries to link to it (e.g. OpenglRender -> lib64OpenglRender), |
| # as it will look for an import library by <target_library_name>.lib. We |
| # just symlink things to make it work. |
| add_custom_command( |
| TARGET ${build_TARGET} |
| POST_BUILD |
| COMMAND |
| ${CMAKE_COMMAND} -E create_symlink |
| $<TARGET_FILE_DIR:${build_TARGET}>/${CMAKE_SHARED_LIBRARY_PREFIX}$<TARGET_LINKER_FILE_NAME:${build_TARGET}> |
| ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/$<TARGET_LINKER_FILE_NAME:${build_TARGET}> |
| COMMENT |
| "ln -sf $<TARGET_FILE_DIR:${build_TARGET}>/${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/$<TARGET_LINKER_FILE_NAME:${build_TARGET}> ${CMAKE_SHARED_LIBRARY_PREFIX}$<TARGET_LINKER_FILE_NAME:${build_TARGET}>" |
| ) |
| endif() |
| endif() |
| |
| if(build_INCLUDES) |
| target_include_directories(${build_TARGET} PUBLIC ${build_INCLUDES}) |
| endif() |
| endfunction() |
| |
| # Discovers all the targets that are registered by this subdirectory. |
| # |
| # result: The variable containing all the targets defined by this project |
| # subdir: The directory of interest |
| function(android_discover_targets result subdir) |
| if(CMAKE_VERSION VERSION_LESS "3.7.0") |
| message( |
| FATAL_ERROR |
| "This function cannot be used by older cmake versions (${CMAKE_VERSION}<3.7.0)" |
| ) |
| endif() |
| get_directory_property(subdirs DIRECTORY "${subdir}" SUBDIRECTORIES) |
| foreach(subdir IN LISTS subdirs) |
| android_discover_targets(${result} "${subdir}") |
| endforeach() |
| get_property(targets_in_dir DIRECTORY "${subdir}" |
| PROPERTY BUILDSYSTEM_TARGETS) |
| set(${result} ${${result}} ${targets_in_dir} PARENT_SCOPE) |
| endfunction() |
| |
| # Adds an external project, transforming all external "executables" to include |
| # the runtime properties. On linux for example this will set the rpath to find |
| # libc++ |
| # |
| # NOTE: This function requires CMake version > 3.7 |
| function(android_add_subdirectory external_directory name) |
| get_filename_component(abs_dir ${external_directory} ABSOLUTE) |
| add_subdirectory(${abs_dir} ${name}) |
| android_discover_targets(targets ${abs_dir}) |
| foreach(target IN LISTS targets) |
| get_target_property(tgt_type ${target} TYPE) |
| if(tgt_type STREQUAL "EXECUTABLE") |
| android_target_properties(${target} all "${RUNTIME_OS_PROPERTIES}") |
| endif() |
| endforeach() |
| endfunction() |
| |
| function(android_clang_tidy name) |
| if(${name} IN_LIST OPTION_CLANG_TIDY) |
| message(STATUS "Tidying ${name}") |
| if(OPTION_CLANG_TIDY_FIX) |
| message(STATUS " ===> Applying fixes to ${name}") |
| endif() |
| set_target_properties(${name} PROPERTIES CXX_CLANG_TIDY "${DO_CLANG_TIDY}") |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Registers the given library as an interface by calculating the source set and setting licenses. |
| # An INTERFACE library target does not directly create build output, though it may have properties |
| # set on it and it may be installed, exported and imported. |
| # |
| # ``TARGET`` The library/executable target. For example emulatory-libyuv |
| # ``LIBNAME`` Public library name, this is how it is known in the world. For example libyuv. |
| # ``URL`` URL where the source code can be found. |
| # ``REPO`` Internal location where the, where the notice can be found. |
| # ``LICENSE`` SPDX License identifier. |
| # ``NOTICE`` Location where the NOTICE can be found |
| # ~~~ |
| function(android_add_interface) |
| _register_target(${ARGN}) |
| set(options "") |
| set(oneValueArgs TARGET) |
| set(multiValueArgs "") |
| cmake_parse_arguments(build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| add_library(${build_TARGET} INTERFACE) |
| endfunction() |
| |
| define_property( |
| GLOBAL PROPERTY LICENSES_LST BRIEF_DOCS "Global list of license definitions" |
| FULL_DOCS "Global list of license definitions") |
| define_property( |
| GLOBAL PROPERTY INSTALL_TARGETS_LST |
| BRIEF_DOCS "Global list of targets that are installed." |
| FULL_DOCS "Global list of targets that are installed.") |
| define_property( |
| GLOBAL PROPERTY ALIAS_LST |
| BRIEF_DOCS "Global list of targets that are an alias for another." |
| FULL_DOCS "Global list of targets that are an alias for another.") |
| set_property(GLOBAL PROPERTY LICENSES_LST " ") |
| set_property(GLOBAL PROPERTY INSTALL_TARGETS_LST " ") |
| set_property(GLOBAL PROPERTY ALIAS_LST " ") |
| |
| # ~~~ |
| # ! android_license: Registers the given license, ands adds it to LICENSES_LST for post processing ! |
| # |
| # ``LIBNAME`` The name of the library, this is how it is usually known in the world. |
| # for example: libpng |
| # ``URL`` The location where the source code for this library can be found. |
| # ``TARGET`` List of targets that are part of the named library. For example crypto;ssl |
| # ``SPDX`` The spdx license identifier. (See https://spdx.org/) |
| # ``LOCAL`` Path to the NOTICE/LICENSE file. |
| # ``LICENSE`` Url to the actual license file. |
| # ~~ |
| function(android_license) |
| # Parse arguments |
| set(options) |
| set(oneValueArgs LIBNAME URL SPDX LICENSE LOCAL) |
| set(multiValueArgs TARGET) |
| cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| string(REPLACE "//" "/" URL "${args_URL}") |
| string(REPLACE ":/" "://" URL "${URL}") |
| string(REPLACE "//" "/" LICENSE "${args_LICENSE}") |
| string(REPLACE ":/" "://" LICENSE "${LICENSE}") |
| set_property( |
| GLOBAL APPEND |
| PROPERTY |
| LICENSES_LST |
| "${args_TARGET}|${args_LIBNAME}|${URL}|${args_SPDX}|${LICENSE}|${args_LOCAL}\n" |
| ) |
| endfunction() |
| |
| # ~~~ |
| # Finalize all licenses: |
| # |
| # 1. Writes out all license related information to a file. |
| # 2. Invokes the python license validator. |
| # ~~~ |
| function(finalize_all_licenses) |
| android_discover_targets(ALL_TARGETS ${ANDROID_QEMU2_TOP_DIR}) |
| get_property(LICENSES GLOBAL PROPERTY LICENSES_LST) |
| get_property(TARGETS GLOBAL PROPERTY INSTALL_TARGETS_LST) |
| get_property(ALIAS GLOBAL PROPERTY ALIAS_LST) |
| |
| file(REMOVE ${CMAKE_BINARY_DIR}/TARGET_DEPS.LST) |
| file(WRITE ${CMAKE_BINARY_DIR}/LICENSES.LST "${LICENSES}") |
| file(WRITE ${CMAKE_BINARY_DIR}/INSTALL_TARGETS.LST "${TARGETS}") |
| file(WRITE ${CMAKE_BINARY_DIR}/ALIAS.LST "${ALIAS}") |
| foreach(tgt ${ALL_TARGETS}) |
| get_target_property(target_type "${tgt}" TYPE) |
| set(DEPS "") |
| if(NOT target_type STREQUAL "INTERFACE_LIBRARY") |
| get_target_property(DEPS ${tgt} LINK_LIBRARIES) |
| endif() |
| file(APPEND ${CMAKE_BINARY_DIR}/TARGET_DEPS.LST |
| ";${tgt}|${target_type}|${DEPS}\n") |
| endforeach() |
| |
| message(STATUS "Validating licenses..") |
| execute_process( |
| COMMAND "${Python_EXECUTABLE}" "android/build/python/aemu/licensing.py" "-w" |
| "${PROJECT_BINARY_DIR}" WORKING_DIRECTORY ${ANDROID_QEMU2_TOP_DIR} |
| RESULT_VARIABLE LICENSE_RES OUTPUT_VARIABLE STD_OUT ERROR_VARIABLE STD_ERR) |
| if(NOT "${LICENSE_RES}" STREQUAL "0") |
| message( |
| FATAL_ERROR |
| "Unable to validate licenses, out: ${STD_OUT}, err: ${STD_ERR}") |
| endif() |
| install(FILES ${CMAKE_BINARY_DIR}/NOTICE.txt ${CMAKE_BINARY_DIR}/NOTICE.csv |
| DESTINATION .) |
| endfunction() |
| |
| # Creates the dependency |
| function(android_install_license tgt targetname) |
| set_property(GLOBAL APPEND PROPERTY INSTALL_TARGETS_LST |
| "${tgt}|${targetname}\n") |
| endfunction() |
| |
| function(android_add_default_test_properties name) |
| # Configure the test to run with asan.. |
| file(READ "${ANDROID_QEMU2_TOP_DIR}/android/asan_overrides" ASAN_OVERRIDES) |
| set_property(TEST ${name} PROPERTY ENVIRONMENT |
| "ASAN_OPTIONS=${ASAN_OVERRIDES}") |
| set_property( |
| TEST ${name} APPEND |
| PROPERTY ENVIRONMENT |
| "LLVM_PROFILE_FILE=$<TARGET_FILE_NAME:${name}>.profraw") |
| set_property( |
| TEST ${name} APPEND |
| PROPERTY ENVIRONMENT "ASAN_SYMBOLIZER_PATH=${ANDROID_LLVM_SYMBOLIZER}") |
| set_property(TEST ${name} PROPERTY TIMEOUT 600) |
| |
| if(WINDOWS_MSVC_X86_64) |
| # Let's include the .dll path for our test runner |
| string( |
| REPLACE |
| "/" |
| "\\" |
| WIN_PATH |
| "${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/gles_swiftshader;${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/qt/lib;$ENV{PATH}" |
| ) |
| string(REPLACE ";" "\;" WIN_PATH "${WIN_PATH}") |
| set_property(TEST ${name} APPEND PROPERTY ENVIRONMENT "PATH=${WIN_PATH}") |
| endif() |
| endfunction() |
| |
| # ~~~ |
| # Adds a test target. It will create and register the test with the given name. |
| # Test targets are marked as NODISTRIBUTE and hence cannot be installed |
| # |
| # ``TARGET`` The library/executable target. For example emulatory-libyuv |
| # ``SRC`` List of source files to be compiled, part of every target. |
| # ``SOURCE_DIR`` Root source directory. This will be prepended to every source file. |
| # ``LINUX`` List of source files to be compiled if the current target is LINUX_X86_64 |
| # ``DARWIN`` List of source files to be compiled if the current target is DARWIN_X86_64 |
| # ``WINDOWS`` List of source files to be compiled if the current target is WINDOWS_MSVC_X86_64 |
| # ``TEST_PARAMS`` Additional parameters for the test executable |
| # ``DEPS`` List of private dependencies. |
| # ~~~ |
| function(android_add_test) |
| set(options "") |
| set(oneValueArgs TARGET SOURCE_DIR) |
| set(multiValueArgs TEST_PARAMS SRC LINUX DARWIN WINDOWS DEPS) |
| cmake_parse_arguments(build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| |
| android_add_executable( |
| TARGET ${build_TARGET} SOURCE_DIR ${build_SOURCE_DIR} SRC ${build_SRC} |
| LINUX ${build_LINUX} DARWIN ${build_DARWIN} WINDOWS ${build_WINDOWS} |
| NODISTRIBUTE) |
| |
| android_target_dependency(${build_TARGET} linux TCMALLOC_OS_DEPENDENCIES) |
| add_test( |
| NAME ${build_TARGET} |
| COMMAND |
| $<TARGET_FILE:${build_TARGET}> |
| --gtest_output=xml:${OPTION_TEST_LOGS}/$<TARGET_FILE_NAME:${build_TARGET}>.xml |
| --gtest_catch_exceptions=0 ${build_TEST_PARAMS} |
| WORKING_DIRECTORY $<TARGET_FILE_DIR:${build_TARGET}>) |
| |
| # Let's not optimize our tests. |
| if(NOT WINDOWS_MSVC_X86_64) |
| target_compile_options(${build_TARGET} PRIVATE -O0) |
| endif() |
| target_link_libraries(${build_TARGET} PRIVATE ${build_DEPS}) |
| |
| android_add_default_test_properties(${build_TARGET}) |
| endfunction() |
| |
| # Installs the given target into ${DBG_INFO}/tests/ directory.. This is mainly |
| # there so we can preserve it as part of our automated builds. |
| function(android_install_as_debug_info name) |
| if(NOT DEFINED DBG_INFO) |
| # Ignore when cross-compiling withouth dbg_info available. |
| return() |
| endif() |
| |
| # TODO(jansene): Would be nice if we could make this part of install. |
| add_custom_command( |
| TARGET ${name} POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${name}> |
| ${DBG_INFO}/tests/$<TARGET_FILE_NAME:${name}>) |
| endfunction() |
| |
| # ~~~ |
| # Adds the given executable, by calculating the source set and registering the license |
| # |
| # ``SHARED`` Option indicating that this is a shared library. |
| # ``NODISTRIBUTE`` Option indicating that we will not distribute this. |
| # ``INSTALL`` Location where this executable should be installed if needed. |
| # ``TARGET`` The library/executable target. For example emulatory-libyuv |
| # ``LIBNAME`` Public library name, this is how it is known in the world. For example libyuv. |
| # ``SRC`` List of source files to be compiled, part of every target. |
| # ``LINUX`` List of source files to be compiled if the current target is LINUX_X86_64 |
| # ``DARWIN`` List of source files to be compiled if the current target is DARWIN_X86_64 |
| # ``WINDOWS`` List of source files to be compiled if the current target is WINDOWS_MSVC_X86_64 |
| # ``MSVC`` List of source files to be compiled if the current target is WINDOWS_MSVC_X86_64 |
| # ``URL`` URL where the source code can be found. |
| # ``REPO`` Internal location where the notice can be found. |
| # ``LICENSE`` SPDX License identifier. |
| # ``NOTICE`` Location where the NOTICE can be found relative to the source URL. Should be written |
| # as REPO/path/to/license. |
| # ~~~ |
| function(android_add_executable) |
| _register_target(${ARGN}) |
| set(options "") |
| set(oneValueArgs TARGET INSTALL) |
| set(multiValueArgs DEPS) |
| cmake_parse_arguments(build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| |
| add_executable(${build_TARGET} ${REGISTERED_SRC}) |
| target_link_libraries(${build_TARGET} PRIVATE ${build_DEPS}) |
| |
| if(LINUX) |
| target_link_options(${build_TARGET} PRIVATE "LINKER:--build-id=sha1") |
| endif() |
| |
| # Clang on mac os does not get properly recognized by cmake |
| if(NOT DARWIN_X86_64 AND NOT DARWIN_AARCH64) |
| target_compile_features(${build_TARGET} PRIVATE cxx_std_17) |
| endif() |
| |
| if(WINDOWS_MSVC_X86_64) |
| target_link_libraries(${build_TARGET} PRIVATE msvc-posix-compat) |
| endif() |
| |
| android_clang_tidy(${build_TARGET}) |
| android_target_dependency(${build_TARGET} all RUNTIME_OS_DEPENDENCIES) |
| android_target_properties(${build_TARGET} all "${RUNTIME_OS_PROPERTIES}") |
| |
| if(ANDROID_CODE_COVERAGE) |
| # TODO Clean out existing .gcda files. |
| endif() |
| |
| if(DEFINED build_INSTALL) |
| android_install_exe(${build_TARGET} ${build_INSTALL}) |
| endif() |
| endfunction() |
| |
| # Adds a protobuf library with the given name. It will export all the needed |
| # headers, and libraries You can take a dependency on this by adding: |
| # target_link_libraries(my_target ${name}) for your target. The generated |
| # library will not use execeptions. Protobuf targets will be licensed under the |
| # Apache-2.0 license. |
| # |
| # name: The name of the generated library. You can take a dependency on this |
| # with setting target_linke_libraries(my_target ${name}) |
| # |
| # protofiles: The set of protofiles to be included. |
| function(android_add_protobuf name protofiles) |
| message( |
| STATUS |
| "This method is deprecated, please use protobuf_generate_with_plugin instead for target ${name}." |
| ) |
| android_add_library(TARGET ${name} LICENSE Apache-2.0) |
| protobuf_generate_with_plugin(TARGET ${name} PROTOS ${protofiles}) |
| target_link_libraries(${name} PRIVATE libprotobuf) |
| endfunction() |
| |
| function(protobuf_generate_with_plugin) |
| include(CMakeParseArguments) |
| set(_options APPEND_PATH) |
| set(_singleargs |
| LANGUAGE |
| OUT_VAR |
| EXPORT_MACRO |
| PROTOC_OUT_DIR |
| PLUGIN |
| PLUGINOUT |
| PROTOPATH |
| HEADERFILEEXTENSION) |
| if(COMMAND target_sources) |
| list(APPEND _singleargs TARGET) |
| endif() |
| set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS) |
| |
| cmake_parse_arguments(protobuf_generate_with_plugin "${_options}" |
| "${_singleargs}" "${_multiargs}" "${ARGN}") |
| |
| if(NOT protobuf_generate_with_plugin_PROTOS |
| AND NOT protobuf_generate_with_plugin_TARGET) |
| message( |
| SEND_ERROR |
| "Error: protobuf_generate_with_plugin called without any targets or source files" |
| ) |
| return() |
| endif() |
| |
| if(protobuf_generate_with_plugin_PLUGIN) |
| set(protobuf_generate_with_plugin_PLUGIN |
| "--plugin=${protobuf_generate_with_plugin_PLUGIN}") |
| endif() |
| |
| if(protobuf_generate_with_plugin_PLUGINOUT) |
| set(protobuf_generate_with_plugin_PLUGINOUT |
| "--plugin_out=${protobuf_generate_with_plugin_PLUGINOUT}") |
| endif() |
| if(NOT protobuf_generate_with_plugin_OUT_VAR |
| AND NOT protobuf_generate_with_plugin_TARGET) |
| message( |
| SEND_ERROR |
| "Error: protobuf_generate called without a target or output variable") |
| return() |
| endif() |
| |
| if(NOT protobuf_generate_with_plugin_LANGUAGE) |
| set(protobuf_generate_with_plugin_LANGUAGE cpp) |
| endif() |
| string(TOLOWER ${protobuf_generate_with_plugin_LANGUAGE} |
| protobuf_generate_with_plugin_LANGUAGE) |
| |
| if(NOT protobuf_generate_with_plugin_PROTOC_OUT_DIR) |
| set(protobuf_generate_with_plugin_PROTOC_OUT_DIR |
| ${CMAKE_CURRENT_BINARY_DIR}) |
| endif() |
| |
| if(protobuf_generate_with_plugin_EXPORT_MACRO |
| AND protobuf_generate_with_plugin_LANGUAGE STREQUAL cpp) |
| set(_dll_export_decl |
| "dllexport_decl=${protobuf_generate_with_plugin_EXPORT_MACRO}:") |
| endif() |
| |
| if(NOT protobuf_generate_with_plugin_GENERATE_EXTENSIONS) |
| if(protobuf_generate_with_plugin_LANGUAGE STREQUAL cpp) |
| set(protobuf_generate_with_plugin_GENERATE_EXTENSIONS |
| ${protobuf_generate_with_plugin_HEADERFILEEXTENSION} .pb.cc) |
| elseif(protobuf_generate_with_plugin_LANGUAGE STREQUAL python) |
| set(protobuf_generate_with_plugin_GENERATE_EXTENSIONS _pb2.py) |
| else() |
| message( |
| SEND_ERROR |
| "Error: protobuf_generatewith_plugin given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS" |
| ) |
| return() |
| endif() |
| endif() |
| |
| if(protobuf_generate_with_plugin_TARGET) |
| get_target_property(_source_list ${protobuf_generate_with_plugin_TARGET} |
| SOURCES) |
| foreach(_file ${_source_list}) |
| if(_file MATCHES "proto$") |
| list(APPEND protobuf_generate_with_plugin_PROTOS ${_file}) |
| endif() |
| endforeach() |
| endif() |
| |
| if(NOT protobuf_generate_with_plugin_PROTOS) |
| message( |
| SEND_ERROR |
| "Error: protobuf_generate_with_plugin could not find any .proto files") |
| return() |
| endif() |
| |
| if(protobuf_generate_with_plugin_APPEND_PATH) |
| # Create an include path for each file specified |
| foreach(_file ${protobuf_generate_with_plugin_PROTOS}) |
| get_filename_component(_abs_file ${_file} ABSOLUTE) |
| get_filename_component(_abs_path ${_abs_file} PATH) |
| list(FIND _protobuf_include_path ${_abs_path} _contains_already) |
| if(${_contains_already} EQUAL -1) |
| list(APPEND _protobuf_include_path -I ${_abs_path}) |
| endif() |
| endforeach() |
| else() |
| set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) |
| endif() |
| |
| foreach(DIR ${protobuf_generate_with_plugin_IMPORT_DIRS}) |
| get_filename_component(ABS_PATH ${DIR} ABSOLUTE) |
| list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) |
| if(${_contains_already} EQUAL -1) |
| list(APPEND _protobuf_include_path -I ${ABS_PATH}) |
| endif() |
| endforeach() |
| |
| separate_arguments(PROTOPATH) |
| |
| set(_generated_srcs_all) |
| foreach(_proto ${protobuf_generate_with_plugin_PROTOS}) |
| get_filename_component(_abs_file ${_proto} ABSOLUTE) |
| get_filename_component(_abs_dir ${_abs_file} DIRECTORY) |
| get_filename_component(_basename ${_proto} NAME_WE) |
| file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir}) |
| |
| string(FIND "${_proto}" "${_rel_dir}" IDX) |
| |
| set(_generated_srcs) |
| foreach(_ext ${protobuf_generate_with_plugin_GENERATE_EXTENSIONS}) |
| if(IDX EQUAL "0") |
| # The protobuf is in a subdirectory under the current source dir we are |
| # processing Construct a complete path. |
| list( |
| APPEND |
| _generated_srcs |
| "${protobuf_generate_with_plugin_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}" |
| ) |
| else() |
| # The protobuf is not part of the source directory itself. |
| list( |
| APPEND _generated_srcs |
| "${protobuf_generate_with_plugin_PROTOC_OUT_DIR}/${_basename}${_ext}") |
| endif() |
| endforeach() |
| list(APPEND _generated_srcs_all ${_generated_srcs}) |
| |
| add_custom_command( |
| OUTPUT ${_generated_srcs} |
| COMMAND |
| protobuf::protoc ARGS --${protobuf_generate_with_plugin_LANGUAGE}_out |
| ${_dll_export_decl}${protobuf_generate_with_plugin_PROTOC_OUT_DIR} |
| ${_protobuf_include_path} ${PROTOPATH} ${_abs_file} |
| ${protobuf_generate_with_plugin_PLUGIN} |
| ${protobuf_generate_with_plugin_PLUGINOUT} |
| DEPENDS ${_abs_file} protobuf::protoc |
| COMMENT |
| "Running ${protobuf_generate_with_plugin_LANGUAGE} protocol buffer compiler on ${_proto}" |
| VERBATIM) |
| endforeach() |
| |
| set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) |
| if(protobuf_generate_with_plugin_OUT_VAR) |
| set(${protobuf_generate_with_plugin_OUT_VAR} ${_generated_srcs_all} |
| PARENT_SCOPE) |
| endif() |
| if(protobuf_generate_with_plugin_TARGET) |
| target_sources(${protobuf_generate_with_plugin_TARGET} |
| PRIVATE ${_generated_srcs_all}) |
| endif() |
| |
| endfunction() |
| |
| function( |
| PROTOBUF_GENERATE_CPP_WITH_PLUGIN |
| HEADERFILEEXTENSION |
| PLUGIN |
| PLUGINOUT |
| PROTOPATH |
| SRCS |
| HDRS) |
| cmake_parse_arguments(protobuf_generate_cpp_with_plugin "" "EXPORT_MACRO" "" |
| ${ARGN}) |
| |
| set(_proto_files "${protobuf_generate_cpp_with_plugin_UNPARSED_ARGUMENTS}") |
| if(NOT _proto_files) |
| message( |
| SEND_ERROR |
| "Error: PROTOBUF_GENERATE_CPP_WITH_PLUGIN() called without any proto files" |
| ) |
| return() |
| endif() |
| |
| if(PROTOBUF_GENERATE_CPP_WITH_PLUGIN_APPEND_PATH) |
| set(_append_arg APPEND_PATH) |
| endif() |
| |
| if(DEFINED Protobuf_IMPORT_DIRS) |
| set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS}) |
| endif() |
| |
| set(_outvar) |
| protobuf_generate_with_plugin( |
| ${_append_arg} |
| LANGUAGE cpp |
| EXPORT_MACRO ${protobuf_generate_cpp_with_plugin_EXPORT_MACRO} |
| OUT_VAR _outvar ${_import_arg} |
| PROTOS ${_proto_files} |
| PLUGIN ${PLUGIN} |
| PLUGINOUT ${PLUGINOUT} |
| PROTOPATH ${PROTOPATH} |
| HEADERFILEEXTENSION ${HEADERFILEEXTENSION}) |
| |
| set(${SRCS}) |
| set(${HDRS}) |
| foreach(_file ${_outvar}) |
| if(_file MATCHES "cc$") |
| list(APPEND ${SRCS} ${_file}) |
| else() |
| list(APPEND ${HDRS} ${_file}) |
| endif() |
| endforeach() |
| set(${SRCS} ${${SRCS}} PARENT_SCOPE) |
| set(${HDRS} ${${HDRS}} PARENT_SCOPE) |
| endfunction() |
| |
| # Adds a protozero library with the given plugin name. |
| function( |
| android_add_protobuf_with_plugin |
| name |
| headerfileextension |
| plugin |
| pluginout |
| protolib |
| PROTOPATH |
| protofile |
| genccpath) |
| protobuf_generate_cpp_with_plugin( |
| ${headerfileextension} |
| ${plugin} |
| ${pluginout} |
| ${PROTOPATH} |
| PROTO_SRCS |
| PROTO_HDRS |
| ${protofile}) |
| get_filename_component(PROTO_SRCS_ABS ${PROTO_SRCS} ABSOLUTE) |
| set(genccpath2 ${CMAKE_CURRENT_BINARY_DIR}/${genccpath}) |
| set_source_files_properties(${genccpath2} PROPERTIES GENERATED TRUE) |
| android_add_library(TARGET ${name} LICENSE Apache-2.0 SRC ${genccpath2} |
| ${PROTO_HDRS}) |
| target_link_libraries(${name} PUBLIC ${protolib}) |
| target_include_directories(${name} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) |
| android_clang_tidy(${name}) |
| endfunction() |
| |
| # For adding big proto files that mingw can't handle. |
| function(android_add_big_protobuf name protofiles) |
| android_add_protobuf(name protofiles) |
| endfunction() |
| |
| # This function generates the hw config file. It translates android- |
| # emu/android/avd/hardware-properties.ini -> android/avd/hw-config-defs.h |
| # |
| # This file will be placed on the current binary dir, so it can be included if |
| # this directory is on the include path. |
| function(android_generate_hw_config) |
| set(ANDROID_HW_CONFIG_H |
| ${CMAKE_CURRENT_BINARY_DIR}/avd_config/android/avd/hw-config-defs.h) |
| add_custom_command( |
| OUTPUT ${ANDROID_HW_CONFIG_H} |
| COMMAND |
| ${Python_EXECUTABLE} |
| ${ANDROID_QEMU2_TOP_DIR}/android/scripts/gen-hw-config.py |
| ${HW_PROPERTIES_INI} ${ANDROID_HW_CONFIG_H} |
| DEPENDS ${HW_PROPERTIES_INI} |
| VERBATIM) |
| android_add_library(TARGET android-hw-config LICENSE Apache-2.0 |
| SRC ${ANDROID_HW_CONFIG_H} dummy.c) |
| set_source_files_properties( |
| ${ANDROID_HW_CONFIG_H} PROPERTIES GENERATED TRUE SKIP_AUTOGEN ON |
| HEADER_FILE_ONLY TRUE) |
| target_include_directories(android-hw-config |
| PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/avd_config) |
| endfunction() |
| |
| # Copies the list of test data files to the given destination The test data |
| # resides in the prebuilts/android-emulator- build/common/testdata folder. |
| # |
| # TGT The target as part of which the test files should be copied. SOURCE_LIST |
| # The list of files that need to be copied DEST The subdirectory under TGT where |
| # the files should be copied to. |
| function(android_copy_test_files TGT SOURCE_LIST DEST) |
| get_filename_component( |
| TESTDATA_ROOT |
| "${ANDROID_QEMU2_TOP_DIR}/../../prebuilts/android-emulator-build/common/" |
| ABSOLUTE) |
| |
| foreach(SRC_FILE ${SOURCE_LIST}) |
| get_filename_component(DEST_FILE ${SRC_FILE} NAME) |
| add_custom_command( |
| TARGET ${TGT} |
| PRE_BUILD |
| COMMAND |
| ${CMAKE_COMMAND} -E copy_if_different ${TESTDATA_ROOT}/${SRC_FILE} |
| $<TARGET_FILE_DIR:${TGT}>/${DEST}/${DEST_FILE}) |
| endforeach() |
| endfunction() |
| |
| # Copies the given file from ${SRC} -> ${DST} if needed. |
| function(android_copy_file TGT SRC DST) |
| add_custom_command( |
| TARGET ${TGT} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different |
| ${SRC} ${DST} MAIN_DEPENDENCY ${SRC}) |
| endfunction() |
| |
| # Copies the given test directory to the given destination. The test data |
| # resides in the prebuilts/android-emulator- build/common/testdata folder. |
| # |
| # TGT The target as part of which the test files should be copied. SRC_DIR The |
| # source directories to copy., DST_DIR The subdirectory under TGT where the |
| # files should be copied to. |
| function(android_copy_test_dir TGT SRC_DIR DST_DIR) |
| get_filename_component( |
| TESTDATA_ROOT |
| "${ANDROID_QEMU2_TOP_DIR}/../../prebuilts/android-emulator-build/common/testdata" |
| ABSOLUTE) |
| |
| add_custom_command( |
| TARGET ${TGT} POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E copy_directory ${TESTDATA_ROOT}/${SRC_DIR} |
| $<TARGET_FILE_DIR:${TGT}>/${DST_DIR}) |
| endfunction() |
| |
| # Append the given flags to the existing CMAKE_C_FLAGS. Be careful as these |
| # flags are global and used for every target! Note this will not do anything |
| # under vs for now |
| function(add_c_flag FLGS) |
| foreach(FLAG ${FLGS}) |
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG}" PARENT_SCOPE) |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}" PARENT_SCOPE) |
| endforeach() |
| endfunction() |
| |
| function(add_cxx_flag FLGS) |
| foreach(FLAG ${FLGS}) |
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}" PARENT_SCOPE) |
| endforeach() |
| endfunction() |
| |
| # This function retrieves th git_version, or reverting to the date if we cannot |
| # fetch it. |
| # |
| # VER The variable to set the version in Sets ${VER} The version as reported by |
| # git, or the date |
| function(get_git_version VER) |
| execute_process( |
| COMMAND "git" "describe" WORKING_DIRECTORY ${ANDROID_QEMU2_TOP_DIR} |
| RESULT_VARIABLE GIT_RES OUTPUT_VARIABLE STD_OUT ERROR_VARIABLE STD_ERR) |
| if(NOT "${GIT_RES}" STREQUAL "0") |
| message( |
| WARNING |
| "Unable to retrieve git version from ${ANDROID_QEMU2_TOP_DIR}, out: ${STD_OUT}, err: ${STD_ERR}, not setting version." |
| ) |
| else() |
| # Clean up and make visibile |
| string(REPLACE "\n" "" STD_OUT "${STD_OUT}") |
| set(${VER} ${STD_OUT} PARENT_SCOPE) |
| endif() |
| |
| endfunction() |
| |
| # ~~~ |
| # ! android_link_complete_archive: Links an archive to be completely included |
| # |
| # For example: |
| # |
| # android_link_complete_archive(TARGET grpc++_reflection AS grpc++_reflection_whole) |
| # target_link_libraries( |
| # android-grpc |
| # PUBLIC grpc++_reflection_whole) |
| # |
| # |
| # |
| # ``TARGET`` The target that should become a complete archive |
| # ``AS`` Target you can use to link it in as a complete archive. |
| # ~~ |
| |
| function(android_link_complete_archive) |
| set(options) |
| set(oneValueArgs TARGET AS) |
| set(multiValueArgs) |
| cmake_parse_arguments(lnk "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| |
| if(DARWIN_X86_64 OR DARWIN_AARCH64) |
| set(WHOLE_LINK_CMD "-Wl,-force_load,$<TARGET_FILE:${lnk_TARGET}>") |
| elseif(WINDOWS_MSVC_X86_64) |
| if(MSVC) |
| # The native build calls the linker directly |
| set(WHOLE_LINK_CMD "-wholearchive:$<TARGET_FILE:${lnk_TARGET}>") |
| else() |
| # The cross compiler calls the linker through clang. |
| set(WHOLE_LINK_CMD "-Wl,-wholearchive:$<TARGET_FILE:${lnk_TARGET}>") |
| endif() |
| else() |
| set(WHOLE_LINK_CMD |
| "-Wl,--whole-archive $<TARGET_FILE:${lnk_TARGET}> -Wl,--no-whole-archive" |
| ) |
| endif() |
| set_property(GLOBAL APPEND PROPERTY ALIAS_LST "${lnk_AS}|${lnk_TARGET}\n") |
| add_library(${lnk_AS} INTERFACE) |
| add_dependencies(${lnk_AS} ${lnk_TARGET}) |
| target_link_libraries(${lnk_AS} INTERFACE ${WHOLE_LINK_CMD}) |
| endfunction() |
| |
| # Constructs a linker command that will make sure the whole archive is included, |
| # not just the ones referenced. |
| # |
| # . LIBCMD The variable which will contain the complete linker command . LIBNAME |
| # The archive that needs to be included completely |
| function(android_complete_archive LIBCMD LIBNAME) |
| if(DARWIN_X86_64 OR DARWIN_AARCH64) |
| set(${LIBCMD} "-Wl,-force_load,$<TARGET_FILE:${LIBNAME}>" PARENT_SCOPE) |
| elseif(WINDOWS_MSVC_X86_64) |
| if(MSVC) |
| # The native build calls the linker directly |
| set(${LIBCMD} "-wholearchive:$<TARGET_FILE:${LIBNAME}>" PARENT_SCOPE) |
| else() |
| # The cross compiler calls the linker through clang. |
| set(${LIBCMD} "-Wl,-wholearchive:$<TARGET_FILE:${LIBNAME}>" PARENT_SCOPE) |
| endif() |
| else() |
| set(${LIBCMD} "-Wl,--whole-archive" ${LIBNAME} "-Wl,--no-whole-archive" |
| PARENT_SCOPE) |
| endif() |
| endfunction() |
| |
| # Constructs the upstream qemu executable. |
| # |
| # ANDROID_AARCH The android architecture name QEMU_AARCH The qemu architecture |
| # name. CONFIG_AARCH The configuration architecture used. STUBS The set of stub |
| # sources to use. CPU The target cpu architecture used by qemu |
| # |
| # (Maybe on one day we will standardize all the naming, between qemu and configs |
| # and cpus..) |
| function(android_build_qemu_variant) |
| # Parse arguments |
| set(options INSTALL) |
| set(oneValueArgs CPU EXE) |
| set(multiValueArgs SOURCES DEFINITIONS LIBRARIES) |
| cmake_parse_arguments(qemu_build "${options}" "${oneValueArgs}" |
| "${multiValueArgs}" ${ARGN}) |
| |
| # translate various names.. because of inconsistent naming in the code base.. |
| if(qemu_build_CPU STREQUAL "x86_64") |
| set(CPU "i386") |
| set(QEMU_AARCH "x86_64") |
| set(CONFIG_AARCH "x86_64") |
| elseif(qemu_build_CPU STREQUAL "i386") |
| set(CPU "i386") |
| set(QEMU_AARCH "i386") |
| set(CONFIG_AARCH "x86") |
| elseif(qemu_build_CPU STREQUAL "aarch64") |
| set(CPU "arm") |
| set(QEMU_AARCH "aarch64") |
| set(CONFIG_AARCH "arm64") |
| elseif(qemu_build_CPU STREQUAL "armel") |
| set(CPU "arm") |
| set(QEMU_AARCH "arm") |
| set(CONFIG_AARCH "arm") |
| else() |
| message(FATAL_ERROR "Unknown cpu type.") |
| endif() |
| |
| # Workaround b/121393952, older cmake does not have proper object archives |
| android_complete_archive(QEMU_COMPLETE_LIB "qemu2-common") |
| android_add_executable( |
| TARGET ${qemu_build_EXE} |
| LICENSE Apache-2.0 |
| LIBNAME |
| qemu-system |
| URL |
| "https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev" |
| REPO "${ANDROID_QEMU2_TOP_DIR}" |
| NOTICE "REPO/LICENSES/LICENSE.APACHE2" |
| SRC ${ANDROID_AUTOGEN}/trace/generated-helpers-wrappers.h |
| ${ANDROID_AUTOGEN}/trace/generated-tcg-tracers.h |
| ${qemu-system-${QEMU_AARCH}_generated_sources} |
| ${qemu-system-${QEMU_AARCH}_sources} |
| ${qemu_build_SOURCES} |
| # These are autogenerated. |
| ) |
| target_include_directories( |
| ${qemu_build_EXE} PRIVATE android-qemu2-glue/config/target-${CONFIG_AARCH} |
| target/${CPU} ${ANDROID_AUTOGEN}) |
| target_compile_definitions(${qemu_build_EXE} |
| PRIVATE ${qemu_build_DEFINITIONS}) |
| target_link_libraries(${qemu_build_EXE} PRIVATE ${QEMU_COMPLETE_LIB} |
| ${qemu_build_LIBRARIES}) |
| # Make the common dependency explicit, as some generators might not detect it |
| # properly (Xcode/MSVC native) |
| add_dependencies(${qemu_build_EXE} qemu2-common) |
| android_sign(TARGET ${qemu_build_EXE}) |
| |
| # XCode bin places this not where we want this... |
| if(qemu_build_INSTALL) |
| set_target_properties( |
| ${qemu_build_EXE} |
| PROPERTIES |
| RUNTIME_OUTPUT_DIRECTORY |
| "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qemu/${ANDROID_TARGET_OS_FLAVOR}-${ANDROID_TARGET_ARCH}" |
| ) |
| android_install_exe( |
| ${qemu_build_EXE} |
| "./qemu/${ANDROID_TARGET_OS_FLAVOR}-${ANDROID_TARGET_ARCH}") |
| endif() |
| endfunction() |
| |
| # Constructs the qemu executable. |
| # |
| # ANDROID_AARCH The android architecture name STUBS The set of stub sources to |
| # use. |
| function(android_add_qemu_executable ANDROID_AARCH STUBS) |
| if(WINDOWS_MSVC_X86_64) |
| set(WINDOWS_LAUNCHER emulator-winqt-launcher) |
| endif() |
| android_build_qemu_variant( |
| INSTALL |
| EXE qemu-system-${ANDROID_AARCH} |
| CPU ${ANDROID_AARCH} |
| SOURCES ${STUBS} android-qemu2-glue/main.cpp vl.c |
| DEFINITIONS |
| -DNEED_CPU_H -DCONFIG_ANDROID |
| -DANDROID_SDK_TOOLS_REVISION=${OPTION_SDK_TOOLS_REVISION} |
| -DANDROID_SDK_TOOLS_BUILD_NUMBER=${OPTION_SDK_TOOLS_BUILD_NUMBER} |
| LIBRARIES libqemu2-glue |
| libqemu2-glue-vm-operations |
| libqemu2-util |
| android-emu |
| android-emu-base-headers |
| android-qemu-deps |
| android-qemu-deps-headful |
| emulator-libusb |
| ${WINDOWS_LAUNCHER} |
| android-emu-wear # vl.c directly refers to wear! |
| android-emu-crash-initializer |
| android-emu-crashreport-consent-ui |
| aemu-ui-qt |
| aemu-ui-common |
| aemu-ui-qt) |
| |
| endfunction() |
| |
| # Constructs the qemu headless executable. |
| # |
| # ANDROID_AARCH The android architecture name STUBS The set of stub sources to |
| # use. |
| function(android_add_qemu_headless_executable ANDROID_AARCH STUBS) |
| android_build_qemu_variant( |
| INSTALL |
| EXE qemu-system-${ANDROID_AARCH}-headless |
| CPU ${ANDROID_AARCH} |
| SOURCES ${STUBS} android-qemu2-glue/main.cpp vl.c |
| DEFINITIONS |
| -DNEED_CPU_H -DCONFIG_ANDROID -DCONFIG_HEADLESS |
| -DANDROID_SDK_TOOLS_REVISION=${OPTION_SDK_TOOLS_REVISION} |
| -DANDROID_SDK_TOOLS_BUILD_NUMBER=${OPTION_SDK_TOOLS_BUILD_NUMBER} |
| LIBRARIES libqemu2-glue |
| libqemu2-glue-vm-operations |
| libqemu2-util |
| android-emu |
| android-emu-base-headers |
| android-qemu-deps |
| android-qemu-deps-headless |
| emulator-libusb |
| android-emu-wear # vl.c directly refers to wear! |
| android-emu-crash-initializer |
| android-emu-crashreport-consent-no-ui |
| aemu-ui-window |
| aemu-ui-common |
| aemu-ui-headless) |
| endfunction() |
| |
| # Constructs the qemu upstream executable. |
| # |
| # ANDROID_AARCH The android architecture name STUBS The set of stub sources to |
| # use. |
| function(android_add_qemu_upstream_executable ANDROID_AARCH STUBS) |
| if(DARWIN_AARCH64) |
| android_build_qemu_variant( |
| # INSTALL We do not install this target. |
| EXE qemu-upstream-${ANDROID_AARCH} |
| CPU ${ANDROID_AARCH} |
| SOURCES ${STUBS} vl.c |
| DEFINITIONS -DNEED_CPU_H |
| LIBRARIES android-emu |
| libqemu2-glue |
| libqemu2-glue-vm-operations |
| libqemu2-util |
| android-qemu-deps |
| android-qemu-deps-headful |
| emulator-libusb) |
| else() |
| android_build_qemu_variant( |
| # INSTALL We do not install this target. |
| EXE qemu-upstream-${ANDROID_AARCH} |
| CPU ${ANDROID_AARCH} |
| SOURCES ${STUBS} vl.c |
| DEFINITIONS -DNEED_CPU_H |
| LIBRARIES android-emu |
| libqemu2-glue |
| libqemu2-glue-vm-operations |
| libqemu2-util |
| android-qemu-deps |
| android-qemu-deps-headful |
| emulator-libusb) |
| endif() |
| endfunction() |
| |
| # Copies a shared library |
| function(android_copy_shared_lib TGT SHARED_LIB NAME) |
| android_copy_file( |
| ${TGT} $<TARGET_FILE:${SHARED_LIB}> |
| $<TARGET_FILE_DIR:${TGT}>/lib64/${NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) |
| endfunction() |
| |
| function(android_log MSG) |
| if(ANDROID_LOG) |
| message(STATUS ${MSG}) |
| endif() |
| endfunction() |
| |
| function(android_validate_sha256 FILE EXPECTED) |
| get_filename_component( |
| DEST "${ANDROID_QEMU2_TOP_DIR}/../../device/generic/goldfish-opengl" |
| ABSOLUTE) |
| android_validate_sha( |
| FILE ${FILE} |
| EXPECTED ${EXPECTED} |
| ERROR |
| "You need to regenerate the cmake files by executing 'make' in ${DEST}") |
| endfunction() |
| |
| function(android_validate_sha) |
| include(CMakeParseArguments) |
| set(_options) |
| set(_singleargs FILE EXPECTED ERROR) |
| set(_multiargs) |
| |
| cmake_parse_arguments(sha "${_options}" "${_singleargs}" "${_multiargs}" |
| "${ARGN}") |
| |
| file(SHA256 ${sha_FILE} CHECKSUM) |
| if(NOT CHECKSUM STREQUAL "${sha_EXPECTED}") |
| message( |
| FATAL_ERROR |
| "Checksum mismatch for sha256(${sha_FILE})=${CHECKSUM}, was expecting: ${sha_EXPECTED}. ${sha_ERROR}" |
| ) |
| endif() |
| endfunction() |
| |
| # Installs the given target executable into the given destinations. Symbols will |
| # be extracted during build, and uploaded during install. |
| function(android_install_exe TGT DST) |
| install(TARGETS ${TGT} RUNTIME DESTINATION ${DST}) |
| |
| # Make it available on the build server if needed.. |
| android_upload_symbols( |
| TARGET ${TGT} DIRECTORY ${ANDROID_SYMBOL_DIR} API_KEY "${BREAKPAD_API_KEY}" |
| URI "${BREAKPAD_API_URL}") |
| android_install_license(${TGT} ${DST}/${TGT}${CMAKE_EXECUTABLE_SUFFIX}) |
| android_sign( |
| INSTALL ${CMAKE_INSTALL_PREFIX}/${DST}/${TGT}${CMAKE_EXECUTABLE_SUFFIX}) |
| if(LINUX_AARCH64) |
| install( |
| CODE "message(STATUS \"Strip: ${TGT}\") |
| execute_process(COMMAND ${CMAKE_STRIP_CMD} ${CMAKE_INSTALL_PREFIX}/${DST}/${TGT}${CMAKE_EXECUTABLE_SUFFIX})" |
| ) |
| endif() |
| endfunction() |
| |
| # Deprecated, use android_install_shared_library instead as it can handle windows corner cases. |
| function(android_install_shared TGT) |
| android_install_shared_library(TARGET ${TGT}) |
| endfunction() |
| |
| # Installs the given shared library. The shared library will end up in ../lib64 |
| # Symbols will be extracted during build, and uploaded during install. |
| function(android_install_shared_library) |
| set(options DUPLICATE_FOR_WINDOWS) |
| set(oneValueArgs TARGET) |
| cmake_parse_arguments(inst "${options}" "${oneValueArgs}" "${multiValueArgs}" |
| ${ARGN}) |
| |
| # We don't want windows to binplace dlls in the exe dir |
| install(TARGETS ${inst_TARGET} RUNTIME DESTINATION lib64 |
| LIBRARY DESTINATION lib64) |
| if(${inst_DUPLICATE_FOR_WINDOWS} AND WINDOWS_MSVC_X86_64) |
| message(STATUS "Windows requires installing ${inst_TARGET} in runtime as well") |
| install(TARGETS ${inst_TARGET} RUNTIME DESTINATION . LIBRARY DESTINATION .) |
| endif() |
| android_upload_symbols( |
| TARGET ${inst_TARGET} DIRECTORY ${ANDROID_SYMBOL_DIR} |
| API_KEY "${BREAKPAD_API_KEY}" URI "${BREAKPAD_API_URL}") |
| android_install_license(${inst_TARGET} |
| ${inst_TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX}) |
| # Account for lib prefix when signing |
| android_sign( |
| INSTALL |
| ${CMAKE_INSTALL_PREFIX}/lib64/lib${TGT}${CMAKE_SHARED_LIBRARY_SUFFIX}) |
| |
| if(LINUX_AARCH64) |
| install( |
| CODE "message(STATUS \"Strip: ${TGT}\") |
| execute_process(COMMAND ${CMAKE_STRIP_CMD} |
| ${CMAKE_INSTALL_PREFIX}/lib64/lib${TGT}${CMAKE_SHARED_LIBRARY_SUFFIX})" |
| ) |
| endif() |
| |
| # Binplace for unit tests |
| if(WINDOWS_MSVC_X86_64) |
| add_custom_command( |
| TARGET ${inst_TARGET} POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:${inst_TARGET}>" |
| "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") |
| endif() |
| endfunction() |
| |
| # Strips the given prebuilt executable during install.. |
| function(android_strip_prebuilt FNAME) |
| # MSVC stores debug info in seperate file, so no need to strip |
| if(NOT WINDOWS_MSVC_X86_64) |
| install( |
| CODE "if(CMAKE_INSTALL_DO_STRIP) |
| execute_process(COMMAND ${CMAKE_STRIP} \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${FNAME}\") |
| endif()") |
| endif() |
| endfunction() |
| |
| # Make the compatibility layer available for every target |
| if(WINDOWS_MSVC_X86_64 AND NOT INCLUDE_MSVC_POSIX) |
| set(INCLUDE_MSVC_POSIX 1) |
| add_subdirectory(${ANDROID_QEMU2_TOP_DIR}/android/msvc-posix-compat/ |
| msvc-posix-compat) |
| endif() |
| |
| function(android_symlink TARGET SYMLINK WORKDIR) |
| file(MAKE_DIRECTORY ${WORKDIR}) |
| if(WIN32 AND NOT CROSSCOMPILE) |
| # message("Creating symlink, mklink ${WIN_PATH} ${WIN_TGT}") |
| file(TO_NATIVE_PATH "${TARGET}" WIN_TGT) |
| file(TO_NATIVE_PATH "${WORKDIR}/${SYMLINK}" WIN_PATH) |
| execute_process(COMMAND cmd.exe /c mklink ${WIN_PATH} ${WIN_TGT} |
| WORKING_DIRECTORY ${WORKDIR}) |
| else() |
| # message("Creating symlink, create_symlink: ${WORKDIR}/${SYMLINK} -> |
| # ${TARGET}") |
| execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${TARGET}" |
| "${SYMLINK}" WORKING_DIRECTORY ${WORKDIR}) |
| endif() |
| endfunction() |