1enable_language(C)
2enable_language(CXX)
3
4if(NOT ANDROID)
5  message(SEND_ERROR "CMake variable 'ANDROID' is not set to a true value.")
6endif()
7
8set(files
9  "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ar${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
10  )
11if(NOT CMAKE_ANDROID_NDK_VERSION VERSION_GREATER_EQUAL 22)
12  list(APPEND files
13    "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ld${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
14    )
15endif()
16if(NOT CMAKE_ANDROID_NDK_VERSION VERSION_GREATER_EQUAL 19)
17  list(APPEND files
18    "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}"
19    "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}g++${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
20    )
21endif()
22foreach(f IN LISTS files)
23  if(NOT EXISTS "${f}")
24    message(SEND_ERROR "Expected file does not exist:\n \"${f}\"")
25  endif()
26endforeach()
27
28string(APPEND CMAKE_C_FLAGS " -Werror -Wno-attributes")
29string(APPEND CMAKE_CXX_FLAGS " -Werror -Wno-attributes")
30string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-no-undefined")
31
32if(CMAKE_ANDROID_NDK)
33  if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION)
34    message(SEND_ERROR "CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION is not set!")
35  elseif(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION MATCHES "^clang")
36    add_definitions(-DCOMPILER_IS_CLANG)
37  elseif(NOT "${CMAKE_C_COMPILER}" MATCHES "toolchains/[^/]+-${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}/prebuilt")
38    message(SEND_ERROR "CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION is\n"
39      "  ${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}\n"
40      "which does not appear in CMAKE_C_COMPILER:\n"
41      "  ${CMAKE_C_COMPILER}")
42  endif()
43  if(NOT CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG)
44    message(SEND_ERROR "CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG is not set!")
45  elseif(NOT "${CMAKE_C_COMPILER}" MATCHES "prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin")
46    message(SEND_ERROR "CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG is\n"
47      "  ${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}\n"
48      "which does not appear in CMAKE_C_COMPILER:\n"
49      "  ${CMAKE_C_COMPILER}")
50  endif()
51elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
52  execute_process(
53    COMMAND ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}/bin/clang --version
54    OUTPUT_VARIABLE _out
55    ERROR_VARIABLE _err
56    RESULT_VARIABLE _res
57    )
58  if(_res EQUAL 0)
59    add_definitions(-DCOMPILER_IS_CLANG)
60  endif()
61endif()
62
63set(gcc ${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX})
64if(EXISTS "${gcc}")
65  execute_process(
66    COMMAND "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}" -dumpmachine
67    OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE
68    ERROR_VARIABLE _err
69    RESULT_VARIABLE _res
70    )
71  if(NOT _res EQUAL 0)
72    message(SEND_ERROR "Failed to run 'gcc -dumpmachine':\n ${_res}")
73  endif()
74  string(REPLACE "--" "-" _out_check "${_out}")
75  if(NOT _out_check STREQUAL "${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
76      AND NOT (_out STREQUAL "arm--linux-android" AND CMAKE_C_ANDROID_TOOLCHAIN_MACHINE STREQUAL "arm-linux-androideabi"))
77    message(SEND_ERROR "'gcc -dumpmachine' produced:\n"
78      " ${_out}\n"
79      "which does not match CMAKE_C_ANDROID_TOOLCHAIN_MACHINE:\n"
80      " ${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
81      )
82  endif()
83endif()
84
85if(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
86  add_definitions(-DSTL_NONE)
87elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "system")
88  add_definitions(-DSTL_SYSTEM)
89elseif(CMAKE_ANDROID_STL_TYPE MATCHES [[^gabi\+\+]])
90  add_definitions(-DSTL_GABI)
91elseif(CMAKE_ANDROID_STL_TYPE MATCHES [[^stlport]])
92  add_definitions(-DSTL_STLPORT)
93endif()
94
95string(REPLACE "-" "_" abi "${CMAKE_ANDROID_ARCH_ABI}")
96add_definitions(-DABI_${abi})
97add_definitions(-DAPI_LEVEL=${CMAKE_SYSTEM_VERSION})
98if(CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi")
99  add_definitions(-DARM_MODE=${CMAKE_ANDROID_ARM_MODE})
100  message(STATUS "CMAKE_ANDROID_ARM_MODE=${CMAKE_ANDROID_ARM_MODE}")
101endif()
102if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
103  add_definitions(-DARM_NEON=${CMAKE_ANDROID_ARM_NEON})
104  message(STATUS "CMAKE_ANDROID_ARM_NEON=${CMAKE_ANDROID_ARM_NEON}")
105endif()
106add_executable(android_c android.c)
107add_executable(android_cxx android.cxx)
108add_library(android_cxx_lib SHARED android_lib.cxx)
109
110set(objdump "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}objdump${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}")
111if(NOT EXISTS "${objdump}")
112  message(FATAL_ERROR "Expected tool missing:\n  ${objdump}")
113endif()
114
115if(NOT CMAKE_ANDROID_STL_TYPE MATCHES "^(system|stlport_static|stlport_shared)$")
116  foreach(tgt android_cxx android_cxx_lib)
117    add_custom_command(TARGET ${tgt} POST_BUILD
118      COMMAND ${CMAKE_COMMAND}
119        -Dobjdump=${objdump}
120        -Dfile=$<TARGET_FILE:${tgt}>
121        -P ${CMAKE_CURRENT_SOURCE_DIR}/check_binary.cmake
122      )
123  endforeach()
124endif()
125
126# Test that an explicit /usr/include is ignored in favor of
127# appearing as a standard include directory at the end.
128set(sysinc_dirs)
129if(CMAKE_ANDROID_NDK)
130  if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
131    list(APPEND sysinc_dirs ${CMAKE_SYSROOT_COMPILE}/usr/include)
132  else()
133    list(APPEND sysinc_dirs ${CMAKE_SYSROOT}/usr/include)
134  endif()
135endif()
136list(APPEND sysinc_dirs ${CMAKE_CURRENT_SOURCE_DIR}/sysinc)
137add_executable(android_sysinc_c android_sysinc.c)
138target_include_directories(android_sysinc_c SYSTEM PRIVATE ${sysinc_dirs})
139add_executable(android_sysinc_cxx android_sysinc.cxx)
140target_include_directories(android_sysinc_cxx SYSTEM PRIVATE ${sysinc_dirs})
141