diff --git a/.gitignore b/.gitignore index adab384..d47e7a8 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ *.lib # Executables -*.exe *.out *.app @@ -47,11 +46,12 @@ *.vsix .cache/ -build/ -build-windows/ -build-linux/ -build-ios/ -build-mac/ -build-android/ +.build/ +.build-windows/ +.build-linux/ +.build-ios/ +.build-mac/ +.build-android-x64/ +.build-android-armv8/ imgui.ini diff --git a/.gitmodules b/.gitmodules index c3c4fff..f96ed8d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "Vendor/SDL"] path = Vendor/SDL url = https://github.com/I-A-S/SDL +[submodule "Vendor/lunasvg"] + path = Vendor/lunasvg + url = https://github.com/sammycage/lunasvg diff --git a/Android/android-ndk-r27d/build/__init__.py b/Android/android-ndk-r27d/build/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Android/android-ndk-r27d/build/cmake/abis.cmake b/Android/android-ndk-r27d/build/cmake/abis.cmake new file mode 100644 index 0000000..27df0e8 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/abis.cmake @@ -0,0 +1,40 @@ +set(NDK_DEFAULT_ABIS "arm64-v8a;armeabi-v7a;x86;x86_64") +set(NDK_DEPRECATED_ABIS "") +set(NDK_KNOWN_DEVICE_ABI32S "armeabi-v7a;x86") +set(NDK_KNOWN_DEVICE_ABI64S "arm64-v8a;riscv64;x86_64") +set(NDK_KNOWN_DEVICE_ABIS "arm64-v8a;armeabi-v7a;riscv64;x86;x86_64") +set(NDK_ABI_armeabi-v7a_PROC "armv7-a") +set(NDK_ABI_armeabi-v7a_ARCH "arm") +set(NDK_ABI_armeabi-v7a_TRIPLE "arm-linux-androideabi") +set(NDK_ABI_armeabi-v7a_LLVM_TRIPLE "armv7-none-linux-androideabi") +set(NDK_ABI_armeabi-v7a_MIN_OS_VERSION "21") +set(NDK_PROC_armv7-a_ABI "armeabi-v7a") +set(NDK_ARCH_arm_ABI "armeabi-v7a") +set(NDK_ABI_arm64-v8a_PROC "aarch64") +set(NDK_ABI_arm64-v8a_ARCH "arm64") +set(NDK_ABI_arm64-v8a_TRIPLE "aarch64-linux-android") +set(NDK_ABI_arm64-v8a_LLVM_TRIPLE "aarch64-none-linux-android") +set(NDK_ABI_arm64-v8a_MIN_OS_VERSION "21") +set(NDK_PROC_aarch64_ABI "arm64-v8a") +set(NDK_ARCH_arm64_ABI "arm64-v8a") +set(NDK_ABI_riscv64_PROC "riscv64") +set(NDK_ABI_riscv64_ARCH "riscv64") +set(NDK_ABI_riscv64_TRIPLE "riscv64-linux-android") +set(NDK_ABI_riscv64_LLVM_TRIPLE "riscv64-none-linux-android") +set(NDK_ABI_riscv64_MIN_OS_VERSION "35") +set(NDK_PROC_riscv64_ABI "riscv64") +set(NDK_ARCH_riscv64_ABI "riscv64") +set(NDK_ABI_x86_PROC "i686") +set(NDK_ABI_x86_ARCH "x86") +set(NDK_ABI_x86_TRIPLE "i686-linux-android") +set(NDK_ABI_x86_LLVM_TRIPLE "i686-none-linux-android") +set(NDK_ABI_x86_MIN_OS_VERSION "21") +set(NDK_PROC_i686_ABI "x86") +set(NDK_ARCH_x86_ABI "x86") +set(NDK_ABI_x86_64_PROC "x86_64") +set(NDK_ABI_x86_64_ARCH "x86_64") +set(NDK_ABI_x86_64_TRIPLE "x86_64-linux-android") +set(NDK_ABI_x86_64_LLVM_TRIPLE "x86_64-none-linux-android") +set(NDK_ABI_x86_64_MIN_OS_VERSION "21") +set(NDK_PROC_x86_64_ABI "x86_64") +set(NDK_ARCH_x86_64_ABI "x86_64") \ No newline at end of file diff --git a/Android/android-ndk-r27d/build/cmake/adjust_api_level.cmake b/Android/android-ndk-r27d/build/cmake/adjust_api_level.cmake new file mode 100644 index 0000000..51e31ab --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/adjust_api_level.cmake @@ -0,0 +1,64 @@ +include(${CMAKE_ANDROID_NDK}/build/cmake/abis.cmake) +include(${CMAKE_ANDROID_NDK}/build/cmake/platforms.cmake) + +function(adjust_api_level api_level result_name) + # If no platform version was chosen by the user, default to the minimum + # version supported by this NDK. + if(NOT api_level) + message(STATUS + "ANDROID_PLATFORM not set. Defaulting to minimum supported version " + "${NDK_MIN_PLATFORM_LEVEL}.") + + set(api_level "android-${NDK_MIN_PLATFORM_LEVEL}") + endif() + + if(api_level STREQUAL "latest") + message(STATUS + "Using latest available ANDROID_PLATFORM: ${NDK_MAX_PLATFORM_LEVEL}.") + set(api_level "android-${NDK_MAX_PLATFORM_LEVEL}") + endif() + + string(REPLACE "android-" "" result ${api_level}) + + # Aliases defined by meta/platforms.json include codename aliases for platform + # API levels as well as cover any gaps in platforms that may not have had NDK + # APIs. + if(NOT "${NDK_PLATFORM_ALIAS_${result}}" STREQUAL "") + message(STATUS + "${api_level} is an alias for ${NDK_PLATFORM_ALIAS_${result}}. Adjusting " + "ANDROID_PLATFORM to match.") + set(api_level "${NDK_PLATFORM_ALIAS_${result}}") + string(REPLACE "android-" "" result ${api_level}) + endif() + + # Pull up to the minimum supported version if an old API level was requested. + if(result LESS NDK_MIN_PLATFORM_LEVEL) + message(STATUS + "${api_level} is unsupported. Using minimum supported version " + "${NDK_MIN_PLATFORM_LEVEL}.") + set(api_level "android-${NDK_MIN_PLATFORM_LEVEL}") + string(REPLACE "android-" "" result ${api_level}) + endif() + + # Pull up any ABI-specific minimum API levels. + set(min_for_abi ${NDK_ABI_${ANDROID_ABI}_MIN_OS_VERSION}) + + if(result LESS min_for_abi) + message(STATUS + "android-${result} is not supported for ${ANDROID_ABI}. Using minimum " + "supported ${ANDROID_ABI} version ${min_for_abi}.") + set(api_level android-${min_for_abi}) + set(result ${min_for_abi}) + endif() + + # ANDROID_PLATFORM beyond the maximum is an error. The correct way to specify + # the latest version is ANDROID_PLATFORM=latest. + if(result GREATER NDK_MAX_PLATFORM_LEVEL) + message(SEND_ERROR + "${api_level} is above the maximum supported version " + "${NDK_MAX_PLATFORM_LEVEL}. Choose a supported API level or set " + "ANDROID_PLATFORM to \"latest\".") + endif() + + set(${result_name} ${result} PARENT_SCOPE) +endfunction() diff --git a/Android/android-ndk-r27d/build/cmake/android-legacy.toolchain.cmake b/Android/android-ndk-r27d/build/cmake/android-legacy.toolchain.cmake new file mode 100644 index 0000000..94d4f5d --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/android-legacy.toolchain.cmake @@ -0,0 +1,752 @@ +# Copyright (C) 2016 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. + +# Configurable variables. +# Modeled after the ndk-build system. +# For any variables defined in: +# https://developer.android.com/ndk/guides/android_mk.html +# https://developer.android.com/ndk/guides/application_mk.html +# if it makes sense for CMake, then replace LOCAL, APP, or NDK with ANDROID, and +# we have that variable below. +# +# ANDROID_TOOLCHAIN +# ANDROID_ABI +# ANDROID_PLATFORM +# ANDROID_STL +# ANDROID_PIE +# ANDROID_CPP_FEATURES +# ANDROID_ALLOW_UNDEFINED_SYMBOLS +# ANDROID_ARM_MODE +# ANDROID_DISABLE_FORMAT_STRING_CHECKS +# ANDROID_CCACHE +# ANDROID_SANITIZE + +cmake_minimum_required(VERSION 3.12.0) + +# Inhibit all of CMake's own NDK handling code. +set(CMAKE_SYSTEM_VERSION 1) + +# Android NDK +get_filename_component(ANDROID_NDK_EXPECTED_PATH + "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +if(NOT ANDROID_NDK) + set(ANDROID_NDK "${ANDROID_NDK_EXPECTED_PATH}") +else() + # Allow the user to specify their own NDK path, but emit a warning. This is an + # uncommon use case, but helpful if users want to use a bleeding edge + # toolchain file with a stable NDK. + # https://github.com/android-ndk/ndk/issues/473 + get_filename_component(ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE) + if(NOT "${ANDROID_NDK}" STREQUAL "${ANDROID_NDK_EXPECTED_PATH}") + message(WARNING "Using custom NDK path (ANDROID_NDK is set): ${ANDROID_NDK}") + endif() +endif() +unset(ANDROID_NDK_EXPECTED_PATH) +file(TO_CMAKE_PATH "${ANDROID_NDK}" ANDROID_NDK) + +# Android NDK revision +# Possible formats: +# * r16, build 1234: 16.0.1234 +# * r16b, build 1234: 16.1.1234 +# * r16 beta 1, build 1234: 16.0.1234-beta1 +# +# Canary builds are not specially marked. +file(READ "${ANDROID_NDK}/source.properties" ANDROID_NDK_SOURCE_PROPERTIES) + +set(ANDROID_NDK_REVISION_REGEX + "^Pkg\\.Desc = Android NDK\nPkg\\.Revision = ([0-9]+)\\.([0-9]+)\\.([0-9]+)(-beta([0-9]+))?") +if(NOT ANDROID_NDK_SOURCE_PROPERTIES MATCHES "${ANDROID_NDK_REVISION_REGEX}") + message(SEND_ERROR "Failed to parse Android NDK revision: ${ANDROID_NDK}/source.properties.\n${ANDROID_NDK_SOURCE_PROPERTIES}") +endif() + +set(ANDROID_NDK_MAJOR "${CMAKE_MATCH_1}") +set(ANDROID_NDK_MINOR "${CMAKE_MATCH_2}") +set(ANDROID_NDK_BUILD "${CMAKE_MATCH_3}") +set(ANDROID_NDK_BETA "${CMAKE_MATCH_5}") +if(ANDROID_NDK_BETA STREQUAL "") + set(ANDROID_NDK_BETA "0") +endif() +set(ANDROID_NDK_REVISION + "${ANDROID_NDK_MAJOR}.${ANDROID_NDK_MINOR}.${ANDROID_NDK_BUILD}${CMAKE_MATCH_4}") + +# Touch toolchain variable to suppress "unused variable" warning. +# This happens if CMake is invoked with the same command line the second time. +if(CMAKE_TOOLCHAIN_FILE) +endif() + +# Compatibility for configurable variables. +# Compatible with configurable variables from the other toolchain file: +# https://github.com/taka-no-me/android-cmake +# TODO: We should consider dropping compatibility to simplify things once most +# of our users have migrated to our standard set of configurable variables. +if(ANDROID_TOOLCHAIN_NAME AND NOT ANDROID_TOOLCHAIN) + if(ANDROID_TOOLCHAIN_NAME MATCHES "-clang([0-9].[0-9])?$") + set(ANDROID_TOOLCHAIN clang) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "-[0-9].[0-9]$") + set(ANDROID_TOOLCHAIN gcc) + endif() +endif() +if(ANDROID_ABI STREQUAL "armeabi-v7a with NEON") + set(ANDROID_ABI armeabi-v7a) +elseif(ANDROID_TOOLCHAIN_NAME AND NOT ANDROID_ABI) + if(ANDROID_TOOLCHAIN_NAME MATCHES "^arm-linux-androideabi-") + set(ANDROID_ABI armeabi-v7a) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^aarch64-linux-android-") + set(ANDROID_ABI arm64-v8a) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86-") + set(ANDROID_ABI x86) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86_64-") + set(ANDROID_ABI x86_64) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^mipsel-linux-android-") + set(ANDROID_ABI mips) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^mips64el-linux-android-") + set(ANDROID_ABI mips64) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^riscv64-") + set(ANDROID_ABI riscv64) + endif() +endif() +if(ANDROID_NATIVE_API_LEVEL AND NOT ANDROID_PLATFORM) + if(ANDROID_NATIVE_API_LEVEL MATCHES "^android-[0-9]+$") + set(ANDROID_PLATFORM ${ANDROID_NATIVE_API_LEVEL}) + elseif(ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$") + set(ANDROID_PLATFORM android-${ANDROID_NATIVE_API_LEVEL}) + endif() +endif() +if(DEFINED ANDROID_APP_PIE AND NOT DEFINED ANDROID_PIE) + set(ANDROID_PIE "${ANDROID_APP_PIE}") +endif() +if(ANDROID_STL_FORCE_FEATURES AND NOT DEFINED ANDROID_CPP_FEATURES) + set(ANDROID_CPP_FEATURES "rtti exceptions") +endif() +if(DEFINED ANDROID_NO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS) + if(ANDROID_NO_UNDEFINED) + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS FALSE) + else() + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS TRUE) + endif() +endif() +if(DEFINED ANDROID_SO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS) + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS "${ANDROID_SO_UNDEFINED}") +endif() +if(DEFINED ANDROID_FORCE_ARM_BUILD AND NOT ANDROID_ARM_MODE) + if(ANDROID_FORCE_ARM_BUILD) + set(ANDROID_ARM_MODE arm) + else() + set(ANDROID_ARM_MODE thumb) + endif() +endif() +if(NDK_CCACHE AND NOT ANDROID_CCACHE) + set(ANDROID_CCACHE "${NDK_CCACHE}") +endif() + +# Default values for configurable variables. +if(NOT ANDROID_TOOLCHAIN) + set(ANDROID_TOOLCHAIN clang) +elseif(ANDROID_TOOLCHAIN STREQUAL gcc) + message(FATAL_ERROR "GCC is no longer supported. See " + "https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.") +endif() +if(NOT ANDROID_ABI) + set(ANDROID_ABI armeabi-v7a) +endif() + +if(ANDROID_ABI STREQUAL armeabi) + message(FATAL_ERROR "armeabi is no longer supported. Use armeabi-v7a.") +elseif(ANDROID_ABI MATCHES "^(mips|mips64)$") + message(FATAL_ERROR "MIPS and MIPS64 are no longer supported.") +endif() + +if(DEFINED ANDROID_ARM_NEON AND NOT ANDROID_ARM_NEON) + message(FATAL_ERROR "Disabling Neon is no longer supported") +endif() + +if(ANDROID_ABI STREQUAL armeabi-v7a) + set(ANDROID_ARM_NEON TRUE) +endif() + +include(${ANDROID_NDK}/build/cmake/abis.cmake) +include(${ANDROID_NDK}/build/cmake/platforms.cmake) + +# If no platform version was chosen by the user, default to the minimum version +# supported by this NDK. +if(NOT ANDROID_PLATFORM) + message(STATUS "\ +ANDROID_PLATFORM not set. Defaulting to minimum supported version +${NDK_MIN_PLATFORM_LEVEL}.") + + set(ANDROID_PLATFORM "android-${NDK_MIN_PLATFORM_LEVEL}") +endif() + +if(ANDROID_PLATFORM STREQUAL "latest") + message(STATUS + "Using latest available ANDROID_PLATFORM: ${NDK_MAX_PLATFORM_LEVEL}.") + set(ANDROID_PLATFORM "android-${NDK_MAX_PLATFORM_LEVEL}") + string(REPLACE "android-" "" ANDROID_PLATFORM_LEVEL ${ANDROID_PLATFORM}) +endif() + +string(REPLACE "android-" "" ANDROID_PLATFORM_LEVEL ${ANDROID_PLATFORM}) + +# Aliases defined by meta/platforms.json include codename aliases for platform +# API levels as well as cover any gaps in platforms that may not have had NDK +# APIs. +if(NOT "${NDK_PLATFORM_ALIAS_${ANDROID_PLATFORM_LEVEL}}" STREQUAL "") + message(STATUS "\ +${ANDROID_PLATFORM} is an alias for \ +${NDK_PLATFORM_ALIAS_${ANDROID_PLATFORM_LEVEL}}. Adjusting ANDROID_PLATFORM to \ +match.") + set(ANDROID_PLATFORM "${NDK_PLATFORM_ALIAS_${ANDROID_PLATFORM_LEVEL}}") + string(REPLACE "android-" "" ANDROID_PLATFORM_LEVEL ${ANDROID_PLATFORM}) +endif() + +# Pull up to the minimum supported version if an old API level was requested. +if(ANDROID_PLATFORM_LEVEL LESS NDK_MIN_PLATFORM_LEVEL) + message(STATUS "\ +${ANDROID_PLATFORM} is unsupported. Using minimum supported version \ +${NDK_MIN_PLATFORM_LEVEL}.") + set(ANDROID_PLATFORM "android-${NDK_MIN_PLATFORM_LEVEL}") + string(REPLACE "android-" "" ANDROID_PLATFORM_LEVEL ${ANDROID_PLATFORM}) +endif() + +# Pull up any ABI-specific minimum API levels. +set(min_for_abi ${NDK_ABI_${ANDROID_ABI}_MIN_OS_VERSION}) + +if(ANDROID_PLATFORM_LEVEL LESS min_for_abi) + message(STATUS + "${ANDROID_PLATFORM} is not supported for ${ANDROID_ABI}. Using minimum " + "supported ${ANDROID_ABI} version ${min_for_abi}.") + set(ANDROID_PLATFORM android-${min_for_abi}) + set(ANDROID_PLATFORM_LEVEL ${min_for_abi}) +endif() + +# ANDROID_PLATFORM beyond the maximum is an error. The correct way to specify +# the latest version is ANDROID_PLATFORM=latest. +if(ANDROID_PLATFORM_LEVEL GREATER NDK_MAX_PLATFORM_LEVEL) + message(SEND_ERROR "\ +${ANDROID_PLATFORM} is above the maximum supported version \ +${NDK_MAX_PLATFORM_LEVEL}. Choose a supported API level or set \ +ANDROID_PLATFORM to \"latest\".") +endif() + +if(NOT ANDROID_STL) + set(ANDROID_STL c++_static) +endif() + +if("${ANDROID_STL}" STREQUAL "gnustl_shared" OR + "${ANDROID_STL}" STREQUAL "gnustl_static" OR + "${ANDROID_STL}" STREQUAL "stlport_shared" OR + "${ANDROID_STL}" STREQUAL "stlport_static") + message(FATAL_ERROR "\ +${ANDROID_STL} is no longer supported. Please switch to either c++_shared or \ +c++_static. See https://developer.android.com/ndk/guides/cpp-support.html \ +for more information.") +endif() + +if("hwaddress" IN_LIST ANDROID_SANITIZE AND "${CMAKE_ANDROID_STL_TYPE}" STREQUAL "c++_static") + message(FATAL_ERROR "\ + hwaddress does not support c++_static. Use system or c++_shared.") +endif() + +set(ANDROID_PIE TRUE) +if(NOT ANDROID_ARM_MODE) + set(ANDROID_ARM_MODE thumb) +endif() + +# Export configurable variables for the try_compile() command. +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + ANDROID_ABI + ANDROID_ALLOW_UNDEFINED_SYMBOLS + ANDROID_ARM_MODE + ANDROID_ARM_NEON + ANDROID_CCACHE + ANDROID_CPP_FEATURES + ANDROID_DISABLE_FORMAT_STRING_CHECKS + ANDROID_PIE + ANDROID_PLATFORM + ANDROID_STL + ANDROID_TOOLCHAIN + ANDROID_USE_LEGACY_TOOLCHAIN_FILE +) + +# Standard cross-compiling stuff. +set(ANDROID TRUE) +set(CMAKE_SYSTEM_NAME Android) + +# https://github.com/android-ndk/ndk/issues/890 +# +# ONLY doesn't do anything when CMAKE_FIND_ROOT_PATH is empty. Without this, +# CMake will wrongly search host sysroots for headers/libraries. The actual path +# used here is fairly meaningless since CMake doesn't handle the NDK sysroot +# layout (per-arch and per-verion subdirectories for libraries), so find_library +# is handled separately by CMAKE_SYSTEM_LIBRARY_PATH. +list(APPEND CMAKE_FIND_ROOT_PATH "${ANDROID_NDK}") + +# Allow users to override these values in case they want more strict behaviors. +# For example, they may want to prevent the NDK's libz from being picked up so +# they can use their own. +# https://github.com/android-ndk/ndk/issues/517 +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +endif() + +# ABI. +set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI}) +if(ANDROID_ABI STREQUAL armeabi-v7a) + set(ANDROID_SYSROOT_ABI arm) + set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi) + set(CMAKE_SYSTEM_PROCESSOR armv7-a) + set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi) +elseif(ANDROID_ABI STREQUAL arm64-v8a) + set(ANDROID_SYSROOT_ABI arm64) + set(CMAKE_SYSTEM_PROCESSOR aarch64) + set(ANDROID_TOOLCHAIN_NAME aarch64-linux-android) + set(ANDROID_LLVM_TRIPLE aarch64-none-linux-android) +elseif(ANDROID_ABI STREQUAL x86) + set(ANDROID_SYSROOT_ABI x86) + set(CMAKE_SYSTEM_PROCESSOR i686) + set(ANDROID_TOOLCHAIN_NAME i686-linux-android) + set(ANDROID_LLVM_TRIPLE i686-none-linux-android) +elseif(ANDROID_ABI STREQUAL x86_64) + set(ANDROID_SYSROOT_ABI x86_64) + set(CMAKE_SYSTEM_PROCESSOR x86_64) + set(ANDROID_TOOLCHAIN_NAME x86_64-linux-android) + set(ANDROID_LLVM_TRIPLE x86_64-none-linux-android) +elseif(ANDROID_ABI STREQUAL riscv64) + set(ANDROID_SYSROOT_ABI riscv64) + set(CMAKE_SYSTEM_PROCESSOR riscv64) + set(ANDROID_TOOLCHAIN_NAME riscv64-linux-android) + set(ANDROID_LLVM_TRIPLE riscv64-none-linux-android) +else() + message(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.") +endif() + +set(ANDROID_LLVM_TRIPLE "${ANDROID_LLVM_TRIPLE}${ANDROID_PLATFORM_LEVEL}") + +set(ANDROID_COMPILER_FLAGS) +set(ANDROID_COMPILER_FLAGS_CXX) +set(ANDROID_COMPILER_FLAGS_DEBUG) +set(ANDROID_COMPILER_FLAGS_RELEASE) +set(ANDROID_LINKER_FLAGS) +set(ANDROID_LINKER_FLAGS_EXE) +set(ANDROID_LINKER_FLAGS_RELEASE) +set(ANDROID_LINKER_FLAGS_RELWITHDEBINFO) +set(ANDROID_LINKER_FLAGS_MINSIZEREL) + +# STL. +set(ANDROID_CXX_STANDARD_LIBRARIES) +if(ANDROID_STL STREQUAL system) + list(APPEND ANDROID_COMPILER_FLAGS_CXX "-stdlib=libstdc++") + if(NOT "x${ANDROID_CPP_FEATURES}" STREQUAL "x") + list(APPEND ANDROID_CXX_STANDARD_LIBRARIES "-lc++abi") + endif() +elseif(ANDROID_STL STREQUAL c++_static) + list(APPEND ANDROID_LINKER_FLAGS "-static-libstdc++") +elseif(ANDROID_STL STREQUAL c++_shared) +elseif(ANDROID_STL STREQUAL none) + list(APPEND ANDROID_COMPILER_FLAGS_CXX "-nostdinc++") + list(APPEND ANDROID_LINKER_FLAGS "-nostdlib++") +else() + message(FATAL_ERROR "Invalid STL: ${ANDROID_STL}.") +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux) + set(ANDROID_HOST_TAG linux-x86_64) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) + set(ANDROID_HOST_TAG darwin-x86_64) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(ANDROID_HOST_TAG windows-x86_64) +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(ANDROID_TOOLCHAIN_SUFFIX .exe) +endif() + +# Toolchain. +set(ANDROID_TOOLCHAIN_ROOT + "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}") + +list(APPEND CMAKE_PREFIX_PATH "${ANDROID_TOOLCHAIN_ROOT}") + +# NB: This variable causes CMake to automatically pass --sysroot to the +# toolchain. Studio currently relies on this to recognize Android builds. If +# this variable is removed, ensure that flag is still passed. +# TODO: Teach Studio to recognize Android builds based on --target. +set(CMAKE_SYSROOT "${ANDROID_TOOLCHAIN_ROOT}/sysroot") + +# Allows CMake to find headers in the architecture-specific include directories. +set(CMAKE_LIBRARY_ARCHITECTURE "${ANDROID_TOOLCHAIN_NAME}") + +# In addition to //lib/, cmake also searches /. +# Adding the API specific path to the beginning of CMAKE_SYSTEM_PREFIX_PATH, to +# make sure it is searched first. +set(CMAKE_SYSTEM_PREFIX_PATH + "/usr/lib/${ANDROID_TOOLCHAIN_NAME}/${ANDROID_PLATFORM_LEVEL}" + "${CMAKE_SYSTEM_PREFIX_PATH}" + ) + +set(ANDROID_HOST_PREBUILTS "${ANDROID_NDK}/prebuilt/${ANDROID_HOST_TAG}") + +set(ANDROID_C_COMPILER + "${ANDROID_TOOLCHAIN_ROOT}/bin/clang${ANDROID_TOOLCHAIN_SUFFIX}") +set(ANDROID_CXX_COMPILER + "${ANDROID_TOOLCHAIN_ROOT}/bin/clang++${ANDROID_TOOLCHAIN_SUFFIX}") +set(ANDROID_ASM_COMPILER + "${ANDROID_TOOLCHAIN_ROOT}/bin/clang${ANDROID_TOOLCHAIN_SUFFIX}") +set(CMAKE_C_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE}) +set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE}) +set(CMAKE_ASM_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE}) +set(ANDROID_AR + "${ANDROID_TOOLCHAIN_ROOT}/bin/llvm-ar${ANDROID_TOOLCHAIN_SUFFIX}") +set(ANDROID_RANLIB + "${ANDROID_TOOLCHAIN_ROOT}/bin/llvm-ranlib${ANDROID_TOOLCHAIN_SUFFIX}") +set(ANDROID_STRIP + "${ANDROID_TOOLCHAIN_ROOT}/bin/llvm-strip${ANDROID_TOOLCHAIN_SUFFIX}") + +if(${CMAKE_VERSION} VERSION_LESS "3.19") + # Older CMake won't pass -target when running the compiler identification + # test, which causes the test to fail on flags like -mthumb. + # https://github.com/android/ndk/issues/1427 + message(WARNING "An old version of CMake is being used that cannot " + "automatically detect compiler attributes. Compiler identification is " + "being bypassed. Some values may be wrong or missing. Update to CMake " + "3.19 or newer to use CMake's built-in compiler identification.") + set(CMAKE_C_COMPILER_ID_RUN TRUE) + set(CMAKE_CXX_COMPILER_ID_RUN TRUE) + set(CMAKE_C_COMPILER_ID Clang) + set(CMAKE_CXX_COMPILER_ID Clang) + # No need to auto-detect the computed standard defaults because CMake 3.6 + # doesn't know about anything past C11 or C++14 (neither does 3.10, so no + # need to worry about 3.7-3.9), and any higher standards that Clang might + # use are clamped to those values. + set(CMAKE_C_STANDARD_COMPUTED_DEFAULT 11) + set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 14) + set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU") + set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU") + include(${ANDROID_NDK}/build/cmake/compiler_id.cmake) +endif() + +# Generic flags. +list(APPEND ANDROID_COMPILER_FLAGS + -g + -DANDROID + -fdata-sections + -ffunction-sections + -funwind-tables + -fstack-protector-strong + -no-canonical-prefixes) + +if(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES) + list(APPEND ANDROID_COMPILER_FLAGS -D__BIONIC_NO_PAGE_SIZE_MACRO) + if(ANDROID_ABI STREQUAL arm64-v8a OR ANDROID_ABI STREQUAL x86_64) + list(APPEND ANDROID_LINKER_FLAGS -Wl,-z,max-page-size=16384) + endif() +endif() + +if(ANDROID_WEAK_API_DEFS) + list(APPEND ANDROID_COMPILER_FLAGS + -D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__ + -Werror=unguarded-availability) +endif() + +if("hwaddress" IN_LIST ANDROID_SANITIZE) + list(APPEND ANDROID_COMPILER_FLAGS -fsanitize=hwaddress -fno-omit-frame-pointer) + list(APPEND ANDROID_LINKER_FLAGS -fsanitize=hwaddress) +endif() + +if("memtag" IN_LIST ANDROID_SANITIZE) + list(APPEND ANDROID_COMPILER_FLAGS -fsanitize=memtag-stack -fno-omit-frame-pointer) + list(APPEND ANDROID_LINKER_FLAGS -fsanitize=memtag-stack,memtag-heap -fsanitize-memtag-mode=sync) + if(ANDROID_ABI STREQUAL arm64-v8a) + list(APPEND ANDROID_COMPILER_FLAGS -march=armv8-a+memtag) + list(APPEND ANDROID_LINKER_FLAGS -march=armv8-a+memtag) + endif() +endif() + +# https://github.com/android/ndk/issues/885 +# If we're using LLD we need to use a slower build-id algorithm to work around +# the old version of LLDB in Android Studio, which doesn't understand LLD's +# default hash ("fast"). +list(APPEND ANDROID_LINKER_FLAGS -Wl,--build-id=sha1) +if(ANDROID_PLATFORM_LEVEL LESS 30) + # https://github.com/android/ndk/issues/1196 + # https://github.com/android/ndk/issues/1589 + list(APPEND ANDROID_LINKER_FLAGS -Wl,--no-rosegment) +endif() + +if (NOT ANDROID_ALLOW_UNDEFINED_VERSION_SCRIPT_SYMBOLS) + list(APPEND ANDROID_LINKER_FLAGS -Wl,--no-undefined-version) +endif() + +list(APPEND ANDROID_LINKER_FLAGS -Wl,--fatal-warnings) + +# --gc-sections should not be present for debug builds because that can strip +# functions that the user may want to evaluate while debugging. +list(APPEND ANDROID_LINKER_FLAGS_RELEASE -Wl,--gc-sections) +list(APPEND ANDROID_LINKER_FLAGS_RELWITHDEBINFO -Wl,--gc-sections) +list(APPEND ANDROID_LINKER_FLAGS_MINSIZEREL -Wl,--gc-sections) + +# Debug and release flags. +list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -O3) +list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -DNDEBUG) +if(ANDROID_TOOLCHAIN STREQUAL clang) + list(APPEND ANDROID_COMPILER_FLAGS_DEBUG -fno-limit-debug-info) +endif() + +# Toolchain and ABI specific flags. +if(ANDROID_ABI STREQUAL x86 AND ANDROID_PLATFORM_LEVEL LESS 24) + # http://b.android.com/222239 + # http://b.android.com/220159 (internal http://b/31809417) + # x86 devices have stack alignment issues. + list(APPEND ANDROID_COMPILER_FLAGS -mstackrealign) +endif() + +list(APPEND ANDROID_COMPILER_FLAGS -D_FORTIFY_SOURCE=2) + +set(CMAKE_C_STANDARD_LIBRARIES_INIT "-latomic -lm") +set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") +if(ANDROID_CXX_STANDARD_LIBRARIES) + string(REPLACE ";" "\" \"" ANDROID_CXX_STANDARD_LIBRARIES "\"${ANDROID_CXX_STANDARD_LIBRARIES}\"") + set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_CXX_STANDARD_LIBRARIES_INIT} ${ANDROID_CXX_STANDARD_LIBRARIES}") +endif() + +# Configuration specific flags. + +# PIE is supported on all currently supported Android releases, but it is not +# supported with static executables, so we still provide ANDROID_PIE as an +# escape hatch for those. +if(ANDROID_PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +endif() + +if(ANDROID_CPP_FEATURES) + separate_arguments(ANDROID_CPP_FEATURES) + foreach(feature ${ANDROID_CPP_FEATURES}) + if(NOT ${feature} MATCHES "^(rtti|exceptions|no-rtti|no-exceptions)$") + message(FATAL_ERROR "Invalid Android C++ feature: ${feature}.") + endif() + list(APPEND ANDROID_COMPILER_FLAGS_CXX + -f${feature}) + endforeach() + string(REPLACE ";" " " ANDROID_CPP_FEATURES "${ANDROID_CPP_FEATURES}") +endif() +if(NOT ANDROID_ALLOW_UNDEFINED_SYMBOLS) + list(APPEND ANDROID_LINKER_FLAGS + -Wl,--no-undefined) +endif() +if(ANDROID_ABI MATCHES "armeabi") + # Clang does not set this up properly when using -fno-integrated-as. + # https://github.com/android-ndk/ndk/issues/906 + list(APPEND ANDROID_COMPILER_FLAGS "-march=armv7-a") + if(ANDROID_ARM_MODE STREQUAL thumb) + list(APPEND ANDROID_COMPILER_FLAGS -mthumb) + elseif(ANDROID_ARM_MODE STREQUAL arm) + # Default behavior. + else() + message(FATAL_ERROR "Invalid Android ARM mode: ${ANDROID_ARM_MODE}.") + endif() +endif() + +# CMake automatically forwards all compiler flags to the linker, and clang +# doesn't like having -Wa flags being used for linking. To prevent CMake from +# doing this would require meddling with the CMAKE__COMPILE_OBJECT rules, +# which would get quite messy. +list(APPEND ANDROID_LINKER_FLAGS -Qunused-arguments) + +if(ANDROID_DISABLE_FORMAT_STRING_CHECKS) + list(APPEND ANDROID_COMPILER_FLAGS + -Wno-error=format-security) +else() + list(APPEND ANDROID_COMPILER_FLAGS + -Wformat -Werror=format-security) +endif() + +# Convert these lists into strings. +string(REPLACE ";" " " ANDROID_COMPILER_FLAGS "${ANDROID_COMPILER_FLAGS}") +string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_CXX "${ANDROID_COMPILER_FLAGS_CXX}") +string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_DEBUG "${ANDROID_COMPILER_FLAGS_DEBUG}") +string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_RELEASE "${ANDROID_COMPILER_FLAGS_RELEASE}") +string(REPLACE ";" " " ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}") +string(REPLACE ";" " " ANDROID_LINKER_FLAGS_EXE "${ANDROID_LINKER_FLAGS_EXE}") +string(REPLACE ";" " " ANDROID_LINKER_FLAGS_RELEASE "${ANDROID_LINKER_FLAGS_RELEASE}") +string(REPLACE ";" " " ANDROID_LINKER_FLAGS_RELWITHDEBINFO "${ANDROID_LINKER_FLAGS_RELWITHDEBINFO}") +string(REPLACE ";" " " ANDROID_LINKER_FLAGS_MINSIZEREL "${ANDROID_LINKER_FLAGS_MINSIZEREL}") + +if(ANDROID_CCACHE) + set(CMAKE_C_COMPILER_LAUNCHER "${ANDROID_CCACHE}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${ANDROID_CCACHE}") +endif() +set(CMAKE_C_COMPILER "${ANDROID_C_COMPILER}") +set(CMAKE_CXX_COMPILER "${ANDROID_CXX_COMPILER}") +set(CMAKE_AR "${ANDROID_AR}" CACHE FILEPATH "Archiver") +set(CMAKE_RANLIB "${ANDROID_RANLIB}" CACHE FILEPATH "Ranlib") +set(CMAKE_STRIP "${ANDROID_STRIP}" CACHE FILEPATH "Strip") + +if(ANDROID_ABI STREQUAL "x86" OR ANDROID_ABI STREQUAL "x86_64") + set(CMAKE_ASM_NASM_COMPILER + "${ANDROID_TOOLCHAIN_ROOT}/bin/yasm${ANDROID_TOOLCHAIN_SUFFIX}") + set(CMAKE_ASM_NASM_COMPILER_ARG1 "-DELF") +endif() + +# Set or retrieve the cached flags. +# This is necessary in case the user sets/changes flags in subsequent +# configures. If we included the Android flags in here, they would get +# overwritten. +set(CMAKE_C_FLAGS "" + CACHE STRING "Flags used by the compiler during all build types.") +set(CMAKE_CXX_FLAGS "" + CACHE STRING "Flags used by the compiler during all build types.") +set(CMAKE_ASM_FLAGS "" + CACHE STRING "Flags used by the compiler during all build types.") +set(CMAKE_C_FLAGS_DEBUG "" + CACHE STRING "Flags used by the compiler during debug builds.") +set(CMAKE_CXX_FLAGS_DEBUG "" + CACHE STRING "Flags used by the compiler during debug builds.") +set(CMAKE_ASM_FLAGS_DEBUG "" + CACHE STRING "Flags used by the compiler during debug builds.") +set(CMAKE_C_FLAGS_RELEASE "" + CACHE STRING "Flags used by the compiler during release builds.") +set(CMAKE_CXX_FLAGS_RELEASE "" + CACHE STRING "Flags used by the compiler during release builds.") +set(CMAKE_ASM_FLAGS_RELEASE "" + CACHE STRING "Flags used by the compiler during release builds.") +set(CMAKE_MODULE_LINKER_FLAGS "" + CACHE STRING "Flags used by the linker during the creation of modules.") +set(CMAKE_SHARED_LINKER_FLAGS "" + CACHE STRING "Flags used by the linker during the creation of dll's.") +set(CMAKE_EXE_LINKER_FLAGS "" + CACHE STRING "Flags used by the linker.") + +set(CMAKE_C_FLAGS "${ANDROID_COMPILER_FLAGS} ${CMAKE_C_FLAGS}") +set(CMAKE_CXX_FLAGS "${ANDROID_COMPILER_FLAGS} ${ANDROID_COMPILER_FLAGS_CXX} ${CMAKE_CXX_FLAGS}") +set(CMAKE_ASM_FLAGS "${ANDROID_COMPILER_FLAGS} ${CMAKE_ASM_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}") +set(CMAKE_CXX_FLAGS_DEBUG "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}") +set(CMAKE_ASM_FLAGS_DEBUG "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_ASM_FLAGS_DEBUG}") +set(CMAKE_C_FLAGS_RELEASE "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_RELEASE "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}") +set(CMAKE_ASM_FLAGS_RELEASE "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_ASM_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}") +set(CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${ANDROID_LINKER_FLAGS_EXE} ${CMAKE_EXE_LINKER_FLAGS}") +set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${ANDROID_LINKER_FLAGS_RELEASE} ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${ANDROID_LINKER_FLAGS_RELEASE} ${CMAKE_MODULE_LINKER_FLAGS_RELEASE}") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${ANDROID_LINKER_FLAGS_RELEASE} ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${ANDROID_LINKER_FLAGS_RELWITHDEBINFO} ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") +set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${ANDROID_LINKER_FLAGS_RELWITHDEBINFO} ${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO}") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${ANDROID_LINKER_FLAGS_RELWITHDEBINFO} ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") +set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${ANDROID_LINKER_FLAGS_MINSIZEREL} ${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL}") +set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${ANDROID_LINKER_FLAGS_MINSIZEREL} ${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL}") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${ANDROID_LINKER_FLAGS_MINSIZEREL} ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL}") + +# Compatibility for read-only variables. +# Read-only variables for compatibility with the other toolchain file. +# We'll keep these around for the existing projects that still use them. +# TODO: All of the variables here have equivalents in our standard set of +# configurable variables, so we can remove these once most of our users migrate +# to those variables. +set(ANDROID_NATIVE_API_LEVEL ${ANDROID_PLATFORM_LEVEL}) +if(ANDROID_ALLOW_UNDEFINED_SYMBOLS) + set(ANDROID_SO_UNDEFINED TRUE) +else() + set(ANDROID_NO_UNDEFINED TRUE) +endif() +set(ANDROID_FUNCTION_LEVEL_LINKING TRUE) +set(ANDROID_GOLD_LINKER TRUE) +set(ANDROID_NOEXECSTACK TRUE) +set(ANDROID_RELRO TRUE) +if(ANDROID_ARM_MODE STREQUAL arm) + set(ANDROID_FORCE_ARM_BUILD TRUE) +endif() +if(ANDROID_CPP_FEATURES MATCHES "rtti" + AND ANDROID_CPP_FEATURES MATCHES "exceptions") + set(ANDROID_STL_FORCE_FEATURES TRUE) +endif() +if(ANDROID_CCACHE) + set(NDK_CCACHE "${ANDROID_CCACHE}") +endif() +if(ANDROID_TOOLCHAIN STREQUAL clang) + set(ANDROID_TOOLCHAIN_NAME ${ANDROID_TOOLCHAIN_NAME}-clang) +else() + set(ANDROID_TOOLCHAIN_NAME ${ANDROID_TOOLCHAIN_NAME}-4.9) +endif() +set(ANDROID_NDK_HOST_X64 TRUE) +set(ANDROID_NDK_LAYOUT RELEASE) +if(ANDROID_ABI STREQUAL armeabi-v7a) + set(ARMEABI_V7A TRUE) + if(ANDROID_ARM_NEON) + set(NEON TRUE) + endif() +elseif(ANDROID_ABI STREQUAL arm64-v8a) + set(ARM64_V8A TRUE) +elseif(ANDROID_ABI STREQUAL x86) + set(X86 TRUE) +elseif(ANDROID_ABI STREQUAL x86_64) + set(X86_64 TRUE) +elseif(ANDROID_ABI STREQUAL riscv64) + set(RISCV64 TRUE) +endif() +set(ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_HOST_TAG}) +set(ANDROID_NDK_ABI_NAME ${ANDROID_ABI}) +set(ANDROID_NDK_RELEASE r${ANDROID_NDK_REVISION}) +set(ANDROID_ARCH_NAME ${ANDROID_SYSROOT_ABI}) +set(TOOL_OS_SUFFIX ${ANDROID_TOOLCHAIN_SUFFIX}) +if(ANDROID_TOOLCHAIN STREQUAL clang) + set(ANDROID_COMPILER_IS_CLANG TRUE) +endif() + +# CMake 3.7+ compatibility. +if (CMAKE_VERSION VERSION_GREATER 3.7.0) + set(CMAKE_ANDROID_NDK ${ANDROID_NDK}) + set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) + + set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL}) + + if(ANDROID_ABI MATCHES "^armeabi(-v7a)?$") + set(CMAKE_ANDROID_ARM_NEON ${ANDROID_ARM_NEON}) + set(CMAKE_ANDROID_ARM_MODE ${ANDROID_ARM_MODE}) + endif() + + # https://github.com/android/ndk/issues/861 + if(ANDROID_ABI STREQUAL armeabi-v7a) + set(CMAKE_ANDROID_ARCH arm) + elseif(ANDROID_ABI STREQUAL arm64-v8a) + set(CMAKE_ANDROID_ARCH arm64) + elseif(ANDROID_ABI STREQUAL x86) + set(CMAKE_ANDROID_ARCH x86) + elseif(ANDROID_ABI STREQUAL x86_64) + set(CMAKE_ANDROID_ARCH x86_64) + elseif(ANDROID_ABI STREQUAL riscv64) + set(CMAKE_ANDROID_ARCH riscv64) + endif() + + # https://github.com/android/ndk/issues/1012 + set(CMAKE_ASM_ANDROID_TOOLCHAIN_MACHINE "${ANDROID_TOOLCHAIN_NAME}") + set(CMAKE_C_ANDROID_TOOLCHAIN_MACHINE "${ANDROID_TOOLCHAIN_NAME}") + set(CMAKE_CXX_ANDROID_TOOLCHAIN_MACHINE "${ANDROID_TOOLCHAIN_NAME}") + + set(CMAKE_ASM_ANDROID_TOOLCHAIN_SUFFIX "${ANDROID_TOOLCHAIN_SUFFIX}") + set(CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX "${ANDROID_TOOLCHAIN_SUFFIX}") + set(CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX "${ANDROID_TOOLCHAIN_SUFFIX}") +endif() diff --git a/Android/android-ndk-r27d/build/cmake/android.toolchain.cmake b/Android/android-ndk-r27d/build/cmake/android.toolchain.cmake new file mode 100644 index 0000000..00e25e8 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/android.toolchain.cmake @@ -0,0 +1,291 @@ +# Copyright (C) 2016 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. + +# Configurable variables. +# Modeled after the ndk-build system. +# For any variables defined in: +# https://developer.android.com/ndk/guides/android_mk.html +# https://developer.android.com/ndk/guides/application_mk.html +# if it makes sense for CMake, then replace LOCAL, APP, or NDK with ANDROID, and +# we have that variable below. +# +# ANDROID_TOOLCHAIN +# ANDROID_ABI +# ANDROID_PLATFORM +# ANDROID_STL +# ANDROID_PIE +# ANDROID_CPP_FEATURES +# ANDROID_ALLOW_UNDEFINED_SYMBOLS +# ANDROID_ARM_MODE +# ANDROID_DISABLE_FORMAT_STRING_CHECKS +# ANDROID_CCACHE +# ANDROID_SANITIZE + +cmake_minimum_required(VERSION 3.12.0) + +# CMake invokes the toolchain file twice during the first build, but only once +# during subsequent rebuilds. This was causing the various flags to be added +# twice on the first build, and on a rebuild ninja would see only one set of the +# flags and rebuild the world. +# https://github.com/android-ndk/ndk/issues/323 +if(ANDROID_NDK_TOOLCHAIN_INCLUDED) + return() +endif(ANDROID_NDK_TOOLCHAIN_INCLUDED) +set(ANDROID_NDK_TOOLCHAIN_INCLUDED true) + +if(DEFINED ANDROID_USE_LEGACY_TOOLCHAIN_FILE) + set(_USE_LEGACY_TOOLCHAIN_FILE ${ANDROID_USE_LEGACY_TOOLCHAIN_FILE}) +else() + # Default to the legacy toolchain file to avoid changing the behavior of + # CMAKE_CXX_FLAGS. See https://github.com/android/ndk/issues/1693. + set(_USE_LEGACY_TOOLCHAIN_FILE true) +endif() +if(_USE_LEGACY_TOOLCHAIN_FILE) + include("${CMAKE_CURRENT_LIST_DIR}/android-legacy.toolchain.cmake") + return() +endif() + +# Android NDK path +get_filename_component(ANDROID_NDK_EXPECTED_PATH + "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) +if(NOT ANDROID_NDK) + set(CMAKE_ANDROID_NDK "${ANDROID_NDK_EXPECTED_PATH}") +else() + # Allow the user to specify their own NDK path, but emit a warning. This is an + # uncommon use case, but helpful if users want to use a bleeding edge + # toolchain file with a stable NDK. + # https://github.com/android-ndk/ndk/issues/473 + get_filename_component(ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE) + if(NOT "${ANDROID_NDK}" STREQUAL "${ANDROID_NDK_EXPECTED_PATH}") + message(WARNING "Using custom NDK path (ANDROID_NDK is set): ${ANDROID_NDK}") + endif() + set(CMAKE_ANDROID_NDK ${ANDROID_NDK}) +endif() +unset(ANDROID_NDK_EXPECTED_PATH) +file(TO_CMAKE_PATH "${CMAKE_ANDROID_NDK}" CMAKE_ANDROID_NDK) + +# Android NDK revision +# Possible formats: +# * r16, build 1234: 16.0.1234 +# * r16b, build 1234: 16.1.1234 +# * r16 beta 1, build 1234: 16.0.1234-beta1 +# +# Canary builds are not specially marked. +file(READ "${CMAKE_ANDROID_NDK}/source.properties" ANDROID_NDK_SOURCE_PROPERTIES) + +set(ANDROID_NDK_REVISION_REGEX + "^Pkg\\.Desc = Android NDK\nPkg\\.Revision = ([0-9]+)\\.([0-9]+)\\.([0-9]+)(-beta([0-9]+))?") +if(NOT ANDROID_NDK_SOURCE_PROPERTIES MATCHES "${ANDROID_NDK_REVISION_REGEX}") + message(SEND_ERROR "Failed to parse Android NDK revision: ${CMAKE_ANDROID_NDK}/source.properties.\n${ANDROID_NDK_SOURCE_PROPERTIES}") +endif() + +set(ANDROID_NDK_MAJOR "${CMAKE_MATCH_1}") +set(ANDROID_NDK_MINOR "${CMAKE_MATCH_2}") +set(ANDROID_NDK_BUILD "${CMAKE_MATCH_3}") +set(ANDROID_NDK_BETA "${CMAKE_MATCH_5}") +if(ANDROID_NDK_BETA STREQUAL "") + set(ANDROID_NDK_BETA "0") +endif() +set(ANDROID_NDK_REVISION + "${ANDROID_NDK_MAJOR}.${ANDROID_NDK_MINOR}.${ANDROID_NDK_BUILD}${CMAKE_MATCH_4}") + +# Touch toolchain variable to suppress "unused variable" warning. +# This happens if CMake is invoked with the same command line the second time. +if(CMAKE_TOOLCHAIN_FILE) +endif() + +# Determine the ABI. +if(NOT CMAKE_ANDROID_ARCH_ABI) + if(ANDROID_ABI STREQUAL "armeabi-v7a with NEON") + set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) + elseif(ANDROID_ABI) + set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI}) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^arm-linux-androideabi-") + set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^aarch64-linux-android-") + set(CMAKE_ANDROID_ARCH_ABI arm64-v8a) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86-") + set(CMAKE_ANDROID_ARCH_ABI x86) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86_64-") + set(CMAKE_ANDROID_ARCH_ABI x86_64) + elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^riscv64-") + set(CMAKE_ANDROID_ARCH_ABI riscv64) + else() + set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a) + endif() +endif() + +if(DEFINED ANDROID_ARM_NEON AND NOT ANDROID_ARM_NEON) + message(FATAL_ERROR "Disabling Neon is no longer supported") +endif() + +if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a") + set(CMAKE_ANDROID_ARM_NEON TRUE) + + if(NOT DEFINED CMAKE_ANDROID_ARM_MODE) + if(DEFINED ANDROID_FORCE_ARM_BUILD) + set(CMAKE_ANDROID_ARM_MODE ${ANDROID_FORCE_ARM_BUILD}) + elseif(DEFINED ANDROID_ARM_MODE) + if(ANDROID_ARM_MODE STREQUAL "arm") + set(CMAKE_ANDROID_ARM_MODE TRUE) + elseif(ANDROID_ARM_MODE STREQUAL "thumb") + set(CMAKE_ANDROID_ARM_MODE FALSE) + else() + message(FATAL_ERROR "Invalid Android ARM mode: ${ANDROID_ARM_MODE}.") + endif() + endif() + endif() +endif() + +# PIE is supported on all currently supported Android releases, but it is not +# supported with static executables, so we still provide ANDROID_PIE as an +# escape hatch for those. +if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) + if(DEFINED ANDROID_PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE ${ANDROID_PIE}) + elseif(DEFINED ANDROID_APP_PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE ${ANDROID_APP_PIE}) + else() + set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + endif() +endif() + +# Default values for configurable variables. +if(NOT ANDROID_TOOLCHAIN) + set(ANDROID_TOOLCHAIN clang) +elseif(ANDROID_TOOLCHAIN STREQUAL gcc) + message(FATAL_ERROR "GCC is no longer supported. See " + "https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.") +endif() + +if(ANDROID_NATIVE_API_LEVEL AND NOT ANDROID_PLATFORM) + if(ANDROID_NATIVE_API_LEVEL MATCHES "^android-[0-9]+$") + set(ANDROID_PLATFORM ${ANDROID_NATIVE_API_LEVEL}) + elseif(ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$") + set(ANDROID_PLATFORM android-${ANDROID_NATIVE_API_LEVEL}) + endif() +endif() +include(${CMAKE_ANDROID_NDK}/build/cmake/adjust_api_level.cmake) +adjust_api_level("${ANDROID_PLATFORM}" CMAKE_SYSTEM_VERSION) + +if(NOT DEFINED CMAKE_ANDROID_STL_TYPE AND DEFINED ANDROID_STL) + set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL}) +endif() + +if("hwaddress" IN_LIST ANDROID_SANITIZE AND "${CMAKE_ANDROID_STL_TYPE}" STREQUAL "c++_static") + message(FATAL_ERROR "\ + hwaddress does not support c++_static. Use system or c++_shared.") +endif() + +if("${CMAKE_ANDROID_STL_TYPE}" STREQUAL "gnustl_shared" OR + "${CMAKE_ANDROID_STL_TYPE}" STREQUAL "gnustl_static" OR + "${CMAKE_ANDROID_STL_TYPE}" STREQUAL "stlport_shared" OR + "${CMAKE_ANDROID_STL_TYPE}" STREQUAL "stlport_static") + message(FATAL_ERROR "\ +${CMAKE_ANDROID_STL_TYPE} is no longer supported. Please switch to either c++_shared \ +or c++_static. See https://developer.android.com/ndk/guides/cpp-support.html \ +for more information.") +endif() + +# Standard cross-compiling stuff. +set(CMAKE_SYSTEM_NAME Android) + +# STL. +if(ANDROID_STL) + set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL}) +endif() + +if(NDK_CCACHE AND NOT ANDROID_CCACHE) + set(ANDROID_CCACHE "${NDK_CCACHE}") +endif() +if(ANDROID_CCACHE) + set(CMAKE_C_COMPILER_LAUNCHER "${ANDROID_CCACHE}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${ANDROID_CCACHE}") +endif() + +# Configuration specific flags. +if(ANDROID_STL_FORCE_FEATURES AND NOT DEFINED ANDROID_CPP_FEATURES) + set(ANDROID_CPP_FEATURES "rtti exceptions") +endif() + +if(ANDROID_CPP_FEATURES) + separate_arguments(ANDROID_CPP_FEATURES) + foreach(feature ${ANDROID_CPP_FEATURES}) + if(NOT ${feature} MATCHES "^(rtti|exceptions|no-rtti|no-exceptions)$") + message(FATAL_ERROR "Invalid Android C++ feature: ${feature}.") + endif() + if(${feature} STREQUAL "rtti") + set(CMAKE_ANDROID_RTTI TRUE) + endif() + if(${feature} STREQUAL "no-rtti") + set(CMAKE_ANDROID_RTTI FALSE) + endif() + if(${feature} STREQUAL "exceptions") + set(CMAKE_ANDROID_EXCEPTIONS TRUE) + endif() + if(${feature} STREQUAL "no-exceptions") + set(CMAKE_ANDROID_EXCEPTIONS FALSE) + endif() + endforeach() + string(REPLACE ";" " " ANDROID_CPP_FEATURES "${ANDROID_CPP_FEATURES}") +endif() + +# Export configurable variables for the try_compile() command. +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + ANDROID_ABI + ANDROID_ALLOW_UNDEFINED_SYMBOLS + ANDROID_ARM_MODE + ANDROID_ARM_NEON + ANDROID_CCACHE + ANDROID_CPP_FEATURES + ANDROID_DISABLE_FORMAT_STRING_CHECKS + ANDROID_PIE + ANDROID_PLATFORM + ANDROID_STL + ANDROID_TOOLCHAIN + ANDROID_USE_LEGACY_TOOLCHAIN_FILE + ANDROID_SANITIZE +) + +if(DEFINED ANDROID_NO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS) + if(ANDROID_NO_UNDEFINED) + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS FALSE) + else() + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS TRUE) + endif() +endif() +if(DEFINED ANDROID_SO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS) + set(ANDROID_ALLOW_UNDEFINED_SYMBOLS "${ANDROID_SO_UNDEFINED}") +endif() + +# Exports compatible variables defined in exports.cmake. +set(_ANDROID_EXPORT_COMPATIBILITY_VARIABLES TRUE) + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux) + set(ANDROID_HOST_TAG linux-x86_64) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) + set(ANDROID_HOST_TAG darwin-x86_64) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(ANDROID_HOST_TAG windows-x86_64) +endif() + +# Toolchain. +set(ANDROID_TOOLCHAIN_ROOT + "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}") + +# NB: This variable causes CMake to automatically pass --sysroot to the +# toolchain. Studio currently relies on this to recognize Android builds. If +# this variable is removed, ensure that flag is still passed. +# TODO: Teach Studio to recognize Android builds based on --target. +set(CMAKE_SYSROOT "${ANDROID_TOOLCHAIN_ROOT}/sysroot") diff --git a/Android/android-ndk-r27d/build/cmake/compiler_id.cmake b/Android/android-ndk-r27d/build/cmake/compiler_id.cmake new file mode 100644 index 0000000..696daae --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/compiler_id.cmake @@ -0,0 +1,4 @@ +# The file is automatically generated when the NDK is built. +set(CMAKE_ASM_COMPILER_VERSION 18.0.4) +set(CMAKE_C_COMPILER_VERSION 18.0.4) +set(CMAKE_CXX_COMPILER_VERSION 18.0.4) diff --git a/Android/android-ndk-r27d/build/cmake/exports.cmake b/Android/android-ndk-r27d/build/cmake/exports.cmake new file mode 100644 index 0000000..e78a2bd --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/exports.cmake @@ -0,0 +1,81 @@ +# Copyright (C) 2020 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. + +# Read-only variables for compatibility with the other toolchain file. +# We'll keep these around for the existing projects that still use them. +# TODO: All of the variables here have equivalents in the standard set of +# cmake configurable variables, so we can remove these once most of our +# users migrate to those variables. + +# From legacy toolchain file. +set(ANDROID_NDK "${CMAKE_ANDROID_NDK}") +set(ANDROID_ABI "${CMAKE_ANDROID_ARCH_ABI}") +set(ANDROID_COMPILER_IS_CLANG TRUE) +set(ANDROID_PLATFORM "android-${CMAKE_SYSTEM_VERSION}") +set(ANDROID_PLATFORM_LEVEL "${CMAKE_SYSTEM_VERSION}") +set(ANDROID_ARM_NEON TRUE) +if(CMAKE_ANDROID_ARM_MODE) + set(ANDROID_ARM_MODE "arm") + set(ANDROID_FORCE_ARM_BUILD TRUE) +else() + set(ANDROID_ARM_MODE "thumb") +endif() +set(ANDROID_ARCH_NAME "${CMAKE_ANDROID_ARCH}") +set(ANDROID_LLVM_TRIPLE "${CMAKE_ANDROID_ARCH_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}") +set(ANDROID_TOOLCHAIN_ROOT "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}") +set(ANDROID_HOST_TAG "${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}") +set(ANDROID_HOST_PREBUILTS "${CMAKE_ANDROID_NDK}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}") +set(ANDROID_AR "${CMAKE_AR}") +set(ANDROID_RANLIB "${CMAKE_RANLIB}") +set(ANDROID_STRIP "${CMAKE_STRIP}") +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(ANDROID_TOOLCHAIN_SUFFIX ".exe") +endif() + +# From other toolchain file. +set(ANDROID_NATIVE_API_LEVEL "${ANDROID_PLATFORM_LEVEL}") +if(ANDROID_ALLOW_UNDEFINED_SYMBOLS) + set(ANDROID_SO_UNDEFINED TRUE) +else() + set(ANDROID_NO_UNDEFINED TRUE) +endif() +set(ANDROID_FUNCTION_LEVEL_LINKING TRUE) +set(ANDROID_GOLD_LINKER TRUE) +set(ANDROID_NOEXECSTACK TRUE) +set(ANDROID_RELRO TRUE) +if(ANDROID_CPP_FEATURES MATCHES "rtti" + AND ANDROID_CPP_FEATURES MATCHES "exceptions") + set(ANDROID_STL_FORCE_FEATURES TRUE) +endif() +if(ANDROID_CCACHE) + set(NDK_CCACHE "${ANDROID_CCACHE}") +endif() +set(ANDROID_NDK_HOST_X64 TRUE) +set(ANDROID_NDK_LAYOUT RELEASE) +if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a") + set(ARMEABI_V7A TRUE) + set(NEON TRUE) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + set(ARM64_V8A TRUE) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86") + set(X86 TRUE) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") + set(X86_64 TRUE) +elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "riscv64") + set(RISCV64 TRUE) +endif() +set(ANDROID_NDK_HOST_SYSTEM_NAME "${ANDROID_HOST_TAG}") +set(ANDROID_NDK_ABI_NAME "${CMAKE_ANDROID_ARCH_ABI}") +set(ANDROID_NDK_RELEASE "r${ANDROID_NDK_REVISION}") +set(TOOL_OS_SUFFIX "${ANDROID_TOOLCHAIN_SUFFIX}") diff --git a/Android/android-ndk-r27d/build/cmake/flags.cmake b/Android/android-ndk-r27d/build/cmake/flags.cmake new file mode 100644 index 0000000..a5403f7 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/flags.cmake @@ -0,0 +1,121 @@ +# Copyright (C) 2020 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 file will be included directly by cmake. It is used to provide +# additional cflags / ldflags. + +cmake_minimum_required(VERSION 3.12.0) + +set(_ANDROID_NDK_INIT_CFLAGS) +set(_ANDROID_NDK_INIT_CFLAGS_DEBUG) +set(_ANDROID_NDK_INIT_CFLAGS_RELEASE) +set(_ANDROID_NDK_INIT_LDFLAGS) +set(_ANDROID_NDK_INIT_LDFLAGS_EXE) + +# Generic flags. +string(APPEND _ANDROID_NDK_INIT_CFLAGS + " -DANDROID" + " -fdata-sections" + " -ffunction-sections" + " -funwind-tables" + " -fstack-protector-strong" + " -no-canonical-prefixes") + +if(ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES) + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -D__BIONIC_NO_PAGE_SIZE_MACRO") + if(ANDROID_ABI STREQUAL arm64-v8a OR ANDROID_ABI STREQUAL x86_64) + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,-z,max-page-size=16384") + endif() +endif() + +if(ANDROID_WEAK_API_DEFS) + string(APPEND _ANDROID_NDK_INIT_CFLAGS + " -D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__" + " -Werror=unguarded-availability") +endif() + +if("hwaddress" IN_LIST ANDROID_SANITIZE) + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -fsanitize=hwaddress -fno-omit-frame-pointer") + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -fsanitize=hwaddress") +endif() + +if("memtag" IN_LIST ANDROID_SANITIZE) + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -fsanitize=memtag-stack -fno-omit-frame-pointer") + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -fsanitize=memtag-stack,memtag-heap -fsanitize-memtag-mode=sync") + if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -march=armv8-a+memtag") + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -march=armv8-a+memtag") + endif() +endif() + +string(APPEND _ANDROID_NDK_INIT_CFLAGS_DEBUG " -fno-limit-debug-info") + +# If we're using LLD we need to use a slower build-id algorithm to work around +# the old version of LLDB in Android Studio, which doesn't understand LLD's +# default hash ("fast"). +# +# https://github.com/android/ndk/issues/885 +string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--build-id=sha1") + +if(CMAKE_SYSTEM_VERSION LESS 30) + # https://github.com/android/ndk/issues/1196 + # https://github.com/android/ndk/issues/1589 + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--no-rosegment") +endif() + +if (NOT ANDROID_ALLOW_UNDEFINED_VERSION_SCRIPT_SYMBOLS) + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--no-undefined-version") +endif() + +string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--fatal-warnings") +# This should only be set for release modes, but CMake doesn't provide a way for +# us to be that specific in the new toolchain file. +# https://github.com/android/ndk/issues/1813 +string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--gc-sections") +string(APPEND _ANDROID_NDK_INIT_LDFLAGS_EXE " -Wl,--gc-sections") + +# Toolchain and ABI specific flags. +if(CMAKE_ANDROID_ARCH_ABI STREQUAL x86 AND CMAKE_SYSTEM_VERSION LESS 24) + # http://b.android.com/222239 + # http://b.android.com/220159 (internal http://b/31809417) + # x86 devices have stack alignment issues. + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -mstackrealign") +endif() + +string(APPEND _ANDROID_NDK_INIT_CFLAGS " -D_FORTIFY_SOURCE=2") + +if(CMAKE_ANDROID_ARCH_ABI MATCHES "armeabi") + # Clang does not set this up properly when using -fno-integrated-as. + # https://github.com/android-ndk/ndk/issues/906 + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -march=armv7-a") + if(NOT CMAKE_ANDROID_ARM_MODE) + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -mthumb") + endif() +endif() + +# CMake automatically forwards all compiler flags to the linker, and clang +# doesn't like having -Wa flags being used for linking. To prevent CMake from +# doing this would require meddling with the CMAKE__COMPILE_OBJECT rules, +# which would get quite messy. +string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Qunused-arguments") + +if(ANDROID_DISABLE_FORMAT_STRING_CHECKS) + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -Wno-error=format-security") +else() + string(APPEND _ANDROID_NDK_INIT_CFLAGS " -Wformat -Werror=format-security") +endif() + +if(NOT ANDROID_ALLOW_UNDEFINED_SYMBOLS) + string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--no-undefined") +endif() diff --git a/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Clang.cmake b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Clang.cmake new file mode 100644 index 0000000..5a3acbf --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Clang.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the end of +# Modules/Platform/Android-Clang.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Determine.cmake b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Determine.cmake new file mode 100644 index 0000000..8e7852f --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Determine.cmake @@ -0,0 +1,22 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the end of +# Modules/Platform/Android-Determine.cmake. + +# android.toolchain.cmake may set this to export old variables. +if(_ANDROID_EXPORT_COMPATIBILITY_VARIABLES) + file(READ "${CMAKE_ANDROID_NDK}/build/cmake/exports.cmake" _EXPORTS) + string(APPEND CMAKE_SYSTEM_CUSTOM_CODE "\n${_EXPORTS}\n") +endif() diff --git a/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Initialize.cmake b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Initialize.cmake new file mode 100644 index 0000000..6e7aafb --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/post/Android-Initialize.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the end of +# Modules/Platform/Android-Initialize.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/post/Android.cmake b/Android/android-ndk-r27d/build/cmake/hooks/post/Android.cmake new file mode 100644 index 0000000..523f4e8 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/post/Android.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the end of +# Modules/Platform/Android.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/post/Determine-Compiler.cmake b/Android/android-ndk-r27d/build/cmake/hooks/post/Determine-Compiler.cmake new file mode 100644 index 0000000..4bab2d4 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/post/Determine-Compiler.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the end of +# Modules/Platform/Android/Determine-Compiler.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Clang.cmake b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Clang.cmake new file mode 100644 index 0000000..929a37b --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Clang.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the beginning of +# Modules/Platform/Android-Clang.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Determine.cmake b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Determine.cmake new file mode 100644 index 0000000..1261981 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Determine.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the beginning of +# Modules/Platform/Android-Determine.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Initialize.cmake b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Initialize.cmake new file mode 100644 index 0000000..8608129 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android-Initialize.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the beginning of +# Modules/Platform/Android-Initialize.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/pre/Android.cmake b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android.cmake new file mode 100644 index 0000000..8813c94 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/pre/Android.cmake @@ -0,0 +1,16 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the beginning of +# Modules/Platform/Android.cmake. diff --git a/Android/android-ndk-r27d/build/cmake/hooks/pre/Determine-Compiler.cmake b/Android/android-ndk-r27d/build/cmake/hooks/pre/Determine-Compiler.cmake new file mode 100644 index 0000000..79cc6c0 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/hooks/pre/Determine-Compiler.cmake @@ -0,0 +1,42 @@ +# Copyright (C) 2020 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 is a hook file that will be included by cmake at the beginning of +# Modules/Platform/Android/Determine-Compiler.cmake. + +# Skip hook for the legacy toolchain workflow. +if(CMAKE_SYSTEM_VERSION EQUAL 1) + return() +endif() + +if(${CMAKE_VERSION} VERSION_LESS "3.22.0") + # If we don't explicitly set the target CMake will ID the compiler using the + # default target, causing MINGW to be defined when a Windows host is used. + # https://github.com/android/ndk/issues/1581 + # https://gitlab.kitware.com/cmake/cmake/-/issues/22647 + if(CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a) + set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi) + elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL arm64-v8a) + set(ANDROID_LLVM_TRIPLE aarch64-none-linux-android) + elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86) + set(ANDROID_LLVM_TRIPLE i686-none-linux-android) + elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL x86_64) + set(ANDROID_LLVM_TRIPLE x86_64-none-linux-android) + else() + message(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.") + endif() + set(CMAKE_ASM_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}") + set(CMAKE_C_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}") + set(CMAKE_CXX_COMPILER_TARGET "${ANDROID_LLVM_TRIPLE}${CMAKE_SYSTEM_VERSION}") +endif() diff --git a/Android/android-ndk-r27d/build/cmake/platforms.cmake b/Android/android-ndk-r27d/build/cmake/platforms.cmake new file mode 100644 index 0000000..4400ba7 --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/platforms.cmake @@ -0,0 +1,23 @@ +set(NDK_MIN_PLATFORM_LEVEL "21") +set(NDK_MAX_PLATFORM_LEVEL "35") +set(NDK_PLATFORM_ALIAS_20 "android-19") +set(NDK_PLATFORM_ALIAS_25 "android-24") +set(NDK_PLATFORM_ALIAS_J "android-16") +set(NDK_PLATFORM_ALIAS_J-MR1 "android-17") +set(NDK_PLATFORM_ALIAS_J-MR2 "android-18") +set(NDK_PLATFORM_ALIAS_K "android-19") +set(NDK_PLATFORM_ALIAS_L "android-21") +set(NDK_PLATFORM_ALIAS_L-MR1 "android-22") +set(NDK_PLATFORM_ALIAS_M "android-23") +set(NDK_PLATFORM_ALIAS_N "android-24") +set(NDK_PLATFORM_ALIAS_N-MR1 "android-24") +set(NDK_PLATFORM_ALIAS_O "android-26") +set(NDK_PLATFORM_ALIAS_O-MR1 "android-27") +set(NDK_PLATFORM_ALIAS_P "android-28") +set(NDK_PLATFORM_ALIAS_Q "android-29") +set(NDK_PLATFORM_ALIAS_R "android-30") +set(NDK_PLATFORM_ALIAS_S "android-31") +set(NDK_PLATFORM_ALIAS_Sv2 "android-32") +set(NDK_PLATFORM_ALIAS_Tiramisu "android-33") +set(NDK_PLATFORM_ALIAS_UpsideDownCake "android-34") +set(NDK_PLATFORM_ALIAS_VanillaIceCream "android-35") \ No newline at end of file diff --git a/Android/android-ndk-r27d/build/cmake/system_libs.cmake b/Android/android-ndk-r27d/build/cmake/system_libs.cmake new file mode 100644 index 0000000..4df7aeb --- /dev/null +++ b/Android/android-ndk-r27d/build/cmake/system_libs.cmake @@ -0,0 +1 @@ +set(NDK_SYSTEM_LIBS "libEGL.so;libGLESv1_CM.so;libGLESv2.so;libGLESv3.so;libOpenMAXAL.so;libOpenSLES.so;libaaudio.so;libamidi.so;libandroid.so;libbinder_ndk.so;libc.so;libcamera2ndk.so;libdl.so;libicu.so;libjnigraphics.so;liblog.so;libm.so;libmediandk.so;libnativehelper.so;libnativewindow.so;libneuralnetworks.so;libstdc++.so;libsync.so;libvulkan.so;libz.so") \ No newline at end of file diff --git a/Android/android-ndk-r27d/build/core/abis.mk b/Android/android-ndk-r27d/build/core/abis.mk new file mode 100644 index 0000000..4476ec3 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/abis.mk @@ -0,0 +1,40 @@ +NDK_DEFAULT_ABIS := arm64-v8a armeabi-v7a x86 x86_64 +NDK_DEPRECATED_ABIS := +NDK_KNOWN_DEVICE_ABI32S := armeabi-v7a x86 +NDK_KNOWN_DEVICE_ABI64S := arm64-v8a riscv64 x86_64 +NDK_KNOWN_DEVICE_ABIS := arm64-v8a armeabi-v7a riscv64 x86 x86_64 +NDK_ABI_armeabi-v7a_PROC := armv7-a +NDK_ABI_armeabi-v7a_ARCH := arm +NDK_ABI_armeabi-v7a_TRIPLE := arm-linux-androideabi +NDK_ABI_armeabi-v7a_LLVM_TRIPLE := armv7-none-linux-androideabi +NDK_ABI_armeabi-v7a_MIN_OS_VERSION := 21 +NDK_PROC_armv7-a_ABI := armeabi-v7a +NDK_ARCH_arm_ABI := armeabi-v7a +NDK_ABI_arm64-v8a_PROC := aarch64 +NDK_ABI_arm64-v8a_ARCH := arm64 +NDK_ABI_arm64-v8a_TRIPLE := aarch64-linux-android +NDK_ABI_arm64-v8a_LLVM_TRIPLE := aarch64-none-linux-android +NDK_ABI_arm64-v8a_MIN_OS_VERSION := 21 +NDK_PROC_aarch64_ABI := arm64-v8a +NDK_ARCH_arm64_ABI := arm64-v8a +NDK_ABI_riscv64_PROC := riscv64 +NDK_ABI_riscv64_ARCH := riscv64 +NDK_ABI_riscv64_TRIPLE := riscv64-linux-android +NDK_ABI_riscv64_LLVM_TRIPLE := riscv64-none-linux-android +NDK_ABI_riscv64_MIN_OS_VERSION := 35 +NDK_PROC_riscv64_ABI := riscv64 +NDK_ARCH_riscv64_ABI := riscv64 +NDK_ABI_x86_PROC := i686 +NDK_ABI_x86_ARCH := x86 +NDK_ABI_x86_TRIPLE := i686-linux-android +NDK_ABI_x86_LLVM_TRIPLE := i686-none-linux-android +NDK_ABI_x86_MIN_OS_VERSION := 21 +NDK_PROC_i686_ABI := x86 +NDK_ARCH_x86_ABI := x86 +NDK_ABI_x86_64_PROC := x86_64 +NDK_ABI_x86_64_ARCH := x86_64 +NDK_ABI_x86_64_TRIPLE := x86_64-linux-android +NDK_ABI_x86_64_LLVM_TRIPLE := x86_64-none-linux-android +NDK_ABI_x86_64_MIN_OS_VERSION := 21 +NDK_PROC_x86_64_ABI := x86_64 +NDK_ARCH_x86_64_ABI := x86_64 \ No newline at end of file diff --git a/Android/android-ndk-r27d/build/core/add-application.mk b/Android/android-ndk-r27d/build/core/add-application.mk new file mode 100644 index 0000000..31294ee --- /dev/null +++ b/Android/android-ndk-r27d/build/core/add-application.mk @@ -0,0 +1,247 @@ +# Copyright (C) 2009 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 script is used to record an application definition in the +# NDK build system, before performing any build whatsoever. +# +# It is included repeatedly from build/core/main.mk and expects a +# variable named '_application_mk' which points to a given Application.mk +# file that will be included here. The latter must define a few variables +# to describe the application to the build system, and the rest of the +# code here will perform book-keeping and basic checks +# + +$(call assert-defined, _application_mk _app) +$(call ndk_log,Parsing $(_application_mk)) + +$(call clear-vars, $(NDK_APP_VARS)) + +# Check that NDK_DEBUG is properly defined. If it is +# the only valid states are: undefined, 0, 1, false and true +# +# We set APP_DEBUG to , 'true' or 'false'. +# +APP_DEBUG := $(strip $(NDK_DEBUG)) +ifeq ($(APP_DEBUG),0) + APP_DEBUG:= false +endif +ifeq ($(APP_DEBUG),1) + APP_DEBUG := true +endif +ifdef APP_DEBUG + ifneq (,$(filter-out true false,$(APP_DEBUG))) + $(call __ndk_warning,NDK_DEBUG is defined to the unsupported value '$(NDK_DEBUG)', will be ignored!) + endif +endif + +include $(_application_mk) + +$(call check-required-vars,$(NDK_APP_VARS_REQUIRED),$(_application_mk)) + +_map := NDK_APP.$(_app) + +# strip the 'lib' prefix in front of APP_MODULES modules +APP_MODULES := $(call strip-lib-prefix,$(APP_MODULES)) + +APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH)) +ifndef APP_PROJECT_PATH + APP_PROJECT_PATH := $(NDK_PROJECT_PATH) +endif + +include $(BUILD_SYSTEM)/setup-app-platform.mk + +# Check that the value of APP_ABI corresponds to known ABIs +# 'all' is a special case that means 'all supported ABIs' +# +# It will be handled in setup-app.mk. We can't hope to change +# the value of APP_ABI is the user enforces it on the command-line +# with a call like: ndk-build APP_ABI=all +# +# Because GNU Make makes the APP_ABI variable read-only (any assignments +# to it will be ignored) +# +APP_ABI := $(subst $(comma),$(space),$(strip $(APP_ABI))) +ifndef APP_ABI + APP_ABI := $(NDK_DEFAULT_ABIS) +endif + +# If APP_BUILD_SCRIPT is defined, check that the file exists. +# If undefined, look in $(APP_PROJECT_PATH)/jni/Android.mk +# +APP_BUILD_SCRIPT := $(strip $(APP_BUILD_SCRIPT)) +ifdef APP_BUILD_SCRIPT + _build_script := $(strip $(wildcard $(APP_BUILD_SCRIPT))) + ifndef _build_script + $(call __ndk_info,Your APP_BUILD_SCRIPT points to an unknown file: $(APP_BUILD_SCRIPT)) + $(call __ndk_error,Aborting...) + endif + APP_BUILD_SCRIPT := $(_build_script) + $(call ndk_log, Using build script $(APP_BUILD_SCRIPT)) +else + ifeq (null,$(APP_PROJECT_PATH)) + $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set APP_BUILD_SCRIPT.) + $(call __ndk_error,Aborting.) + endif + + _build_script := $(strip $(wildcard $(APP_PROJECT_PATH)/jni/Android.mk)) + ifndef _build_script + $(call __ndk_info,There is no Android.mk under $(APP_PROJECT_PATH)/jni) + $(call __ndk_info,If this is intentional, please define APP_BUILD_SCRIPT to point) + $(call __ndk_info,to a valid NDK build script.) + $(call __ndk_error,Aborting...) + endif + APP_BUILD_SCRIPT := $(_build_script) + $(call ndk_log, Defaulted to APP_BUILD_SCRIPT=$(APP_BUILD_SCRIPT)) +endif + +# Determine whether the application should be debuggable. +# - If APP_DEBUG is set to 'true', then it always should. +# - If APP_DEBUG is set to 'false', then it never should +# - Otherwise, extract the android:debuggable attribute from the manifest. +# +ifdef APP_DEBUG + APP_DEBUGGABLE := $(APP_DEBUG) + ifeq ($(NDK_LOG),1) + ifeq ($(APP_DEBUG),true) + $(call ndk_log,Application '$(_app)' forced debuggable through NDK_DEBUG) + else + $(call ndk_log,Application '$(_app)' forced *not* debuggable through NDK_DEBUG) + endif + endif +else + # NOTE: To make unit-testing simpler, handle the case where there is no manifest. + APP_DEBUGGABLE := false + ifdef APP_MANIFEST + APP_DEBUGGABLE := $(shell $(HOST_PYTHON) $(BUILD_PY)/extract_manifest.py debuggable $(call host-path,$(APP_MANIFEST))) + endif + ifeq ($(NDK_LOG),1) + ifeq ($(APP_DEBUGGABLE),true) + $(call ndk_log,Application '$(_app)' *is* debuggable) + else + $(call ndk_log,Application '$(_app)' is not debuggable) + endif + endif +endif + +# LOCAL_BUILD_MODE will be either release or debug +# +# If APP_OPTIM is defined in the Application.mk, just use this. +# +# Otherwise, set to 'debug' if android:debuggable is set to TRUE, +# and to 'release' if not. +# +ifneq ($(APP_OPTIM),) + # check that APP_OPTIM, if defined, is either 'release' or 'debug' + $(if $(filter-out release debug,$(APP_OPTIM)),\ + $(call __ndk_info, The APP_OPTIM defined in $(_application_mk) must only be 'release' or 'debug')\ + $(call __ndk_error,Aborting)\ + ) + $(call ndk_log,Selecting optimization mode through Application.mk: $(APP_OPTIM)) +else + ifeq ($(APP_DEBUGGABLE),true) + $(call ndk_log,Selecting debug optimization mode (app is debuggable)) + APP_OPTIM := debug + else + $(call ndk_log,Selecting release optimization mode (app is not debuggable)) + APP_OPTIM := release + endif +endif + +APP_CFLAGS := $(strip $(APP_CFLAGS)) +APP_CONLYFLAGS := $(strip $(APP_CONLYFLAGS)) +APP_CPPFLAGS := $(strip $(APP_CPPFLAGS)) +APP_CXXFLAGS := $(strip $(APP_CXXFLAGS)) +APP_ASFLAGS := $(strip $(APP_ASFLAGS)) +APP_ASMFLAGS := $(strip $(APP_ASMFLAGS)) +APP_LDFLAGS := $(strip $(APP_LDFLAGS)) + +# Check that APP_STL is defined. If not, use the default value (system) +# otherwise, check that the name is correct. +APP_STL := $(strip $(APP_STL)) +ifndef APP_STL + APP_STL := system +else + ifneq ($(filter $(APP_STL),gnustl_static gnustl_shared stlport_static stlport_shared),) + $(call __ndk_error,APP_STL $(APP_STL) is no longer supported. Please \ + switch to either c++_static or c++_shared. See \ + https://developer.android.com/ndk/guides/cpp-support.html for more \ + information.) + endif + $(call ndk-stl-check,$(APP_STL)) +endif + +# wrap.sh files can be specified in the user's Application.mk in either an +# ABI-generic (APP_WRAP_SH) or ABI-specific (APP_WRAP_SH_x86, etc) fashion. +# These two approaches cannot be combined; if any ABI-specific wrap.sh files are +# specified then it is an error to also specify an ABI-generic one. +# +# After this block, only the ABI-specific values should be checked; if there is +# an ABI-generic script specified the ABI-specific variables will be populated +# with the generic script. +NDK_NO_USER_WRAP_SH := true +ifneq ($(APP_WRAP_SH),) + NDK_NO_USER_WRAP_SH := false +endif + +NDK_HAVE_ABI_SPECIFIC_WRAP_SH := false +$(foreach _abi,$(NDK_ALL_ABIS),\ + $(if $(APP_WRAP_SH_$(_abi)),\ + $(eval NDK_HAVE_ABI_SPECIFIC_WRAP_SH := true))) + +ifeq ($(NDK_HAVE_ABI_SPECIFIC_WRAP_SH),true) + # It is an error to have both ABI-specific and ABI-generic wrap.sh files + # specified. + ifneq ($(APP_WRAP_SH),) + $(call __ndk_error,Found both ABI-specific and ABI-generic APP_WRAP_SH \ + directives. Must use either all ABI-specific or only ABI-generic.) + endif + NDK_NO_USER_WRAP_SH := false +else + # If we have no ABI-specific wrap.sh files but we *do* have an ABI-generic + # one, install the generic one for all ABIs. + $(foreach _abi,$(NDK_ALL_ABIS),\ + $(eval APP_WRAP_SH_$(_abi) := $(APP_WRAP_SH))) +endif + +# Stripping can be configured both at the app (APP_STRIP_MODE) and module level +# (LOCAL_STRIP_MODE). The module setting always overrides the application +# setting. +# +# This value is passed as-is as the flag to the strip command except when it is +# set to the special value "none". If set to "none", the binary will not be +# stripped at all. +ifeq ($(APP_STRIP_MODE),) + # The strip command is only used for shared libraries and executables. It is + # thus safe to use --strip-unneeded, which is only dangerous when applied to + # static libraries or object files. + APP_STRIP_MODE := --strip-unneeded +endif + +$(if $(call get,$(_map),defined),\ + $(call __ndk_info,Weird, the application $(_app) is already defined by $(call get,$(_map),defined))\ + $(call __ndk_error,Aborting)\ +) + +$(call set,$(_map),defined,$(_application_mk)) + +# Record all app-specific variable definitions +$(foreach __name,$(NDK_APP_VARS),\ + $(call set,$(_map),$(__name),$($(__name)))\ +) + +# Record the Application.mk for debugging +$(call set,$(_map),Application.mk,$(_application_mk)) + +NDK_ALL_APPS += $(_app) diff --git a/Android/android-ndk-r27d/build/core/add-toolchain.mk b/Android/android-ndk-r27d/build/core/add-toolchain.mk new file mode 100644 index 0000000..d852754 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/add-toolchain.mk @@ -0,0 +1,85 @@ +# Copyright (C) 2009 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 script is included repeatedly by main.mk to add a new toolchain +# definition to the NDK build system. +# +# '_config_mk' must be defined as the path of a toolchain +# configuration file (config.mk) that will be included here. +# +$(call assert-defined, _config_mk) + +# The list of variables that must or may be defined +# by the toolchain configuration file +# +NDK_TOOLCHAIN_VARS_REQUIRED := TOOLCHAIN_ABIS TOOLCHAIN_ARCH +NDK_TOOLCHAIN_VARS_OPTIONAL := + +# Clear variables that are supposed to be defined by the config file +$(call clear-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED)) +$(call clear-vars,$(NDK_TOOLCHAIN_VARS_OPTIONAL)) + +# Include the config file +include $(_config_mk) + +ifeq ($(TOOLCHAIN_ABIS)$(TOOLCHAIN_ARCH),) +# Ignore if both TOOLCHAIN_ABIS and TOOLCHAIN_ARCH are not defined +else + +# Check that the proper variables were defined +$(call check-required-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED),$(_config_mk)) + +# Check that the file didn't do something stupid +$(call assert-defined, _config_mk) + +# Now record the toolchain-specific information +_dir := $(patsubst %/,%,$(dir $(_config_mk))) +_name := $(notdir $(_dir)) +_arch := $(TOOLCHAIN_ARCH) +_abis := $(TOOLCHAIN_ABIS) + +_toolchain := NDK_TOOLCHAIN.$(_name) + +# check that the toolchain name is unique +$(if $(strip $($(_toolchain).defined)),\ + $(call __ndk_error,Toolchain $(_name) defined in $(_parent) is\ + already defined in $(NDK_TOOLCHAIN.$(_name).defined))) + +$(_toolchain).defined := $(_toolchain_config) +$(_toolchain).arch := $(_arch) +$(_toolchain).abis := $(_abis) +$(_toolchain).setup := $(wildcard $(_dir)/setup.mk) + +$(if $(strip $($(_toolchain).setup)),,\ + $(call __ndk_error, Toolchain $(_name) lacks a setup.mk in $(_dir))) + +NDK_ALL_TOOLCHAINS += $(_name) +NDK_ALL_ARCHS += $(_arch) +NDK_ALL_ABIS += $(_abis) + +# NDK_ABI..toolchains records the list of toolchains that support +# a given ABI +# +$(foreach _abi,$(_abis),\ + $(eval NDK_ABI.$(_abi).toolchains += $(_name)) \ + $(eval NDK_ABI.$(_abi).arch := $(sort $(NDK_ABI.$(_abi).arch) $(_arch)))\ +) + +NDK_ARCH.$(_arch).toolchains += $(_name) +NDK_ARCH.$(_arch).abis := $(sort $(NDK_ARCH.$(_arch).abis) $(_abis)) + +endif + +# done diff --git a/Android/android-ndk-r27d/build/core/build-all.mk b/Android/android-ndk-r27d/build/core/build-all.mk new file mode 100644 index 0000000..630c490 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-all.mk @@ -0,0 +1,125 @@ +# Copyright (C) 2009-2010 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 script is used to build all wanted NDK binaries. It is included +# by several scripts. +# + +# ensure that the following variables are properly defined +$(call assert-defined,NDK_APPS NDK_APP_OUT) + +# ==================================================================== +# +# Prepare the build for parsing Android.mk files +# +# ==================================================================== + +# These phony targets are used to control various stages of the build +.PHONY: \ + all \ + host_libraries \ + host_executables \ + installed_modules \ + executables libraries \ + static_libraries \ + shared_libraries \ + clean clean-objs-dir \ + clean-executables clean-libraries \ + clean-installed-modules \ + clean-installed-binaries \ + clang_tidy_rules \ + +# These macros are used in Android.mk to include the corresponding +# build script that will parse the LOCAL_XXX variable definitions. +# +CLEAR_VARS := $(BUILD_SYSTEM)/clear-vars.mk +BUILD_HOST_EXECUTABLE := $(BUILD_SYSTEM)/build-host-executable.mk +BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk +BUILD_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-static-library.mk +BUILD_SHARED_LIBRARY := $(BUILD_SYSTEM)/build-shared-library.mk +BUILD_EXECUTABLE := $(BUILD_SYSTEM)/build-executable.mk +PREBUILT_SHARED_LIBRARY := $(BUILD_SYSTEM)/prebuilt-shared-library.mk +PREBUILT_STATIC_LIBRARY := $(BUILD_SYSTEM)/prebuilt-static-library.mk + +# this is the list of directories containing dependency information +# generated during the build. It will be updated by build scripts +# when module definitions are parsed. +# +ALL_DEPENDENCY_DIRS := + +# this is the list of all generated files that we would need to clean +ALL_HOST_EXECUTABLES := +ALL_HOST_STATIC_LIBRARIES := +ALL_STATIC_LIBRARIES := +ALL_SHARED_LIBRARIES := +ALL_EXECUTABLES := + +WANTED_INSTALLED_MODULES := + +# the first rule +all: installed_modules host_libraries host_executables clang_tidy_rules + + +$(foreach _app,$(NDK_APPS),\ + $(eval include $(BUILD_SYSTEM)/setup-app.mk)\ +) + +ifeq (,$(strip $(WANTED_INSTALLED_MODULES))) + ifneq (,$(strip $(NDK_APP_MODULES))) + $(call __ndk_warning,WARNING: No modules to build, your APP_MODULES definition is probably incorrect!) + else + $(call __ndk_warning,WARNING: There are no modules to build in this project!) + endif +endif + +# ==================================================================== +# +# Now finish the build preparation with a few rules that depend on +# what has been effectively parsed and recorded previously +# +# ==================================================================== + +clean: clean-intermediates clean-installed-binaries + +distclean: clean + +installed_modules: clean-installed-binaries libraries $(WANTED_INSTALLED_MODULES) +host_libraries: $(HOST_STATIC_LIBRARIES) +host_executables: $(HOST_EXECUTABLES) + +# clang-tidy rules add themselves as dependencies of this phony rule in +# ev-clang-tidy. +clang_tidy_rules: + +static_libraries: $(STATIC_LIBRARIES) +shared_libraries: $(SHARED_LIBRARIES) +executables: $(EXECUTABLES) + +ifeq ($(GEN_COMPILE_COMMANDS_DB),true) +all: $(COMPILE_COMMANDS_JSON) +endif + +libraries: static_libraries shared_libraries + +clean-host-intermediates: + $(hide) $(call host-rm,$(HOST_EXECUTABLES) $(HOST_STATIC_LIBRARIES)) + +clean-intermediates: clean-host-intermediates + $(hide) $(call host-rm,$(EXECUTABLES) $(STATIC_LIBRARIES) $(SHARED_LIBRARIES)) + +# include dependency information +ALL_DEPENDENCY_DIRS := $(patsubst %/,%,$(sort $(ALL_DEPENDENCY_DIRS))) +-include $(wildcard $(ALL_DEPENDENCY_DIRS:%=%/*.d)) diff --git a/Android/android-ndk-r27d/build/core/build-binary.mk b/Android/android-ndk-r27d/build/core/build-binary.mk new file mode 100644 index 0000000..7940c66 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-binary.mk @@ -0,0 +1,714 @@ +# Copyright (C) 2008 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. +# + +# Check that LOCAL_MODULE is defined, then restore its LOCAL_XXXX values +$(call assert-defined,LOCAL_MODULE) +$(call module-restore-locals,$(LOCAL_MODULE)) + +# As in build-module.mk, eval sucks. Manually unstash the flags variations to +# preserve -Werror=#warnings. +LOCAL_ASFLAGS := $(__ndk_modules.$(LOCAL_MODULE).ASFLAGS) +LOCAL_ASMFLAGS := $(__ndk_modules.$(LOCAL_MODULE).ASMFLAGS) +LOCAL_CFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CFLAGS) +LOCAL_CLANG_TIDY_FLAGS := $(__ndk_modules.$(LOCAL_MODULE).CLANG_TIDY_FLAGS) +LOCAL_CONLYFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CONLYFLAGS) +LOCAL_CPPFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CPPFLAGS) +LOCAL_CXXFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CXXFLAGS) +LOCAL_LDFLAGS := $(__ndk_modules.$(LOCAL_MODULE).LDFLAGS) + +# For now, only support target (device-specific modules). +# We may want to introduce support for host modules in the future +# but that is too experimental for now. +# +my := POISONED + +# LOCAL_MAKEFILE must also exist and name the Android.mk that +# included the module build script. +# +$(call assert-defined,LOCAL_MAKEFILE LOCAL_BUILD_SCRIPT LOCAL_BUILT_MODULE) + +# A list of LOCAL_XXX variables that are ignored for static libraries. +# Print a warning if they are present inside a module definition to let +# the user know this won't do what he/she expects. +not_in_static_libs := \ + LOCAL_LDFLAGS \ + LOCAL_LDLIBS \ + LOCAL_ALLOW_UNDEFINED_SYMBOLS + +ifeq ($(call module-get-class,$(LOCAL_MODULE)),STATIC_LIBRARY) +$(foreach _notvar,$(not_in_static_libs),\ + $(if $(strip $($(_notvar))),\ + $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): $(_notvar) is always ignored for static libraries)\ + )\ +) +endif + +# Some developers like to add library names (e.g. -lfoo) to LOCAL_LDLIBS +# and LOCAL_LDFLAGS directly. This is very fragile and can lead to broken +# builds and other nasty surprises, because it doesn't tell ndk-build +# that the corresponding module depends on these files. Emit a warning +# when we detect this case. +libs_in_ldflags := $(filter -l% %.so %.a,$(LOCAL_LDLIBS) $(LOCAL_LDFLAGS)) + +# Since the above will glob anything ending in .so or .a, we need to filter out +# any cases of -Wl,--exclude-libs since we use that to hide symbols in STLs. +libs_in_ldflags := \ + $(filter-out -Wl$(comma)--exclude-libs$(comma)%,$(libs_in_ldflags)) + +include $(BUILD_SYSTEM)/system_libs.mk + +# The only way to statically link libomp.a is with +# `-Wl,-Bstatic -lomp -Wl,-Bdynamic`, so we need to accept `-lomp`. +# https://github.com/android-ndk/ndk/issues/1028 +NDK_SYSTEM_LIBS += libomp.so + +libs_in_ldflags := $(filter-out $(NDK_SYSTEM_LIBS:lib%.so=-l%),$(libs_in_ldflags)) + +ifneq (,$(strip $(libs_in_ldflags))) + $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): non-system libraries in linker flags: $(libs_in_ldflags)) + $(call __ndk_info, This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES) + $(call __ndk_info, or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the) + $(call __ndk_info, current module) +endif + +include $(BUILD_SYSTEM)/import-locals.mk + +# Check for LOCAL_THIN_ARCHIVE / APP_THIN_ARCHIVE and print a warning if +# it is defined for non-static library modules. +thin_archive := $(strip $(LOCAL_THIN_ARCHIVE)) +ifdef thin_archive +ifneq (STATIC_LIBRARY,$(call module-get-class,$(LOCAL_MODULE))) + $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_THIN_ARCHIVE is for building static libraries) +endif +endif + +ifndef thin_archive + thin_archive := $(strip $(NDK_APP_THIN_ARCHIVE)) +endif +# Print a warning if the value is not 'true', 'false' or empty. +ifneq (,$(filter-out true false,$(thin_archive))) + $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): Invalid LOCAL_THIN_ARCHIVE value '$(thin_archive)' ignored!) + thin_archive := +endif + +# +# Ensure that 'make ' and 'make clean-' work +# +.PHONY: $(LOCAL_MODULE) +$(LOCAL_MODULE): $(LOCAL_BUILT_MODULE) + +cleantarget := clean-$(LOCAL_MODULE)-$(TARGET_ARCH_ABI) +.PHONY: $(cleantarget) +clean: $(cleantarget) + +$(cleantarget): PRIVATE_ABI := $(TARGET_ARCH_ABI) +$(cleantarget): PRIVATE_MODULE := $(LOCAL_MODULE) +ifneq ($(LOCAL_BUILT_MODULE_NOT_COPIED),true) +$(cleantarget): PRIVATE_CLEAN_FILES := $(LOCAL_BUILT_MODULE) \ + $(LOCAL_OBJS_DIR) +else +$(cleantarget): PRIVATE_CLEAN_FILES := $(LOCAL_OBJS_DIR) +endif +$(cleantarget):: + $(call host-echo-build-step,$(PRIVATE_ABI),Clean) "$(PRIVATE_MODULE) [$(PRIVATE_ABI)]" + $(hide) $(call host-rmdir,$(PRIVATE_CLEAN_FILES)) + +# list of generated object files +LOCAL_OBJECTS := + +# always define ANDROID when building binaries +# +LOCAL_CFLAGS := -DANDROID $(LOCAL_CFLAGS) + +ifeq ($(APP_SUPPORT_FLEXIBLE_PAGE_SIZES),true) + LOCAL_CFLAGS += -D__BIONIC_NO_PAGE_SIZE_MACRO + ifneq (,$(filter $(APP_ABI),arm64-v8a x86_64)) + LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 + endif +endif + +# +# Add the default system shared libraries to the build +# +ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none) + LOCAL_SHARED_LIBRARIES += $(TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES) +else + LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES) +endif + +# +# Check LOCAL_CPP_EXTENSION +# +bad_cpp_extensions := $(strip $(filter-out .%,$(LOCAL_CPP_EXTENSION))) +ifdef bad_cpp_extensions + $(call __ndk_info,WARNING: Invalid LOCAL_CPP_EXTENSION values: $(bad_cpp_extensions)) + LOCAL_CPP_EXTENSION := $(filter $(bad_cpp_extensions),$(LOCAL_CPP_EXTENSIONS)) +endif +LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION)) +ifeq ($(LOCAL_CPP_EXTENSION),) + # Match the default GCC C++ extensions. + LOCAL_CPP_EXTENSION := $(default-c++-extensions) +endif + +include $(BUILD_SYSTEM)/stl.mk + +# +# If LOCAL_ALLOW_UNDEFINED_SYMBOLS is not true, the linker will allow the generation +# of a binary that uses undefined symbols. +# +ifneq ($(LOCAL_ALLOW_UNDEFINED_SYMBOLS),true) + LOCAL_LDFLAGS += $(TARGET_NO_UNDEFINED_LDFLAGS) +endif + +# We enable fatal linker warnings by default. +# If LOCAL_DISABLE_FATAL_LINKER_WARNINGS is true, we don't enable this check. +ifneq ($(LOCAL_DISABLE_FATAL_LINKER_WARNINGS),true) + LOCAL_LDFLAGS += -Wl,--fatal-warnings +endif + +# By default, we protect against format string vulnerabilities +# If LOCAL_DISABLE_FORMAT_STRING_CHECKS is true, we disable the protections. +ifeq ($(LOCAL_DISABLE_FORMAT_STRING_CHECKS),true) + LOCAL_CFLAGS += $(TARGET_DISABLE_FORMAT_STRING_CFLAGS) +else + LOCAL_CFLAGS += $(TARGET_FORMAT_STRING_CFLAGS) +endif + +# Enable branch protection for arm64-v8a +LOCAL_BRANCH_PROTECTION := $(strip $(LOCAL_BRANCH_PROTECTION)) +ifdef LOCAL_BRANCH_PROTECTION + ifeq ($(TARGET_ARCH_ABI),arm64-v8a) + LOCAL_CFLAGS += -mbranch-protection=$(LOCAL_BRANCH_PROTECTION) + endif +endif + +# http://b.android.com/222239 +# http://b.android.com/220159 (internal http://b/31809417) +# x86 devices have stack alignment issues. +ifeq ($(TARGET_ARCH_ABI),x86) + ifneq (,$(call lt,$(APP_PLATFORM_LEVEL),24)) + LOCAL_CFLAGS += -mstackrealign + endif +endif + +ifneq ($(LOCAL_ALLOW_UNDEFINED_VERSION_SCRIPT_SYMBOLS),true) + LOCAL_LDFLAGS += -Wl,--no-undefined-version +endif + +# +# The original Android build system allows you to use the .arm prefix +# to a source file name to indicate that it should be defined in either +# 'thumb' or 'arm' mode, depending on the value of LOCAL_ARM_MODE +# +# First, check LOCAL_ARM_MODE, it should be empty, 'thumb' or 'arm' +# We make the default 'thumb' +# +LOCAL_ARM_MODE := $(strip $(LOCAL_ARM_MODE)) +ifdef LOCAL_ARM_MODE + ifneq ($(words $(LOCAL_ARM_MODE)),1) + $(call __ndk_info, LOCAL_ARM_MODE in $(LOCAL_MAKEFILE) must be one word, not '$(LOCAL_ARM_MODE)') + $(call __ndk_error, Aborting) + endif + # check that LOCAL_ARM_MODE is defined to either 'arm' or 'thumb' + $(if $(filter-out thumb arm, $(LOCAL_ARM_MODE)),\ + $(call __ndk_info, LOCAL_ARM_MODE must be defined to either 'arm' or 'thumb' in $(LOCAL_MAKEFILE) not '$(LOCAL_ARM_MODE)')\ + $(call __ndk_error, Aborting)\ + ) + my_link_arm_mode := $(LOCAL_ARM_MODE) +else + my_link_arm_mode := thumb +endif + +# As a special case, the original Android build system +# allows one to specify that certain source files can be +# forced to build in ARM mode by using a '.arm' suffix +# after the extension, e.g. +# +# LOCAL_SRC_FILES := foo.c.arm +# +# to build source file $(LOCAL_PATH)/foo.c as ARM +# + +$(call clear-all-src-tags) + +# Historically the NDK supported both Neon and non-Neon as variants of the +# armeabi-v7a ABI. These were practically two ABIs but the distinction was not +# official (APKs did not have separate libraries for Neon and non-Neon devices). +# As of NDK r24 non-Neon devices are no longer supported, so any options opting +# *in* to Neon are ignored, and options explicitly opting out of Neon are an +# error. Users that choose a non-Neon -mfpu in their CFLAGS will receive no +# diagnostic. + +LOCAL_ARM_NEON := $(strip $(LOCAL_ARM_NEON)) + +ifeq ($(LOCAL_ARM_NEON),false) + $(call __ndk_error,Building non-Neon code is no longer supported.) +endif + +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:%.neon=%) + +# strip the .arm suffix from LOCAL_SRC_FILES +# and tag the relevant sources with the 'arm' tag +# +arm_sources := $(filter %.arm,$(LOCAL_SRC_FILES)) +arm_sources := $(arm_sources:%.arm=%) +thumb_sources := $(filter-out %.arm,$(LOCAL_SRC_FILES)) +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:%.arm=%) + +ifeq ($(LOCAL_ARM_MODE),arm) + arm_sources := $(LOCAL_SRC_FILES) + # tag the precompiled header with 'arm' tag if it exists + ifneq (,$(LOCAL_PCH)) + $(call tag-src-files,$(LOCAL_PCH),arm) + endif +endif +ifeq ($(LOCAL_ARM_MODE),thumb) + arm_sources := $(empty) +endif +$(call tag-src-files,$(arm_sources),arm) + +# tag debug if APP_OPTIM is 'debug' +# +ifeq ($(APP_OPTIM),debug) + $(call tag-src-files,$(LOCAL_SRC_FILES),debug) + ifneq (,$(LOCAL_PCH)) + $(call tag-src-files,$(LOCAL_PCH),debug) + endif +endif + +# add PCH to LOCAL_SRC_FILES so that TARGET-process-src-files-tags could process it +ifneq (,$(LOCAL_PCH)) + LOCAL_SRC_FILES += $(LOCAL_PCH) +endif + +# Process all source file tags to determine toolchain-specific +# target compiler flags, and text. +# +$(call TARGET-process-src-files-tags) + +# now remove PCH from LOCAL_SRC_FILES to prevent getting NDK warning about +# unsupported source file extensions +ifneq (,$(LOCAL_PCH)) + LOCAL_SRC_FILES := $(filter-out $(LOCAL_PCH),$(LOCAL_SRC_FILES)) +endif + +# only call dump-src-file-tags during debugging +#$(dump-src-file-tags) + +LOCAL_DEPENDENCY_DIRS := + +# all_source_patterns contains the list of filename patterns that correspond +# to source files recognized by our build system +ifneq ($(filter x86 x86_64, $(TARGET_ARCH_ABI)),) +all_source_extensions := .c .s .S .asm $(LOCAL_CPP_EXTENSION) +else +all_source_extensions := .c .s .S $(LOCAL_CPP_EXTENSION) +endif +all_source_patterns := $(foreach _ext,$(all_source_extensions),%$(_ext)) +all_cpp_patterns := $(foreach _ext,$(LOCAL_CPP_EXTENSION),%$(_ext)) + +unknown_sources := $(strip $(filter-out $(all_source_patterns),$(LOCAL_SRC_FILES))) +ifdef unknown_sources + $(call __ndk_info,WARNING: Unsupported source file extensions in $(LOCAL_MAKEFILE) for module $(LOCAL_MODULE)) + $(call __ndk_info, $(unknown_sources)) +endif + +# LOCAL_OBJECTS will list all object files corresponding to the sources +# listed in LOCAL_SRC_FILES, in the *same* order. +# +LOCAL_OBJECTS := $(LOCAL_SRC_FILES) +$(foreach _ext,$(all_source_extensions),\ + $(eval LOCAL_OBJECTS := $$(LOCAL_OBJECTS:%$(_ext)=%$$(TARGET_OBJ_EXTENSION)))\ +) +LOCAL_OBJECTS := $(filter %$(TARGET_OBJ_EXTENSION),$(LOCAL_OBJECTS)) +LOCAL_OBJECTS := $(subst ../,__/,$(LOCAL_OBJECTS)) +LOCAL_OBJECTS := $(subst :,_,$(LOCAL_OBJECTS)) +LOCAL_OBJECTS := $(foreach _obj,$(LOCAL_OBJECTS),$(LOCAL_OBJS_DIR)/$(_obj)) + +# If the module has any kind of C++ features, enable them in LOCAL_CPPFLAGS +# +ifneq (,$(call module-has-c++-features,$(LOCAL_MODULE),rtti)) + LOCAL_CPPFLAGS += -frtti +endif +ifneq (,$(call module-has-c++-features,$(LOCAL_MODULE),exceptions)) + LOCAL_CPPFLAGS += -fexceptions +endif + +# Build PCH + +get-pch-name = $(strip \ + $(subst ../,__/,\ + $(eval __pch := $1)\ + $(eval __pch := $(__pch:%.h=%.precompiled.h))\ + $(__pch)\ + )) + +ifneq (,$(LOCAL_PCH)) + # Build PCH into obj directory + LOCAL_BUILT_PCH := $(call get-pch-name,$(LOCAL_PCH)) + + # Clang whines about a "c-header" (.h rather than .hpp) being used in C++ + # mode (note that we use compile-cpp-source to build the header). + LOCAL_SRC_FILES_TARGET_CFLAGS.$(LOCAL_PCH) += -x c++-header + + # Build PCH + $(call compile-cpp-source,$(LOCAL_PCH),$(LOCAL_BUILT_PCH).gch) + + # The PCH must be compiled the same way as the sources (thumb vs arm must + # match). This means that we'd have to generate a PCH for both foo.c and + # foo.c.arm. + # + # Since files with those source tags should be the minority, precompiling + # that header might be a net loss compared to just using it normally. As + # such, we only use the PCH for the default compilation mode for the module. + # + # See https://github.com/android-ndk/ndk/issues/14 + TAGS_TO_FILTER := + + # If we're building thumb, strip out .arm files. + ifneq (arm,$(LOCAL_ARM_MODE)) + TAGS_TO_FILTER += arm + endif + + # There is no .thumb. No need to filter them out if we're building ARM. + + allowed_src := $(foreach src,$(filter $(all_cpp_patterns),$(LOCAL_SRC_FILES)),\ + $(if $(filter $(TAGS_TO_FILTER),$(LOCAL_SRC_FILES_TAGS.$(src))),,$(src))\ + ) + # All files without tags depend on PCH + $(foreach src,$(allowed_src),\ + $(eval $(LOCAL_OBJS_DIR)/$(call get-object-name,$(src)) : $(LOCAL_OBJS_DIR)/$(LOCAL_BUILT_PCH).gch)\ + ) + # Make sure those files are built with PCH + $(call add-src-files-target-cflags,$(allowed_src),-Winvalid-pch -include $(LOCAL_OBJS_DIR)/$(LOCAL_BUILT_PCH)) + + # Insert PCH dir at beginning of include search path + LOCAL_C_INCLUDES := \ + $(LOCAL_OBJS_DIR) \ + $(LOCAL_C_INCLUDES) +endif + +# Build the sources to object files +# + +do_tidy := $(NDK_APP_CLANG_TIDY) +ifdef LOCAL_CLANG_TIDY + do_tidy := $(LOCAL_CLANG_TIDY) +endif + +ifeq ($(do_tidy),true) + $(foreach src,$(filter %.c,$(LOCAL_SRC_FILES)),\ + $(call clang-tidy-c,$(src),$(call get-object-name,$(src)))) + $(foreach src,$(filter $(all_cpp_patterns),$(LOCAL_SRC_FILES)),\ + $(call clang-tidy-cpp,$(src),$(call get-object-name,$(src)))) +endif + +$(foreach src,$(filter %.c,$(LOCAL_SRC_FILES)), $(call compile-c-source,$(src),$(call get-object-name,$(src)))) +$(foreach src,$(filter %.S %.s,$(LOCAL_SRC_FILES)), $(call compile-s-source,$(src),$(call get-object-name,$(src)))) +$(foreach src,$(filter $(all_cpp_patterns),$(LOCAL_SRC_FILES)),\ + $(call compile-cpp-source,$(src),$(call get-object-name,$(src)))\ +) + +ifneq ($(filter x86 x86_64, $(TARGET_ARCH_ABI)),) +$(foreach src,$(filter %.asm,$(LOCAL_SRC_FILES)), $(call compile-asm-source,$(src),$(call get-object-name,$(src)))) +endif + +# +# The compile-xxx-source calls updated LOCAL_OBJECTS and LOCAL_DEPENDENCY_DIRS +# +ALL_DEPENDENCY_DIRS += $(sort $(LOCAL_DEPENDENCY_DIRS)) +CLEAN_OBJS_DIRS += $(LOCAL_OBJS_DIR) + +# +# Handle the static and shared libraries this module depends on +# + +# https://github.com/android/ndk/issues/885 +# If we're using LLD we need to use a slower build-id algorithm to work around +# the old version of LLDB in Android Studio, which doesn't understand LLD's +# default hash ("fast"). +linker_ldflags := -Wl,--build-id=sha1 + +ifneq (,$(call lt,$(APP_PLATFORM_LEVEL),30)) + # https://github.com/android/ndk/issues/1196 + # https://github.com/android/ndk/issues/1589 + linker_ldflags += -Wl,--no-rosegment +endif + +my_ldflags := $(TARGET_LDFLAGS) $(linker_ldflags) $(NDK_APP_LDFLAGS) $(LOCAL_LDFLAGS) + +# https://github.com/android/ndk/issues/1390 +# Only a warning rather than an error because the API level cannot be configured +# on a per-module basis. If the user has an APP_PLATFORM that happens to be able +# to build the static executables there's no need to fail the build. +ifneq (,$(filter -static,$(my_ldflags))) + ifneq ($(APP_PLATFORM),$(NDK_MAX_PLATFORM)) + $(call __ndk_info,WARNING: Building static executable but APP_PLATFORM \ + $(APP_PLATFORM) is not the latest API level $(NDK_MAX_PLATFORM). \ + Build may not succeed.) + endif +endif + +# When LOCAL_SHORT_COMMANDS is defined to 'true' we are going to write the +# list of all object files and/or static/shared libraries that appear on the +# command line to a file, then use the @ syntax to invoke it. +# +# This allows us to link or archive a huge number of stuff even on Windows +# with its puny 8192 max character limit on its command-line. +# +LOCAL_SHORT_COMMANDS := $(strip $(LOCAL_SHORT_COMMANDS)) +ifndef LOCAL_SHORT_COMMANDS + LOCAL_SHORT_COMMANDS := $(strip $(NDK_APP_SHORT_COMMANDS)) +endif + +$(call generate-file-dir,$(LOCAL_BUILT_MODULE)) + +$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS := $(LOCAL_OBJECTS) +$(LOCAL_BUILT_MODULE): PRIVATE_LIBATOMIC := $(TARGET_LIBATOMIC) + +$(LOCAL_BUILT_MODULE): PRIVATE_LD := $(TARGET_LD) +$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(my_ldflags) +$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS := $(LOCAL_LDLIBS) $(TARGET_LDLIBS) + +$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE)) +$(LOCAL_BUILT_MODULE): PRIVATE_CXX := $(TARGET_CXX) +$(LOCAL_BUILT_MODULE): PRIVATE_CC := $(TARGET_CC) +$(LOCAL_BUILT_MODULE): PRIVATE_SYSROOT_API_LIB_DIR := $(SYSROOT_API_LIB_DIR) + +ifeq (,$(call module_needs_clangxx,$(LOCAL_MODULE))) +$(LOCAL_BUILT_MODULE): PRIVATE_LD_DRIVER := $(TARGET_CC) +else +$(LOCAL_BUILT_MODULE): PRIVATE_LD_DRIVER := $(TARGET_CXX) +endif + +ifeq ($(call module-get-class,$(LOCAL_MODULE)),STATIC_LIBRARY) + +# +# This is a static library module, things are very easy. We only need +# to build the object files and archive them with 'ar'. Note that module +# dependencies can be ignored here, i.e. if the module depends on other +# static or shared libraries, there is no need to actually build them +# before, so don't add Make dependencies to them. +# +# In other words, consider the following graph: +# +# libfoo.so -> libA.a ->libB.a +# +# then libA.a and libB.a can be built in parallel, only linking libfoo.so +# depends on their completion. +# + +ar_objects := $(call host-path,$(LOCAL_OBJECTS)) + +ifeq ($(LOCAL_SHORT_COMMANDS),true) + $(call ndk_log,Building static library module '$(LOCAL_MODULE)' with linker list file) + ar_list_file := $(LOCAL_OBJS_DIR)/archiver.list + $(call generate-list-file,\ + $(call escape-backslashes,$(ar_objects)),$(ar_list_file)) + ar_objects := @$(call host-path,$(ar_list_file)) + $(LOCAL_BUILT_MODULE): $(ar_list_file) +endif + +# Compute 'ar' flags. Thin archives simply require 'T' here. +ar_flags := $(TARGET_ARFLAGS) +ifeq (true,$(thin_archive)) + $(call ndk_log,$(TARGET_ARCH_ABI):Building static library '$(LOCAL_MODULE)' as thin archive) + ar_flags := $(ar_flags)T +endif + +$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI) +$(LOCAL_BUILT_MODULE): PRIVATE_AR := $(TARGET_AR) $(ar_flags) $(TARGET_AR_FLAGS) +$(LOCAL_BUILT_MODULE): PRIVATE_AR_OBJECTS := $(ar_objects) +$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_STATIC_LIB := $(cmd-build-static-library) + +$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS) + $(call host-echo-build-step,$(PRIVATE_ABI),StaticLibrary) "$(PRIVATE_NAME)" + $(hide) $(call host-rm,$@) + $(hide) $(PRIVATE_BUILD_STATIC_LIB) + +ALL_STATIC_LIBRARIES += $(LOCAL_BUILT_MODULE) + +endif + +ifneq (,$(filter SHARED_LIBRARY EXECUTABLE,$(call module-get-class,$(LOCAL_MODULE)))) + +# +# This is a shared library or an executable, so computing dependencies properly is +# crucial. The general rule to apply is the following: +# +# - collect the list of all static libraries that need to be part +# of the link, and in the right order. To do so, get the transitive +# closure of LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES +# and ensure they are ordered topologically. +# +# - collect the list of all shared libraries that need to be part of +# the link. This is the transitive closure of the list of +# LOCAL_SHARED_LIBRARIES for the module and all its dependent static +# libraries identified in the step above. Of course, need to be +# ordered topologically too. +# +# - add Make dependencies to ensure that all these libs are built +# before the module itself too. +# +# A few quick examples: +# +# main.exe -> libA.a -> libB.a -> libfoo.so -> libC.a +# +# static_libs(main.exe) = libA.a libB.a (i.e. no libC.a) +# shared_libs(main.exe) = libfoo.so +# static_libs(libfoo.so) = libC.a +# +# main.exe -> libA.a ---> libB.a +# | ^ +# v | +# libC.a ------ +# +# static_libs(main.exe) = libA.a libC.a libB.a +# (i.e. libB.a must appear after all libraries that depend on it). +# +all_libs := $(call module-get-link-libs,$(LOCAL_MODULE)) +shared_libs := $(call module-filter-shared-libraries,$(all_libs)) +static_libs := $(call module-filter-static-libraries,$(all_libs)) +whole_static_libs := $(call module-extract-whole-static-libs,$(LOCAL_MODULE),$(static_libs)) +static_libs := $(filter-out $(whole_static_libs),$(static_libs)) +all_defined_libs := $(shared_libs) $(static_libs) $(whole_static_libs) +undefined_libs := $(filter-out $(all_defined_libs),$(all_libs)) + +ifdef undefined_libs + $(call __ndk_warning,Module $(LOCAL_MODULE) depends on undefined modules: $(undefined_libs)) + + # https://github.com/android-ndk/ndk/issues/208 + # ndk-build didn't used to fail the build for a missing dependency. This + # seems to have always been the behavior, so there's a good chance that + # there are builds out there that depend on this behavior (as of right now, + # anything using libc++ on ARM has this problem because of libunwind). + # + # By default we will abort in this situation because this is so completely + # broken. A user may define APP_ALLOW_MISSING_DEPS to "true" in their + # Application.mk or on the command line to revert to the old, broken + # behavior. + ifneq ($(APP_ALLOW_MISSING_DEPS),true) + $(call __ndk_error,Note that old versions of ndk-build silently ignored \ + this error case. If your project worked on those versions$(comma) \ + the missing libraries were not needed and you can remove those \ + dependencies from the module to fix your build. \ + Alternatively$(comma) set APP_ALLOW_MISSING_DEPS=true to allow \ + missing dependencies.) + $(call __ndk_error,Aborting.) + endif +endif + +$(call -ndk-mod-debug,module $(LOCAL_MODULE) [$(LOCAL_BUILT_MODULE)]) +$(call -ndk-mod-debug,. all_libs='$(all_libs)') +$(call -ndk-mod-debug,. shared_libs='$(shared_libs)') +$(call -ndk-mod-debug,. static_libs='$(static_libs)') +$(call -ndk-mod-debug,. whole_static_libs='$(whole_static_libs)') + +shared_libs := $(call map,module-get-built,$(shared_libs)) +static_libs := $(call map,module-get-built,$(static_libs)) +whole_static_libs := $(call map,module-get-built,$(whole_static_libs)) + +$(call -ndk-mod-debug,. built_shared_libs='$(shared_libs)') +$(call -ndk-mod-debug,. built_static_libs='$(static_libs)') +$(call -ndk-mod-debug,. built_whole_static_libs='$(whole_static_libs)') + +# The list of object/static/shared libraries passed to the linker when +# building shared libraries and executables. order is important. +linker_objects_and_libraries = $(strip $(call TARGET-get-linker-objects-and-libraries,\ + $(LOCAL_OBJECTS), \ + $(static_libs), \ + $(whole_static_libs), \ + $(shared_libs))) + +ifeq ($(LOCAL_SHORT_COMMANDS),true) + $(call ndk_log,Building ELF binary module '$(LOCAL_MODULE)' with linker list file) + linker_options := $(linker_objects_and_libraries) + linker_list_file := $(LOCAL_OBJS_DIR)/linker.list + linker_objects_and_libraries := @$(call host-path,$(linker_list_file)) + $(call generate-list-file,\ + $(call escape-backslashes,$(linker_options)),$(linker_list_file)) + $(LOCAL_BUILT_MODULE): $(linker_list_file) +endif + +$(LOCAL_BUILT_MODULE): $(shared_libs) $(static_libs) $(whole_static_libs) +$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI) +$(LOCAL_BUILT_MODULE): PRIVATE_LINKER_OBJECTS_AND_LIBRARIES := $(linker_objects_and_libraries) +$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libs) +$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(whole_static_libs) +$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libs) + +endif + +# +# If this is a shared library module +# +ifeq ($(call module-get-class,$(LOCAL_MODULE)),SHARED_LIBRARY) +$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_SHARED_LIB := $(cmd-build-shared-library) +$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS) + $(call host-echo-build-step,$(PRIVATE_ABI),SharedLibrary) "$(PRIVATE_NAME)" + $(hide) $(PRIVATE_BUILD_SHARED_LIB) + +ALL_SHARED_LIBRARIES += $(LOCAL_BUILT_MODULE) +endif + +# +# If this is an executable module +# +ifeq ($(call module-get-class,$(LOCAL_MODULE)),EXECUTABLE) +$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI) +$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_EXECUTABLE := $(cmd-build-executable) +$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS) + $(call host-echo-build-step,$(PRIVATE_ABI),Executable) "$(PRIVATE_NAME)" + $(hide) $(PRIVATE_BUILD_EXECUTABLE) + +ALL_EXECUTABLES += $(LOCAL_BUILT_MODULE) +endif + +# +# If this is a copyable prebuilt module +# +ifeq ($(call module-is-copyable,$(LOCAL_MODULE)),$(true)) +$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS) + $(call host-echo-build-step,$(PRIVATE_ABI),Prebuilt) "$(PRIVATE_NAME) <= $(call pretty-dir,$(dir $<))" + $(hide) $(call host-cp,$<,$@) +endif + +ifeq ($(LOCAL_STRIP_MODE),) + NDK_STRIP_MODE := $(NDK_APP_STRIP_MODE) +else + NDK_STRIP_MODE := $(LOCAL_STRIP_MODE) +endif + +# +# If this is an installable module +# +ifeq ($(call module-is-installable,$(LOCAL_MODULE)),$(true)) +$(LOCAL_INSTALLED): PRIVATE_ABI := $(TARGET_ARCH_ABI) +$(LOCAL_INSTALLED): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE)) +$(LOCAL_INSTALLED): PRIVATE_SRC := $(LOCAL_BUILT_MODULE) +$(LOCAL_INSTALLED): PRIVATE_DST_DIR := $(NDK_APP_DST_DIR) +$(LOCAL_INSTALLED): PRIVATE_DST := $(LOCAL_INSTALLED) +$(LOCAL_INSTALLED): PRIVATE_STRIP := $(TARGET_STRIP) +$(LOCAL_INSTALLED): PRIVATE_STRIP_MODE := $(NDK_STRIP_MODE) +$(LOCAL_INSTALLED): PRIVATE_STRIP_CMD := $(call cmd-strip, $(PRIVATE_DST)) + +$(LOCAL_INSTALLED): $(LOCAL_BUILT_MODULE) clean-installed-binaries + $(call host-echo-build-step,$(PRIVATE_ABI),Install) "$(PRIVATE_NAME) => $(call pretty-dir,$(PRIVATE_DST))" + $(hide) $(call host-install,$(PRIVATE_SRC),$(PRIVATE_DST)) + $(if $(filter none,$(PRIVATE_STRIP_MODE)),,$(hide) $(PRIVATE_STRIP_CMD)) + +$(call generate-file-dir,$(LOCAL_INSTALLED)) + +endif diff --git a/Android/android-ndk-r27d/build/core/build-executable.mk b/Android/android-ndk-r27d/build/core/build-executable.mk new file mode 100644 index 0000000..4647db8 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-executable.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2009 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 file is included from Android.mk files to build a target-specific +# executable program +# + +LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE +LOCAL_MAKEFILE := $(local-makefile) + +$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT)) +$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) +$(call check-LOCAL_MODULE_FILENAME) + +$(call handle-module-filename,,) +$(call handle-module-built) + +LOCAL_MODULE_CLASS := EXECUTABLE +include $(BUILD_SYSTEM)/build-module.mk diff --git a/Android/android-ndk-r27d/build/core/build-local.mk b/Android/android-ndk-r27d/build/core/build-local.mk new file mode 100644 index 0000000..32423f4 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-local.mk @@ -0,0 +1,225 @@ +# Copyright (C) 2010 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 file is designed to be called from the 'ndk-build' script +# or similar wrapper tool. +# + +# Detect the NDK installation path by processing this Makefile's location. +# This assumes we are located under $NDK_ROOT/build/core/main.mk +# + +# Don't output to stdout if we're being invoked to dump a variable +DUMP_VAR := $(patsubst DUMP_%,%,$(filter DUMP_%,$(MAKECMDGOALS))) +ifneq (,$(DUMP_VAR)) + NDK_NO_INFO := 1 + NDK_NO_WARNINGS := 1 +endif + +NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST))) +NDK_ROOT := $(subst \,/,$(NDK_ROOT)) +NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%)) +NDK_ROOT := $(NDK_ROOT:%/=%) +ifeq ($(NDK_ROOT),) + # for the case when we're invoked from the NDK install path + NDK_ROOT := . +endif +ifeq ($(NDK_LOG),1) + $(info Android NDK: NDK installation path auto-detected: '$(NDK_ROOT)') +endif +ifneq ($(words $(NDK_ROOT)),1) + $(info Android NDK: Your NDK installation path contains spaces.) + $(info Android NDK: Please re-install to a different location to fix the issue !) + $(error Aborting.) +endif + +include $(NDK_ROOT)/build/core/init.mk + +# ==================================================================== +# +# If NDK_PROJECT_PATH is not defined, find the application's project +# path by looking at the manifest file in the current directory or +# any of its parents. If none is found, try again with 'jni/Android.mk' +# +# Note that we first look at the current directory to avoid using +# absolute NDK_PROJECT_PATH values. This reduces the length of all +# source, object and binary paths that are passed to build commands. +# +# It turns out that some people use ndk-build to generate static +# libraries without a full Android project tree. +# +# If NDK_PROJECT_PATH=null, ndk-build make no attempt to look for it, but does +# need the following variables depending on NDK_PROJECT_PATH to be explicitly +# specified (from the default, if any): +# +# NDK_OUT +# NDK_LIBS_OUT +# APP_BUILD_SCRIPT +# NDK_DEBUG (optional, default to 0) +# Other APP_* used to be in Application.mk +# +# This behavior may be useful in an integrated build system. +# +# ==================================================================== + +find-project-dir = $(strip $(call find-project-dir-inner,$(abspath $1),$2)) + +find-project-dir-inner = \ + $(eval __found_project_path := )\ + $(eval __find_project_path := $1)\ + $(eval __find_project_file := $2)\ + $(call find-project-dir-inner-2)\ + $(__found_project_path) + +find-project-dir-inner-2 = \ + $(call ndk_log,Looking for $(__find_project_file) in $(__find_project_path))\ + $(eval __find_project_manifest := $(strip $(wildcard $(__find_project_path)/$(__find_project_file))))\ + $(if $(__find_project_manifest),\ + $(call ndk_log, Found it !)\ + $(eval __found_project_path := $(__find_project_path))\ + ,\ + $(eval __find_project_parent := $(call parent-dir,$(__find_project_path)))\ + $(if $(__find_project_parent),\ + $(eval __find_project_path := $(__find_project_parent))\ + $(call find-project-dir-inner-2)\ + )\ + ) + +NDK_PROJECT_PATH := $(strip $(NDK_PROJECT_PATH)) +APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH)) + +ifneq (,$(APP_PROJECT_PATH)) + ifeq (,$(NDK_PROJECT_PATH)) + # If NDK_PROJECT_PATH isn't set and APP_PROJECT_PATH is present, use APP_PROJECT_PATH + $(call ndk_log,Use APP_PROJECT_PATH for NDK_PROJECT_PATH: $(APP_PROJECT_PATH)) + NDK_PROJECT_PATH := $(APP_PROJECT_PATH) + else + # If both NDK_PROJECT_PATH and APP_PROJECT_PATH are present, check consistency + ifneq ($(NDK_PROJECT_PATH),$(APP_PROJECT_PATH)) + $(call __ndk_info,WARNING: NDK_PROJECT_PATH and APP_PROJECT_PATH are both set but not equal literally) + $(call __ndk_info, NDK_PROJECT_PATH = $(NDK_PROJECT_PATH)) + $(call __ndk_info, APP_PROJECT_PATH = $(APP_PROJECT_PATH)) + endif + endif +endif + +ifeq (null,$(NDK_PROJECT_PATH)) + +$(call ndk_log,Make no attempt to look for NDK_PROJECT_PATH.) + +else + +# To keep paths as short as possible during the build, we first look if the +# current directory is the top of our project path. If this is the case, we +# will define NDK_PROJECT_PATH to simply '.' +# +# Otherwise, we will use find-project-dir which will first get the absolute +# path of the current directory the climb back the hierarchy until we find +# something. The result will always be a much longer definition for +# NDK_PROJECT_PATH +# +ifndef NDK_PROJECT_PATH + ifneq (,$(strip $(wildcard AndroidManifest.xml))) + NDK_PROJECT_PATH := . + else + ifneq (,$(strip $(wildcard jni/Android.mk))) + NDK_PROJECT_PATH := . + endif + endif +endif +ifndef NDK_PROJECT_PATH + NDK_PROJECT_PATH := $(call find-project-dir,.,jni/Android.mk) +endif +ifndef NDK_PROJECT_PATH + NDK_PROJECT_PATH := $(call find-project-dir,.,AndroidManifest.xml) +endif +ifndef NDK_PROJECT_PATH + $(call __ndk_info,Could not find application project directory !) + $(call __ndk_info,Please define the NDK_PROJECT_PATH variable to point to it.) + $(call __ndk_error,Aborting) +endif + +# Check that there are no spaces in the project path, or bad things will happen +ifneq ($(words $(NDK_PROJECT_PATH)),1) + $(call __ndk_info,Your Android application project path contains spaces: '$(NDK_PROJECT_PATH)') + $(call __ndk_info,The Android NDK build cannot work here. Please move your project to a different location.) + $(call __ndk_error,Aborting.) +endif + +$(call ndk_log,Found project path: $(NDK_PROJECT_PATH)) + +NDK_APPLICATION_MK := $(strip $(wildcard $(NDK_PROJECT_PATH)/jni/Application.mk)) + +endif # NDK_PROJECT_PATH == null + +ifndef NDK_APPLICATION_MK + NDK_APPLICATION_MK := $(NDK_ROOT)/build/core/default-application.mk +endif + + +# Place all generated intermediate files here +NDK_APP_OUT := $(strip $(NDK_OUT)) +ifndef NDK_APP_OUT + ifeq (null,$(NDK_PROJECT_PATH)) + $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_OUT to directory for all generated intermediate files.) + $(call __ndk_error,Aborting.) + endif + NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj +endif +$(call ndk_log,Ouput path for intermediate files: $(NDK_APP_OUT)) + +# Place all generated library files here. This is rarely changed since aapt expects the default libs/ +NDK_APP_LIBS_OUT := $(strip $(NDK_LIBS_OUT)) +ifndef NDK_APP_LIBS_OUT + ifeq (null,$(NDK_PROJECT_PATH)) + $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set NDK_LIBS_OUT to directory for generated library files.) + $(call __ndk_error,Aborting.) + endif + NDK_APP_LIBS_OUT := $(NDK_PROJECT_PATH)/libs +endif +$(call ndk_log,Ouput path for generated library files: $(NDK_APP_LIBS_OUT)) + +# Fake an application named 'local' +_app := local +_application_mk := $(NDK_APPLICATION_MK) +NDK_APPS := $(_app) + +include $(BUILD_SYSTEM)/add-application.mk + +# If a goal is DUMP_xxx then we dump a variable xxx instead +# of building anything +# +MAKECMDGOALS := $(filter-out DUMP_$(DUMP_VAR),$(MAKECMDGOALS)) + +include $(BUILD_SYSTEM)/setup-imports.mk + +ifneq (,$(DUMP_VAR)) + +# We only support a single DUMP_XXX goal at a time for now. +ifneq ($(words $(DUMP_VAR)),1) + $(call __ndk_error,!!TOO-MANY-DUMP-VARIABLES!!) +endif + +$(foreach _app,$(NDK_APPS),\ + $(eval include $(BUILD_SYSTEM)/setup-app.mk)\ +) + +.PHONY : DUMP_$(DUMP_VAR) +DUMP_$(DUMP_VAR): + @echo $($(DUMP_VAR)) +else + # Build it + include $(BUILD_SYSTEM)/build-all.mk +endif diff --git a/Android/android-ndk-r27d/build/core/build-module.mk b/Android/android-ndk-r27d/build/core/build-module.mk new file mode 100644 index 0000000..323c05c --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-module.mk @@ -0,0 +1,46 @@ +# Copyright (C) 2010 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. +# + +$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT)) +$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) + +# This file is used to record the LOCAL_XXX definitions of a given +# module. It is included by BUILD_STATIC_LIBRARY, BUILD_SHARED_LIBRARY +# and others. +# +LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS)) +ifndef LOCAL_MODULE_CLASS +$(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_CLASS definition is missing !) +$(call __ndk_error,Aborting) +endif + +$(if $(call module-class-check,$(LOCAL_MODULE_CLASS)),,\ +$(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): Unknown LOCAL_MODULE_CLASS value: $(LOCAL_MODULE_CLASS))\ +$(call __ndk_error,Aborting)\ +) + +$(call module-add,$(LOCAL_MODULE)) + +# Eval sucks. It's not possible to preserve even properly escaped # characters +# as far as I can tell, and we need that for -Werror=#warnings. Manually stash +# all the flags variations so we can preserve these. +__ndk_modules.$(LOCAL_MODULE).ASFLAGS := $(LOCAL_ASFLAGS) +__ndk_modules.$(LOCAL_MODULE).ASMFLAGS := $(LOCAL_ASMFLAGS) +__ndk_modules.$(LOCAL_MODULE).CFLAGS := $(LOCAL_CFLAGS) +__ndk_modules.$(LOCAL_MODULE).CLANG_TIDY_FLAGS := $(LOCAL_CLANG_TIDY_FLAGS) +__ndk_modules.$(LOCAL_MODULE).CONLYFLAGS := $(LOCAL_CONLYFLAGS) +__ndk_modules.$(LOCAL_MODULE).CPPFLAGS := $(LOCAL_CPPFLAGS) +__ndk_modules.$(LOCAL_MODULE).CXXFLAGS := $(LOCAL_CXXFLAGS) +__ndk_modules.$(LOCAL_MODULE).LDFLAGS := $(LOCAL_LDFLAGS) diff --git a/Android/android-ndk-r27d/build/core/build-shared-library.mk b/Android/android-ndk-r27d/build/core/build-shared-library.mk new file mode 100644 index 0000000..9731ce4 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-shared-library.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2009 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 file is included from Android.mk files to build a target-specific +# shared library +# + +LOCAL_BUILD_SCRIPT := BUILD_SHARED_LIBRARY +LOCAL_MAKEFILE := $(local-makefile) + +$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT)) +$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) +$(call check-LOCAL_MODULE_FILENAME) + +$(call handle-module-filename,lib,$(TARGET_SONAME_EXTENSION)) +$(call handle-module-built) + +LOCAL_MODULE_CLASS := SHARED_LIBRARY +include $(BUILD_SYSTEM)/build-module.mk diff --git a/Android/android-ndk-r27d/build/core/build-static-library.mk b/Android/android-ndk-r27d/build/core/build-static-library.mk new file mode 100644 index 0000000..21b5897 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/build-static-library.mk @@ -0,0 +1,31 @@ +# Copyright (C) 2009 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 file is included from Android.mk files to build a target-specific +# static library +# + +LOCAL_BUILD_SCRIPT := BUILD_STATIC_LIBRARY +LOCAL_MAKEFILE := $(local-makefile) + +$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT)) +$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) + +$(call handle-module-filename,lib,$(TARGET_LIB_EXTENSION)) +$(call handle-module-built) + +LOCAL_MODULE_CLASS := STATIC_LIBRARY +include $(BUILD_SYSTEM)/build-module.mk + diff --git a/Android/android-ndk-r27d/build/core/check-cygwin-make.mk b/Android/android-ndk-r27d/build/core/check-cygwin-make.mk new file mode 100644 index 0000000..27bc227 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/check-cygwin-make.mk @@ -0,0 +1,43 @@ +# Copyright (C) 2010 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. +# + +# Check that we have a Cygwin-compatible make. +# +# For some reason, a lot of application developers on Windows +# have another GNU Make installed in their path, that fails +# miserably with our build scripts. If we can detect this use +# case, early, we will be able to dump a human-readable error +# message with some help to fix the issue. +# + +.PHONY: all +all: + +# Get the cygwin-specific path to the make executable +# (e.g. /cygdrive/c/cygwin/usr/bin/make), then strip the +# .exe suffix, if any. +# +CYGWIN_MAKE := $(shell cygpath --unix --absolute $(firstword $(MAKE))) +CYGWIN_MAKE := $(CYGWIN_MAKE:%.exe=%) + +# Now try to find it on the file system, a non-cygwin compatible +# GNU Make, even if launched from a Cygwin shell, will not +# +SELF_MAKE := $(strip $(wildcard $(CYGWIN_MAKE).exe)) +ifeq ($(SELF_MAKE),) + $(error Android NDK: $(firstword $(MAKE)) is not cygwin-compatible) +endif + +# that's all diff --git a/Android/android-ndk-r27d/build/core/clear-vars.mk b/Android/android-ndk-r27d/build/core/clear-vars.mk new file mode 100644 index 0000000..83c6e0e --- /dev/null +++ b/Android/android-ndk-r27d/build/core/clear-vars.mk @@ -0,0 +1,23 @@ +# Copyright (C) 2009 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 file is included repeatedly from Android.mk files in order to clean +# the module-specific variables from the environment, + +# Note: As a special exception, we don't want to clear LOCAL_PATH +$(call clear-vars, $(filter-out LOCAL_PATH,$(modules-LOCALS:%=LOCAL_%))) + +# strip LOCAL_PATH +LOCAL_PATH := $(strip $(LOCAL_PATH)) diff --git a/Android/android-ndk-r27d/build/core/default-application.mk b/Android/android-ndk-r27d/build/core/default-application.mk new file mode 100644 index 0000000..81147b0 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/default-application.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2010 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 is the default Application.mk that is being used for applications +# that don't provide $PROJECT_PATH/jni/Application.mk +# +APP_PROJECT_PATH := $(NDK_PROJECT_PATH) + +# We expect the build script to be located here +ifndef APP_BUILD_SCRIPT + ifeq (null,$(NDK_PROJECT_PATH)) + $(call __ndk_info,NDK_PROJECT_PATH==null. Please explicitly set APP_BUILD_SCRIPT.) + $(call __ndk_error,Aborting.) + endif + APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/jni/Android.mk +endif \ No newline at end of file diff --git a/Android/android-ndk-r27d/build/core/default-build-commands.mk b/Android/android-ndk-r27d/build/core/default-build-commands.mk new file mode 100644 index 0000000..59c0592 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/default-build-commands.mk @@ -0,0 +1,155 @@ +# The following definitions are the defaults used by all toolchains. +# This is included in setup-toolchain.mk just before the inclusion +# of the toolchain's specific setup.mk file which can then override +# these definitions. +# + +# These flags are used to ensure that a binary doesn't reference undefined +# flags. +TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined + + +# Return the list of object, static libraries and shared libraries as they +# must appear on the final static linker command (order is important). +# +# This can be over-ridden by a specific toolchain. Note that by default +# we always put libgcc _after_ all static libraries and _before_ shared +# libraries. This ensures that any libgcc function used by the final +# executable will be copied into it. Otherwise, it could contain +# symbol references to the same symbols as exported by shared libraries +# and this causes binary compatibility problems when they come from +# system libraries (e.g. libc.so and others). +# +# IMPORTANT: The result must use the host path convention. +# +# $1: object files +# $2: static libraries +# $3: whole static libraries +# $4: shared libraries +# +TARGET-get-linker-objects-and-libraries = \ + $(call host-path, $1) \ + $(call link-whole-archives,$3) \ + $(call host-path, $2) \ + $(PRIVATE_LIBATOMIC) \ + $(call host-path, $4) \ + +# This flag are used to provide compiler protection against format +# string vulnerabilities. +TARGET_FORMAT_STRING_CFLAGS := -Wformat -Werror=format-security + +# This flag disables the above security checks +TARGET_DISABLE_FORMAT_STRING_CFLAGS := -Wno-error=format-security + +define cmd-build-shared-library +$(PRIVATE_LD_DRIVER) \ + -Wl,-soname,$(notdir $(LOCAL_BUILT_MODULE)) \ + -shared \ + $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \ + $(GLOBAL_LDFLAGS) \ + $(PRIVATE_LDFLAGS) \ + $(PRIVATE_LDLIBS) \ + -o $(call host-path,$(LOCAL_BUILT_MODULE)) +endef + +# The following -rpath-link= are needed for ld.bfd (default for ARM64) when +# linking executables to supress warning about missing symbol from libraries not +# directly needed. ld.gold (default for all other architectures) doesn't emulate +# this buggy behavior. +define cmd-build-executable +$(PRIVATE_LD_DRIVER) \ + -Wl,-rpath-link=$(call host-path,$(PRIVATE_SYSROOT_API_LIB_DIR)) \ + -Wl,-rpath-link=$(call host-path,$(TARGET_OUT)) \ + $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \ + $(GLOBAL_LDFLAGS) \ + $(PRIVATE_LDFLAGS) \ + $(PRIVATE_LDLIBS) \ + -o $(call host-path,$(LOCAL_BUILT_MODULE)) +endef + +define cmd-build-static-library +$(PRIVATE_AR) $(call host-path,$(LOCAL_BUILT_MODULE)) $(PRIVATE_AR_OBJECTS) +endef + +cmd-strip = $(PRIVATE_STRIP) $(PRIVATE_STRIP_MODE) $(call host-path,$1) + +# arm32 currently uses a linker script in place of libgcc to ensure that +# libunwind is linked in the correct order. --exclude-libs does not propagate to +# the contents of the linker script and can't be specified within the linker +# script. Hide both regardless of architecture to future-proof us in case we +# move other architectures to a linker script (which we may want to do so we +# automatically link libclangrt on other architectures). +TARGET_LIBATOMIC = -latomic +TARGET_LDLIBS := -lc -lm + +LLVM_TOOLCHAIN_PREFIX := $(TOOLCHAIN_ROOT)/bin/ + +# IMPORTANT: The following definitions must use lazy assignment because +# the value of TOOLCHAIN_NAME or TARGET_CFLAGS can be changed later by +# the toolchain's setup.mk script. +TOOLCHAIN_PREFIX = $(TOOLCHAIN_ROOT)/bin/$(TOOLCHAIN_NAME)- + +TARGET_CC = $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT) +TARGET_CXX = $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT) + +CLANG_TIDY = $(LLVM_TOOLCHAIN_PREFIX)clang-tidy$(HOST_EXEEXT) + +GLOBAL_CFLAGS = \ + -target $(LLVM_TRIPLE)$(TARGET_PLATFORM_LEVEL) \ + -fdata-sections \ + -ffunction-sections \ + -fstack-protector-strong \ + -funwind-tables \ + -no-canonical-prefixes \ + +# This is unnecessary given the new toolchain layout, but Studio will not +# recognize this as an Android build if there is no --sysroot flag. +# TODO: Teach Studio to recognize Android builds based on --target. +GLOBAL_CFLAGS += --sysroot $(call host-path,$(NDK_UNIFIED_SYSROOT_PATH)) + +# Always enable debug info. We strip binaries when needed. +GLOBAL_CFLAGS += -g + +# TODO: Remove. +GLOBAL_CFLAGS += \ + -Wno-invalid-command-line-argument \ + -Wno-unused-command-line-argument \ + +GLOBAL_CFLAGS += -D_FORTIFY_SOURCE=2 + + +ifeq ($(APP_WEAK_API_DEFS), true) + GLOBAL_CFLAGS += \ + -D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__ \ + -Werror=unguarded-availability \ + +endif + +GLOBAL_LDFLAGS = \ + -target $(LLVM_TRIPLE)$(TARGET_PLATFORM_LEVEL) \ + -no-canonical-prefixes \ + +ifeq ($(APP_OPTIM),release) + GLOBAL_LDFLAGS += -Wl,--gc-sections +endif + +GLOBAL_CXXFLAGS = $(GLOBAL_CFLAGS) -fno-exceptions -fno-rtti + +TARGET_CFLAGS = +TARGET_CONLYFLAGS = +TARGET_CXXFLAGS = $(TARGET_CFLAGS) + +TARGET_ASM = $(TOOLCHAIN_ROOT)/bin/yasm +TARGET_ASMFLAGS = + +TARGET_LD = $(TOOLCHAIN_ROOT)/bin/ld +TARGET_LDFLAGS := + +TARGET_AR = $(LLVM_TOOLCHAIN_PREFIX)llvm-ar$(HOST_EXEEXT) +TARGET_ARFLAGS := crsD + +TARGET_STRIP = $(LLVM_TOOLCHAIN_PREFIX)llvm-strip$(HOST_EXEEXT) + +TARGET_OBJ_EXTENSION := .o +TARGET_LIB_EXTENSION := .a +TARGET_SONAME_EXTENSION := .so diff --git a/Android/android-ndk-r27d/build/core/define-missing-prebuilt.mk b/Android/android-ndk-r27d/build/core/define-missing-prebuilt.mk new file mode 100644 index 0000000..30adbc4 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/define-missing-prebuilt.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2021 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. +# + +# https://github.com/android/ndk/issues/1559 +# +# When LOCAL_ALLOW_MISSING_PREBUILT is true we avoid checking for missing +# prebuilt libraries early and instead let the copy rule fail. This leads to a +# worse diagnostic but supports the use case where AGP runs `ndk-build -n` to +# get the build commands during sync time and the "pre" built library is +# actually built by another module that hasn't been built yet. +# +# This phony target is only generated when the library actually is missing (see +# the callsite in prebuilt-library.mk). +.PHONY: $(prebuilt) diff --git a/Android/android-ndk-r27d/build/core/definitions-graph.mk b/Android/android-ndk-r27d/build/core/definitions-graph.mk new file mode 100644 index 0000000..68e7fa9 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/definitions-graph.mk @@ -0,0 +1,538 @@ +# Copyright (C) 2012 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. +# +# Definitions of various graph-related generic functions, used by +# ndk-build internally. +# + +# Coding style note: +# +# All internal variables in this file begin with '_ndk_mod_' +# All internal functions in this file begin with '-ndk-mod-' +# + +# Set this to true if you want to debug the functions here. +_ndk_mod_debug := $(if $(NDK_DEBUG_MODULES),true) +_ndk_topo_debug := $(if $(NDK_DEBUG_TOPO),true) + +# Use $(call -ndk-mod-debug,) to print a debug message only +# if _ndk_mod_debug is set to 'true'. Useful for debugging the functions +# available here. +# +ifeq (true,$(_ndk_mod_debug)) +-ndk-mod-debug = $(info $1) +else +-ndk-mod-debug := $(empty) +endif + +ifeq (true,$(_ndk_topo_debug)) +-ndk-topo-debug = $(info $1) +else +-ndk-topo-debug = $(empty) +endif + +####################################################################### +# Filter a list of module with a predicate function +# $1: list of module names. +# $2: predicate function, will be called with $(call $2,), if the +# result is not empty, will be added to the result. +# Out: subset of input list, where each item passes the predicate. +####################################################################### +-ndk-mod-filter = $(strip \ + $(foreach _ndk_mod_filter_n,$1,\ + $(if $(call $2,$(_ndk_mod_filter_n)),$(_ndk_mod_filter_n))\ + )) + +-test-ndk-mod-filter = \ + $(eval -local-func = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call -ndk-mod-filter,,-local-func))\ + $(call test-expect,foo,$(call -ndk-mod-filter,foo,-local-func))\ + $(call test-expect,foo,$(call -ndk-mod-filter,foo bar,-local-func))\ + $(call test-expect,foo foo,$(call -ndk-mod-filter,aaa foo bar foo,-local-func))\ + $(eval -local-func = $$(call sne,foo,$$1))\ + $(call test-expect,,$(call -ndk-mod-filter,,-local-func))\ + $(call test-expect,,$(call -ndk-mod-filter,foo,-local-func))\ + $(call test-expect,bar,$(call -ndk-mod-filter,foo bar,-local-func))\ + $(call test-expect,aaa bar,$(call -ndk-mod-filter,aaa foo bar,-local-func)) + + +####################################################################### +# Filter out a list of modules with a predicate function +# $1: list of module names. +# $2: predicate function, will be called with $(call $2,), if the +# result is not empty, will be added to the result. +# Out: subset of input list, where each item doesn't pass the predicate. +####################################################################### +-ndk-mod-filter-out = $(strip \ + $(foreach _ndk_mod_filter_n,$1,\ + $(if $(call $2,$(_ndk_mod_filter_n)),,$(_ndk_mod_filter_n))\ + )) + +-test-ndk-mod-filter-out = \ + $(eval -local-func = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\ + $(call test-expect,,$(call -ndk-mod-filter-out,foo,-local-func))\ + $(call test-expect,bar,$(call -ndk-mod-filter-out,foo bar,-local-func))\ + $(call test-expect,aaa bar,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func))\ + $(eval -local-func = $$(call sne,foo,$$1))\ + $(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\ + $(call test-expect,foo,$(call -ndk-mod-filter-out,foo,-local-func))\ + $(call test-expect,foo,$(call -ndk-mod-filter-out,foo bar,-local-func))\ + $(call test-expect,foo foo,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func)) + + +####################################################################### +# Find the first item in a list that checks a valid predicate. +# $1: list of names. +# $2: predicate function, will be called with $(call $2,), if the +# result is not empty, will be added to the result. +# Out: subset of input list. +####################################################################### +-ndk-mod-find-first = $(firstword $(call -ndk-mod-filter,$1,$2)) + +-test-ndk-mod-find-first.empty = \ + $(eval -local-pred = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call -ndk-mod-find-first,,-local-pred))\ + $(call test-expect,,$(call -ndk-mod-find-first,bar,-local-pred)) + +-test-ndk-mod-find-first.simple = \ + $(eval -local-pred = $$(call seq,foo,$$1))\ + $(call test-expect,foo,$(call -ndk-mod-find-first,foo,-local-pred))\ + $(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo bar,-local-pred))\ + $(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo foo bar,-local-pred)) + +######################################################################## +# Many tree walking operations require setting a 'visited' flag on +# specific graph nodes. The following helper functions help implement +# this while hiding details to the callers. +# +# Technical note: +# _ndk_mod_tree_visited. will be 'true' if the node was visited, +# or empty otherwise. +# +# _ndk_mod_tree_visitors lists all visited nodes, used to clean all +# _ndk_mod_tree_visited. variables in -ndk-mod-tree-setup-visit. +# +####################################################################### + +# Call this before tree traversal. +-ndk-mod-tree-setup-visit = \ + $(foreach _ndk_mod_tree_visitor,$(_ndk_mod_tree_visitors),\ + $(eval _ndk_mod_tree_visited.$$(_ndk_mod_tree_visitor) :=))\ + $(eval _ndk_mod_tree_visitors :=) + +# Returns non-empty if a node was visited. +-ndk-mod-tree-is-visited = \ + $(_ndk_mod_tree_visited.$1) + +# Set the visited state of a node to 'true' +-ndk-mod-tree-set-visited = \ + $(eval _ndk_mod_tree_visited.$1 := true)\ + $(eval _ndk_mod_tree_visitors += $1) + +######################################################################## +# Many graph walking operations require a work queue and computing +# dependencies / children nodes. Here are a few helper functions that +# can be used to make their code clearer. This uses a few global +# variables that should be defined as follows during the operation: +# +# _ndk_mod_module current graph node name. +# _ndk_mod_wq current node work queue. +# _ndk_mod_list current result (list of nodes). +# _ndk_mod_depends current graph node's children. +# you must call -ndk-mod-get-depends to set this. +# +####################################################################### + +# Pop first item from work-queue into _ndk_mod_module. +-ndk-mod-pop-first = \ + $(eval _ndk_mod_module := $$(call first,$$(_ndk_mod_wq)))\ + $(eval _ndk_mod_wq := $$(call rest,$$(_ndk_mod_wq))) + +-test-ndk-mod-pop-first = \ + $(eval _ndk_mod_wq := A B C)\ + $(call -ndk-mod-pop-first)\ + $(call test-expect,A,$(_ndk_mod_module))\ + $(call test-expect,B C,$(_ndk_mod_wq))\ + + +# Push list of items at the back of the work-queue. +-ndk-mod-push-back = \ + $(eval _ndk_mod_wq := $(strip $(_ndk_mod_wq) $1)) + +-test-ndk-mod-push-back = \ + $(eval _ndk_mod_wq := A B C)\ + $(call -ndk-mod-push-back, D E)\ + $(call test-expect,A B C D E,$(_ndk_mod_wq)) + +# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module +-ndk-mod-get-depends = \ + $(eval _ndk_mod_depends := $$(call $$(_ndk_mod_deps_func),$$(_ndk_mod_module))) + +# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module that +# are not already in _ndk_mod_list. +-ndk-mod-get-new-depends = \ + $(call -ndk-mod-get-depends)\ + $(eval _ndk_mod_depends := $$(filter-out $$(_ndk_mod_list),$$(_ndk_mod_depends))) + +########################################################################## +# Compute the transitive closure +# $1: list of modules. +# $2: dependency function, $(call $2,) should return all the +# module that depends on. +# Out: transitive closure of all modules from those in $1. Always includes +# the modules in $1. Order is random. +# +# Implementation note: +# we use the -ndk-mod-tree-xxx functions to flag 'visited' nodes +# in the graph. A node is visited once it has been put into the work +# queue. For each item in the work queue, get the dependencies and +# append all those that were not visited yet. +####################################################################### +-ndk-mod-get-closure = $(strip \ + $(eval _ndk_mod_wq :=)\ + $(eval _ndk_mod_list :=)\ + $(eval _ndk_mod_deps_func := $2)\ + $(call -ndk-mod-tree-setup-visit)\ + $(foreach _ndk_mod_module,$1,\ + $(call -ndk-mod-closure-visit,$(_ndk_mod_module))\ + )\ + $(call -ndk-mod-closure-recursive)\ + $(eval _ndk_mod_deps :=)\ + $(_ndk_mod_list)\ + ) + +# Used internally to visit a new node during -ndk-mod-get-closure. +# This appends the node to the work queue, and set its 'visit' flag. +-ndk-mod-closure-visit = \ + $(call -ndk-mod-push-back,$1)\ + $(call -ndk-mod-tree-set-visited,$1) + +-ndk-mod-closure-recursive = \ + $(call -ndk-mod-pop-first)\ + $(eval _ndk_mod_list += $$(_ndk_mod_module))\ + $(call -ndk-mod-get-depends)\ + $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\ + $(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_dep)),,\ + $(call -ndk-mod-closure-visit,$(_ndk_mod_dep))\ + )\ + )\ + $(if $(_ndk_mod_wq),$(call -ndk-mod-closure-recursive)) + +-test-ndk-mod-get-closure.empty = \ + $(eval -local-deps = $$($$1_depends))\ + $(call test-expect,,$(call -ndk-mod-get-closure,,-local-deps)) + +-test-ndk-mod-get-closure.single = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends :=)\ + $(call test-expect,A,$(call -ndk-mod-get-closure,A,-local-deps)) + +-test-ndk-mod-get-closure.double = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends :=)\ + $(call test-expect,A B,$(call -ndk-mod-get-closure,A,-local-deps)) + +-test-ndk-mod-get-closure.circular-deps = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends := C)\ + $(eval C_depends := A)\ + $(call test-expect,A B C,$(call -ndk-mod-get-closure,A,-local-deps)) + +-test-ndk-mod-get-closure.ABCDE = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends := D)\ + $(eval C_depends := D E)\ + $(eval D_depends :=)\ + $(eval E_depends :=)\ + $(call test-expect,A B C D E,$(call -ndk-mod-get-closure,A,-local-deps)) + + +######################################################################### +# For topological sort, we need to count the number of incoming edges +# in each graph node. The following helper functions implement this and +# hide implementation details. +# +# Count the number of incoming edges for each node during topological +# sort with a string of xxxxs. I.e.: +# 0 edge -> '' +# 1 edge -> 'x' +# 2 edges -> 'xx' +# 3 edges -> 'xxx' +# etc. +######################################################################### + +# zero the incoming edge counter for module $1 +-ndk-mod-topo-zero-incoming = \ + $(eval _ndk_mod_topo_incoming.$1 :=) + +# increment the incoming edge counter for module $1 +-ndk-mod-topo-increment-incoming = \ + $(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1)x) + +# decrement the incoming edge counter for module $1 +-ndk-mod-topo-decrement-incoming = \ + $(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1:%x=%)) + +# return non-empty if the module $1's incoming edge counter is > 0 +-ndk-mod-topo-has-incoming = $(_ndk_mod_topo_incoming.$1) + +# Find first node in a list that has zero incoming edges. +# $1: list of nodes +# Out: first node that has zero incoming edges, or empty. +-ndk-mod-topo-find-first-zero-incoming = $(firstword $(call -ndk-mod-filter-out,$1,-ndk-mod-topo-has-incoming)) + +# Only use for debugging: +-ndk-mod-topo-dump-count = \ + $(foreach _ndk_mod_module,$1,\ + $(info .. $(_ndk_mod_module) incoming='$(_ndk_mod_topo_incoming.$(_ndk_mod_module))')) + + + +######################################################################### +# Return the topologically ordered closure of all nodes from a top-level +# one. This means that a node A, in the result, will always appear after +# node B if A depends on B. Assumes that the graph is a DAG (if there are +# circular dependencies, this property cannot be guaranteed, but at least +# the function should not loop infinitely). +# +# $1: top-level node name. +# $2: dependency function, i.e. $(call $2,) returns the children +# nodes for . +# Return: list of nodes, include $1, which will always be the first. +######################################################################### +-ndk-mod-get-topo-list = $(strip \ + $(eval _ndk_mod_top_module := $1)\ + $(eval _ndk_mod_deps_func := $2)\ + $(eval _ndk_mod_nodes := $(call -ndk-mod-get-closure,$1,$2))\ + $(call -ndk-mod-topo-count,$(_ndk_mod_nodes))\ + $(eval _ndk_mod_list :=)\ + $(eval _ndk_mod_wq := $(call -ndk-mod-topo-find-first-zero-incoming,$(_ndk_mod_nodes)))\ + $(call -ndk-mod-topo-sort)\ + $(_ndk_mod_list) $(_ndk_mod_nodes)\ + ) + +# Given a closure list of nodes, count their incoming edges. +# $1: list of nodes, must be a graph closure. +-ndk-mod-topo-count = \ + $(foreach _ndk_mod_module,$1,\ + $(call -ndk-mod-topo-zero-incoming,$(_ndk_mod_module)))\ + $(foreach _ndk_mod_module,$1,\ + $(call -ndk-mod-get-depends)\ + $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\ + $(call -ndk-mod-topo-increment-incoming,$(_ndk_mod_dep))\ + )\ + ) + +-ndk-mod-topo-sort = \ + $(call -ndk-topo-debug,-ndk-mod-topo-sort: wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)')\ + $(call -ndk-mod-pop-first)\ + $(if $(_ndk_mod_module),\ + $(eval _ndk_mod_list += $(_ndk_mod_module))\ + $(eval _ndk_mod_nodes := $(filter-out $(_ndk_mod_module),$(_ndk_mod_nodes)))\ + $(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_module))\ + $(call -ndk-mod-get-depends)\ + $(call -ndk-topo-debug,-ndk-mod-topo-sort: deps='$(_ndk_mod_depends)')\ + $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\ + $(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_dep))\ + $(if $(call -ndk-mod-topo-has-incoming,$(_ndk_mod_dep)),,\ + $(call -ndk-mod-push-back,$(_ndk_mod_dep))\ + )\ + )\ + $(call -ndk-mod-topo-sort)\ + ) + + +-test-ndk-mod-get-topo-list.empty = \ + $(eval -local-deps = $$($$1_depends))\ + $(call test-expect,,$(call -ndk-mod-get-topo-list,,-local-deps)) + +-test-ndk-mod-get-topo-list.single = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends :=)\ + $(call test-expect,A,$(call -ndk-mod-get-topo-list,A,-local-deps)) + +-test-ndk-mod-get-topo-list.no-infinite-loop = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends := C)\ + $(eval C_depends := A)\ + $(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps)) + +-test-ndk-mod-get-topo-list.ABC = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends :=)\ + $(eval C_depends := B)\ + $(call test-expect,A C B,$(call -ndk-mod-get-topo-list,A,-local-deps)) + +-test-ndk-mod-get-topo-list.ABCD = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends := D)\ + $(eval C_depends := B)\ + $(eval D_depends :=)\ + $(call test-expect,A C B D,$(call -ndk-mod-get-topo-list,A,-local-deps)) + +-test-ndk-mod-get-topo-list.ABC.circular = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends := C)\ + $(eval C_depends := B)\ + $(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps)) + +######################################################################### +# Return the topologically ordered closure of all dependencies from a +# top-level node. +# +# $1: top-level node name. +# $2: dependency function, i.e. $(call $2,) returns the children +# nodes for . +# Return: list of nodes, include $1, which will never be included. +######################################################################### +-ndk-mod-get-topological-depends = $(call rest,$(call -ndk-mod-get-topo-list,$1,$2)) + +-test-ndk-mod-get-topological-depends.simple = \ + $(eval -local-get-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends :=)\ + $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\ + $(call test-expect,B,$(topo_deps),topo dependencies) + +-test-ndk-mod-get-topological-depends.ABC = \ + $(eval -local-get-deps = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends :=)\ + $(eval C_depends := B)\ + $(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\ + $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\ + $(call test-expect,B C,$(bfs_deps),dfs dependencies)\ + $(call test-expect,C B,$(topo_deps),topo dependencies) + +-test-ndk-mod-get-topological-depends.circular = \ + $(eval -local-get-deps = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends := C)\ + $(eval C_depends := B)\ + $(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\ + $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\ + $(call test-expect,B C,$(bfs_deps),dfs dependencies)\ + $(call test-expect,B C,$(topo_deps),topo dependencies) + +######################################################################### +# Return breadth-first walk of a graph, starting from an arbitrary +# node. +# +# This performs a breadth-first walk of the graph and will return a +# list of nodes. Note that $1 will always be the first in the list. +# +# $1: root node name. +# $2: dependency function, i.e. $(call $2,) returns the nodes +# that depends on. +# Result: list of dependent modules, $1 will be part of it. +######################################################################### +-ndk-mod-get-bfs-list = $(strip \ + $(eval _ndk_mod_wq := $(call strip-lib-prefix,$1)) \ + $(eval _ndk_mod_deps_func := $2)\ + $(eval _ndk_mod_list :=)\ + $(call -ndk-mod-tree-setup-visit)\ + $(call -ndk-mod-tree-set-visited,$(_ndk_mod_wq))\ + $(call -ndk-mod-bfs-recursive) \ + $(_ndk_mod_list)) + +# Recursive function used to perform a depth-first scan. +# Must initialize _ndk_mod_list, _ndk_mod_field, _ndk_mod_wq +# before calling this. +-ndk-mod-bfs-recursive = \ + $(call -ndk-mod-debug,-ndk-mod-bfs-recursive wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)' visited='$(_ndk_mod_tree_visitors)')\ + $(call -ndk-mod-pop-first)\ + $(eval _ndk_mod_list += $$(_ndk_mod_module))\ + $(call -ndk-mod-get-depends)\ + $(call -ndk-mod-debug,. node='$(_ndk_mod_module)' deps='$(_ndk_mod_depends)')\ + $(foreach _ndk_mod_child,$(_ndk_mod_depends),\ + $(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_child)),,\ + $(call -ndk-mod-tree-set-visited,$(_ndk_mod_child))\ + $(call -ndk-mod-push-back,$(_ndk_mod_child))\ + )\ + )\ + $(if $(_ndk_mod_wq),$(call -ndk-mod-bfs-recursive)) + +-test-ndk-mod-get-bfs-list.empty = \ + $(eval -local-deps = $$($$1_depends))\ + $(call test-expect,,$(call -ndk-mod-get-bfs-list,,-local-deps)) + +-test-ndk-mod-get-bfs-list.A = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends :=)\ + $(call test-expect,A,$(call -ndk-mod-get-bfs-list,A,-local-deps)) + +-test-ndk-mod-get-bfs-list.ABCDEF = \ + $(eval -local-deps = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends := D E)\ + $(eval C_depends := F E)\ + $(eval D_depends :=)\ + $(eval E_depends :=)\ + $(eval F_depends :=)\ + $(call test-expect,A B C D E F,$(call -ndk-mod-get-bfs-list,A,-local-deps)) + +######################################################################### +# Return breadth-first walk of a graph, starting from an arbitrary +# node. +# +# This performs a breadth-first walk of the graph and will return a +# list of nodes. Note that $1 will _not_ be part of the list. +# +# $1: root node name. +# $2: dependency function, i.e. $(call $2,) returns the nodes +# that depends on. +# Result: list of dependent modules, $1 will not be part of it. +######################################################################### +-ndk-mod-get-bfs-depends = $(call rest,$(call -ndk-mod-get-bfs-list,$1,$2)) + +-test-ndk-mod-get-bfs-depends.simple = \ + $(eval -local-deps-func = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends :=)\ + $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\ + $(call test-expect,B,$(deps)) + +-test-ndk-mod-get-bfs-depends.ABC = \ + $(eval -local-deps-func = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends :=)\ + $(eval C_depends := B)\ + $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\ + $(call test-expect,B C,$(deps))\ + +-test-ndk-mod-get-bfs-depends.ABCDE = \ + $(eval -local-deps-func = $$($$1_depends))\ + $(eval A_depends := B C)\ + $(eval B_depends := D)\ + $(eval C_depends := D E F)\ + $(eval D_depends :=)\ + $(eval E_depends :=)\ + $(eval F_depends :=)\ + $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\ + $(call test-expect,B C D E F,$(deps))\ + +-test-ndk-mod-get-bfs-depends.loop = \ + $(eval -local-deps-func = $$($$1_depends))\ + $(eval A_depends := B)\ + $(eval B_depends := A)\ + $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\ + $(call test-expect,B,$(deps)) diff --git a/Android/android-ndk-r27d/build/core/definitions-host.mk b/Android/android-ndk-r27d/build/core/definitions-host.mk new file mode 100644 index 0000000..3501e50 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/definitions-host.mk @@ -0,0 +1,218 @@ +# Copyright (C) 2009 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. +# + +# These definitions contain a few host-specific functions. I.e. they are +# typically used to generate shell commands during the build and their +# implementation will depend on the value of the HOST_OS variable. +# + +# ----------------------------------------------------------------------------- +# Function : host-path +# Arguments: 1: file path +# Returns : file path, as understood by the host file system +# Usage : $(call host-path,) +# Rationale: This function is used to translate Cygwin paths into +# Cygwin-specific ones. On other platforms, it will just +# return its argument. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),cygwin) +host-path = $(if $(strip $1),$(call cygwin-to-host-path,$1)) +else +host-path = $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-rm +# Arguments: 1: list of files +# Usage : $(call host-rm,) +# Rationale: This function expands to the host-specific shell command used +# to remove some files. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-rm = \ + $(eval __host_rm_files := $(foreach __host_rm_file,$1,$(subst /,\,$(wildcard $(__host_rm_file)))))\ + $(if $(__host_rm_files),del /f/q $(__host_rm_files) >NUL 2>NUL) +else +host-rm = rm -f $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-rmdir +# Arguments: 1: list of files or directories +# Usage : $(call host-rm,) +# Rationale: This function expands to the host-specific shell command used +# to remove some files _and_ directories. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-rmdir = \ + $(eval __host_rmdir_files := $(foreach __host_rmdir_file,$1,$(subst /,\,$(wildcard $(__host_rmdir_file)))))\ + $(if $(__host_rmdir_files),del /f/s/q $(__host_rmdir_files) >NUL 2>NUL) +else +host-rmdir = rm -rf $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-mkdir +# Arguments: 1: directory path +# Usage : $(call host-mkdir, +# Rationale: This function expands to the host-specific shell command used +# to create a path if it doesn't exist. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-mkdir = md $(subst /,\,"$1") >NUL 2>NUL || rem +else +host-mkdir = mkdir -p $1 +endif + +# ----------------------------------------------------------------------------- +# Function : host-cp +# Arguments: 1: source file +# 2: target file +# Usage : $(call host-cp,,) +# Rationale: This function expands to the host-specific shell command used +# to copy a single file +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-cp = copy /b/y $(subst /,\,"$1" "$2") > NUL +else +host-cp = cp -f $1 $2 +endif + +# ----------------------------------------------------------------------------- +# Function : host-mv +# Arguments: 1: source file +# 2: target file +# Usage : $(call host-mv,,) +# Rationale: This function expands to the host-specific shell command used +# to move a single file +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-mv = move /y $(subst /,\,"$1" "$2") > NUL +else +host-mv = mv -f $1 $2 +endif + +# ----------------------------------------------------------------------------- +# Function : host-install +# Arguments: 1: source file +# 2: target file +# Usage : $(call host-install,,) +# Rationale: This function expands to the host-specific shell command used +# to install a file or directory, while preserving its timestamps +# (if possible). +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-install = copy /b/y $(subst /,\,"$1" "$2") > NUL +else +host-install = install -p $1 $2 +endif + +# ----------------------------------------------------------------------------- +# Function : host-echo-build-step +# Arguments: 1: ABI +# 2: Step description (e.g. 'Compile C++', or 'StaticLibrary') +# Usage : ---->|$(call host-echo-build-step,Compile) ....other text... +# Rationale: This function expands to the host-specific shell command used +# to print the prefix of a given build step / command. +# ----------------------------------------------------------------------------- +host-echo-build-step = @ $(HOST_ECHO) [$1] $(call left-justify-quoted-15,$2): + +# ----------------------------------------------------------------------------- +# Function : host-c-includes +# Arguments: 1: list of file paths (e.g. "foo bar") +# Returns : list of include compiler options (e.g. "-Ifoo -Ibar") +# Usage : $(call host-c-includes,) +# Rationale: This function is used to translate Cygwin paths into +# Cygwin-specific ones. On other platforms, it will just +# return its argument. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),cygwin) +host-c-includes = $(patsubst %,-I%,$(call host-path,$1)) +else +host-c-includes = $(1:%=-I%) +endif + +# ----------------------------------------------------------------------------- +# Function : host-copy-if-differ +# Arguments: 1: source file +# 2: destination file +# Usage : $(call host-copy-if-differ,,) +# Rationale: This function copy source file to destination file if contents are +# different. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +host-copy-if-differ = $(HOST_CMP) -s $1 $2 > NUL || copy /b/y $(subst /,\,"$1" "$2") > NUL +else +host-copy-if-differ = $(HOST_CMP) -s $1 $2 > /dev/null 2>&1 || cp -f $1 $2 +endif + + +# ----------------------------------------------------------------------------- +# Function : host-path-is-absolute +# Arguments: 1: file path +# Usage : $(call host-path-is-absolute,) +# Rationale: This function returns a non-empty result if the input path is +# absolute on the host filesystem. +# ----------------------------------------------------------------------------- + +# On Windows, we need to take care drive prefix in file paths, e.g.: +# /foo -> top-level 'foo' directory on current drive. +# //bar/foo -> top-level 'foo' on network share 'bar' +# c:/foo -> top-level 'foo' directory on C drive. +# c:foo -> 'foo' subdirectory on C drive's current directory. +# +# Treat all of them as absolute. Filtering the first two cases is easy +# by simply looking at the first character. The other ones are more +# complicated and the simplest way is still to try all alphabet letters +# directly. Anything else involves very complicated GNU Make parsing +# voodoo. +ndk-windows-drive-letters := a b c d e f g h i j k l m n o p q r s t u v w x y z \ + A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + +ndk-windows-drive-patterns := $(foreach _drive,$(ndk-windows-drive-letters),$(_drive):%) + +windows-path-is-absolute = $(if $(filter /% $(ndk-windows-drive-patterns),$(subst \,/,$1)),true) + +ifeq ($(HOST_OS),windows) +host-path-is-absolute = $(call windows-path-is-absolute,$1) +else +host-path-is-absolute = $(if $(filter /%,$1),true) +endif + +-test-host-path-is-absolute.relative-paths = \ + $(call test-expect,,$(call host-path-is-absolute,foo))\ + $(call test-expect,,$(call host-path-is-absolute,foo/bar))\ + $(call test-expect,,$(call host-path-is-absolute,.))\ + $(call test-expect,,$(call host-path-is-absolute,..)) + +-test-host-path-is-absolute.absolute-paths = \ + $(call test-expect,true,$(call host-path-is-absolute,/))\ + $(call test-expect,true,$(call host-path-is-absolute,/foo))\ + $(call test-expect,true,$(call host-path-is-absolute,/foo/bar))\ + $(call test-expect,true,$(call host-path-is-absolute,//foo))\ + $(call test-expect,true,$(call host-path-is-absolute,/.)) + +-test-host-path-is-asbolute.windows-relative-paths = \ + $(call test-expect,$(call windows-path-is-absolute,foo))\ + $(call test-expect,$(call windows-path-is-absolute,foo/bar))\ + $(call test-expect,$(call windows-path-is-absolute,.))\ + $(call test-expect,$(call windows-path-is-absolute,..)) + +-test-host-path-is-asbolute.windows-absolute-paths = \ + $(call test-expect,true,$(call windows-path-is-absolute,c:/))\ + $(call test-expect,true,$(call windows-path-is-absolute,x:))\ + $(call test-expect,true,$(call windows-path-is-absolute,K:foo))\ + $(call test-expect,true,$(call windows-path-is-absolute,C:\Foo\Bar))\ + $(call test-expect,true,$(call windows-path-is-absolute,\Foo)) diff --git a/Android/android-ndk-r27d/build/core/definitions-tests.mk b/Android/android-ndk-r27d/build/core/definitions-tests.mk new file mode 100644 index 0000000..074036b --- /dev/null +++ b/Android/android-ndk-r27d/build/core/definitions-tests.mk @@ -0,0 +1,106 @@ +# Copyright (C) 2012 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. +# +# Definitions for the Android NDK build system's internal unit tests. +# + +# +# A function which names begin with -test- (e.g. -test-foo) is assumed +# to be an internal unit test. It will be run automatically by ndk-build +# if NDK_UNIT_TESTS is defined in your environment. +# +# Each test should call one of the following functions that will +# register a failure: +# +# $(call test-expect,,) +# +# This will check that is equal to . +# If not, this will print an error message and increment the failure +# counter. +# +# $(call test-assert,,) +# +# This is similar to test-expect, though it will abort the program +# immediately after displaying an error message. +# +# Here's an example that checks that the 'filter' function works correctly: +# +# -test-filter = \ +# $(call test-expect,foo,$(filter bar,foo bar)) +# +# + +-ndk-test-start = \ + $(eval _test_name := $1)\ + $(eval _test_list += $1)\ + $(eval _test_failed :=)\ + $(info [$1 RUN]) + +# End current unit test. +# +-ndk-test-end = \ + $(if $(_test_failed),\ + $(info [$(_test_name) FAIL])$(error Aborting)\ + $(eval _test_failures += $$(_test_name))\ + ,\ + $(info [$(_test_name) OK])\ + ) + +# Define NDK_UNIT_TESTS to 2 to dump each test-expect/assert check. +# +ifeq (2,$(NDK_UNIT_TESTS)) +-ndk-test-log = $(info . $(_test_name): $1) +else +-ndk-test-log = $(empty) +endif + +test-expect = \ + $(call -ndk-test-log,expect '$2' == '$1')\ + $(if $(call sne,$1,$2),\ + $(info ERROR <$(_test_name)>:$3)\ + $(info . expected value:'$1')\ + $(info . actual value: '$2')\ + $(eval _test_failed := true)\ + ) + +test-assert = \ + $(call -ndk-test-log,assert '$2' == '$1')\ + $(if $(call sne,$1,$2),\ + $(info ASSERT <$(_test_name)>:$3)\ + $(info . expected value:'$1')\ + $(info . actual value: '$2')\ + $(eval _test_failed := true)\ + $(error Aborting.)\ + ) + +# Run all the tests, i.e. all functions that are defined with a -test- +# prefix will be called now in succession. +ndk-run-all-tests = \ + $(info ================= STARTING NDK-BUILD UNIT TESTS =================)\ + $(eval _test_list :=)\ + $(eval _test_failures :=)\ + $(foreach _test,$(filter -test-%,$(.VARIABLES)),\ + $(call -ndk-test-start,$(_test))\ + $(call $(_test))\ + $(call -ndk-test-end)\ + )\ + $(eval _test_count := $$(words $$(_test_list)))\ + $(eval _test_fail_count := $$(words $$(_test_failures)))\ + $(if $(_test_failures),\ + $(info @@@@@@@@@@@ FAILED $(_test_fail_count) of $(_test_count) NDK-BUILD UNIT TESTS @@@@@@@)\ + $(foreach _test_name,$(_test_failures),\ + $(info . $(_test_name)))\ + ,\ + $(info =================== PASSED $(_test_count) NDK-BUILD UNIT TESTS =================)\ + ) diff --git a/Android/android-ndk-r27d/build/core/definitions-utils.mk b/Android/android-ndk-r27d/build/core/definitions-utils.mk new file mode 100644 index 0000000..555d601 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/definitions-utils.mk @@ -0,0 +1,272 @@ +# Copyright (C) 2009 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. +# + +# Common utility functions. +# +# NOTE: All the functions here should be purely functional, i.e. avoid +# using global variables or depend on the file system / environment +# variables. This makes testing easier. + +# ----------------------------------------------------------------------------- +# Macro : empty +# Returns : an empty macro +# Usage : $(empty) +# ----------------------------------------------------------------------------- +empty := + +# ----------------------------------------------------------------------------- +# Macro : space +# Returns : a single space +# Usage : $(space) +# ----------------------------------------------------------------------------- +space := $(empty) $(empty) + +space4 := $(space)$(space)$(space)$(space) + +# ----------------------------------------------------------------------------- +# Macro : comma +# Returns : a single comma +# Usage : $(comma) +# ----------------------------------------------------------------------------- +comma := , + +# ----------------------------------------------------------------------------- +# Macro : colon +# Returns : a single colon +# Usage : $(colon) +# ----------------------------------------------------------------------------- +colon := : + +define newline + + +endef + +# ----------------------------------------------------------------------------- +# Function : remove-duplicates +# Arguments: a list +# Returns : the list with duplicate items removed, order is preserved. +# Usage : $(call remove-duplicates, ) +# Note : This is equivalent to the 'uniq' function provided by GMSL, +# however this implementation is non-recursive and *much* +# faster. It will also not explode the stack with a lot of +# items like 'uniq' does. +# ----------------------------------------------------------------------------- +remove-duplicates = $(strip \ + $(eval __uniq_ret :=) \ + $(foreach __uniq_item,$1,\ + $(if $(findstring $(__uniq_item),$(__uniq_ret)),,\ + $(eval __uniq_ret += $(__uniq_item))\ + )\ + )\ + $(__uniq_ret)) + +-test-remove-duplicates = \ + $(call test-expect,,$(call remove-duplicates))\ + $(call test-expect,foo bar,$(call remove-duplicates,foo bar))\ + $(call test-expect,foo bar,$(call remove-duplicates,foo bar foo bar))\ + $(call test-expect,foo bar,$(call remove-duplicates,foo foo bar bar bar)) + +# ----------------------------------------------------------------------------- +# Function : clear-vars +# Arguments: 1: list of variable names +# 2: file where the variable should be defined +# Returns : None +# Usage : $(call clear-vars, VAR1 VAR2 VAR3...) +# Rationale: Clears/undefines all variables in argument list +# ----------------------------------------------------------------------------- +clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty))) + +# ----------------------------------------------------------------------------- +# Function : filter-by +# Arguments: 1: list +# 2: predicate function, will be called as $(call $2,) +# and it this returns a non-empty value, then +# will be appended to the result. +# Returns : elements of $1 that satisfy the predicate function $2 +# ----------------------------------------------------------------------------- +filter-by = $(strip \ + $(foreach __filter_by_n,$1,\ + $(if $(call $2,$(__filter_by_n)),$(__filter_by_n)))) + +-test-filter-by = \ + $(eval -local-func = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call filter-by,,-local-func))\ + $(call test-expect,foo,$(call filter-by,foo,-local-func))\ + $(call test-expect,foo,$(call filter-by,foo bar,-local-func))\ + $(call test-expect,foo foo,$(call filter-by,aaa foo bar foo,-local-func))\ + $(eval -local-func = $$(call sne,foo,$$1))\ + $(call test-expect,,$(call filter-by,,-local-func))\ + $(call test-expect,,$(call filter-by,foo,-local-func))\ + $(call test-expect,bar,$(call filter-by,foo bar,-local-func))\ + $(call test-expect,aaa bar,$(call filter-by,aaa foo bar,-local-func)) + +# ----------------------------------------------------------------------------- +# Function : filter-out-by +# Arguments: 1: list +# 2: predicate function, will be called as $(call $2,) +# and it this returns an empty value, then +# will be appended to the result. +# Returns : elements of $1 that do not satisfy the predicate function $2 +# ----------------------------------------------------------------------------- +filter-out-by = $(strip \ + $(foreach __filter_out_by_n,$1,\ + $(if $(call $2,$(__filter_out_by_n)),,$(__filter_out_by_n)))) + +-test-filter-out-by = \ + $(eval -local-func = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call filter-out-by,,-local-func))\ + $(call test-expect,,$(call filter-out-by,foo,-local-func))\ + $(call test-expect,bar,$(call filter-out-by,foo bar,-local-func))\ + $(call test-expect,aaa bar,$(call filter-out-by,aaa foo bar foo,-local-func))\ + $(eval -local-func = $$(call sne,foo,$$1))\ + $(call test-expect,,$(call filter-out-by,,-local-func))\ + $(call test-expect,foo,$(call filter-out-by,foo,-local-func))\ + $(call test-expect,foo,$(call filter-out-by,foo bar,-local-func))\ + $(call test-expect,foo foo,$(call filter-out-by,aaa foo bar foo,-local-func)) + +# ----------------------------------------------------------------------------- +# Function : find-first +# Arguments: 1: list +# 2: predicate function, will be called as $(call $2,). +# Returns : the first item of $1 that satisfies the predicate. +# ----------------------------------------------------------------------------- +find-first = $(firstword $(call filter-by,$1,$2)) + +-test-find-first.empty = \ + $(eval -local-pred = $$(call seq,foo,$$1))\ + $(call test-expect,,$(call find-first,,-local-pred))\ + $(call test-expect,,$(call find-first,bar,-local-pred)) + +-test-find-first.simple = \ + $(eval -local-pred = $$(call seq,foo,$$1))\ + $(call test-expect,foo,$(call find-first,foo,-local-pred))\ + $(call test-expect,foo,$(call find-first,aaa foo bar,-local-pred))\ + $(call test-expect,foo,$(call find-first,aaa foo foo bar,-local-pred)) + +# ----------------------------------------------------------------------------- +# Function : parent-dir +# Arguments: 1: path +# Returns : Parent dir or path of $1, with final separator removed. +# ----------------------------------------------------------------------------- +ifeq ($(HOST_OS),windows) +# On Windows, defining parent-dir is a bit more tricky because the +# GNU Make $(dir ...) function doesn't return an empty string when it +# reaches the top of the directory tree, and we want to enforce this to +# avoid infinite loops. +# +# $(dir C:) -> C: (empty expected) +# $(dir C:/) -> C:/ (empty expected) +# $(dir C:\) -> C:\ (empty expected) +# $(dir C:/foo) -> C:/ (correct) +# $(dir C:\foo) -> C:\ (correct) +# +parent-dir = $(patsubst %/,%,$(strip \ + $(eval __dir_node := $(patsubst %/,%,$(subst \,/,$1)))\ + $(eval __dir_parent := $(dir $(__dir_node)))\ + $(filter-out $1,$(__dir_parent))\ + )) +else +parent-dir = $(patsubst %/,%,$(dir $(1:%/=%))) +endif + +-test-parent-dir = \ + $(call test-expect,,$(call parent-dir))\ + $(call test-expect,.,$(call parent-dir,foo))\ + $(call test-expect,foo,$(call parent-dir,foo/bar))\ + $(call test-expect,foo,$(call parent-dir,foo/bar/)) + +# ----------------------------------------------------------------------------- +# Strip any 'lib' prefix in front of a given string. +# +# Function : strip-lib-prefix +# Arguments: 1: module name +# Returns : module name, without any 'lib' prefix if any +# Usage : $(call strip-lib-prefix,$(LOCAL_MODULE)) +# ----------------------------------------------------------------------------- +strip-lib-prefix = $(1:lib%=%) + +-test-strip-lib-prefix = \ + $(call test-expect,,$(call strip-lib-prefix,))\ + $(call test-expect,foo,$(call strip-lib-prefix,foo))\ + $(call test-expect,foo,$(call strip-lib-prefix,libfoo))\ + $(call test-expect,nolibfoo,$(call strip-lib-prefix,nolibfoo))\ + $(call test-expect,foolib,$(call strip-lib-prefix,foolib))\ + $(call test-expect,foo bar,$(call strip-lib-prefix,libfoo libbar)) + +# ----------------------------------------------------------------------------- +# Left-justify input string with spaces to fill a width of 15. +# Function: left-justify-quoted-15 +# Arguments: 1: Input text +# Returns: A quoted string that can be used in command scripts to print +# the left-justified input with host-echo. +# +# Usage: ---->@$(call host-echo, $(call left-justify-quoted-15,$(_TEXT)): Do stuff) +# Where ----> is a TAB character. +# ----------------------------------------------------------------------------- +left-justify-quoted-15 = $(call -left-justify,$1,xxxxxxxxxxxxxxx) + +-test-left-justify-quoted-15 = \ + $(call test-expect," ",$(call left-justify-quoted-15,))\ + $(call test-expect,"Foo Bar ",$(call left-justify-quoted-15,Foo Bar))\ + $(call test-expect,"Very long string over 15 characters wide",$(strip \ + $(call left-justify-quoted-15,Very long string over 15 characters wide))) + +# Used internally to compute a quoted left-justified text string. +# $1: Input string. +# $2: A series of contiguous x's, its length determines the full width to justify to. +# Return: A quoted string with the input text left-justified appropriately. +-left-justify = $(strip \ + $(eval __lj_temp := $(subst $(space),x,$1))\ + $(foreach __lj_a,$(__gmsl_characters),$(eval __lj_temp := $$(subst $$(__lj_a),x,$(__lj_temp))))\ + $(eval __lj_margin := $$(call -justification-margin,$(__lj_temp),$2)))"$1$(subst x,$(space),$(__lj_margin))" + +-test-left-justify = \ + $(call test-expect,"",$(call -left-justify,,))\ + $(call test-expect,"foo",$(call -left-justify,foo,xxx))\ + $(call test-expect,"foo ",$(call -left-justify,foo,xxxx))\ + $(call test-expect,"foo ",$(call -left-justify,foo,xxxxxx))\ + $(call test-expect,"foo ",$(call -left-justify,foo,xxxxxxxxxxxx))\ + $(call test-expect,"very long string",$(call -left-justify,very long string,xxx))\ + +# Used internally to compute a justification margin. +# Expects $1 to be defined to a string of consecutive x's (e.g. 'xxxx') +# Expects $2 to be defined to a maximum string of x's (e.g. 'xxxxxxxxx') +# Returns a string of x's such as $1 + $(result) is equal to $2 +# If $1 is larger than $2, return empty string.. +-justification-margin = $(strip \ + $(if $2,\ + $(if $1,\ + $(call -justification-margin-inner,$1,$2),\ + $2\ + ),\ + $1)) + +-justification-margin-inner = $(if $(findstring $2,$1),,x$(call -justification-margin-inner,x$1,$2)) + +-test-justification-margin = \ + $(call test-expect,,$(call -justification-margin,,))\ + $(call test-expect,,$(call -justification-margin,xxx,xxx))\ + $(call test-expect,xxxxxx,$(call -justification-margin,,xxxxxx))\ + $(call test-expect,xxxxx,$(call -justification-margin,x,xxxxxx))\ + $(call test-expect,xxxx,$(call -justification-margin,xx,xxxxxx))\ + $(call test-expect,xxx,$(call -justification-margin,xxx,xxxxxx))\ + $(call test-expect,xx,$(call -justification-margin,xxxx,xxxxxx))\ + $(call test-expect,x,$(call -justification-margin,xxxxx,xxxxxx))\ + $(call test-expect,,$(call -justification-margin,xxxxxx,xxxxxx))\ + $(call test-expect,,$(call -justification-margin,xxxxxxxxxxx,xxxxxx))\ + +# Escapes \ to \\. Useful for escaping Windows paths. +escape-backslashes = $(subst \,\\,$1) diff --git a/Android/android-ndk-r27d/build/core/definitions.mk b/Android/android-ndk-r27d/build/core/definitions.mk new file mode 100644 index 0000000..2d9a7f8 --- /dev/null +++ b/Android/android-ndk-r27d/build/core/definitions.mk @@ -0,0 +1,1885 @@ +# Copyright (C) 2009 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. +# +# Common definitions for the Android NDK build system +# + +# We use the GNU Make Standard Library +include $(NDK_ROOT)/build/gmsl/gmsl + +include $(BUILD_SYSTEM)/definitions-tests.mk +include $(BUILD_SYSTEM)/definitions-utils.mk +include $(BUILD_SYSTEM)/definitions-host.mk +include $(BUILD_SYSTEM)/definitions-graph.mk + +include $(BUILD_SYSTEM)/version.mk + +ndk-major-at-least = $(if $(filter $(true),$(call gte,$(NDK_MAJOR),$1)),true,false) + +# ----------------------------------------------------------------------------- +# Macro : this-makefile +# Returns : the name of the current Makefile in the inclusion stack +# Usage : $(this-makefile) +# ----------------------------------------------------------------------------- +this-makefile = $(lastword $(MAKEFILE_LIST)) + +# ----------------------------------------------------------------------------- +# Macro : local-makefile +# Returns : the name of the last parsed Android.mk file +# Usage : $(local-makefile) +# ----------------------------------------------------------------------------- +_last_android_mk = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST))) +_last_non_ndk_makefile = $(lastword $(filter-out $(NDK_ROOT)%,$(MAKEFILE_LIST))) +local-makefile = $(if $(_last_android_mk),$(_last_android_mk),$(_last_non_ndk_makefile)) + +# ----------------------------------------------------------------------------- +# Function : assert-defined +# Arguments: 1: list of variable names +# Returns : None +# Usage : $(call assert-defined, VAR1 VAR2 VAR3...) +# Rationale: Checks that all variables listed in $1 are defined, or abort the +# build +# ----------------------------------------------------------------------------- +assert-defined = $(foreach __varname,$(strip $1),\ + $(if $(strip $($(__varname))),,\ + $(call __ndk_error, Assertion failure: $(__varname) is not defined)\ + )\ +) + +# ----------------------------------------------------------------------------- +# Function : check-required-vars +# Arguments: 1: list of variable names +# 2: file where the variable(s) should be defined +# Returns : None +# Usage : $(call check-required-vars, VAR1 VAR2 VAR3..., ) +# Rationale: Checks that all required vars listed in $1 were defined by $2 +# or abort the build with an error +# ----------------------------------------------------------------------------- +check-required-vars = $(foreach __varname,$1,\ + $(if $(strip $($(__varname))),,\ + $(call __ndk_info, Required variable $(__varname) is not defined by $2)\ + $(call __ndk_error,Aborting)\ + )\ +) + +# The list of default C++ extensions supported by GCC. +default-c++-extensions := .cc .cp .cxx .cpp .CPP .c++ .C + +# ----------------------------------------------------------------------------- +# Function : generate-empty-file +# Arguments: 1: file path +# Usage : $(call generate-empty-file,) +# Rationale: This function writes an empty file. Use this function as a +# portable replacement for "touch" to update an empty timestamp +# file. +# ----------------------------------------------------------------------------- +generate-empty-file = $(HOST_ECHO_N) "" > $1 + +# ----------------------------------------------------------------------------- +# Function : generate-dir +# Arguments: 1: directory path +# Returns : Generate a rule, but not dependency, to create a directory with +# host-mkdir. +# Usage : $(call generate-dir,) +# ----------------------------------------------------------------------------- +define ev-generate-dir +__ndk_dir := $1 +ifeq (,$$(__ndk_dir_flag__$$(__ndk_dir))) +# Note that the following doesn't work because path in windows may contain +# ':' if ndk-build is called inside jni/ directory when path is expanded +# to full-path, eg. C:/path/to/project/jni/ +# +# __ndk_dir_flag__$1 := true +# +__ndk_dir_flag__$$(__ndk_dir) := true +$1: + @$$(call host-mkdir,$$@) +endif +endef + +generate-dir = $(eval $(call ev-generate-dir,$1)) + +# ----------------------------------------------------------------------------- +# Function : generate-file-dir +# Arguments: 1: file path +# Returns : Generate a dependency and a rule to ensure that the parent +# directory of the input file path will be created before it. +# This is used to enforce a call to host-mkdir. +# Usage : $(call generate-file-dir,) +# Rationale: Many object files will be stored in the same output directory. +# Introducing a dependency on the latter avoids calling mkdir -p +# for every one of them. +# +# ----------------------------------------------------------------------------- + +define ev-generate-file-dir +__ndk_file_dir := $(call parent-dir,$1) +$$(call generate-dir,$$(__ndk_file_dir)) +$1:| $$(__ndk_file_dir) +endef + +generate-file-dir = $(eval $(call ev-generate-file-dir,$1)) + +# ----------------------------------------------------------------------------- +# Function : generate-list-file +# Arguments: 1: list of strings (possibly very long) +# 2: file name +# Returns : write the content of a possibly very long string list to a file. +# this shall be used in commands and will work around limitations +# of host command-line lengths. +# Usage : $(call host-echo-to-file,,) +# Rationale: When there is a very large number of objects and/or libraries at +# link time, the size of the command becomes too large for the +# host system's maximum. Various tools however support the +# @ syntax, where is the path of a file +# which content will be parsed as if they were options. +# +# This function is used to generate such a list file from a long +# list of strings in input. +# +# ----------------------------------------------------------------------------- + +define generate-list-file-ev + +__list_file := $2 + +.PHONY: $$(__list_file).tmp + +$$(call generate-file-dir,$$(__list_file).tmp) + +$$(__list_file).tmp: + $$(file >$$@,$1) + +$$(__list_file): $$(__list_file).tmp + $$(hide) $$(call host-copy-if-differ,$$@.tmp,$$@) + $$(hide) $$(call host-rm,$$@.tmp) + +endef + +generate-list-file = $(eval $(call generate-list-file-ev,$1,$2)) + +# ----------------------------------------------------------------------------- +# Function : link-whole-archives +# Arguments: 1: list of whole static libraries +# Returns : linker flags to use the whole static libraries +# Usage : $(call link-whole-archives,) +# Rationale: This function is used to put the list of whole static libraries +# inside a -Wl,--whole-archive ... -Wl,--no-whole-archive block. +# If the list is empty, it returns an empty string. +# This function also calls host-path to translate the library +# paths. +# ----------------------------------------------------------------------------- +link-whole-archives = $(if $(strip $1),$(call link-whole-archive-flags,$1)) +link-whole-archive-flags = -Wl,--whole-archive $(call host-path,$1) -Wl,--no-whole-archive + +-test-link-whole-archive = \ + $(call test-expect,,$(call link-whole-archives))\ + $(eval _start := -Wl,--whole-archive)\ + $(eval _end := -Wl,--no-whole-archive)\ + $(call test-expect,$(_start) foo $(_end),$(call link-whole-archives,foo))\ + $(call test-expect,$(_start) foo bar $(_end),$(call link-whole-archives,foo bar)) + +# ============================================================================= +# +# Modules database +# +# The following declarations are used to manage the list of modules +# defined in application's Android.mk files. +# +# Technical note: +# We use __ndk_modules to hold the list of all modules corresponding +# to a given application. +# +# For each module 'foo', __ndk_modules.foo. is used +# to store module-specific information. +# +# type -> type of module (e.g. 'static', 'shared', ...) +# depends -> list of other modules this module depends on +# +# Also, LOCAL_XXXX values defined for a module are recorded in XXXX, e.g.: +# +# PATH -> recorded LOCAL_PATH for the module +# CFLAGS -> recorded LOCAL_CFLAGS for the module +# ... +# +# Some of these are created by build scripts like BUILD_STATIC_LIBRARY: +# +# MAKEFILE -> The Android.mk where the module is defined. +# LDFLAGS -> Final linker flags +# OBJECTS -> List of module objects +# BUILT_MODULE -> location of module built file (e.g. obj///libfoo.so) +# +# Note that some modules are never installed (e.g. static libraries). +# +# ============================================================================= + +# The list of LOCAL_XXXX variables that are recorded for each module definition +# These are documented by docs/ANDROID-MK.TXT. Exception is LOCAL_MODULE +# +modules-LOCALS := \ + ALLOW_MISSING_PREBUILT \ + ALLOW_UNDEFINED_SYMBOLS \ + ALLOW_UNDEFINED_VERSION_SCRIPT_SYMBOLS \ + ARM_MODE \ + ARM_NEON \ + ASFLAGS \ + ASMFLAGS \ + BUILT_MODULE_NOT_COPIED \ + CFLAGS \ + CLANG_TIDY \ + CLANG_TIDY_FLAGS \ + CONLYFLAGS \ + CPPFLAGS \ + CPP_EXTENSION \ + CPP_FEATURES \ + CXXFLAGS \ + C_INCLUDES \ + DISABLE_FATAL_LINKER_WARNINGS \ + DISABLE_FORMAT_STRING_CHECKS \ + EXPORT_ASMFLAGS \ + EXPORT_CFLAGS \ + EXPORT_CONLYFLAGS \ + EXPORT_CPPFLAGS \ + EXPORT_C_INCLUDES \ + EXPORT_LDFLAGS \ + EXPORT_LDLIBS \ + EXPORT_SHARED_LIBRARIES \ + EXPORT_STATIC_LIBRARIES \ + FILTER_ASM \ + HAS_CPP \ + LDLIBS \ + MODULE \ + MODULE_FILENAME \ + PATH \ + PCH \ + SHARED_LIBRARIES \ + SHORT_COMMANDS \ + SRC_FILES \ + STATIC_LIBRARIES \ + STRIP_MODE \ + THIN_ARCHIVE \ + WHOLE_STATIC_LIBRARIES \ + +# The following are generated by the build scripts themselves + +# LOCAL_MAKEFILE will contain the path to the Android.mk defining the module +modules-LOCALS += MAKEFILE + +# LOCAL_LDFLAGS will contain the set of final linker flags for the module +modules-LOCALS += LDFLAGS + +# LOCAL_OBJECTS will contain the list of object files generated from the +# module's sources, if any. +modules-LOCALS += OBJECTS + +# LOCAL_BUILT_MODULE will contain the location of the symbolic version of +# the generated module (i.e. the one containing all symbols used during +# native debugging). It is generally under $PROJECT/obj/local/ +modules-LOCALS += BUILT_MODULE + +# LOCAL_OBJS_DIR will contain the location where the object files for +# this module will be stored. Usually $PROJECT/obj/local//obj +modules-LOCALS += OBJS_DIR + +# LOCAL_INSTALLED will contain the location of the installed version +# of the module. Usually $PROJECT/libs// +# where and depend on the module class. +modules-LOCALS += INSTALLED + +# LOCAL_MODULE_CLASS will contain the type of the module +# (e.g. STATIC_LIBRARY, SHARED_LIBRARY, etc...) +modules-LOCALS += MODULE_CLASS + +# the list of managed fields per module +modules-fields = depends \ + $(modules-LOCALS) + +# ----------------------------------------------------------------------------- +# Function : modules-clear +# Arguments: None +# Returns : None +# Usage : $(call modules-clear) +# Rationale: clears the list of defined modules known by the build system +# ----------------------------------------------------------------------------- +modules-clear = \ + $(foreach __mod,$(__ndk_modules),\ + $(foreach __field,$(modules-fields),\ + $(eval __ndk_modules.$(__mod).$(__field) := $(empty))\ + )\ + )\ + $(eval __ndk_modules := $(empty_set)) \ + $(eval __ndk_top_modules := $(empty)) \ + $(eval __ndk_import_list := $(empty)) \ + $(eval __ndk_import_depth := $(empty)) + +# ----------------------------------------------------------------------------- +# Function : modules-get-list +# Arguments: None +# Returns : The list of all recorded modules +# Usage : $(call modules-get-list) +# ----------------------------------------------------------------------------- +modules-get-list = $(__ndk_modules) + +# ----------------------------------------------------------------------------- +# Function : modules-get-top-list +# Arguments: None +# Returns : The list of all recorded non-imported modules +# Usage : $(call modules-get-top-list) +# ----------------------------------------------------------------------------- +modules-get-top-list = $(__ndk_top_modules) + +# ----------------------------------------------------------------------------- +# Function : module-add +# Arguments: 1: module name +# Returns : None +# Usage : $(call module-add,) +# Rationale: add a new module. If it is already defined, print an error message +# and abort. This will record all LOCAL_XXX variables for the module. +# ----------------------------------------------------------------------------- +module-add = \ + $(call assert-defined,LOCAL_MAKEFILE LOCAL_BUILT_MODULE LOCAL_OBJS_DIR LOCAL_MODULE_CLASS)\ + $(if $(call set_is_member,$(__ndk_modules),$1),\ + $(call __ndk_info,Trying to define local module '$1' in $(LOCAL_MAKEFILE).)\ + $(call __ndk_info,But this module was already defined by $(__ndk_modules.$1.MAKEFILE).)\ + $(call __ndk_error,Aborting.)\ + )\ + $(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\ + $(if $(strip $(__ndk_import_depth)),,\ + $(eval __ndk_top_modules := $(call set_insert,$(__ndk_top_modules),$1))\ + )\ + $(if $(call module-class-is-installable,$(LOCAL_MODULE_CLASS)),\ + $(eval LOCAL_INSTALLED := $(NDK_APP_DST_DIR)/$(notdir $(LOCAL_BUILT_MODULE))),\ + $(eval LOCAL_INSTALLED := $(LOCAL_BUILT_MODULE))\ + )\ + $(foreach __field,STATIC_LIBRARIES WHOLE_STATIC_LIBRARIES SHARED_LIBRARIES,\ + $(eval LOCAL_$(__field) := $(call strip-lib-prefix,$(LOCAL_$(__field)))))\ + $(foreach __local,$(modules-LOCALS),\ + $(eval __ndk_modules.$1.$(__local) := $(LOCAL_$(__local)))\ + )\ + $(call module-handle-c++-features,$1) + + +# Retrieve the class of module $1 +module-get-class = $(__ndk_modules.$1.MODULE_CLASS) + +# Retrieve built location of module $1 +module-get-built = $(__ndk_modules.$1.BUILT_MODULE) + +# Returns $(true) is module $1 is installable +# An installable module is one that will be copied to $PROJECT/libs// +# (e.g. shared libraries). +# +module-is-installable = $(call module-class-is-installable,$(call module-get-class,$1)) + +# Returns $(true) if module $1 is a copyable prebuilt +# A copyable prebuilt module is one that will be copied to $NDK_OUT// +# at build time. At the moment, this is only used for prebuilt shared +# libraries, since it helps ndk-gdb. +# +module-is-copyable = $(call module-class-is-copyable,$(call module-get-class,$1)) + +# ----------------------------------------------------------------------------- +# Function : module-get-export +# Arguments: 1: module name +# 2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS') +# Returns : Exported value +# Usage : $(call module-get-export,,) +# Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for module $1 +# ----------------------------------------------------------------------------- +module-get-export = $(__ndk_modules.$1.EXPORT_$2) + +# ----------------------------------------------------------------------------- +# Function : module-get-listed-export +# Arguments: 1: list of module names +# 2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS') +# Returns : Exported values +# Usage : $(call module-get-listed-export,,) +# Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for modules +# listed in $1. +# ----------------------------------------------------------------------------- +module-get-listed-export = $(strip \ + $(foreach __listed_module,$1,\ + $(call module-get-export,$(__listed_module),$2)\ + )) + +# ----------------------------------------------------------------------------- +# Function : modules-restore-locals +# Arguments: 1: module name +# Returns : None +# Usage : $(call module-restore-locals,) +# Rationale: Restore the recorded LOCAL_XXX definitions for a given module. +# ----------------------------------------------------------------------------- +module-restore-locals = \ + $(foreach __local,$(modules-LOCALS),\ + $(eval LOCAL_$(__local) := $(__ndk_modules.$1.$(__local)))\ + ) + +# Dump all module information. Only use this for debugging +modules-dump-database = \ + $(info Modules [$(TARGET_ARCH_ABI)]: $(__ndk_modules)) \ + $(foreach __mod,$(__ndk_modules),\ + $(info $(space4)$(__mod):)\ + $(foreach __field,$(modules-fields),\ + $(eval __fieldval := $(strip $(__ndk_modules.$(__mod).$(__field))))\ + $(if $(__fieldval),\ + $(if $(filter 1,$(words $(__fieldval))),\ + $(info $(space4)$(space4)$(__field): $(__fieldval)),\ + $(info $(space4)$(space4)$(__field): )\ + $(foreach __fielditem,$(__fieldval),\ + $(info $(space4)$(space4)$(space4)$(__fielditem))\ + )\ + )\ + )\ + )\ + )\ + $(info Top modules: $(__ndk_top_modules))\ + $(info --- end of modules list) + + +# ----------------------------------------------------------------------------- +# Function : module-add-static-depends +# Arguments: 1: module name +# 2: list/set of static library modules this module depends on. +# Returns : None +# Usage : $(call module-add-static-depends,,) +# Rationale: Record that a module depends on a set of static libraries. +# Use module-get-static-dependencies to retrieve final list. +# ----------------------------------------------------------------------------- +module-add-static-depends = \ + $(call module-add-depends-any,$1,$2,depends) \ + +# ----------------------------------------------------------------------------- +# Function : module-add-shared-depends +# Arguments: 1: module name +# 2: list/set of shared library modules this module depends on. +# Returns : None +# Usage : $(call module-add-shared-depends,,) +# Rationale: Record that a module depends on a set of shared libraries. +# Use modulge-get-shared-dependencies to retrieve final list. +# ----------------------------------------------------------------------------- +module-add-shared-depends = \ + $(call module-add-depends-any,$1,$2,depends) \ + +# Used internally by module-add-static-depends and module-add-shared-depends +# NOTE: this function must not modify the existing dependency order when new depends are added. +# +module-add-depends-any = \ + $(eval __ndk_modules.$1.$3 += $(filter-out $(__ndk_modules.$1.$3),$2)) + + +# ----------------------------------------------------------------------------- +# Returns non-empty if a module is a static library +# Arguments: 1: module name +# Returns : non-empty iff the module is a static library. +# Usage : $(if $(call module-is-static-library,),...) +# ----------------------------------------------------------------------------- +module-is-static-library = $(strip \ + $(filter STATIC_LIBRARY PREBUILT_STATIC_LIBRARY,\ + $(call module-get-class,$1))) + +# ----------------------------------------------------------------------------- +# Returns non-empty if a module is a shared library +# Arguments: 1: module name +# Returns : non-empty iff the module is a shared library. +# Usage : $(if $(call module-is-shared-library,),...) +# ----------------------------------------------------------------------------- +module-is-shared-library = $(strip \ + $(filter SHARED_LIBRARY PREBUILT_SHARED_LIBRARY,\ + $(call module-get-class,$1))) + +# ----------------------------------------------------------------------------- +# Filter a list of module names to retain only the static libraries. +# Arguments: 1: module name list +# Returns : input list modules which are static libraries. +# ----------------------------------------------------------------------------- +module-filter-static-libraries = $(call filter-by,$1,module-is-static-library) + +# ----------------------------------------------------------------------------- +# Filter a list of module names to retain only the shared libraries. +# Arguments: 1: module name list +# Returns : input list modules which are shared libraries. +# ----------------------------------------------------------------------------- +module-filter-shared-libraries = $(call filter-by,$1,module-is-shared-library) + +# ----------------------------------------------------------------------------- +# Return the LOCAL_STATIC_LIBRARIES for a given module. +# Arguments: 1: module name +# Returns : List of static library modules. +# ----------------------------------------------------------------------------- +module-get-static-libs = $(__ndk_modules.$1.STATIC_LIBRARIES) + +# ----------------------------------------------------------------------------- +# Return the LOCAL_WHOLE_STATIC_LIBRARIES for a given module. +# Arguments: 1: module name +# Returns : List of whole static library modules. +# ----------------------------------------------------------------------------- +module-get-whole-static-libs = $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES) + +# ----------------------------------------------------------------------------- +# Return all static libraries for a given module. +# Arguments: 1: module name +# Returns : List of static library modules (whole or not). +# ----------------------------------------------------------------------------- +module-get-all-static-libs = $(strip \ + $(__ndk_modules.$1.STATIC_LIBRARIES) \ + $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES)) + +# ----------------------------------------------------------------------------- +# Return the list of LOCAL_SHARED_LIBRARIES for a given module. +# Arguments: 1: module name +# Returns : List of shared library modules. +# ----------------------------------------------------------------------------- +module-get-shared-libs = $(__ndk_modules.$1.SHARED_LIBRARIES) + +# ----------------------------------------------------------------------------- +# Return the list of all libraries a modules depends directly on. +# This is the concatenation of its LOCAL_STATIC_LIBRARIES, +# LOCAL_WHOLE_STATIC_LIBRARIES, and LOCAL_SHARED_LIBRARIES variables. +# Arguments: 1: module name +# Returns : List of library modules (static or shared). +# ----------------------------------------------------------------------------- +module-get-direct-libs = $(strip \ + $(__ndk_modules.$1.STATIC_LIBRARIES) \ + $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES) \ + $(__ndk_modules.$1.SHARED_LIBRARIES)) + + +# ----------------------------------------------------------------------------- +# Computes the full closure of a module and its dependencies. Order is +# defined by a breadth-first walk of the graph. +# $1 will be the first item in the result. +# +# Arguments: 1: module name +# Returns : List of all modules $1 depends on. +# +# Note: Do not use this to determine build dependencies. The returned list +# is much too large for this. For example consider the following +# dependency graph: +# +# main.exe -> libA.a -> libfoo.so -> libB.a +# +# This function will return all four modules in the result, while +# at link time building main.exe only requires the first three. +# +# ----------------------------------------------------------------------------- +module-get-all-dependencies = $(call -ndk-mod-get-closure,$1,module-get-depends) + +# Same as module-get-all-dependencies, but topologically sorted. +module-get-all-dependencies-topo = \ + $(call -ndk-mod-get-topological-depends,$1,module-get-all-dependencies) + +# ----------------------------------------------------------------------------- +# Compute the list of all static and shared libraries required to link a +# given module. +# +# Note that the result is topologically ordered, i.e. if library A depends +# on library B, then A will always appear after B in the result. +# +# Arguments: 1: module name +# Returns : List of all library $1 depends at link time. +# +# Note: This doesn't differentiate between regular and whole static +# libraries. Use module-extract-whole-static-libs to filter the +# result returned by this function. +# ----------------------------------------------------------------------------- +module-get-link-libs = $(strip \ + $(eval _ndk_mod_link_module := $1) \ + $(call -ndk-mod-get-topological-depends,$1,-ndk-mod-link-deps)) + +# Special dependency function used by module-get-link-libs. +# The rules to follow are the following: +# - if $1 is the link module, or if it is a static library, then all +# direct dependencies. +# - otherwise, the module is a shared library, don't add build deps. +-ndk-mod-link-deps = \ + $(if $(call seq,$1,$(_ndk_mod_link_module))$(call module-is-static-library,$1),\ + $(call module-get-direct-libs,$1)) + +# ----------------------------------------------------------------------------- +# This function is used to extract the list of static libraries that need +# to be linked as whole, i.e. placed in a special section on the final +# link command. +# Arguments: $1: module name. +# $2: list of all static link-time libraries (regular or whole). +# Returns : list of static libraries from '$2' that need to be linked +# as whole. +# ----------------------------------------------------------------------------- +module-extract-whole-static-libs = $(strip \ + $(eval _ndk_mod_whole_all := $(call map,module-get-whole-static-libs,$1 $2))\ + $(eval _ndk_mod_whole_result := $(filter $(_ndk_mod_whole_all),$2))\ + $(_ndk_mod_whole_result)) + +# Used to recompute all dependencies once all module information has been recorded. +modules-compute-dependencies = \ + $(foreach __module,$(__ndk_modules),\ + $(call module-compute-depends,$(__module))\ + ) + +# Recurses though modules imported by $1 to come up with the transitive closure +# of imports. +# $1: Module +# $2: Import type (STATIC_LIBRARIES or SHARED_LIBRARIES) +module_get_recursive_imports = \ + $(eval _from_static_libs.$1 := \ + $(call module-get-listed-export,\ + $(__ndk_modules.$1.STATIC_LIBRARIES),$2))\ + $(eval _from_shared_libs.$1 := \ + $(call module-get-listed-export,\ + $(__ndk_modules.$1.SHARED_LIBRARIES),$2))\ + $(eval _from_imports.$1 := \ + $(foreach _import,$(_from_static_libs.1),\ + $(call module_get_recursive_imports,$(_import),$2))\ + $(foreach _import,$(_from_shared_libs.$1),\ + $(call module_get_recursive_imports,$(_import),$2)))\ + $(_from_static_libs.$1) $(_from_shared_libs.$1) $(_from_imports.$1) + +# Fills __ndk_modules.$1.depends with a list of all the modules that $1 depends +# on. Note that this runs before import-locals.mk is run (import-locals.mk needs +# this information), so we have to explicitly check for exported libraries from +# our dependencies. Imported libraries might in turn export more libraries to +# us, so do this recursively. +module-compute-depends = \ + $(call module-add-static-depends,$1,$(__ndk_modules.$1.STATIC_LIBRARIES))\ + $(call module-add-static-depends,$1,$(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES))\ + $(call module-add-shared-depends,$1,$(__ndk_modules.$1.SHARED_LIBRARIES))\ + $(call module-add-static-depends,$1,\ + $(call module_get_recursive_imports,$1,STATIC_LIBRARIES))\ + $(call module-add-shared-depends,$1,\ + $(call module_get_recursive_imports,$1,SHARED_LIBRARIES))\ + +module-get-installed = $(__ndk_modules.$1.INSTALLED) + +module-get-depends = $(__ndk_modules.$1.depends) + +# ----------------------------------------------------------------------------- +# Function : modules-get-all-installable +# Arguments: 1: list of module names +# Returns : List of all the installable modules $1 depends on transitively. +# Usage : $(call modules-all-get-installable,) +# Rationale: This computes the closure of all installable module dependencies starting from $1 +# ----------------------------------------------------------------------------- +# For now, only the closure of LOCAL_SHARED_LIBRARIES is enough +modules-get-all-installable = $(strip \ + $(foreach __alldep,$(call module-get-all-dependencies,$1),\ + $(if $(call module-is-installable,$(__alldep)),$(__alldep))\ + )) + +# Return the C++ extension(s) of a given module +# $1: module name +module-get-c++-extensions = $(strip \ + $(if $(__ndk_modules.$1.CPP_EXTENSION),\ + $(__ndk_modules.$1.CPP_EXTENSION),\ + $(default-c++-extensions)\ + )) + +# Return the list of C++ sources of a given module +# +module-get-c++-sources = \ + $(eval __files := $(__ndk_modules.$1.SRC_FILES:%.neon=%)) \ + $(eval __files := $(__files:%.arm=%)) \ + $(eval __extensions := $(call module-get-c++-extensions,$1))\ + $(filter $(foreach __extension,$(__extensions),%$(__extension)),$(__files)) + +# Returns a non-empty string if a module has C++ sources +module-has-c++-sources = $(strip $(call module-get-c++-sources,$1) \ + $(filter true,$(__ndk_modules.$1.HAS_CPP))) + +# Return the compiler flags used to compile a C++ module +# Order matters and should match the one used by the build command +module-get-c++-flags = $(strip \ + $(__ndk_modules.$1.CFLAGS) \ + $(__ndk_modules.$1.CPPFLAGS) \ + $(__ndk_modules.$1.CXXFLAGS)) + +# This function is used to remove certain flags from a module compiler flags +# $1: Module name +# $2: List of flags to remove +# +module-filter-out-compiler-flags = \ + $(eval __ndk_modules.$1.CFLAGS := $(filter-out $2,$(__ndk_modules.$1.CFLAGS)))\ + $(eval __ndk_modules.$1.CONLYFLAGS := $(filter-out $2,$(__ndk_modules.$1.CONLYFLAGS)))\ + $(eval __ndk_modules.$1.CPPFLAGS := $(filter-out $2,$(__ndk_modules.$1.CPPFLAGS)))\ + $(eval __ndk_modules.$1.CXXFLAGS := $(filter-out $2,$(__ndk_modules.$1.CXXFLAGS)))\ + $(eval __ndk_modules.$1.ASMFLAGS := $(filter-out $2,$(__ndk_modules.$1.ASMFLAGS))) + +# Return true if a module's compiler flags enable rtti +# We just look at -frtti and -fno-rtti on the command-line +# and keep the last one of these flags. +module-flags-have-rtti = $(strip \ + $(filter -frtti,\ + $(lastword $(filter -frtti -fno-rtti,$(call module-get-c++-flags,$1)))\ + )\ + ) + +# Same with C++ exception support (i.e. -fexceptions and -fno-exceptions) +# +module-flags-have-exceptions = $(strip \ + $(filter -fexceptions,\ + $(lastword $(filter -fexceptions -fno-execeptions,$(call module-get-c++-flags,$1)))\ + )\ + ) + +# Handle the definition of LOCAL_CPP_FEATURES, i.e.: +# +# - If it is defined, check that it only contains valid values +# - If it is undefined, try to compute its value automatically by +# looking at the C++ compiler flags used to build the module +# +# After this, we remove all features flags from the module's command-line +# And add only the correct ones back in LOCAL_CPP_FLAGS +# +module-handle-c++-features = \ + $(if $(strip $(__ndk_modules.$1.CPP_FEATURES)),\ + $(eval __cxxbad := $(filter-out rtti exceptions,$(__ndk_modules.$1.CPP_FEATURES)))\ + $(if $(__cxxbad),\ + $(call __ndk_info,WARNING: Ignoring invalid values in LOCAL_CPP_FEATURES definition in $(__ndk_modules.$1.MAKEFILE): $(__cxxbad))\ + $(eval __ndk_modules.$1.CPP_FEATURES := $(strip $(filter-out $(__cxxbad),$(__ndk_modules.$1.CPP_FEATURES))))\ + )\ + ,\ + $(eval __ndk_modules.$1.CPP_FEATURES := $(strip \ + $(if $(call module-flags-have-rtti,$1),rtti) \ + $(if $(call module-flags-have-exceptions,$1),exceptions) \ + )) \ + )\ + $(call module-filter-out-compiler-flags,$1,-frtti -fno-rtti -fexceptions -fno-exceptions)\ + +# Returns true if a module or its dependencies have specific C++ features +# (i.e. RTTI or Exceptions) +# +# $1: module name +# $2: list of features (e.g. 'rtti' or 'exceptions') +# +module-has-c++-features = $(strip \ + $(eval __cxxdeps := $(call module-get-all-dependencies,$1))\ + $(eval __cxxflags := $(foreach __cxxdep,$(__cxxdeps),$(__ndk_modules.$(__cxxdep).CPP_FEATURES)))\ + $(if $(filter $2,$(__cxxflags)),true,)\ + ) + +# Returns a non-empty string if the module should be linked with clang++ rather +# than clang. +# +# A module should use clang++ iff it has C++ sources itself or if it depends on +# a static library with C++ sources. We do not need to use clang++ for shared +# library dependencies. +module_needs_clangxx = $(strip \ + $(call module-has-c++-sources,$1)\ + $(foreach __dep,$(call module-get-all-dependencies,$1),\ + $(if $(call module-is-static-library,$(__dep)),\ + $(call module-has-c++-sources,$(__dep))\ + )\ + )\ +) + +# ============================================================================= +# +# Utility functions +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Function : pretty-dir +# Arguments: 1: path +# Returns : Remove NDK_PROJECT_PATH prefix from a given path. This can be +# used to perform pretty-printing for logs. +# ----------------------------------------------------------------------------- +pretty-dir = $(patsubst $(NDK_ROOT)/%,/%,\ + $(patsubst $(NDK_PROJECT_PATH)/%,%,$1)) + +# Note: NDK_PROJECT_PATH is typically defined after this test is run. +-test-pretty-dir = \ + $(eval NDK_PROJECT_PATH ?= .)\ + $(call test-expect,foo,$(call pretty-dir,foo))\ + $(call test-expect,foo,$(call pretty-dir,$(NDK_PROJECT_PATH)/foo))\ + $(call test-expect,foo/bar,$(call pretty-dir,$(NDK_PROJECT_PATH)/foo/bar))\ + $(call test-expect,/foo,$(call pretty-dir,$(NDK_ROOT)/foo))\ + $(call test-expect,/foo/bar,$(call pretty-dir,$(NDK_ROOT)/foo/bar)) + +# ----------------------------------------------------------------------------- +# Function : check-user-define +# Arguments: 1: name of variable that must be defined by the user +# 2: name of Makefile where the variable should be defined +# 3: name/description of the Makefile where the check is done, which +# must be included by $2 +# Returns : None +# ----------------------------------------------------------------------------- +check-user-define = $(if $(strip $($1)),,\ + $(call __ndk_error,Missing $1 before including $3 in $2)) + +# ----------------------------------------------------------------------------- +# This is used to check that LOCAL_MODULE is properly defined by an Android.mk +# file before including one of the $(BUILD_SHARED_LIBRARY), etc... files. +# +# Function : check-user-LOCAL_MODULE +# Arguments: 1: name/description of the included build Makefile where the +# check is done +# Returns : None +# Usage : $(call check-user-LOCAL_MODULE, BUILD_SHARED_LIBRARY) +# ----------------------------------------------------------------------------- +check-defined-LOCAL_MODULE = \ + $(call check-user-define,LOCAL_MODULE,$(local-makefile),$(1)) \ + $(if $(call seq,$(words $(LOCAL_MODULE)),1),,\ + $(call __ndk_info,LOCAL_MODULE definition in $(local-makefile) must not contain space)\ + $(call __ndk_error,Please correct error. Aborting)\ + ) + +# ----------------------------------------------------------------------------- +# This is used to check that LOCAL_MODULE_FILENAME, if defined, is correct. +# +# Function : check-user-LOCAL_MODULE_FILENAME +# Returns : None +# Usage : $(call check-user-LOCAL_MODULE_FILENAME) +# ----------------------------------------------------------------------------- +check-LOCAL_MODULE_FILENAME = \ + $(if $(strip $(LOCAL_MODULE_FILENAME)),\ + $(if $(call seq,$(words $(LOCAL_MODULE_FILENAME)),1),,\ + $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain spaces)\ + $(call __ndk_error,Plase correct error. Aborting)\ + )\ + $(if $(filter %$(TARGET_LIB_EXTENSION) %$(TARGET_SONAME_EXTENSION),$(LOCAL_MODULE_FILENAME)),\ + $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME should not include file extensions)\ + )\ + ) + +# ----------------------------------------------------------------------------- +# Function : handle-module-filename +# Arguments : 1: default file prefix +# 2: file suffix +# Returns : None +# Usage : $(call handle-module-filename,,) +# Rationale : To be used to check and or set the module's filename through +# the LOCAL_MODULE_FILENAME variable. +# ----------------------------------------------------------------------------- +handle-module-filename = $(eval $(call ev-handle-module-filename,$1,$2)) + +# +# Check that LOCAL_MODULE_FILENAME is properly defined +# - with one single item +# - without a library file extension +# - with no directory separators +# +define ev-check-module-filename +ifneq (1,$$(words $$(LOCAL_MODULE_FILENAME))) + $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain any space) + $$(call __ndk_error,Aborting) +endif +ifneq (,$$(filter %$$(TARGET_LIB_EXTENSION) %$$(TARGET_SONAME_EXTENSION),$$(LOCAL_MODULE_FILENAME))) + $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain a file extension) + $$(call __ndk_error,Aborting) +endif +ifneq (1,$$(words $$(subst /, ,$$(LOCAL_MODULE_FILENAME)))) + $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain directory separators) + $$(call __ndk_error,Aborting) +endif +endef + +# +# Check the definition of LOCAL_MODULE_FILENAME. If none exists, +# infer it from the LOCAL_MODULE name. +# +# $1: default file prefix +# $2: default file suffix +# +define ev-handle-module-filename +LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME)) +ifndef LOCAL_MODULE_FILENAME + LOCAL_MODULE_FILENAME := $1$$(LOCAL_MODULE) +endif +$$(eval $$(call ev-check-module-filename)) +LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$2 +endef + +handle-prebuilt-module-filename = $(eval $(call ev-handle-prebuilt-module-filename,$1)) + +# +# Check the definition of LOCAL_MODULE_FILENAME for a _prebuilt_ module. +# If none exists, infer it from $(LOCAL_SRC_FILES) +# +# $1: default file suffix +# +define ev-handle-prebuilt-module-filename +LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME)) +ifndef LOCAL_MODULE_FILENAME + LOCAL_MODULE_FILENAME := $$(notdir $(LOCAL_SRC_FILES)) + LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_LIB_EXTENSION)=%) + LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_SONAME_EXTENSION)=%) +endif +LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$1 +$$(eval $$(call ev-check-module-filename)) +endef + + +# ----------------------------------------------------------------------------- +# Function : handle-module-built +# Returns : None +# Usage : $(call handle-module-built) +# Rationale : To be used to automatically compute the location of the generated +# binary file, and the directory where to place its object files. +# ----------------------------------------------------------------------------- +handle-module-built = \ + $(eval LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(LOCAL_MODULE_FILENAME))\ + $(eval LOCAL_OBJS_DIR := $(TARGET_OBJS)/$(LOCAL_MODULE)) + +# ----------------------------------------------------------------------------- +# Compute the real path of a prebuilt file. +# +# Function : local-prebuilt-path +# Arguments: 1: prebuilt path (as listed in $(LOCAL_SRC_FILES)) +# Returns : full path. If $1 begins with a /, the path is considered +# absolute and returned as-is. Otherwise, $(LOCAL_PATH)/$1 is +# returned instead. +# Usage : $(call local-prebuilt-path,$(LOCAL_SRC_FILES)) +# ----------------------------------------------------------------------------- +local-prebuilt-path = $(call local-source-file-path,$1) + +# ----------------------------------------------------------------------------- +# This is used to strip any lib prefix from LOCAL_MODULE, then check that +# the corresponding module name is not already defined. +# +# Function : check-user-LOCAL_MODULE +# Arguments: 1: path of Android.mk where this LOCAL_MODULE is defined +# Returns : None +# Usage : $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE)) +# ----------------------------------------------------------------------------- +check-LOCAL_MODULE = \ + $(eval LOCAL_MODULE := $$(call strip-lib-prefix,$$(LOCAL_MODULE))) + +# ----------------------------------------------------------------------------- +# Macro : my-dir +# Returns : the directory of the current Makefile +# Usage : $(my-dir) +# ----------------------------------------------------------------------------- +my-dir = $(call parent-dir,$(lastword $(MAKEFILE_LIST))) + +# ----------------------------------------------------------------------------- +# Function : all-makefiles-under +# Arguments: 1: directory path +# Returns : a list of all makefiles immediately below some directory +# Usage : $(call all-makefiles-under, ) +# ----------------------------------------------------------------------------- +all-makefiles-under = $(wildcard $1/*/Android.mk) + +# ----------------------------------------------------------------------------- +# Macro : all-subdir-makefiles +# Returns : list of all makefiles in subdirectories of the current Makefile's +# location +# Usage : $(all-subdir-makefiles) +# ----------------------------------------------------------------------------- +all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir)) + +# ============================================================================= +# +# Source file tagging support. +# +# Each source file listed in LOCAL_SRC_FILES can have any number of +# 'tags' associated to it. A tag name must not contain space, and its +# usage can vary. +# +# For example, the 'debug' tag is used to sources that must be built in debug +# mode, the 'arm' tag is used for sources that must be built using the 32-bit +# instruction set on ARM platforms. Historically .neon was used to enable Neon +# for a given source file, but Neon was made the default in r21 and non-Neon +# mode is no longer supported in r24 so these tags are accepted but have no +# effect. A no_neon tag was supported as an implementation detail only; it could +# not be used by Android.mk files, and is no longer present. +# +# More tags might be introduced in the future. +# +# LOCAL_SRC_TAGS contains the list of all tags used (initially empty) +# LOCAL_SRC_FILES contains the list of all source files. +# LOCAL_SRC_TAG. contains the set of source file names tagged +# with +# LOCAL_SRC_FILES_TAGS. contains the set of tags for a given +# source file name +# +# Tags are processed by a toolchain-specific function (e.g. TARGET-compute-cflags) +# which will call various functions to compute source-file specific settings. +# These are currently stored as: +# +# LOCAL_SRC_FILES_TARGET_CFLAGS. contains the list of +# target-specific C compiler flags used to compile a given +# source file. This is set by the function TARGET-set-cflags +# defined in the toolchain's setup.mk script. +# +# LOCAL_SRC_FILES_TEXT. contains the 'text' that will be +# displayed along the label of the build output line. For example +# 'thumb' or 'arm ' with ARM-based toolchains. +# +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Macro : escape-colon-in-path +# Returns : replace colon in $1 with $(colon) +# Usage : $(escape-colon-in-path,) +# ----------------------------------------------------------------------------- +escape-colon-in-path = $(subst $(colon),$$(colon),$1) + +# ----------------------------------------------------------------------------- +# Macro : clear-all-src-tags +# Returns : remove all source file tags and associated data. +# Usage : $(clear-all-src-tags) +# ----------------------------------------------------------------------------- +clear-all-src-tags = \ +$(foreach __tag,$(LOCAL_SRC_TAGS), \ + $(eval LOCAL_SRC_TAG.$(__tag) := $(empty)) \ +) \ +$(foreach __src,$(LOCAL_SRC_FILES), \ + $(eval LOCAL_SRC_FILES_TAGS.$(call escape-colon-in-path,$(__src)) := $(empty)) \ + $(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) := $(empty)) \ + $(eval LOCAL_SRC_FILES_TEXT.$(call escape-colon-in-path,$(__src)) := $(empty)) \ +) \ +$(eval LOCAL_SRC_TAGS := $(empty_set)) + +# ----------------------------------------------------------------------------- +# Macro : tag-src-files +# Arguments: 1: list of source files to tag +# 2: tag name (must not contain space) +# Usage : $(call tag-src-files,,) +# Rationale: Add a tag to a list of source files +# ----------------------------------------------------------------------------- +tag-src-files = \ +$(eval LOCAL_SRC_TAGS := $(call set_insert,$2,$(LOCAL_SRC_TAGS))) \ +$(eval LOCAL_SRC_TAG.$2 := $(call set_union,$1,$(LOCAL_SRC_TAG.$2))) \ +$(foreach __src,$1, \ + $(eval LOCAL_SRC_FILES_TAGS.$(call escape-colon-in-path,$(__src)) += $2) \ +) + +# ----------------------------------------------------------------------------- +# Macro : get-src-files-with-tag +# Arguments: 1: tag name +# Usage : $(call get-src-files-with-tag,) +# Return : The list of source file names that have been tagged with +# ----------------------------------------------------------------------------- +get-src-files-with-tag = $(LOCAL_SRC_TAG.$1) + +# ----------------------------------------------------------------------------- +# Macro : get-src-files-without-tag +# Arguments: 1: tag name +# Usage : $(call get-src-files-without-tag,) +# Return : The list of source file names that have NOT been tagged with +# ----------------------------------------------------------------------------- +get-src-files-without-tag = $(filter-out $(LOCAL_SRC_TAG.$1),$(LOCAL_SRC_FILES)) + +# ----------------------------------------------------------------------------- +# Macro : set-src-files-target-cflags +# Arguments: 1: list of source files +# 2: list of compiler flags +# Usage : $(call set-src-files-target-cflags,,) +# Rationale: Set or replace the set of compiler flags that will be applied +# when building a given set of source files. This function should +# normally be called from the toolchain-specific function that +# computes all compiler flags for all source files. +# ----------------------------------------------------------------------------- +set-src-files-target-cflags = \ + $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) := $2)) + +# ----------------------------------------------------------------------------- +# Macro : add-src-files-target-cflags +# Arguments: 1: list of source files +# 2: list of compiler flags +# Usage : $(call add-src-files-target-cflags,,) +# Rationale: A variant of set-src-files-target-cflags that can be used +# to append, instead of replace, compiler flags for specific +# source files. +# ----------------------------------------------------------------------------- +add-src-files-target-cflags = \ + $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) += $2)) + +# ----------------------------------------------------------------------------- +# Macro : get-src-file-target-cflags +# Arguments: 1: single source file name +# Usage : $(call get-src-file-target-cflags,) +# Rationale: Return the set of target-specific compiler flags that must be +# applied to a given source file. These must be set prior to this +# call using set-src-files-target-cflags or add-src-files-target-cflags +# ----------------------------------------------------------------------------- +get-src-file-target-cflags = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$1) + +# ----------------------------------------------------------------------------- +# Macro : set-src-files-text +# Arguments: 1: list of source files +# 2: text +# Usage : $(call set-src-files-text,,) +# Rationale: Set or replace the 'text' associated to a set of source files. +# The text is a very short string that complements the build +# label. For example, it will be either 'thumb' or 'arm ' for +# ARM-based toolchains. This function must be called by the +# toolchain-specific functions that processes all source files. +# ----------------------------------------------------------------------------- +set-src-files-text = \ + $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TEXT.$(call escape-colon-in-path,$(__src)) := $2)) + +# ----------------------------------------------------------------------------- +# Macro : get-src-file-text +# Arguments: 1: single source file +# Usage : $(call get-src-file-text,) +# Rationale: Return the 'text' associated to a given source file when +# set-src-files-text was called. +# ----------------------------------------------------------------------------- +get-src-file-text = $(LOCAL_SRC_FILES_TEXT.$1) + +# This should only be called for debugging the source files tagging system +dump-src-file-tags = \ +$(info LOCAL_SRC_TAGS := $(LOCAL_SRC_TAGS)) \ +$(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES)) \ +$(foreach __tag,$(LOCAL_SRC_TAGS),$(info LOCAL_SRC_TAG.$(__tag) = $(LOCAL_SRC_TAG.$(__tag)))) \ +$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TAGS.$(__src) = $(LOCAL_SRC_FILES_TAGS.$(__src)))) \ +$(info WITH arm = $(call get-src-files-with-tag,arm)) \ +$(info WITHOUT arm = $(call get-src-files-without-tag,arm)) \ +$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src)))) \ +$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TEXT.$(__src) = $(LOCAL_SRC_FILES_TEXT.$(__src)))) \ + + +# ============================================================================= +# +# Application.mk support +# +# ============================================================================= + +# the list of variables that *must* be defined in Application.mk files +NDK_APP_VARS_REQUIRED := + +# the list of variables that *may* be defined in Application.mk files +NDK_APP_VARS_OPTIONAL := \ + APP_ABI \ + APP_ASFLAGS \ + APP_ASMFLAGS \ + APP_BUILD_SCRIPT \ + APP_CFLAGS \ + APP_CLANG_TIDY \ + APP_CLANG_TIDY_FLAGS \ + APP_CONLYFLAGS \ + APP_CPPFLAGS \ + APP_CXXFLAGS \ + APP_LDFLAGS \ + APP_MODULES \ + APP_OPTIM \ + APP_PLATFORM \ + APP_PROJECT_PATH \ + APP_SHORT_COMMANDS \ + APP_STL \ + APP_STRIP_MODE \ + APP_SUPPORT_FLEXIBLE_PAGE_SIZES \ + APP_THIN_ARCHIVE \ + APP_WEAK_API_DEFS \ + APP_WRAP_SH \ + +# NDK_ALL_ABIS is not configured yet. +NDK_APP_VARS_OPTIONAL += \ + APP_WRAP_SH_armeabi-v7a \ + APP_WRAP_SH_arm64-v8a \ + APP_WRAP_SH_riscv64 \ + APP_WRAP_SH_x86 \ + APP_WRAP_SH_x86_64 \ + +# the list of all variables that may appear in an Application.mk file +# or defined by the build scripts. +NDK_APP_VARS := \ + $(NDK_APP_VARS_REQUIRED) \ + $(NDK_APP_VARS_OPTIONAL) \ + APP_DEBUG \ + APP_DEBUGGABLE \ + APP_MANIFEST \ + +# ============================================================================= +# +# Android.mk support +# +# ============================================================================= + +# ============================================================================= +# +# Build commands support +# +# ============================================================================= + +get-object-name = $(strip \ + $(subst ../,__/,\ + $(subst :,_,\ + $(eval __obj := $1)\ + $(foreach __ext,.c .s .S .asm $(LOCAL_CPP_EXTENSION),\ + $(eval __obj := $(__obj:%$(__ext)=%$(TARGET_OBJ_EXTENSION)))\ + )\ + $(__obj)\ + ))) + +-test-get-object-name = \ + $(eval TARGET_OBJ_EXTENSION=.o)\ + $(eval LOCAL_CPP_EXTENSION ?= .cpp)\ + $(call test-expect,foo.o,$(call get-object-name,foo.c))\ + $(call test-expect,bar.o,$(call get-object-name,bar.s))\ + $(call test-expect,zoo.o,$(call get-object-name,zoo.S))\ + $(call test-expect,tot.o,$(call get-object-name,tot.cpp))\ + $(call test-expect,goo.o,$(call get-object-name,goo.asm)) + +# ----------------------------------------------------------------------------- +# Macro : hide +# Returns : nothing +# Usage : $(hide) +# Rationale: To be used as a prefix for Make build commands to hide them +# by default during the build. To show them, set V=1 in your +# environment or command-line. +# +# For example: +# +# foo.o: foo.c +# -->|$(hide) +# +# Where '-->|' stands for a single tab character. +# +# ----------------------------------------------------------------------------- +ifeq ($(V),1) +hide = $(empty) +else +hide = @ +endif + + +# ----------------------------------------------------------------------------- +# Function : local-source-file-path +# Parameters: $1: source file (as listed in LOCAL_SRC_FILES) +# Returns : full source file path of $1 +# Usage : $(call local-source-file-path,$1) +# Rationale : Used to compute the full path of a source listed in +# LOCAL_SRC_FILES. If it is an absolute path, then this +# returns the input, otherwise, prepends $(LOCAL_PATH)/ +# to the result. +# ----------------------------------------------------------------------------- +local-source-file-path = $(if $(call host-path-is-absolute,$1),$1,$(LOCAL_PATH)/$1) + +# This assumes that many variables have been pre-defined: +# _SRC: source file +# _OBJ: destination file +# _CC: 'compiler' command +# _FLAGS: 'compiler' flags +# _TEXT: Display text (e.g. "Compile++ thumb", must be EXACTLY 15 chars long) +# +# The output object is removed before the compile step as a fix for +# https://github.com/android-ndk/ndk/issues/603. tl;dr: Object files may not +# necessarily be removed when compilation fails. .DELETE_ON_ERROR may not help +# here because that only removes the output if the output changes. +define ev-build-file +$$(_OBJ): PRIVATE_ABI := $$(TARGET_ARCH_ABI) +$$(_OBJ): PRIVATE_SRC := $$(_SRC) +$$(_OBJ): PRIVATE_OBJ := $$(_OBJ) +$$(_OBJ): PRIVATE_DEPS := $$(call host-path,$$(_OBJ).d) +$$(_OBJ): PRIVATE_MODULE := $$(LOCAL_MODULE) +$$(_OBJ): PRIVATE_TEXT := $$(_TEXT) +$$(_OBJ): PRIVATE_CC := $$(_CC) +$$(_OBJ): PRIVATE_CFLAGS := $$(_FLAGS) + +ifeq ($$(LOCAL_SHORT_COMMANDS),true) +_OPTIONS_LISTFILE := $$(_OBJ).cflags +$$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE)) +$$(_OBJ): PRIVATE_CFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE)) +$$(_OBJ): $$(_OPTIONS_LISTFILE) +endif + +$$(call generate-file-dir,$$(_OBJ)) +$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) + $$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))" + $$(hide) $$(call host-rm,$$(call host-path,$$(PRIVATE_OBJ))) + $$(hide) $$(PRIVATE_CC) -MMD -MP -MF $$(PRIVATE_DEPS) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) + +_JSON_INTERMEDIATE := $$(_OBJ).commands.json + +_COMPILE_COMMAND := \ + $$(_CC) $$(_FLAGS) \ + $$(call host-path,$$(_SRC)) \ + -o $$(call host-path,$$(_OBJ)) \ + +_COMPILE_COMMAND_ARG := $$(_COMPILE_COMMAND) + +ifeq ($$(LOCAL_SHORT_COMMANDS),true) +_SUB_COMMANDS_LIST_FILE := $$(_OBJ).commands.list +$$(call generate-list-file,$$(_COMPILE_COMMAND),$$(_SUB_COMMANDS_LIST_FILE)) +$$(_JSON_INTERMEDIATE): $$(_SUB_COMMANDS_LIST_FILE) +_COMPILE_COMMAND_ARG := --command-file "$$(_SUB_COMMANDS_LIST_FILE)" +endif + +$$(call generate-file-dir,$$(_JSON_INTERMEDIATE)) +$$(_JSON_INTERMEDIATE): PRIVATE_CC := $$(_CC) +$$(_JSON_INTERMEDIATE): PRIVATE_SRC := $$(_SRC) +$$(_JSON_INTERMEDIATE): PRIVATE_OBJ := $$(_OBJ) +$$(_JSON_INTERMEDIATE): PRIVATE_CFLAGS := $$(_FLAGS) +$$(_JSON_INTERMEDIATE): PRIVATE_COMPILE_COMMAND_ARG := $$(_COMPILE_COMMAND_ARG) + +$$(_JSON_INTERMEDIATE): $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) + $$(hide) $$(HOST_PYTHON) $$(BUILD_PY)/dump_compile_commands.py \ + -o $$@ \ + --directory "$$(CURDIR)" \ + --file "$$(call host-path,$$(PRIVATE_SRC))" \ + --object-file "$$(PRIVATE_OBJ)" \ + $$(PRIVATE_COMPILE_COMMAND_ARG) + +$$(COMPILE_COMMANDS_JSON): $$(_JSON_INTERMEDIATE) +sub_commands_json += $$(_JSON_INTERMEDIATE) +endef + +# This assumes the same things than ev-build-file, but will handle +# the definition of LOCAL_FILTER_ASM as well. +define ev-build-source-file +LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ)) +ifndef LOCAL_FILTER_ASM + # Trivial case: Directly generate an object file + $$(eval $$(call ev-build-file)) +else + # This is where things get hairy, we first transform + # the source into an assembler file, send it to the + # filter, then generate a final object file from it. + # + + # First, remember the original settings and compute + # the location of our temporary files. + # + _ORG_SRC := $$(_SRC) + _ORG_OBJ := $$(_OBJ) + _ORG_FLAGS := $$(_FLAGS) + _ORG_TEXT := $$(_TEXT) + + _OBJ_ASM_ORIGINAL := $$(patsubst %$$(TARGET_OBJ_EXTENSION),%.s,$$(_ORG_OBJ)) + _OBJ_ASM_FILTERED := $$(patsubst %$$(TARGET_OBJ_EXTENSION),%.filtered.s,$$(_ORG_OBJ)) + + # If the source file is a plain assembler file, we're going to + # use it directly in our filter. + ifneq (,$$(filter %.s,$$(_SRC))) + _OBJ_ASM_ORIGINAL := $$(_SRC) + endif + + #$$(info SRC=$$(_SRC) OBJ=$$(_OBJ) OBJ_ORIGINAL=$$(_OBJ_ASM_ORIGINAL) OBJ_FILTERED=$$(_OBJ_ASM_FILTERED)) + + # We need to transform the source into an assembly file, instead of + # an object. The proper way to do that depends on the file extension. + # + # For C and C++ source files, simply replace the -c by an -S in the + # compilation command (this forces the compiler to generate an + # assembly file). + # + # For assembler templates (which end in .S), replace the -c with -E + # to send it to the preprocessor instead. + # + # Don't do anything for plain assembly files (which end in .s) + # + ifeq (,$$(filter %.s,$$(_SRC))) + _OBJ := $$(_OBJ_ASM_ORIGINAL) + ifneq (,$$(filter %.S,$$(_SRC))) + _FLAGS := $$(patsubst -c,-E,$$(_ORG_FLAGS)) + else + _FLAGS := $$(patsubst -c,-S,$$(_ORG_FLAGS)) + endif + $$(eval $$(call ev-build-file)) + endif + + # Next, process the assembly file with the filter + $$(_OBJ_ASM_FILTERED): PRIVATE_ABI := $$(TARGET_ARCH_ABI) + $$(_OBJ_ASM_FILTERED): PRIVATE_SRC := $$(_OBJ_ASM_ORIGINAL) + $$(_OBJ_ASM_FILTERED): PRIVATE_DST := $$(_OBJ_ASM_FILTERED) + $$(_OBJ_ASM_FILTERED): PRIVATE_FILTER := $$(LOCAL_FILTER_ASM) + $$(_OBJ_ASM_FILTERED): PRIVATE_MODULE := $$(LOCAL_MODULE) + $$(_OBJ_ASM_FILTERED): $$(_OBJ_ASM_ORIGINAL) + $$(call host-echo-build-step,$$(PRIVATE_ABI),AsmFilter) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))" + $$(hide) $$(PRIVATE_FILTER) $$(PRIVATE_SRC) $$(PRIVATE_DST) + + # Then, generate the final object, we need to keep assembler-specific + # flags which look like -Wa,